summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/cache/lvmcache.c16
-rw-r--r--lib/cache/lvmcache.h3
-rw-r--r--tools/toollib.c28
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);
}
}