diff options
-rw-r--r-- | lib/device/device.h | 1 | ||||
-rw-r--r-- | lib/device/device_id.c | 14 | ||||
-rw-r--r-- | lib/label/hints.c | 14 | ||||
-rw-r--r-- | lib/label/label.c | 8 |
4 files changed, 37 insertions, 0 deletions
diff --git a/lib/device/device.h b/lib/device/device.h index 9e471a9b5..8c3a8c30e 100644 --- a/lib/device/device.h +++ b/lib/device/device.h @@ -40,6 +40,7 @@ #define DEV_IS_NVME 0x00040000 /* set if dev is nvme */ #define DEV_MATCHED_USE_ID 0x00080000 /* matched an entry from cmd->use_devices */ #define DEV_SCAN_FOUND_NOLABEL 0x00100000 /* label_scan read, passed filters, but no lvm label */ +#define DEV_SCAN_NOT_READ 0x00200000 /* label_scan not able to read dev */ /* * Support for external device info. diff --git a/lib/device/device_id.c b/lib/device/device_id.c index aeaa1ffc6..7fe581571 100644 --- a/lib/device/device_id.c +++ b/lib/device/device_id.c @@ -1725,6 +1725,13 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, continue; /* + * The matched device could not be read so we do not have + * the PVID from disk and cannot verify the devices file entry. + */ + if (dev->flags & DEV_SCAN_NOT_READ) + continue; + + /* * du and dev may have been matched, but the dev could still * have been excluded by other filters during label scan. * This shouldn't generally happen, but if it does the user @@ -1806,6 +1813,13 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, if (scanned_devs && !dev_in_device_list(dev, scanned_devs)) continue; + /* + * The matched device could not be read so we do not have + * the PVID from disk and cannot verify the devices file entry. + */ + if (dev->flags & DEV_SCAN_NOT_READ) + continue; + if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) { log_warn("Devices file %s is excluded by filter: %s.", dev_name(dev), dev_filtered_reason(dev)); diff --git a/lib/label/hints.c b/lib/label/hints.c index 3ce9634f2..95d5d77b8 100644 --- a/lib/label/hints.c +++ b/lib/label/hints.c @@ -234,6 +234,7 @@ static int _touch_newhints(void) return_0; if (fclose(fp)) stack; + log_debug("newhints created"); return 1; } @@ -504,6 +505,19 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints) if (!hint->chosen) continue; + /* + * label_scan was unable to read the dev so we don't know its pvid. + * Since we are unable to verify the hint is correct, it's possible + * that the PVID is actually found on a different device, so don't + * depend on hints. (This would also fail the following pvid check.) + */ + if (dev->flags & DEV_SCAN_NOT_READ) { + log_debug("Uncertain hint for unread device %d:%d %s", + major(hint->devt), minor(hint->devt), dev_name(dev)); + ret = 0; + continue; + } + if (strcmp(dev->pvid, hint->pvid)) { log_debug("Invalid hint device %d:%d %s pvid %s had hint pvid %s", major(hint->devt), minor(hint->devt), dev_name(dev), diff --git a/lib/label/label.c b/lib/label/label.c index 9fac3e464..354ab35e2 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -686,6 +686,8 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, dm_list_iterate_items_safe(devl, devl2, devs) { + devl->dev->flags &= ~DEV_SCAN_NOT_READ; + /* * If we prefetch more devs than blocks in the cache, then the * cache will wait for earlier reads to complete, toss the @@ -701,6 +703,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, log_debug_devs("Scan failed to open %s.", dev_name(devl->dev)); dm_list_del(&devl->list); dm_list_add(&reopen_devs, &devl->list); + devl->dev->flags |= DEV_SCAN_NOT_READ; continue; } } @@ -724,6 +727,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, log_debug_devs("Scan failed to read %s.", dev_name(devl->dev)); scan_read_errors++; scan_failed_count++; + devl->dev->flags |= DEV_SCAN_NOT_READ; lvmcache_del_dev(devl->dev); if (bb) bcache_put(bb); @@ -1113,6 +1117,10 @@ int label_scan(struct cmd_context *cmd) * filter", and this result needs to be cleared (wiped) so that the * complete set of filters (including those that require data) can be * checked in _process_block, where headers have been read. + * + * FIXME: devs that are filtered with data in _process_block + * are not moved to the filtered_devs list like devs filtered + * here without data. Does that have any effect? */ log_debug_devs("Filtering devices to scan (nodata)"); |