diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c index 1492181fb..980dd3cbc 100644 --- a/lib/device/dev-cache.c +++ b/lib/device/dev-cache.c @@ -15,6 +15,7 @@ #include "base/memory/zalloc.h" #include "lib/misc/lib.h" +#include "lib/device/dev-type.h" #include "lib/datastruct/btree.h" #include "lib/config/config.h" #include "lib/commands/toolcontext.h" @@ -1634,3 +1635,21 @@ const char *dev_name(const struct device *dev) return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str : unknown_device_name(); } + +bool dev_cache_has_md_with_end_superblock(struct dev_types *dt) +{ + struct btree_iter *iter = btree_first(_cache.devices); + struct device *dev; + + while (iter) { + dev = btree_get_data(iter); + + if (dev_is_md_with_end_superblock(dt, dev)) + return true; + + iter = btree_next(iter); + } + + return false; +} + diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h index 8a1c27781..46c86c27a 100644 --- a/lib/device/dev-cache.h +++ b/lib/device/dev-cache.h @@ -17,6 +17,7 @@ #define _LVM_DEV_CACHE_H #include "lib/device/device.h" +#include "lib/device/dev-type.h" #include "lib/misc/lvm-wrappers.h" struct cmd_context; @@ -71,4 +72,6 @@ void dev_reset_error_count(struct cmd_context *cmd); void dev_cache_failed_path(struct device *dev, const char *path); +bool dev_cache_has_md_with_end_superblock(struct dev_types *dt); + #endif diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c index 08143b7fa..9d0a36363 100644 --- a/lib/device/dev-md.c +++ b/lib/device/dev-md.c @@ -302,12 +302,12 @@ static int _md_sysfs_attribute_scanf(struct dev_types *dt, return ret; if (!(fp = fopen(path, "r"))) { - log_sys_error("fopen", path); + log_debug("_md_sysfs_attribute_scanf fopen failed %s", path); return ret; } if (!fgets(buffer, sizeof(buffer), fp)) { - log_sys_error("fgets", path); + log_debug("_md_sysfs_attribute_scanf fgets failed %s", path); goto out; } @@ -449,7 +449,7 @@ int dev_is_md_with_end_superblock(struct dev_types *dt, struct device *dev) if (_md_sysfs_attribute_scanf(dt, dev, attribute, "%s", &version_string) != 1) - return -1; + return 0; log_very_verbose("Device %s %s is %s.", dev_name(dev), attribute, version_string); diff --git a/lib/label/label.c b/lib/label/label.c index 8b841f6bd..fb7ad1d56 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -893,6 +893,20 @@ int label_scan(struct cmd_context *cmd) */ dev_cache_scan(); + /* + * If we know that there will be md components with an end + * superblock, then enable the full md filter before label + * scan begins. FIXME: we could skip the full md check on + * devs that are not identified as PVs, but then we'd need + * to do something other than using the standard md filter. + */ + if (cmd->md_component_detection && !cmd->use_full_md_check && + !strcmp(cmd->md_component_checks, "auto") && + dev_cache_has_md_with_end_superblock(cmd->dev_types)) { + log_debug("Enable full md component check."); + cmd->use_full_md_check = 1; + } + /* * Set up the iterator that is needed to step through each device in * dev cache. @@ -931,19 +945,6 @@ int label_scan(struct cmd_context *cmd) bcache_invalidate_fd(scan_bcache, dev->bcache_fd); _scan_dev_close(dev); } - - /* - * When md devices exist that use the old superblock at the - * end of the device, then in order to detect and filter out - * the component devices of those md devs, we enable the full - * md filter which scans both the start and the end of every - * device. This doubles the amount of scanning i/o, which we - * want to avoid. FIXME: this forces start+end scanning of - * every device, but it would be more efficient to limit the - * end scan only to PVs. - */ - if (dev_is_md_with_end_superblock(cmd->dev_types, dev)) - cmd->use_full_md_check = 1; }; dev_iter_destroy(iter); diff --git a/tools/pvscan.c b/tools/pvscan.c index facc70c86..2a88eaa0e 100644 --- a/tools/pvscan.c +++ b/tools/pvscan.c @@ -938,6 +938,13 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv) /* Creates a list of dev names from /dev, sysfs, etc; does not read any. */ dev_cache_scan(); + if (cmd->md_component_detection && !cmd->use_full_md_check && + !strcmp(cmd->md_component_checks, "auto") && + dev_cache_has_md_with_end_superblock(cmd->dev_types)) { + log_debug("Enable full md component check."); + cmd->use_full_md_check = 1; + } + /* * For each device command arg (from either position or --major/--minor), * decide if that device is being added to the system (a dev node exists