diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index 6cdf766f3..6a9a05f47 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -76,6 +76,7 @@ static int _scanning_in_progress = 0; static int _has_scanned = 0; static int _vgs_locked = 0; static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */ +static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */ int lvmcache_init(void) { @@ -402,6 +403,16 @@ int lvmcache_vgs_locked(void) return _vgs_locked; } +/* + * When lvmcache sees a duplicate PV, this is set. + * process_each_pv() can avoid searching for duplicates + * by checking this and seeing that no duplicate PVs exist. + */ +int lvmcache_found_duplicate_pvs(void) +{ + return _found_duplicate_pvs; +} + static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo, struct lvmcache_info *info) { @@ -1560,10 +1571,12 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid, //else if (dm_is_dm_major(MAJOR(existing->dev->dev)) && //dm_is_dm_major(MAJOR(dev->dev))) // - else if (!strcmp(pvid_s, existing->dev->pvid)) + else if (!strcmp(pvid_s, existing->dev->pvid)) { log_error("Found duplicate PV %s: using %s not " "%s", pvid, dev_name(dev), dev_name(existing->dev)); + _found_duplicate_pvs = 1; + } } if (strcmp(pvid_s, existing->dev->pvid)) log_debug_cache("Updating pvid cache to %s (%s) from %s (%s)", diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h index 7a049175b..0a7d8987a 100644 --- a/lib/cache/lvmcache.h +++ b/lib/cache/lvmcache.h @@ -160,4 +160,6 @@ uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info); void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv, struct device *dev); +int lvmcache_found_duplicate_pvs(void); + #endif diff --git a/tools/toollib.c b/tools/toollib.c index 41e1581fb..17a9c7114 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -2329,11 +2329,9 @@ static int _process_pvs_in_vg(struct cmd_context *cmd, * duplicate devices are being displayed by pvs -a, and * we want each of them to be displayed in the context * of this VG, so that this VG name appears next to it. - * FIXME: the repeated search through all devices is a - * high cost to pay for a very rare benefit. */ - if (process_all_devices) { + if (process_all_devices && lvmcache_found_duplicate_pvs()) { while ((dil = _device_list_find_pvid(all_devices, pv))) { _device_list_remove(all_devices, dil->dev);