mrc0mmand / rpms / lvm2

Forked from rpms/lvm2 2 years ago
Clone
Blob Blame History Raw
 lib/device/dev-cache.c | 19 +++++++++++++++++++
 lib/device/dev-cache.h |  3 +++
 lib/device/dev-md.c    |  6 +++---
 lib/label/label.c      | 27 ++++++++++++++-------------
 tools/pvscan.c         |  7 +++++++
 5 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 1492181..980dd3c 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 8a1c277..46c86c2 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 08143b7..9d0a363 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 a8d87ec..4c21d97 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -901,6 +901,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.
 	 */
@@ -938,19 +952,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 db813ad..0a91add 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