1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-30 17:18:21 +03:00

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.
This commit is contained in:
David Teigland 2020-07-20 12:48:36 -05:00
parent ff3945777b
commit 450f272b31
17 changed files with 112 additions and 17 deletions

48
lib/cache/lvmcache.c vendored
View File

@ -23,6 +23,7 @@
#include "lib/mm/memlock.h" #include "lib/mm/memlock.h"
#include "lib/format_text/format-text.h" #include "lib/format_text/format-text.h"
#include "lib/config/config.h" #include "lib/config/config.h"
#include "lib/filters/filter.h"
/* One per device */ /* One per device */
struct lvmcache_info { struct lvmcache_info {
@ -2683,3 +2684,50 @@ bool lvmcache_is_outdated_dev(struct cmd_context *cmd,
return false; 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";
}

View File

@ -217,4 +217,7 @@ void lvmcache_get_mdas(struct cmd_context *cmd,
const char *vgname, const char *vgid, const char *vgname, const char *vgid,
struct dm_list *mda_list); struct dm_list *mda_list);
const char *dev_filtered_reason(struct device *dev);
const char *devname_error_reason(const char *devname);
#endif #endif

View File

@ -1423,17 +1423,9 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
return dev_name(dev); return dev_name(dev);
} }
/* Provide a custom reason when a device is ignored */ struct device *dev_hash_get(const char *name)
const char *dev_cache_filtered_reason(const char *name)
{ {
const char *reason = "not found"; return (struct device *) dm_hash_lookup(_cache.names, name);
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;
} }
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f) 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; return false;
} }

View File

