Blame SOURCES/lvm2-2_02_183-pvscan-lvmetad-use-udev-info-to-improve-md-component.patch

3a5d46
 lib/device/dev-md.c   | 14 ++++++++++--
3a5d46
 lib/device/dev-type.c | 62 +++++++++++++++++++++++++++++++++++++++++----------
3a5d46
 lib/device/dev-type.h |  1 +
3a5d46
 tools/pvscan.c        |  3 ++-
3a5d46
 4 files changed, 65 insertions(+), 15 deletions(-)
3a5d46
3a5d46
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
3a5d46
index 185499b..9728507 100644
3a5d46
--- a/lib/device/dev-md.c
3a5d46
+++ b/lib/device/dev-md.c
3a5d46
@@ -190,14 +190,24 @@ out:
3a5d46
 
3a5d46
 int dev_is_md(struct device *dev, uint64_t *offset_found, int full)
3a5d46
 {
3a5d46
+	int ret;
3a5d46
 
3a5d46
 	/*
3a5d46
 	 * If non-native device status source is selected, use it
3a5d46
 	 * only if offset_found is not requested as this
3a5d46
 	 * information is not in udev db.
3a5d46
 	 */
3a5d46
-	if ((dev->ext.src == DEV_EXT_NONE) || offset_found)
3a5d46
-		return _native_dev_is_md(dev, offset_found, full);
3a5d46
+	if ((dev->ext.src == DEV_EXT_NONE) || offset_found) {
3a5d46
+		ret = _native_dev_is_md(dev, offset_found, full);
3a5d46
+
3a5d46
+		if (!full) {
3a5d46
+			if (!ret || (ret == -EAGAIN)) {
3a5d46
+				if (udev_dev_is_md_component(dev))
3a5d46
+					return 1;
3a5d46
+			}
3a5d46
+		}
3a5d46
+		return ret;
3a5d46
+	}
3a5d46
 
3a5d46
 	if (dev->ext.src == DEV_EXT_UDEV)
3a5d46
 		return _udev_dev_is_md(dev);
3a5d46
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
3a5d46
index eda7982..331fe07 100644
3a5d46
--- a/lib/device/dev-type.c
3a5d46
+++ b/lib/device/dev-type.c
3a5d46
@@ -1003,25 +1003,23 @@ int dev_is_rotational(struct dev_types *dt, struct device *dev)
3a5d46
  *        failed already due to timeout in udev - in both cases the
3a5d46
  *        udev_device_get_is_initialized returns 0.
3a5d46
  */
3a5d46
-#define UDEV_DEV_IS_MPATH_COMPONENT_ITERATION_COUNT 100
3a5d46
-#define UDEV_DEV_IS_MPATH_COMPONENT_USLEEP 100000
3a5d46
+#define UDEV_DEV_IS_COMPONENT_ITERATION_COUNT 100
3a5d46
+#define UDEV_DEV_IS_COMPONENT_USLEEP 100000
3a5d46
 
3a5d46
-int udev_dev_is_mpath_component(struct device *dev)
3a5d46
+static struct udev_device *_udev_get_dev(struct device *dev)
3a5d46
 {
3a5d46
 	struct udev *udev_context = udev_get_library_context();
3a5d46
 	struct udev_device *udev_device = NULL;
3a5d46
-	const char *value;
3a5d46
 	int initialized = 0;
3a5d46
 	unsigned i = 0;
3a5d46
-	int ret = 0;
3a5d46
 
3a5d46
 	if (!udev_context) {
3a5d46
 		log_warn("WARNING: No udev context available to check if device %s is multipath component.", dev_name(dev));
3a5d46
-		return 0;
3a5d46
+		return NULL;
3a5d46
 	}
3a5d46
 
3a5d46
 	while (1) {
3a5d46
-		if (i >= UDEV_DEV_IS_MPATH_COMPONENT_ITERATION_COUNT)
3a5d46
+		if (i >= UDEV_DEV_IS_COMPONENT_ITERATION_COUNT)
3a5d46
 			break;
3a5d46
 
3a5d46
 		if (udev_device)
3a5d46
@@ -1029,7 +1027,7 @@ int udev_dev_is_mpath_component(struct device *dev)
3a5d46
 
3a5d46
 		if (!(udev_device = udev_device_new_from_devnum(udev_context, 'b', dev->dev))) {
3a5d46
 			log_warn("WARNING: Failed to get udev device handler for device %s.", dev_name(dev));
3a5d46
-			return 0;
3a5d46
+			return NULL;
3a5d46
 		}
3a5d46
 
3a5d46
 #ifdef HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED
3a5d46
@@ -1041,19 +1039,32 @@ int udev_dev_is_mpath_component(struct device *dev)
3a5d46
 #endif
3a5d46
 
3a5d46
 		log_debug("Device %s not initialized in udev database (%u/%u, %u microseconds).", dev_name(dev),
3a5d46
-			   i + 1, UDEV_DEV_IS_MPATH_COMPONENT_ITERATION_COUNT,
3a5d46
-			   i * UDEV_DEV_IS_MPATH_COMPONENT_USLEEP);
3a5d46
+			   i + 1, UDEV_DEV_IS_COMPONENT_ITERATION_COUNT,
3a5d46
+			   i * UDEV_DEV_IS_COMPONENT_USLEEP);
3a5d46
 
3a5d46
-		usleep(UDEV_DEV_IS_MPATH_COMPONENT_USLEEP);
3a5d46
+		usleep(UDEV_DEV_IS_COMPONENT_USLEEP);
3a5d46
 		i++;
3a5d46
 	}
3a5d46
 
3a5d46
 	if (!initialized) {
3a5d46
 		log_warn("WARNING: Device %s not initialized in udev database even after waiting %u microseconds.",
3a5d46
-			  dev_name(dev), i * UDEV_DEV_IS_MPATH_COMPONENT_USLEEP);
3a5d46
+			  dev_name(dev), i * UDEV_DEV_IS_COMPONENT_USLEEP);
3a5d46
 		goto out;
3a5d46
 	}
