mrc0mmand / rpms / lvm2

Forked from rpms/lvm2 3 years ago
Clone

Blame SOURCES/lvm2-2_03_06-enable-full-md-component-detection-at-the-right-time.patch

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