From aa94d4e48b01760a8e778d2702d5d71391e8190a Mon Sep 17 00:00:00 2001 From: David Teigland Date: Thu, 12 May 2016 16:19:57 -0500 Subject: pvremove: allow clearing a duplicate PV Add a special case to allow modifying a duplicate PV to erase it with pvremove -ff. --- lib/cache/lvmcache.c | 13 +++++++++++++ lib/cache/lvmcache.h | 2 ++ tools/toollib.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index fe2ad07ae..0934b2068 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -459,6 +459,19 @@ int lvmcache_get_unused_duplicate_devs(struct cmd_context *cmd, struct dm_list * return 1; } +void lvmcache_remove_unchosen_duplicate(struct device *dev) +{ + struct device_list *devl; + + dm_list_iterate_items(devl, &_unused_duplicate_devs) { + if (devl->dev == dev) { + dm_list_del(&devl->list); + return; + } + } +} + + static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo, struct lvmcache_info *info) { diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h index 45318b95e..4fb74dbac 100644 --- a/lib/cache/lvmcache.h +++ b/lib/cache/lvmcache.h @@ -211,4 +211,6 @@ void lvmcache_lock_ordering(int enable); int lvmcache_dev_is_unchosen_duplicate(struct device *dev); +void lvmcache_remove_unchosen_duplicate(struct device *dev); + #endif diff --git a/tools/toollib.c b/tools/toollib.c index 429ab9111..ab1361d3d 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -4199,6 +4199,7 @@ int pvcreate_each_device(struct cmd_context *cmd, struct physical_volume *pv; struct volume_group *orphan_vg; struct lvmcache_info *info; + struct dm_list remove_duplicates; struct dm_list arg_sort; struct pv_list *pvl; struct pv_list *vgpvl; @@ -4210,6 +4211,7 @@ int pvcreate_each_device(struct cmd_context *cmd, set_pv_notify(cmd); + dm_list_init(&remove_duplicates); dm_list_init(&arg_sort); handle->custom_handle = pp; @@ -4294,6 +4296,23 @@ int pvcreate_each_device(struct cmd_context *cmd, if (pp->check_failed) goto_bad; + /* + * Special case: pvremove -ff is allowed to clear a duplicate device in + * the unchosen duplicates list. PVs in the unchosen duplicates list + * won't be found by normal process_each searches -- they are not in + * lvmcache and can't be processed normally. We save them here and + * erase them below without going through the normal processing code. + */ + if (pp->is_remove && (pp->force == DONT_PROMPT_OVERRIDE) && + !dm_list_empty(&pp->arg_devices) && lvmcache_found_duplicate_pvs()) { + dm_list_iterate_items_safe(pd, pd2, &pp->arg_devices) { + if (lvmcache_dev_is_unchosen_duplicate(pd->dev)) { + log_debug("Found pvremove arg %s: device is a duplicate.", pd->name); + dm_list_move(&remove_duplicates, &pd->list); + } + } + } + /* * Check if all arg_devices were found by process_each_pv. */ @@ -4313,9 +4332,9 @@ int pvcreate_each_device(struct cmd_context *cmd, goto_bad; /* - * The command cannot continue if there are no devices to create. + * The command cannot continue if there are no devices to process. */ - if (dm_list_empty(&pp->arg_process)) { + if (dm_list_empty(&pp->arg_process) && dm_list_empty(&remove_duplicates)) { log_debug("No devices to process."); goto bad; } @@ -4606,6 +4625,28 @@ do_command: pd->name); } + /* + * Special case: pvremove duplicate PVs (also see above). + */ + dm_list_iterate_items_safe(pd, pd2, &remove_duplicates) { + if (!label_remove(pd->dev)) { + log_error("Failed to wipe existing label(s) on %s.", pd->name); + dm_list_move(&pp->arg_fail, &pd->list); + continue; + } + + if (!lvmetad_pv_gone_by_dev(pd->dev, NULL)) { + log_error("Failed to remove PV %s from lvmetad.", pd->name); + dm_list_move(&pp->arg_fail, &pd->list); + continue; + } + + lvmcache_remove_unchosen_duplicate(pd->dev); + + log_print_unless_silent("Labels on physical volume \"%s\" successfully wiped.", + pd->name); + } + dm_list_iterate_items(pd, &pp->arg_fail) log_debug("%s: command failed for %s.", cmd->command->name, pd->name); -- cgit v1.2.1