3a5d46
 
3a5d46
+out:
3a5d46
+	return udev_device;
3a5d46
+}
3a5d46
+
3a5d46
+int udev_dev_is_mpath_component(struct device *dev)
3a5d46
+{
3a5d46
+	struct udev_device *udev_device;
3a5d46
+	const char *value;
3a5d46
+	int ret = 0;
3a5d46
+
3a5d46
+	if (!(udev_device = _udev_get_dev(dev)))
3a5d46
+		return 0;
3a5d46
+
3a5d46
 	value = udev_device_get_property_value(udev_device, DEV_EXT_UDEV_BLKID_TYPE);
3a5d46
 	if (value && !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_MPATH)) {
3a5d46
 		log_debug("Device %s is multipath component based on blkid variable in udev db (%s=\"%s\").",
3a5d46
@@ -1073,6 +1084,28 @@ out:
3a5d46
 	udev_device_unref(udev_device);
3a5d46
 	return ret;
3a5d46
 }
3a5d46
+
3a5d46
+int udev_dev_is_md_component(struct device *dev)
3a5d46
+{
3a5d46
+	struct udev_device *udev_device;
3a5d46
+	const char *value;
3a5d46
+	int ret = 0;
3a5d46
+
3a5d46
+	if (!(udev_device = _udev_get_dev(dev)))
3a5d46
+		return 0;
3a5d46
+
3a5d46
+	value = udev_device_get_property_value(udev_device, DEV_EXT_UDEV_BLKID_TYPE);
3a5d46
+	if (value && !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_SW_RAID)) {
3a5d46
+		log_debug("Device %s is md raid component based on blkid variable in udev db (%s=\"%s\").",
3a5d46
+			   dev_name(dev), DEV_EXT_UDEV_BLKID_TYPE, value);
3a5d46
+		ret = 1;
3a5d46
+		goto out;
3a5d46
+	}
3a5d46
+out:
3a5d46
+	udev_device_unref(udev_device);
3a5d46
+	return ret;
3a5d46
+}
3a5d46
+
3a5d46
 #else
3a5d46
 
3a5d46
 int udev_dev_is_mpath_component(struct device *dev)
3a5d46
@@ -1080,4 +1113,9 @@ int udev_dev_is_mpath_component(struct device *dev)
3a5d46
 	return 0;
3a5d46
 }
3a5d46
 
3a5d46
+int udev_dev_is_md_component(struct device *dev)
3a5d46
+{
3a5d46
+	return 0;
3a5d46
+}
3a5d46
+
3a5d46
 #endif
3a5d46
diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h
3a5d46
index f629a02..2644383 100644
3a5d46
--- a/lib/device/dev-type.h
3a5d46
+++ b/lib/device/dev-type.h
3a5d46
@@ -62,6 +62,7 @@ int dev_is_swap(struct device *dev, uint64_t *signature, int full);
3a5d46
 int dev_is_luks(struct device *dev, uint64_t *signature, int full);
3a5d46
 int dasd_is_cdl_formatted(struct device *dev);
3a5d46
 int udev_dev_is_mpath_component(struct device *dev);
3a5d46
+int udev_dev_is_md_component(struct device *dev);
3a5d46
 
3a5d46
 int dev_is_lvm1(struct device *dev, char *buf, int buflen);
3a5d46
 int dev_is_pool(struct device *dev, char *buf, int buflen);
3a5d46
diff --git a/tools/pvscan.c b/tools/pvscan.c
3a5d46
index 47ad0f1..cdccfb5 100644
3a5d46
--- a/tools/pvscan.c
3a5d46
+++ b/tools/pvscan.c
3a5d46
@@ -455,7 +455,8 @@ static int _pvscan_cache(struct cmd_context *cmd, int argc, char **argv)
3a5d46
 		if (dev_is_md_with_end_superblock(cmd->dev_types, dev)) {
3a5d46
 			cmd->use_full_md_check = 1;
3a5d46
 			use_full_md_check = 1;
3a5d46
-			log_debug("Found md with end superblock %s", dev_name(dev));
3a5d46
+			log_debug("Found md component in sysfs with end superblock %s", dev_name(dev));
3a5d46
+			break;
3a5d46
 		}
3a5d46
 	}
3a5d46
 	dev_iter_destroy(iter);