diff options
-rw-r--r-- | lib/cache/lvmcache.c | 16 | ||||
-rw-r--r-- | lib/cache/lvmcache.h | 3 | ||||
-rw-r--r-- | tools/toollib.c | 28 |
3 files changed, 45 insertions, 2 deletions
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index 746d58cd2..d93494879 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -1467,6 +1467,22 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted) return 1; } +void lvmcache_change_pv_dev(struct cmd_context *cmd, const char *pvid, + struct device *dev) +{ + struct lvmcache_info *info; + char pvid_s[ID_LEN + 1] __attribute__((aligned(8))); + + strncpy(pvid_s, pvid, 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; +} + struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid, struct device *dev, const char *vgname, const char *vgid, diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h index d43866dca..d1d131326 100644 --- a/lib/cache/lvmcache.h +++ b/lib/cache/lvmcache.h @@ -157,4 +157,7 @@ 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_change_pv_dev(struct cmd_context *cmd, const char *pvid, + struct device *dev); + #endif diff --git a/tools/toollib.c b/tools/toollib.c index 542ac8b39..3aecfbd3d 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -2224,6 +2224,18 @@ static int _device_list_match_pvid(struct dm_list *devices, struct physical_volu return 0; } +static struct device *_device_list_find_pvid(struct dm_list *devices, struct physical_volume *pv) +{ + struct device_list *devl; + + dm_list_iterate_items(devl, devices) { + if (id_equal((struct id *) devl->dev->pvid, &pv->id)) + return devl->dev; + } + + return 0; +} + static int _process_device_list(struct cmd_context *cmd, struct dm_list *all_devices, void *handle, process_single_pv_fn_t process_single_pv) { @@ -2349,15 +2361,27 @@ static int _process_pvs_in_vg(struct cmd_context *cmd, */ if (!skip && !dm_list_empty(arg_devices) && !dm_list_empty(arg_duplicates) && _device_list_match_pvid(arg_devices, pv)) { - log_warn("PV %s is repeated for duplicate command arg.", pv_name); + struct device *dev_dup; - _device_list_remove_pvid(arg_devices, pv); + /* Munge things so PV now looks like it's on dev_dup. */ + + dev_dup = _device_list_find_pvid(arg_devices, pv); + if (dev_dup) { + log_warn("Repeat device %s as duplicate %s", + dev_name(pv->dev), dev_name(dev_dup)); + + lvmcache_change_pv_dev(cmd, (const char *)&pv->id, dev_dup); + pv->dev = dev_dup; + /* Swap things back after process_single? */ + } ret = process_single_pv(cmd, vg, pv, handle); if (ret != ECMD_PROCESSED) stack; if (ret > ret_max) ret_max = ret; + + _device_list_remove_pvid(arg_devices, pv); } } |