Gitweb:
https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=450f272b31ef95bd7cb...
Commit: 450f272b31ef95bd7cb61812d9ef0525c7c1c341
Parent: ff3945777ba6cb093174b99a9870df2494f4c29b
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jul 20 12:48:36 2020 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Oct 1 12:00:09 2020 -0500
devices: support printing the filter that rejects a device
Use of this new message function needs to be added
to various commands to improve the output.
---
lib/cache/lvmcache.c | 48 ++++++++++++++++++++++++++++++++++++++++
lib/cache/lvmcache.h | 3 +++
lib/device/dev-cache.c | 13 ++---------
lib/device/dev-cache.h | 3 ++-
lib/device/device.h | 1 +
lib/filters/filter-fwraid.c | 4 ++++
lib/filters/filter-internal.c | 3 +++
lib/filters/filter-md.c | 4 ++++
lib/filters/filter-mpath.c | 3 +++
lib/filters/filter-partitioned.c | 3 +++
lib/filters/filter-regex.c | 6 ++++-
lib/filters/filter-signature.c | 5 +++++
lib/filters/filter-sysfs.c | 3 +++
lib/filters/filter-type.c | 3 +++
lib/filters/filter-usable.c | 9 +++++++-
lib/filters/filter.h | 12 ++++++++++
tools/pvck.c | 6 ++---
17 files changed, 112 insertions(+), 17 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 9716eccaf..a2fa0e3fb 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -23,6 +23,7 @@
#include "lib/mm/memlock.h"
#include "lib/format_text/format-text.h"
#include "lib/config/config.h"
+#include "lib/filters/filter.h"
/* One per device */
struct lvmcache_info {
@@ -2683,3 +2684,50 @@ bool lvmcache_is_outdated_dev(struct cmd_context *cmd,
return false;
}
+
+const char *dev_filtered_reason(struct device *dev)
+{
+ if (dev->filtered_flags & DEV_FILTERED_REGEX)
+ return "device is rejected by filter config";
+ if (dev->filtered_flags & DEV_FILTERED_INTERNAL)
+ return "device is restricted internally";
+ if (dev->filtered_flags & DEV_FILTERED_MD_COMPONENT)
+ return "device is an md component";
+ if (dev->filtered_flags & DEV_FILTERED_MPATH_COMPONENT)
+ return "device is a multipath component";
+ if (dev->filtered_flags & DEV_FILTERED_PARTITIONED)
+ return "device is partitioned";
+ if (dev->filtered_flags & DEV_FILTERED_SIGNATURE)
+ return "device has a signature";
+ if (dev->filtered_flags & DEV_FILTERED_SYSFS)
+ return "device is missing sysfs info";
+ if (dev->filtered_flags & DEV_FILTERED_DEVTYPE)
+ return "device type is unknown";
+ if (dev->filtered_flags & DEV_FILTERED_MINSIZE)
+ return "device is too small (pv_min_size)";
+ if (dev->filtered_flags & DEV_FILTERED_UNUSABLE)
+ return "device is not in a usable state";
+
+ /* flag has not been added here */
+ if (dev->filtered_flags)
+ return "device is filtered";
+
+ return "device cannot be used";
+}
+
+const char *devname_error_reason(const char *devname)
+{
+ struct device *dev;
+
+ if ((dev = dev_hash_get(devname))) {
+ if (dev->filtered_flags)
+ return dev_filtered_reason(dev);
+ if (lvmcache_dev_is_unused_duplicate(dev))
+ return "device is a duplicate";
+ /* Avoid this case by adding by adding other more descriptive checks above. */
+ return "device cannot be used";
+ }
+
+ return "device not found";
+}
+
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 1ee99b534..7a718cad8 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -217,4 +217,7 @@ void lvmcache_get_mdas(struct cmd_context *cmd,
const char *vgname, const char *vgid,
struct dm_list *mda_list);
+const char *dev_filtered_reason(struct device *dev);
+const char *devname_error_reason(const char *devname);
+
#endif
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 84d65c4db..d5f18ff45 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1423,17 +1423,9 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
return dev_name(dev);
}
-/* Provide a custom reason when a device is ignored */
-const char *dev_cache_filtered_reason(const char *name)
+struct device *dev_hash_get(const char *name)
{
- const char *reason = "not found";
- struct device *d = (struct device *) dm_hash_lookup(_cache.names, name);
-
- if (d)
- /* FIXME Record which filter caused the exclusion */
- reason = "excluded by a filter";
-
- return reason;
+ return (struct device *) dm_hash_lookup(_cache.names, name);
}
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter
*f)
@@ -1657,4 +1649,3 @@ bool dev_cache_has_md_with_end_superblock(struct dev_types *dt)
return false;
}
-
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index 46c86c27a..533e4561d 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -54,10 +54,11 @@ int dev_cache_has_scanned(void);
int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter
*f);
-const char *dev_cache_filtered_reason(const char *name);
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t device, struct
dev_filter *f, int *filtered);
+struct device *dev_hash_get(const char *name);
+
void dev_set_preferred_name(struct dm_str_list *sl, struct device *dev);
/*
diff --git a/lib/device/device.h b/lib/device/device.h
index 2706f28e1..a58bff8e3 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -73,6 +73,7 @@ struct device {
int bcache_fd;
int bcache_di;
uint32_t flags;
+ uint32_t filtered_flags;
unsigned size_seqno;
uint64_t size;
uint64_t end;
diff --git a/lib/filters/filter-fwraid.c b/lib/filters/filter-fwraid.c
index 992eba8b8..f82f87397 100644
--- a/lib/filters/filter-fwraid.c
+++ b/lib/filters/filter-fwraid.c
@@ -69,6 +69,8 @@ static int _ignore_fwraid(struct cmd_context *cmd, struct dev_filter *f
__attrib
{
int ret;
+ dev->filtered_flags &= ~DEV_FILTERED_FWRAID;
+
if (!fwraid_filtering())
return 1;
@@ -80,12 +82,14 @@ static int _ignore_fwraid(struct cmd_context *cmd, struct dev_filter
*f __attrib
else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle);
+ dev->filtered_flags |= DEV_FILTERED_FWRAID;
return 0;
}
if (ret < 0) {
log_debug_devs("%s: Skipping: error in firmware RAID component detection",
dev_name(dev));
+ dev->filtered_flags |= DEV_FILTERED_FWRAID;
return 0;
}
diff --git a/lib/filters/filter-internal.c b/lib/filters/filter-internal.c
index c10e8105f..a49c07e53 100644
--- a/lib/filters/filter-internal.c
+++ b/lib/filters/filter-internal.c
@@ -42,6 +42,8 @@ static int _passes_internal(struct cmd_context *cmd, struct dev_filter
*f __attr
{
struct device_list *devl;
+ dev->filtered_flags &= ~DEV_FILTERED_INTERNAL;
+
if (!internal_filtering())
return 1;
@@ -50,6 +52,7 @@ static int _passes_internal(struct cmd_context *cmd, struct dev_filter
*f __attr
return 1;
}
+ dev->filtered_flags |= DEV_FILTERED_INTERNAL;
log_debug_devs("%s: Skipping for internal filtering.", dev_name(dev));
return 0;
}
diff --git a/lib/filters/filter-md.c b/lib/filters/filter-md.c
index 28903be3f..b530e407d 100644
--- a/lib/filters/filter-md.c
+++ b/lib/filters/filter-md.c
@@ -86,6 +86,8 @@ static int _passes_md_filter(struct cmd_context *cmd, struct dev_filter
*f __att
{
int ret;
+ dev->filtered_flags &= ~DEV_FILTERED_MD_COMPONENT;
+
/*
* When md_component_dectection=0, don't even try to skip md
* components.
@@ -112,12 +114,14 @@ static int _passes_md_filter(struct cmd_context *cmd, struct
dev_filter *f __att
else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle);
+ dev->filtered_flags |= DEV_FILTERED_MD_COMPONENT;
return 0;
}
if (ret < 0) {
log_debug_devs("%s: Skipping: error in md component detection",
dev_name(dev));
+ dev->filtered_flags |= DEV_FILTERED_MD_COMPONENT;
return 0;
}
diff --git a/lib/filters/filter-mpath.c b/lib/filters/filter-mpath.c
index 53a767c5e..85d1625f6 100644
--- a/lib/filters/filter-mpath.c
+++ b/lib/filters/filter-mpath.c
@@ -274,12 +274,15 @@ static int _dev_is_mpath(struct dev_filter *f, struct device *dev)
static int _ignore_mpath(struct cmd_context *cmd, struct dev_filter *f, struct device
*dev, const char *use_filter_name)
{
+ dev->filtered_flags &= ~DEV_FILTERED_MPATH_COMPONENT;
+
if (_dev_is_mpath(f, dev) == 1) {
if (dev->ext.src == DEV_EXT_NONE)
log_debug_devs(MSG_SKIPPING, dev_name(dev));
else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle);
+ dev->filtered_flags |= DEV_FILTERED_MPATH_COMPONENT;
return 0;
}
diff --git a/lib/filters/filter-partitioned.c b/lib/filters/filter-partitioned.c
index 1a700543c..22194f81c 100644
--- a/lib/filters/filter-partitioned.c
+++ b/lib/filters/filter-partitioned.c
@@ -24,6 +24,8 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct
dev_filter
struct dev_types *dt = (struct dev_types *) f->private;
int ret;
+ dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED;
+
ret = dev_is_partitioned(dt, dev);
if (ret == -EAGAIN) {
@@ -39,6 +41,7 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct
dev_filter
else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle);
+ dev->filtered_flags |= DEV_FILTERED_PARTITIONED;
return 0;
}
diff --git a/lib/filters/filter-regex.c b/lib/filters/filter-regex.c
index e439b36b5..7575981af 100644
--- a/lib/filters/filter-regex.c
+++ b/lib/filters/filter-regex.c
@@ -151,6 +151,8 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f,
struct devic
struct rfilter *rf = (struct rfilter *) f->private;
struct dm_str_list *sl;
+ dev->filtered_flags &= ~DEV_FILTERED_REGEX;
+
dm_list_iterate_items(sl, &dev->aliases) {
m = dm_regex_match(rf->engine, sl->str);
@@ -168,8 +170,10 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f,
struct devic
first = 0;
}
- if (rejected)
+ if (rejected) {
+ dev->filtered_flags |= DEV_FILTERED_REGEX;
log_debug_devs("%s: Skipping (regex)", dev_name(dev));
+ }
/*
* pass everything that doesn't match
diff --git a/lib/filters/filter-signature.c b/lib/filters/filter-signature.c
index 6a81203a9..f32bb2450 100644
--- a/lib/filters/filter-signature.c
+++ b/lib/filters/filter-signature.c
@@ -27,6 +27,8 @@ static int _ignore_signature(struct cmd_context *cmd, struct dev_filter
*f __att
char buf[BUFSIZE];
int ret = 0;
+ dev->filtered_flags &= ~DEV_FILTERED_SIGNATURE;
+
if (!scan_bcache) {
/* let pass, call again after scan */
log_debug_devs("filter signature deferred %s", dev_name(dev));
@@ -40,18 +42,21 @@ static int _ignore_signature(struct cmd_context *cmd, struct
dev_filter *f __att
log_debug_devs("%s: Skipping: error in signature detection",
dev_name(dev));
ret = 0;
+ dev->filtered_flags |= DEV_FILTERED_SIGNATURE;
goto out;
}
if (dev_is_lvm1(dev, buf, BUFSIZE)) {
log_debug_devs("%s: Skipping lvm1 device", dev_name(dev));
ret = 0;
+ dev->filtered_flags |= DEV_FILTERED_SIGNATURE;
goto out;
}
if (dev_is_pool(dev, buf, BUFSIZE)) {
log_debug_devs("%s: Skipping gfs-pool device", dev_name(dev));
ret = 0;
+ dev->filtered_flags |= DEV_FILTERED_SIGNATURE;
goto out;
}
ret = 1;
diff --git a/lib/filters/filter-sysfs.c b/lib/filters/filter-sysfs.c
index ebca8087c..b2ac63d7b 100644
--- a/lib/filters/filter-sysfs.c
+++ b/lib/filters/filter-sysfs.c
@@ -264,6 +264,8 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f,
struct devic
{
struct dev_set *ds = (struct dev_set *) f->private;
+ dev->filtered_flags &= ~DEV_FILTERED_SYSFS;
+
if (!ds->initialised)
_init_devs(ds);
@@ -273,6 +275,7 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f,
struct devic
if (!_set_lookup(ds, dev->dev)) {
log_debug_devs("%s: Skipping (sysfs)", dev_name(dev));
+ dev->filtered_flags |= DEV_FILTERED_SYSFS;
return 0;
}
diff --git a/lib/filters/filter-type.c b/lib/filters/filter-type.c
index 1d083707f..bfb8edd34 100644
--- a/lib/filters/filter-type.c
+++ b/lib/filters/filter-type.c
@@ -22,10 +22,13 @@ static int _passes_lvm_type_device_filter(struct cmd_context *cmd,
struct dev_fi
struct dev_types *dt = (struct dev_types *) f->private;
const char *name = dev_name(dev);
+ dev->filtered_flags &= ~DEV_FILTERED_DEVTYPE;
+
/* Is this a recognised device type? */
if (!dt->dev_type_array[MAJOR(dev->dev)].max_partitions) {
log_debug_devs("%s: Skipping: Unrecognised LVM device type %"
PRIu64, name, (uint64_t) MAJOR(dev->dev));
+ dev->filtered_flags |= DEV_FILTERED_DEVTYPE;
return 0;
}
diff --git a/lib/filters/filter-usable.c b/lib/filters/filter-usable.c
index b3ff65075..8a5b0d828 100644
--- a/lib/filters/filter-usable.c
+++ b/lib/filters/filter-usable.c
@@ -113,6 +113,9 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct
dev_filter *f,
struct dev_usable_check_params ucp = {0};
int r = 1;
+ dev->filtered_flags &= ~DEV_FILTERED_MINSIZE;
+ dev->filtered_flags &= ~DEV_FILTERED_UNUSABLE;
+
/* further checks are done on dm devices only */
if (dm_is_dm_major(MAJOR(dev->dev))) {
switch (mode) {
@@ -142,8 +145,10 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct
dev_filter *f,
break;
}
- if (!(r = device_is_usable(dev, ucp)))
+ if (!(r = device_is_usable(dev, ucp))) {
+ dev->filtered_flags |= DEV_FILTERED_UNUSABLE;
log_debug_devs("%s: Skipping unusable device.", dev_name(dev));
+ }
}
if (r) {
@@ -153,6 +158,8 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct
dev_filter *f,
/* fall through */
case FILTER_MODE_PRE_LVMETAD:
r = _check_pv_min_size(dev);
+ if (!r)
+ dev->filtered_flags |= DEV_FILTERED_MINSIZE;
break;
case FILTER_MODE_POST_LVMETAD:
/* nothing to do here */
diff --git a/lib/filters/filter.h b/lib/filters/filter.h
index 7333cfe3c..bfd045be5 100644
--- a/lib/filters/filter.h
+++ b/lib/filters/filter.h
@@ -52,4 +52,16 @@ typedef enum {
} filter_mode_t;
struct dev_filter *usable_filter_create(struct cmd_context *cmd, struct dev_types *dt,
filter_mode_t mode);
+#define DEV_FILTERED_FWRAID 0x00000001
+#define DEV_FILTERED_INTERNAL 0x00000002
+#define DEV_FILTERED_MD_COMPONENT 0x00000004
+#define DEV_FILTERED_MPATH_COMPONENT 0x00000008
+#define DEV_FILTERED_PARTITIONED 0x00000010
+#define DEV_FILTERED_REGEX 0x00000020
+#define DEV_FILTERED_SIGNATURE 0x00000040
+#define DEV_FILTERED_SYSFS 0x00000080
+#define DEV_FILTERED_DEVTYPE 0x00000100
+#define DEV_FILTERED_MINSIZE 0x00000200
+#define DEV_FILTERED_UNUSABLE 0x00000400
+
#endif /* _LVM_FILTER_H */
diff --git a/tools/pvck.c b/tools/pvck.c
index 39449af68..7ae4976e5 100644
--- a/tools/pvck.c
+++ b/tools/pvck.c
@@ -3040,7 +3040,7 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
clear_hint_file(cmd);
if (!(dev = dev_cache_get(cmd, pv_name, cmd->filter))) {
- log_error("No device found for %s %s.", pv_name,
dev_cache_filtered_reason(pv_name));
+ log_error("Cannot use %s: %s.", pv_name, devname_error_reason(pv_name));
return ECMD_FAILED;
}
}
@@ -3054,7 +3054,7 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
def = get_devicefile(pv_name);
if (!dev && !def) {
- log_error("No device found for %s %s.", pv_name,
dev_cache_filtered_reason(pv_name));
+ log_error("Cannot use %s: %s.", pv_name, devname_error_reason(pv_name));
return ECMD_FAILED;
}
}
@@ -3143,7 +3143,7 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
pv_name = argv[i];
if (!(dev = dev_cache_get(cmd, argv[i], cmd->filter))) {
- log_error("Device %s %s.", pv_name, dev_cache_filtered_reason(pv_name));
+ log_error("Cannot use %s: %s.", pv_name, devname_error_reason(pv_name));
continue;
}