diff options
author | David Teigland <teigland@redhat.com> | 2015-10-15 13:30:31 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2015-11-04 10:42:15 -0600 |
commit | ecd6ab58771822a2c35ebb95762a8194457df4bc (patch) | |
tree | 3b5840b9cfa646c0ae1b5b43091e6aacbbe1eebf | |
parent | 76c1965d1a47a9cb24096526baa4d76f5035b840 (diff) | |
download | lvm2-dev-dct-lvmetad-12.tar.gz |
Strictly ignore duplicate PVsdev-dct-lvmetad-12
In commands and lvmetad, if a pvid already exists on
one device, and a second device appears with the same
pvid, then ignore the second device.
Previously, commands and lvmetad attempted to juggle both
devices for the same PV.
-rw-r--r-- | daemons/lvmetad/lvmetad-core.c | 175 | ||||
-rw-r--r-- | lib/cache/lvmcache.c | 272 | ||||
-rw-r--r-- | lib/cache/lvmcache.h | 7 | ||||
-rw-r--r-- | lib/cache/lvmetad.c | 42 | ||||
-rw-r--r-- | tools/toollib.c | 77 |
5 files changed, 32 insertions, 541 deletions
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c index e847a7304..026299e85 100644 --- a/daemons/lvmetad/lvmetad-core.c +++ b/daemons/lvmetad/lvmetad-core.c @@ -1895,39 +1895,6 @@ out: return retval; } -static dev_t device_remove(lvmetad_state *s, struct dm_config_tree *pvmeta, dev_t device) -{ - struct dm_config_node *pvmeta_tmp; - struct dm_config_value *v = NULL; - dev_t alt_device = 0, prim_device = 0; - - if ((pvmeta_tmp = dm_config_find_node(pvmeta->root, "pvmeta/devices_alternate"))) - v = pvmeta_tmp->v; - - prim_device = dm_config_find_int64(pvmeta->root, "pvmeta/device", 0); - - /* it is the primary device */ - if (device > 0 && device == prim_device && pvmeta_tmp && pvmeta_tmp->v) - { - alt_device = pvmeta_tmp->v->v.i; - pvmeta_tmp->v = pvmeta_tmp->v->next; - pvmeta_tmp = dm_config_find_node(pvmeta->root, "pvmeta/device"); - pvmeta_tmp->v->v.i = alt_device; - } else if (device != prim_device) - alt_device = prim_device; - - /* it is an alternate device */ - if (device > 0 && v && v->v.i == device) - pvmeta_tmp->v = v->next; - else while (device > 0 && pvmeta_tmp && v) { - if (v->next && v->next->v.i == device) - v->next = v->next->next; - v = v->next; - } - - return alt_device; -} - static response pv_gone(lvmetad_state *s, request r) { const char *arg_pvid = NULL; @@ -1964,17 +1931,7 @@ static response pv_gone(lvmetad_state *s, request r) vgid = dm_hash_lookup(s->pvid_to_vgid, pvid); dm_hash_remove_binary(s->device_to_pvid, &device, sizeof(device)); - - alt_device = device_remove(s, pvmeta, device); - - if (!alt_device) { - /* The PV was not a duplicate, so remove it. */ - dm_hash_remove(s->pvid_to_pvmeta, pvid); - } else { - /* The PV remains on another device. */ - DEBUGLOG(s, "pv_gone %s device %" PRIu64 " has alt_device %" PRIu64, - pvid, device, alt_device); - } + dm_hash_remove(s->pvid_to_pvmeta, pvid); unlock_pvid_to_pvmeta(s); @@ -1996,18 +1953,11 @@ static response pv_gone(lvmetad_state *s, request r) vgid = NULL; } - if (!alt_device) { - dm_config_destroy(pvmeta); - if (old_pvid) - dm_free(old_pvid); - } + dm_config_destroy(pvmeta); + if (old_pvid) + dm_free(old_pvid); - if (alt_device) { - return daemon_reply_simple("OK", - "device = %"PRId64, alt_device, - NULL); - } else - return daemon_reply_simple("OK", NULL ); + return daemon_reply_simple("OK", NULL ); } static response pv_clear_all(lvmetad_state *s, request r) @@ -2126,8 +2076,6 @@ static response pv_found(lvmetad_state *s, request r) struct dm_config_tree *new_pvmeta = NULL; struct dm_config_tree *prev_pvmeta_on_dev = NULL; struct dm_config_tree *vgmeta = NULL; - struct dm_config_node *altdev = NULL; - struct dm_config_value *altdev_v = NULL; const char *arg_pvid = NULL; const char *arg_pvid_dup = NULL; const char *arg_pvid_lookup = NULL; @@ -2307,40 +2255,14 @@ static response pv_found(lvmetad_state *s, request r) } else if (new_pvid && !new_device) { /* * New PV on old device (existing device reused for new PV). - * The previous PV on arg_device may or may not still exist, - * this is determined by device_remove() which checks the - * pvmeta for the previous PV (prev_pvid_on_dev and - * prev_pvmeta_on_dev) to see if arg_device was the only - * device for the PV, or if arg_device was a duplicate for - * the PV. If arg_device was previously a duplicate, then - * the prev PV should be kept, but with arg_device removed. - * If arg_device was the only device for the prev PV, then - * the prev PV should be removed entirely. + * The previous PV on arg_device is replaced by the new one. * - * In either case, don't free prev_pvid or prev_vgid - * strings because they are used at the end to check - * the VG metadata. + * Don't free prev_pvid or prev_vgid strings because they are + * used at the end to check the VG metadata. */ changed |= 1; - if (prev_pvmeta_on_dev && - !device_remove(s, prev_pvmeta_on_dev, arg_device)) { - /* - * The prev PV has no remaining device after - * removing arg_device, so arg_device was not a - * duplicate; remove the prev PV entirely. - * - * (hash_remove in pvid_to_vgid is done at the - * end after the VG metadata is checked) - * - * FIXME: we could check if the new pvid is a new - * duplicate of another existing PV. This can happen: - * start with two different pvs A and B, - * dd if=A of=B, pvscan --cache B. This detects that - * B is removed, but doesn't detect that A is now a - * duplicate. ('pvscan --cache' does detect the - * dup because all pvs are scanned.) - */ + if (prev_pvmeta_on_dev) { DEBUGLOG(s, "pv_found new pvid device_to_pvid %" PRIu64 " to %s removes prev pvid %s", arg_device, new_pvid, prev_pvid_on_dev); @@ -2350,23 +2272,21 @@ static response pv_found(lvmetad_state *s, request r) /* removes arg_device/prev_pvid_on_dev mapping */ dm_hash_remove_binary(s->device_to_pvid, &arg_device, sizeof(arg_device)); - } else { + /* - * The prev PV existing on a remaining alternate - * device after removing arg_device, so arg_device - * was a duplicate; keep the prev PV. - * - * FIXME: if the duplicate devices were path aliases - * to the same underlying device, then keeping the - * prev PV for the remaining alt device isn't nice. + * The new PV replacing the prev PV was copied from + * another existing PV, creating a duplicate PV which + * we ignore. */ - DEBUGLOG(s, "pv_found new pvid device_to_pvid %" PRIu64 " to %s keeping prev pvid %s", - arg_device, new_pvid, prev_pvid_on_dev); - - /* removes arg_device/prev_pvid_on_dev mapping */ - dm_hash_remove_binary(s->device_to_pvid, &arg_device, sizeof(arg_device)); + if (dm_hash_lookup(s->pvid_to_pvmeta, new_pvid)) { + DEBUGLOG(s, "pv_found ignore duplicate device %" PRIu64 " of existing PV for pvid %s", + arg_device, arg_pvid); + unlock_pvid_to_pvmeta(s); + return reply_fail("Ignore duplicate PV"); + } } + if (!(new_pvid_dup = dm_strdup(new_pvid))) goto nomem; @@ -2379,57 +2299,12 @@ static response pv_found(lvmetad_state *s, request r) } else if (new_device && !new_pvid) { /* * Old PV on new device (duplicate) - * . add new_device/arg_pvid mapping - * . leave existing old_device/arg_pvid mapping - * . add new_pvmeta, replacing old_pvmeta - * . modify new_pvmeta, adding an alternate device entry for old_device + * Ignore it. */ - changed |= 1; - - DEBUGLOG(s, "pv_found new device device_to_pvid %" PRIu64 " to %s also %" PRIu64 " to %s", - new_device, arg_pvid, old_device, arg_pvid); - - if (!(arg_pvid_dup = dm_strdup(arg_pvid))) - goto nomem; - - if (!dm_hash_insert_binary(s->device_to_pvid, &new_device, sizeof(new_device), (char *)arg_pvid_dup)) - goto nomem; - - if (!dm_hash_insert(s->pvid_to_pvmeta, arg_pvid, new_pvmeta)) - goto nomem; - - /* Copy existing altdev info, or create new, and add it to new pvmeta. */ - if ((altdev = dm_config_find_node(old_pvmeta->root, "pvmeta/devices_alternate"))) { - if (!(altdev = dm_config_clone_node(new_pvmeta, altdev, 0))) - goto nomem; - chain_node(altdev, new_pvmeta->root, 0); - } else { - if (!(altdev = make_config_node(new_pvmeta, "devices_alternate", new_pvmeta->root, 0))) - goto nomem; - } - - /* Add an altdev entry for old_device. */ - altdev_v = altdev->v; - while (1) { - if (altdev_v && altdev_v->v.i == old_device) - break; - if (altdev_v) - altdev_v = altdev_v->next; - if (!altdev_v) { - if (!(altdev_v = dm_config_create_value(new_pvmeta))) - goto nomem; - altdev_v->next = altdev->v; - altdev->v = altdev_v; - altdev->v->v.i = old_device; - break; - } - }; - altdev_v = altdev->v; - while (altdev_v) { - if (altdev_v->next && altdev_v->next->v.i == new_device) - altdev_v->next = altdev_v->next->next; - altdev_v = altdev_v->next; - } + DEBUGLOG(s, "pv_found ignore duplicate device %" PRIu64 " of existing device %" PRIu64 " for pvid %s", + new_device, old_device, arg_pvid); + unlock_pvid_to_pvmeta(s); + return reply_fail("Ignore duplicate PV"); } unlock_pvid_to_pvmeta(s); diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index 8ab1a3191..f392fd79c 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -68,7 +68,6 @@ struct lvmcache_vginfo { unsigned vg_use_count; /* Counter of vg reusage */ unsigned precommitted; /* Is vgmetadata live or precommitted? */ unsigned cached_vg_invalidated; /* Signal to regenerate cached_vg */ - unsigned preferred_duplicates; /* preferred duplicate pvs have been set */ }; static struct dm_hash_table *_pvid_hash = NULL; @@ -80,7 +79,6 @@ 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) { @@ -117,47 +115,6 @@ int lvmcache_init(void) return 1; } -/* - * Once PV info has been populated in lvmcache and - * lvmcache has chosen preferred duplicate devices, - * set this flag so that lvmcache will not try to - * compare and choose preferred duplicate devices - * again (which may result in different preferred - * devices.) PV info can be populated in lvmcache - * multiple times, each time causing lvmcache to - * compare the duplicate devices, so we need to - * record that the comparison/preferences have - * already been done, so the preferrences from the - * first time through are not changed. - * - * This is something of a hack to work around the - * fact that the code isn't really designed to - * handle duplicate PVs, and the fact that lvmetad - * has its own way of picking a preferred duplicate - * and lvmcache has another way based on having - * more information than lvmetad does. - * - * If we come up with a better overall method to - * handle duplicate PVs, then this can probably be - * removed. - * - * FIXME: if we want to make lvmetad work with clvmd, - * then this may need to be changed to set - * preferred_duplicates back to 0. - */ - -void lvmcache_set_preferred_duplicates(const char *vgid) -{ - struct lvmcache_vginfo *vginfo; - - if (!(vginfo = lvmcache_vginfo_from_vgid(vgid))) { - stack; - return; - } - - vginfo->preferred_duplicates = 1; -} - void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd) { if (!lvmetad_active() || _has_scanned) @@ -451,16 +408,6 @@ 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) { @@ -1597,85 +1544,6 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted) return 1; } -/* - * Replace pv->dev with dev so that dev will appear for reporting. - */ - -void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv, - struct device *dev) -{ - struct lvmcache_info *info; - char pvid_s[ID_LEN + 1] __attribute__((aligned(8))); - - strncpy(pvid_s, (char *) &pv->id, sizeof(pvid_s) - 1); - pvid_s[sizeof(pvid_s) - 1] = '\0'; - - if (!(info = lvmcache_info_from_pvid(pvid_s, 0))) - return; - - info->dev = dev; - info->label->dev = dev; - pv->dev = dev; -} - -/* - * We can see multiple different devices with the - * same pvid, i.e. duplicates. - * - * There may be different reasons for seeing two - * devices with the same pvid: - * - multipath showing two paths to the same thing - * - one device copied to another, e.g. with dd, - * also referred to as cloned devices. - * - a "subsystem" taking a device and creating - * another device of its own that represents the - * underlying device it is using, e.g. using dm - * to create an identity mapping of a PV. - * - * Given duplicate devices, we have to choose one - * of them to be the "preferred" dev, i.e. the one - * that will be referenced in lvmcache, by pv->dev. - * We can keep the existing dev, that's currently - * used in lvmcache, or we can replace the existing - * dev with the new duplicate. - * - * Regardless of which device is preferred, we need - * to print messages explaining which devices were - * found so that a user can sort out for themselves - * what has happened if the preferred device is not - * the one they are interested in. - * - * If a user wants to use the non-preferred device, - * they will need to filter out the device that - * lvm is preferring. - * - * The dev_subsystem calls check if the major number - * of the dev is part of a subsystem like DM/MD/DRBD. - * A dev that's part of a subsystem is preferred over a - * duplicate of that dev that is not part of a - * subsystem. - * - * The has_holders calls check if the device is being - * used by another, and prefers one that's being used. - * - * FIXME: why do we prefer a device without holders - * over a device with holders? We should understand - * the reason for that choice. - * - * FIXME: there may be other reasons to prefer one - * device over another: - * - * . are there other use/open counts we could check - * beyond the holders? - * - * . check if either is bad/usable and prefer - * the good one? - * - * . prefer the one with smaller minor number? - * Might avoid disturbing things due to a new - * transient duplicate? - */ - struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid, struct device *dev, const char *vgname, const char *vgid, @@ -1723,142 +1591,10 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid, lvmcache_del_bas(info); } else { if (existing->dev != dev) { - int old_in_subsystem = 0; - int new_in_subsystem = 0; - int old_is_dm = 0; - int new_is_dm = 0; - int old_has_holders = 0; - int new_has_holders = 0; - - /* - * Here are different devices with the same pvid: - * duplicates. See comment above. - */ - - /* - * This flag tells the process_each_pv code to search - * the devices list for duplicates, so that devices - * can be processed together with their duplicates - * (while processing the VG, rather than reporting - * pv->dev under the VG, and its duplicate outside - * the VG context.) - */ - _found_duplicate_pvs = 1; - - /* - * The new dev may not have pvid set. - * The process_each_pv code needs to have the pvid - * set in each device to detect that the devices - * are duplicates. - */ - strncpy(dev->pvid, pvid_s, sizeof(dev->pvid)); - - /* - * Now decide if we are going to ignore the new - * device, or replace the existing/old device in - * lvmcache with the new one. - */ - old_in_subsystem = dev_subsystem_part_major(dt, existing->dev); - new_in_subsystem = dev_subsystem_part_major(dt, dev); - - old_is_dm = dm_is_dm_major(MAJOR(existing->dev->dev)); - new_is_dm = dm_is_dm_major(MAJOR(dev->dev)); - - old_has_holders = dm_device_has_holders(MAJOR(existing->dev->dev), MINOR(existing->dev->dev)); - new_has_holders = dm_device_has_holders(MAJOR(dev->dev), MINOR(dev->dev)); - - if (old_has_holders && new_has_holders) { - /* - * This is not a selection of old or new, but - * just a warning to be aware of. - */ - log_warn("WARNING: duplicate PV %s is being used from both devices %s and %s", - pvid_s, - dev_name(existing->dev), - dev_name(dev)); - } - - if (existing->vginfo->preferred_duplicates) { - /* - * The preferred duplicate devs have already - * been chosen during a previous populating of - * lvmcache, so just use the existing preferences. - */ - log_warn("Found duplicate PV %s: using existing dev %s", - pvid_s, - dev_name(existing->dev)); - return NULL; - } - - if (old_in_subsystem && !new_in_subsystem) { - /* Use old, ignore new. */ - log_warn("Found duplicate PV %s: using %s not %s", - pvid_s, - dev_name(existing->dev), - dev_name(dev)); - log_warn("Using duplicate PV %s from subsystem %s, ignoring %s", - dev_name(existing->dev), - dev_subsystem_name(dt, existing->dev), - dev_name(dev)); - return NULL; - - } else if (!old_in_subsystem && new_in_subsystem) { - /* Use new, replace old. */ - log_warn("Found duplicate PV %s: using %s not %s", - pvid_s, - dev_name(dev), - dev_name(existing->dev)); - log_warn("Using duplicate PV %s from subsystem %s, replacing %s", - dev_name(dev), - dev_subsystem_name(dt, dev), - dev_name(existing->dev)); - - } else if (old_has_holders && !new_has_holders) { - /* Use new, replace old. */ - /* FIXME: why choose the one without olders? */ - log_warn("Found duplicate PV %s: using %s not %s", - pvid_s, - dev_name(dev), - dev_name(existing->dev)); - log_warn("Using duplicate PV %s without holders, replacing %s", - dev_name(dev), - dev_name(existing->dev)); - - } else if (!old_has_holders && new_has_holders) { - /* Use old, ignore new. */ - log_warn("Found duplicate PV %s: using %s not %s", - pvid_s, - dev_name(existing->dev), - dev_name(dev)); - log_warn("Using duplicate PV %s without holders, ignoring %s", - dev_name(existing->dev), - dev_name(dev)); - return NULL; - - } else if (old_is_dm && new_is_dm) { - /* Use new, replace old. */ - /* FIXME: why choose the new instead of the old? */ - log_warn("Found duplicate PV %s: using %s not %s", - pvid_s, - dev_name(dev), - dev_name(existing->dev)); - log_warn("Using duplicate PV %s which is last seen, replacing %s", - dev_name(dev), - dev_name(existing->dev)); - - } else if (!strcmp(pvid_s, existing->dev->pvid)) { - /* No criteria to use for preferring old or new. */ - /* FIXME: why choose the new instead of the old? */ - /* FIXME: a transient duplicate would be a reason - * to select the old instead of the new. */ - log_warn("Found duplicate PV %s: using %s not %s", - pvid_s, - dev_name(dev), - dev_name(existing->dev)); - log_warn("Using duplicate PV %s which is last seen, replacing %s", - dev_name(dev), - dev_name(existing->dev)); - } + log_warn("Ignore duplicate PV on device %s. Already using PV from device %s. (%s)", + dev_name(dev), dev_name(existing->dev), pvid_s); + log_warn("Use the global_filter to select a different device."); + return NULL; } else { /* * The new dev is the same as the existing dev. diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h index ccf3eb498..b2abfa549 100644 --- a/lib/cache/lvmcache.h +++ b/lib/cache/lvmcache.h @@ -181,13 +181,6 @@ unsigned lvmcache_mda_count(struct lvmcache_info *info); int lvmcache_vgid_is_cached(const char *vgid); 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); - -void lvmcache_set_preferred_duplicates(const char *vgid); - int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd); void lvmcache_get_max_name_lengths(struct cmd_context *cmd, diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c index 7b3b2c6ab..cbf96a67c 100644 --- a/lib/cache/lvmetad.c +++ b/lib/cache/lvmetad.c @@ -469,17 +469,15 @@ static int _pv_populate_lvmcache(struct cmd_context *cmd, struct dm_config_node *cn, struct format_type *fmt, dev_t fallback) { - struct device *dev, *dev_alternate, *dev_alternate_cache = NULL; + struct device *dev; struct label *label; struct id pvid, vgid; char mda_id[32]; char da_id[32]; int i = 0; struct dm_config_node *mda, *da; - struct dm_config_node *alt_devices = dm_config_find_node(cn->child, "devices_alternate"); - struct dm_config_value *alt_device = NULL; uint64_t offset, size; - struct lvmcache_info *info, *info_alternate; + struct lvmcache_info *info; const char *pvid_txt = dm_config_find_str(cn->child, "id", NULL), *vgid_txt = dm_config_find_str(cn->child, "vgid", NULL), *vgname = dm_config_find_str(cn->child, "vgname", NULL), @@ -562,41 +560,6 @@ static int _pv_populate_lvmcache(struct cmd_context *cmd, ++i; } while (da); - if (alt_devices) - alt_device = alt_devices->v; - - while (alt_device) { - dev_alternate = dev_cache_get_by_devt(alt_device->v.i, cmd->filter); - - log_verbose("PV on device %s (%d:%d %d) is also on device %s (%d:%d %d) %s", - dev_name(dev), - (int)MAJOR(devt), (int)MINOR(devt), (int)devt, - dev_alternate ? dev_name(dev_alternate) : "unknown", - (int)MAJOR(alt_device->v.i), (int)MINOR(alt_device->v.i), (int)alt_device->v.i, - pvid_txt); - - if (dev_alternate) { - if ((info_alternate = lvmcache_add(fmt->labeller, (const char *)&pvid, dev_alternate, - vgname, (const char *)&vgid, 0))) { - dev_alternate_cache = dev_alternate; - info = info_alternate; - lvmcache_get_label(info)->dev = dev_alternate; - } - } - alt_device = alt_device->next; - } - - /* - * Update lvmcache with the info about the alternate device by - * reading its label, which should update lvmcache. - */ - if (dev_alternate_cache) { - if (!label_read(dev_alternate_cache, &label, 0)) { - log_warn("No PV label found on duplicate device %s.", dev_name(dev_alternate_cache)); - } - } - - lvmcache_set_preferred_duplicates((const char *)&vgid); return 1; } @@ -1514,6 +1477,7 @@ static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler struct dev_iter *iter; struct device *dev; daemon_reply reply; + struct lvmcache_info *info; int r = 1; char *future_token; int was_silent; diff --git a/tools/toollib.c b/tools/toollib.c index 42ac71a13..f5c1e0084 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -2883,83 +2883,6 @@ static int _process_pvs_in_vg(struct cmd_context *cmd, if (ret > ret_max) ret_max = ret; } - - /* - * We have processed the PV on device pv->dev. Now - * deal with any duplicates of this PV on other - * devices. - */ - - /* - * This is a very rare and obscure case where multiple - * duplicate devices are specified on the command line - * referring to this PV. In this case we want to - * process this PV once for each specified device. - */ - if (!skip && !dm_list_empty(arg_devices)) { - while ((dil = _device_list_find_pvid(arg_devices, pv))) { - _device_list_remove(arg_devices, dil->dev); - - /* - * Replace pv->dev with this dil->dev - * in lvmcache so the duplicate dev - * info will be reported. FIXME: it - * would be nicer to override pv->dev - * without munging lvmcache content. - */ - dev_orig = pv->dev; - lvmcache_replace_dev(cmd, pv, dil->dev); - - log_very_verbose("Processing PV %s device %s in VG %s.", - pv_name, dev_name(dil->dev), vg->name); - - ret = process_single_pv(cmd, vg, pv, handle); - if (ret != ECMD_PROCESSED) - stack; - if (ret > ret_max) - ret_max = ret; - - /* Put the cache state back as it was. */ - lvmcache_replace_dev(cmd, pv, dev_orig); - } - } - - /* - * This is another rare and obscure case where multiple - * 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. - */ - if (process_all_devices && lvmcache_found_duplicate_pvs()) { - while ((dil = _device_list_find_pvid(all_devices, pv))) { - _device_list_remove(all_devices, dil->dev); - - dev_orig = pv->dev; - lvmcache_replace_dev(cmd, pv, dil->dev); - - ret = process_single_pv(cmd, vg, pv, handle); - if (ret != ECMD_PROCESSED) - stack; - if (ret > ret_max) - ret_max = ret; - - lvmcache_replace_dev(cmd, pv, dev_orig); - } - } - - /* - * Remove any duplicates of the processed device from - * the list of all devices. If they were left in the - * list of all devices, they would be considered - * "missed" at the end. - */ - if (process_all_pvs && lvmcache_found_duplicate_pvs()) { - while ((dil = _device_list_find_pvid(all_devices, pv))) { - log_very_verbose("Skip duplicate device %s of processed device %s", - dev_name(dil->dev), dev_name(pv->dev)); - _device_list_remove(all_devices, dil->dev); - } - } } /* |