554da53f00
Fix the bug 1145231 OBS-URL: https://build.opensuse.org/request/show/725505 OBS-URL: https://build.opensuse.org/package/show/Base:System/lvm2?expand=0&rev=246
216 lines
6.7 KiB
Diff
216 lines
6.7 KiB
Diff
From a188b1e513ed5ca0f5f3702c823490f5610d4495 Mon Sep 17 00:00:00 2001
|
|
From: David Teigland <teigland@redhat.com>
|
|
Date: Fri, 30 Nov 2018 16:32:32 -0600
|
|
Subject: [PATCH] pvscan lvmetad: use udev info to improve md component
|
|
detection
|
|
|
|
When no md devs are started, pvscan will only scan the start of
|
|
an md component, and if it has a superblock at the end may not
|
|
exclude it. udev may already have info identifying it as an
|
|
md component, so use that.
|
|
---
|
|
lib/device/dev-md.c | 14 ++++++++++--
|
|
lib/device/dev-type.c | 62 +++++++++++++++++++++++++++++++++++++++++----------
|
|
lib/device/dev-type.h | 1 +
|
|
lib/label/label.c | 6 +++++
|
|
tools/pvscan.c | 3 ++-
|
|
5 files changed, 71 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
|
|
index 185499baf..972850726 100644
|
|
--- a/lib/device/dev-md.c
|
|
+++ b/lib/device/dev-md.c
|
|
@@ -190,14 +190,24 @@ out:
|
|
|
|
int dev_is_md(struct device *dev, uint64_t *offset_found, int full)
|
|
{
|
|
+ int ret;
|
|
|
|
/*
|
|
* If non-native device status source is selected, use it
|
|
* only if offset_found is not requested as this
|
|
* information is not in udev db.
|
|
*/
|
|
- if ((dev->ext.src == DEV_EXT_NONE) || offset_found)
|
|
- return _native_dev_is_md(dev, offset_found, full);
|
|
+ if ((dev->ext.src == DEV_EXT_NONE) || offset_found) {
|
|
+ ret = _native_dev_is_md(dev, offset_found, full);
|
|
+
|
|
+ if (!full) {
|
|
+ if (!ret || (ret == -EAGAIN)) {
|
|
+ if (udev_dev_is_md_component(dev))
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+ return ret;
|
|
+ }
|
|
|
|
if (dev->ext.src == DEV_EXT_UDEV)
|
|
return _udev_dev_is_md(dev);
|
|
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
|
|
index af4b40760..33ebb73b2 100644
|
|
--- a/lib/device/dev-type.c
|
|
+++ b/lib/device/dev-type.c
|
|
@@ -1004,25 +1004,23 @@ int dev_is_rotational(struct dev_types *dt, struct device *dev)
|
|
* failed already due to timeout in udev - in both cases the
|
|
* udev_device_get_is_initialized returns 0.
|
|
*/
|
|
-#define UDEV_DEV_IS_MPATH_COMPONENT_ITERATION_COUNT 100
|
|
-#define UDEV_DEV_IS_MPATH_COMPONENT_USLEEP 100000
|
|
+#define UDEV_DEV_IS_COMPONENT_ITERATION_COUNT 100
|
|
+#define UDEV_DEV_IS_COMPONENT_USLEEP 100000
|
|
|
|
-int udev_dev_is_mpath_component(struct device *dev)
|
|
+static struct udev_device *_udev_get_dev(struct device *dev)
|
|
{
|
|
struct udev *udev_context = udev_get_library_context();
|
|
struct udev_device *udev_device = NULL;
|
|
- const char *value;
|
|
int initialized = 0;
|
|
unsigned i = 0;
|
|
- int ret = 0;
|
|
|
|
if (!udev_context) {
|
|
log_warn("WARNING: No udev context available to check if device %s is multipath component.", dev_name(dev));
|
|
- return 0;
|
|
+ return NULL;
|
|
}
|
|
|
|
while (1) {
|
|
- if (i >= UDEV_DEV_IS_MPATH_COMPONENT_ITERATION_COUNT)
|
|
+ if (i >= UDEV_DEV_IS_COMPONENT_ITERATION_COUNT)
|
|
break;
|
|
|
|
if (udev_device)
|
|
@@ -1030,7 +1028,7 @@ int udev_dev_is_mpath_component(struct device *dev)
|
|
|
|
if (!(udev_device = udev_device_new_from_devnum(udev_context, 'b', dev->dev))) {
|
|
log_warn("WARNING: Failed to get udev device handler for device %s.", dev_name(dev));
|
|
- return 0;
|
|
+ return NULL;
|
|
}
|
|
|
|
#ifdef HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED
|
|
@@ -1042,19 +1040,32 @@ int udev_dev_is_mpath_component(struct device *dev)
|
|
#endif
|
|
|
|
log_debug("Device %s not initialized in udev database (%u/%u, %u microseconds).", dev_name(dev),
|
|
- i + 1, UDEV_DEV_IS_MPATH_COMPONENT_ITERATION_COUNT,
|
|
- i * UDEV_DEV_IS_MPATH_COMPONENT_USLEEP);
|
|
+ i + 1, UDEV_DEV_IS_COMPONENT_ITERATION_COUNT,
|
|
+ i * UDEV_DEV_IS_COMPONENT_USLEEP);
|
|
|
|
- usleep(UDEV_DEV_IS_MPATH_COMPONENT_USLEEP);
|
|
+ usleep(UDEV_DEV_IS_COMPONENT_USLEEP);
|
|
i++;
|
|
}
|
|
|
|
if (!initialized) {
|
|
log_warn("WARNING: Device %s not initialized in udev database even after waiting %u microseconds.",
|
|
- dev_name(dev), i * UDEV_DEV_IS_MPATH_COMPONENT_USLEEP);
|
|
+ dev_name(dev), i * UDEV_DEV_IS_COMPONENT_USLEEP);
|
|
goto out;
|
|
}
|
|
|
|
+out:
|
|
+ return udev_device;
|
|
+}
|
|
+
|
|
+int udev_dev_is_mpath_component(struct device *dev)
|
|
+{
|
|
+ struct udev_device *udev_device;
|
|
+ const char *value;
|
|
+ int ret = 0;
|
|
+
|
|
+ if (!(udev_device = _udev_get_dev(dev)))
|
|
+ return 0;
|
|
+
|
|
value = udev_device_get_property_value(udev_device, DEV_EXT_UDEV_BLKID_TYPE);
|
|
if (value && !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_MPATH)) {
|
|
log_debug("Device %s is multipath component based on blkid variable in udev db (%s=\"%s\").",
|
|
@@ -1074,6 +1085,28 @@ out:
|
|
udev_device_unref(udev_device);
|
|
return ret;
|
|
}
|
|
+
|
|
+int udev_dev_is_md_component(struct device *dev)
|
|
+{
|
|
+ struct udev_device *udev_device;
|
|
+ const char *value;
|
|
+ int ret = 0;
|
|
+
|
|
+ if (!(udev_device = _udev_get_dev(dev)))
|
|
+ return 0;
|
|
+
|
|
+ value = udev_device_get_property_value(udev_device, DEV_EXT_UDEV_BLKID_TYPE);
|
|
+ if (value && !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_SW_RAID)) {
|
|
+ log_debug("Device %s is md raid component based on blkid variable in udev db (%s=\"%s\").",
|
|
+ dev_name(dev), DEV_EXT_UDEV_BLKID_TYPE, value);
|
|
+ ret = 1;
|
|
+ goto out;
|
|
+ }
|
|
+out:
|
|
+ udev_device_unref(udev_device);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
#else
|
|
|
|
int udev_dev_is_mpath_component(struct device *dev)
|
|
@@ -1081,4 +1114,9 @@ int udev_dev_is_mpath_component(struct device *dev)
|
|
return 0;
|
|
}
|
|
|
|
+int udev_dev_is_md_component(struct device *dev)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
#endif
|
|
diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h
|
|
index f629a0278..264438339 100644
|
|
--- a/lib/device/dev-type.h
|
|
+++ b/lib/device/dev-type.h
|
|
@@ -62,6 +62,7 @@ int dev_is_swap(struct device *dev, uint64_t *signature, int full);
|
|
int dev_is_luks(struct device *dev, uint64_t *signature, int full);
|
|
int dasd_is_cdl_formatted(struct device *dev);
|
|
int udev_dev_is_mpath_component(struct device *dev);
|
|
+int udev_dev_is_md_component(struct device *dev);
|
|
|
|
int dev_is_lvm1(struct device *dev, char *buf, int buflen);
|
|
int dev_is_pool(struct device *dev, char *buf, int buflen);
|
|
diff --git a/lib/label/label.c b/lib/label/label.c
|
|
index b26ff3370..e01608d2c 100644
|
|
--- a/lib/label/label.c
|
|
+++ b/lib/label/label.c
|
|
@@ -957,6 +957,12 @@ int label_scan_pvscan_all(struct cmd_context *cmd, struct dm_list *scan_devs)
|
|
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
|
|
_scan_dev_close(dev);
|
|
}
|
|
+
|
|
+ if (dev_is_md_with_end_superblock(cmd->dev_types, dev)) {
|
|
+ cmd->use_full_md_check = 1;
|
|
+ use_full_md_check = 1;
|
|
+ log_debug("Found md component in sysfs with end superblock %s", dev_name(dev));
|
|
+ }
|
|
};
|
|
dev_iter_destroy(iter);
|
|
|
|
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
|
index 3755684d2..877b6b2db 100644
|
|
--- a/tools/pvscan.c
|
|
+++ b/tools/pvscan.c
|
|
@@ -455,7 +455,8 @@ static int _pvscan_cache(struct cmd_context *cmd, int argc, char **argv)
|
|
if (dev_is_md_with_end_superblock(cmd->dev_types, dev)) {
|
|
cmd->use_full_md_check = 1;
|
|
use_full_md_check = 1;
|
|
- log_debug("Found md with end superblock %s", dev_name(dev));
|
|
+ log_debug("Found md component in sysfs with end superblock %s", dev_name(dev));
|
|
+ break;
|
|
}
|
|
}
|
|
dev_iter_destroy(iter);
|
|
--
|
|
2.12.3
|
|
|