summaryrefslogtreecommitdiff
path: root/lib/label/label.c
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2018-05-29 17:02:27 -0500
committerDavid Teigland <teigland@redhat.com>2018-05-30 09:05:18 -0500
commit6d14d5d16b92c520b5f4ee464f171684cac40735 (patch)
tree7f8d9d8d9ff83ab184fb3c77d54ee92793658ced /lib/label/label.c
parent06c789eda19445d5e59a9c8044d91300fa1d2000 (diff)
downloadlvm2-6d14d5d16b92c520b5f4ee464f171684cac40735.tar.gz
scan: removed failed paths for devices
Drop a device path when the scan fails to open it.
Diffstat (limited to 'lib/label/label.c')
-rw-r--r--lib/label/label.c65
1 files changed, 50 insertions, 15 deletions
diff --git a/lib/label/label.c b/lib/label/label.c
index 8ecaa6165..97a43599c 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -501,15 +501,6 @@ retry_open:
(int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev));
}
- /*
- * FIXME: do we want to try opening this device using
- * one of the other path aliases for the same
- * major:minor from dev->aliases? We could iterate
- * through those aliases to try opening each of them to
- * find one that works. What are the consequences of
- * using a different, non-preferred alias to a device?
- */
-
if (!retried) {
/*
* FIXME: remove this, the theory for this retry is that
@@ -550,6 +541,37 @@ static int _scan_dev_close(struct device *dev)
return 1;
}
+static void _drop_bad_aliases(struct device *dev)
+{
+ struct dm_str_list *strl, *strl2;
+ const char *name;
+ struct stat sbuf;
+ int major = (int)MAJOR(dev->dev);
+ int minor = (int)MINOR(dev->dev);
+ int bad;
+
+ dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
+ name = strl->str;
+ bad = 0;
+
+ if (stat(name, &sbuf)) {
+ bad = 1;
+ log_debug_devs("Device path check %d:%d %s stat failed errno %d",
+ major, minor, name, errno);
+ } else if (sbuf.st_rdev != dev->dev) {
+ bad = 1;
+ log_debug_devs("Device path check %d:%d %s stat %d:%d does not match.",
+ major, minor, name,
+ (int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev));
+ }
+
+ if (bad) {
+ log_debug_devs("Device path check %d:%d dropping path %s.", major, minor, name);
+ dev_cache_failed_path(dev, name);
+ }
+ }
+}
+
/*
* Read or reread label/metadata from selected devs.
*
@@ -635,7 +657,11 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
scan_failed_count++;
lvmcache_del_dev(devl->dev);
} else {
- log_debug_devs("Processing data from device %s fd %d block %p", dev_name(devl->dev), devl->dev->bcache_fd, bb);
+ log_debug_devs("Processing data from device %s %d:%d fd %d block %p",
+ dev_name(devl->dev),
+ (int)MAJOR(devl->dev->dev),
+ (int)MINOR(devl->dev->dev),
+ devl->dev->bcache_fd, bb);
ret = _process_block(cmd, f, devl->dev, bb, 0, 0, &is_lvm_device);
@@ -675,11 +701,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
* to open the devs on the reopen_devs list.
*
* FIXME: it's not clear if or why this helps.
- *
- * FIXME: should we delete the first path name from dev->aliases that
- * we failed to open the first time before retrying? If that path
- * still exists on the system, dev_cache_scan should put it back, but
- * if it doesn't exist we don't want to try using it again.
*/
if (!dm_list_empty(&reopen_devs)) {
if (retried_open) {
@@ -690,6 +711,20 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
}
retried_open = 1;
+ dm_list_iterate_items_safe(devl, devl2, &reopen_devs) {
+ _drop_bad_aliases(devl->dev);
+
+ if (dm_list_empty(&devl->dev->aliases)) {
+ log_warn("WARNING: Scan ignoring device %d:%d with no paths.",
+ (int)MAJOR(devl->dev->dev),
+ (int)MINOR(devl->dev->dev));
+
+ dm_list_del(&devl->list);
+ lvmcache_del_dev(devl->dev);
+ scan_failed_count++;
+ }
+ }
+
/*
* This will search the system's /dev for new path names and
* could help us reopen the device if it finds a new preferred