@ -54,10 +54,11 @@ int dev_cache_has_scanned(void);
int dev_cache_add_dir(const char *path); int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f); 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_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); void dev_set_preferred_name(struct dm_str_list *sl, struct device *dev);
/* /*

View File

@ -73,6 +73,7 @@ struct device {
int bcache_fd; int bcache_fd;
int bcache_di; int bcache_di;
uint32_t flags; uint32_t flags;
uint32_t filtered_flags;
unsigned size_seqno; unsigned size_seqno;
uint64_t size; uint64_t size;
uint64_t end; uint64_t end;

View File

@ -69,6 +69,8 @@ static int _ignore_fwraid(struct cmd_context *cmd, struct dev_filter *f __attrib
{ {
int ret; int ret;
dev->filtered_flags &= ~DEV_FILTERED_FWRAID;
if (!fwraid_filtering()) if (!fwraid_filtering())
return 1; return 1;
@ -80,12 +82,14 @@ static int _ignore_fwraid(struct cmd_context *cmd, struct dev_filter *f __attrib
else else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev), log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle); dev_ext_name(dev), dev->ext.handle);
dev->filtered_flags |= DEV_FILTERED_FWRAID;
return 0; return 0;
} }
if (ret < 0) { if (ret < 0) {
log_debug_devs("%s: Skipping: error in firmware RAID component detection", log_debug_devs("%s: Skipping: error in firmware RAID component detection",
dev_name(dev)); dev_name(dev));
dev->filtered_flags |= DEV_FILTERED_FWRAID;
return 0; return 0;
} }

View File

@ -42,6 +42,8 @@ static int _passes_internal(struct cmd_context *cmd, struct dev_filter *f __attr
{ {
struct device_list *devl; struct device_list *devl;
dev->filtered_flags &= ~DEV_FILTERED_INTERNAL;
if (!internal_filtering()) if (!internal_filtering())
return 1; return 1;
@ -50,6 +52,7 @@ static int _passes_internal(struct cmd_context *cmd, struct dev_filter *f __attr
return 1; return 1;
} }
dev->filtered_flags |= DEV_FILTERED_INTERNAL;
log_debug_devs("%s: Skipping for internal filtering.", dev_name(dev)); log_debug_devs("%s: Skipping for internal filtering.", dev_name(dev));
return 0; return 0;
} }

View File

@ -86,6 +86,8 @@ static int _passes_md_filter(struct cmd_context *cmd, struct dev_filter *f __att
{ {
int ret; int ret;
dev->filtered_flags &= ~DEV_FILTERED_MD_COMPONENT;
/* /*
* When md_component_dectection=0, don't even try to skip md * When md_component_dectection=0, don't even try to skip md
* components. * components.
@ -112,12 +114,14 @@ static int _passes_md_filter(struct cmd_context *cmd, struct dev_filter *f __att
else else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev), log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle); dev_ext_name(dev), dev->ext.handle);
dev->filtered_flags |= DEV_FILTERED_MD_COMPONENT;
return 0; return 0;
} }
if (ret < 0) { if (ret < 0) {
log_debug_devs("%s: Skipping: error in md component detection", log_debug_devs("%s: Skipping: error in md component detection",
dev_name(dev)); dev_name(dev));
dev->filtered_flags |= DEV_FILTERED_MD_COMPONENT;
return 0; return 0;
} }

View File

@ -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) 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_is_mpath(f, dev) == 1) {
if (dev->ext.src == DEV_EXT_NONE) if (dev->ext.src == DEV_EXT_NONE)
log_debug_devs(MSG_SKIPPING, dev_name(dev)); log_debug_devs(MSG_SKIPPING, dev_name(dev));
else else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev), log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle); dev_ext_name(dev), dev->ext.handle);
dev->filtered_flags |= DEV_FILTERED_MPATH_COMPONENT;
return 0; return 0;
} }

View File

@ -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; struct dev_types *dt = (struct dev_types *) f->private;
int ret; int ret;
dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED;
ret = dev_is_partitioned(dt, dev); ret = dev_is_partitioned(dt, dev);
if (ret == -EAGAIN) { if (ret == -EAGAIN) {
@ -39,6 +41,7 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter
else else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev), log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle); dev_ext_name(dev), dev->ext.handle);
dev->filtered_flags |= DEV_FILTERED_PARTITIONED;
return 0; return 0;
} }

View File

@ -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 rfilter *rf = (struct rfilter *) f->private;
struct dm_str_list *sl; struct dm_str_list *sl;
dev->filtered_flags &= ~DEV_FILTERED_REGEX;
dm_list_iterate_items(sl, &dev->aliases) { dm_list_iterate_items(sl, &dev->aliases) {
m = dm_regex_match(rf->engine, sl->str); 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; first = 0;
} }
if (rejected) if (rejected) {
dev->filtered_flags |= DEV_FILTERED_REGEX;
log_debug_devs("%s: Skipping (regex)", dev_name(dev)); log_debug_devs("%s: Skipping (regex)", dev_name(dev));
}
/* /*
* pass everything that doesn't match * pass everything that doesn't match

View File

@ -27,6 +27,8 @@ static int _ignore_signature(struct cmd_context *cmd, struct dev_filter *f __att
char buf[BUFSIZE]; char buf[BUFSIZE];
int ret = 0; int ret = 0;
dev->filtered_flags &= ~DEV_FILTERED_SIGNATURE;
if (!scan_bcache) { if (!scan_bcache) {
/* let pass, call again after scan */ /* let pass, call again after scan */
log_debug_devs("filter signature deferred %s", dev_name(dev)); 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", log_debug_devs("%s: Skipping: error in signature detection",
dev_name(dev)); dev_name(dev));
ret = 0; ret = 0;
dev->filtered_flags |= DEV_FILTERED_SIGNATURE;
goto out; goto out;
} }
if (dev_is_lvm1(dev, buf, BUFSIZE)) { if (dev_is_lvm1(dev, buf, BUFSIZE)) {
log_debug_devs("%s: Skipping lvm1 device", dev_name(dev)); log_debug_devs("%s: Skipping lvm1 device", dev_name(dev));
ret = 0; ret = 0;
dev->filtered_flags |= DEV_FILTERED_SIGNATURE;
goto out; goto out;
} }
if (dev_is_pool(dev, buf, BUFSIZE)) { if (dev_is_pool(dev, buf, BUFSIZE)) {
log_debug_devs("%s: Skipping gfs-pool device", dev_name(dev)); log_debug_devs("%s: Skipping gfs-pool device", dev_name(dev));
ret = 0; ret = 0;
dev->filtered_flags |= DEV_FILTERED_SIGNATURE;
goto out; goto out;
} }
ret = 1; ret = 1;

