From 63b469c1609fe5d3395b7757eebaf35a4a77ea7a Mon Sep 17 00:00:00 2001 From: David Teigland Date: Mon, 9 Oct 2023 16:08:18 -0500 Subject: [PATCH] device_id: fix hints with device ids Fix some interactions between device IDs and hints. Hints may limit the scanned devices which should not always trigger a search for the PVs that were intentionally not scanned. Hints should also be invalidated if they contain a device that's become excluded by an internal filter such as the device_id filter. --- lib/device/device_id.c | 24 +++++++++++++++++++++++- lib/device/device_id.h | 2 +- lib/label/hints.c | 24 ++++++++++++++++++++++++ lib/label/label.c | 2 +- tools/lvmdevices.c | 2 +- 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/device/device_id.c b/lib/device/device_id.c index d4f5b676f..b6a535498 100644 --- a/lib/device/device_id.c +++ b/lib/device/device_id.c @@ -2342,7 +2342,7 @@ static void _get_devs_with_serial_numbers(struct cmd_context *cmd, struct dm_lis * use_devices entries from the devices file. */ -void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int noupdate) +void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int noupdate, int using_hints) { struct dm_list wrong_devs; struct device *dev = NULL; @@ -2768,6 +2768,28 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, } else { log_debug("Validated device ids: invalid=%d, no update needed.", cmd->device_ids_invalid); } + + /* + * label_scan can use hints to scan only the devs for a specific + * VG as an optimization. If that limited subset of devs were + * all matched properly in the devices file, then override + * device_ids_invalid which may be set due to other entries + * not being matched, which this command doesn't care about. + */ + if (using_hints && scanned_devs) { + int found_scanned = 1; + dm_list_iterate_items(devl, scanned_devs) { + du = get_du_for_dev(cmd, devl->dev); + if (du && !memcmp(du->pvid, devl->dev->pvid, ID_LEN)) + continue; + found_scanned = 0; + break; + } + if (found_scanned && cmd->device_ids_invalid) { + log_debug("Override device_ids_invalid for complete hints."); + cmd->device_ids_invalid = 0; + } + } } /* diff --git a/lib/device/device_id.h b/lib/device/device_id.h index 6d42ef235..dd1079762 100644 --- a/lib/device/device_id.h +++ b/lib/device/device_id.h @@ -33,7 +33,7 @@ void device_id_pvremove(struct cmd_context *cmd, struct device *dev); void device_ids_match(struct cmd_context *cmd); int device_ids_match_dev(struct cmd_context *cmd, struct device *dev); void device_ids_match_device_list(struct cmd_context *cmd); -void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int noupdate); +void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int noupdate, int using_hints); int device_ids_version_unchanged(struct cmd_context *cmd); void device_ids_check_serial(struct cmd_context *cmd, struct dm_list *scan_devs, int *update_needed, int noupdate); void device_ids_refresh(struct cmd_context *cmd, struct dm_list *dev_list, int *search_count, int noupdate); diff --git a/lib/label/hints.c b/lib/label/hints.c index 825788369..1e382198b 100644 --- a/lib/label/hints.c +++ b/lib/label/hints.c @@ -468,6 +468,7 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints) struct hint *hint; struct dev_iter *iter; struct device *dev; + int valid_hints = 0; int ret = 1; /* No commands are using hints. */ @@ -478,6 +479,8 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints) if (!cmd->use_hints && !cmd->pvscan_recreate_hints) return 0; + log_debug("Validating hints"); + if (lvmcache_has_duplicate_devs()) { log_debug("Hints not used with duplicate pvs"); ret = 0; @@ -504,6 +507,17 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints) if (!(hint = _find_hint_name(hints, dev_name(dev)))) continue; + /* + * If this dev is excluded by any filter then hints invalid. + * use cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent") ? + */ + if (dev->filtered_flags) { + log_debug("Hints invalid for filtered %s: %s", + dev_name(dev), dev_filtered_reason(dev)); + ret = 0; + break; + } + /* The cmd hasn't needed this hint's dev so it's not been scanned. */ if (!hint->chosen) continue; @@ -527,6 +541,8 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints) dev->pvid, hint->pvid); ret = 0; } + + valid_hints++; } dev_iter_destroy(iter); @@ -576,6 +592,14 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints) } } + /* + * hints considered invalid if none are used. + */ + if (!valid_hints) { + log_debug("Invalid hints: none used."); + ret = 0; + } + out: if (!ret) { /* diff --git a/lib/label/label.c b/lib/label/label.c index f519493b9..c422cbe06 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -1457,7 +1457,7 @@ int label_scan(struct cmd_context *cmd) * Check if the devices_file content is up to date and * if not update it. */ - device_ids_validate(cmd, &scan_devs, 0); + device_ids_validate(cmd, &scan_devs, 0, using_hints); dm_list_iterate_items_safe(devl, devl2, &all_devs) { dm_list_del(&devl->list); diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c index 154592759..34a6fd103 100644 --- a/tools/lvmdevices.c +++ b/tools/lvmdevices.c @@ -230,7 +230,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv) * from use_devices does not pass the filters that have been * run just above. */ - device_ids_validate(cmd, NULL, 1); + device_ids_validate(cmd, NULL, 1, 0); if (cmd->device_ids_invalid) update_needed = 1;