View File

@ -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; struct dev_set *ds = (struct dev_set *) f->private;
dev->filtered_flags &= ~DEV_FILTERED_SYSFS;
if (!ds->initialised) if (!ds->initialised)
_init_devs(ds); _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)) { if (!_set_lookup(ds, dev->dev)) {
log_debug_devs("%s: Skipping (sysfs)", dev_name(dev)); log_debug_devs("%s: Skipping (sysfs)", dev_name(dev));
dev->filtered_flags |= DEV_FILTERED_SYSFS;
return 0; return 0;
} }

View File

@ -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; struct dev_types *dt = (struct dev_types *) f->private;
const char *name = dev_name(dev); const char *name = dev_name(dev);
dev->filtered_flags &= ~DEV_FILTERED_DEVTYPE;
/* Is this a recognised device type? */ /* Is this a recognised device type? */
if (!dt->dev_type_array[MAJOR(dev->dev)].max_partitions) { if (!dt->dev_type_array[MAJOR(dev->dev)].max_partitions) {
log_debug_devs("%s: Skipping: Unrecognised LVM device type %" log_debug_devs("%s: Skipping: Unrecognised LVM device type %"
PRIu64, name, (uint64_t) MAJOR(dev->dev)); PRIu64, name, (uint64_t) MAJOR(dev->dev));
dev->filtered_flags |= DEV_FILTERED_DEVTYPE;
return 0; return 0;
} }

View File

@ -113,6 +113,9 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct dev_filter *f,
struct dev_usable_check_params ucp = {0}; struct dev_usable_check_params ucp = {0};
int r = 1; int r = 1;
dev->filtered_flags &= ~DEV_FILTERED_MINSIZE;
dev->filtered_flags &= ~DEV_FILTERED_UNUSABLE;
/* further checks are done on dm devices only */ /* further checks are done on dm devices only */
if (dm_is_dm_major(MAJOR(dev->dev))) { if (dm_is_dm_major(MAJOR(dev->dev))) {
switch (mode) { switch (mode) {
@ -142,8 +145,10 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct dev_filter *f,
break; 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)); log_debug_devs("%s: Skipping unusable device.", dev_name(dev));
}
} }
if (r) { if (r) {
@ -153,6 +158,8 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct dev_filter *f,
/* fall through */ /* fall through */
case FILTER_MODE_PRE_LVMETAD: case FILTER_MODE_PRE_LVMETAD:
r = _check_pv_min_size(dev); r = _check_pv_min_size(dev);
if (!r)
dev->filtered_flags |= DEV_FILTERED_MINSIZE;
break; break;
case FILTER_MODE_POST_LVMETAD: case FILTER_MODE_POST_LVMETAD:
/* nothing to do here */ /* nothing to do here */

View File

@ -52,4 +52,16 @@ typedef enum {
} filter_mode_t; } filter_mode_t;
struct dev_filter *usable_filter_create(struct cmd_context *cmd, struct dev_types *dt, filter_mode_t mode); 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 */ #endif /* _LVM_FILTER_H */

View File

@ -3040,7 +3040,7 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
clear_hint_file(cmd); clear_hint_file(cmd);
if (!(dev = dev_cache_get(cmd, pv_name, cmd->filter))) { 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; return ECMD_FAILED;
} }
} }
@ -3054,7 +3054,7 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
def = get_devicefile(pv_name); def = get_devicefile(pv_name);
if (!dev && !def) { 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; return ECMD_FAILED;
} }
} }
@ -3143,7 +3143,7 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
pv_name = argv[i]; pv_name = argv[i];
if (!(dev = dev_cache_get(cmd, argv[i], cmd->filter))) { 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; continue;
} }