From e97023804a8aa94d723025506fa23cf4a5c323e9 Mon Sep 17 00:00:00 2001 From: Petr Rockai Date: Tue, 6 Jan 2015 14:17:53 +0100 Subject: [PATCH] pvremove: Avoid metadata re-reads & related error messages. --- WHATS_NEW | 1 + lib/metadata/metadata-exported.h | 4 ++- lib/metadata/pv_manip.c | 61 +++++++++++++++++++++++--------- liblvm/lvm_pv.c | 9 ++++- test/shell/pvremove-warnings.sh | 5 +++ tools/pvremove.c | 15 ++++---- 6 files changed, 69 insertions(+), 26 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index c1a38c70c..37611da78 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.115 - ===================================== + Avoid excessive re-reading of metadata and related error messages in pvremove. Check for cmirror availability during cluster mirror creation and activation. Add cache_policy and cache_settings reporting fields. Add missing recognition for --binary option with {pv,vg,lv}display -C. diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index b8946ba6c..14a5ef518 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -635,7 +635,9 @@ struct physical_volume *pv_create(const struct cmd_context *cmd, int pvremove_single(struct cmd_context *cmd, const char *pv_name, void *handle __attribute__((unused)), unsigned force_count, - unsigned prompt); + unsigned prompt, struct dm_list *pvslist); +int pvremove_many(struct cmd_context *cmd, struct dm_list *pv_names, + unsigned force_count, unsigned prompt); int pv_resize_single(struct cmd_context *cmd, struct volume_group *vg, diff --git a/lib/metadata/pv_manip.c b/lib/metadata/pv_manip.c index 6499e361d..ce7f66140 100644 --- a/lib/metadata/pv_manip.c +++ b/lib/metadata/pv_manip.c @@ -24,6 +24,7 @@ #include "display.h" #include "label.h" #include "archiver.h" +#include "lvm-signal.h" static struct pv_segment *_alloc_pv_segment(struct dm_pool *mem, struct physical_volume *pv, @@ -694,12 +695,11 @@ const char _really_wipe[] = * 0 indicates we may not. */ static int pvremove_check(struct cmd_context *cmd, const char *name, - unsigned force_count, unsigned prompt) + unsigned force_count, unsigned prompt, struct dm_list *pvslist) { struct device *dev; struct label *label; struct pv_list *pvl; - struct dm_list *pvslist; struct physical_volume *pv = NULL; int r = 0; @@ -720,10 +720,6 @@ static int pvremove_check(struct cmd_context *cmd, const char *name, return 0; } - lvmcache_seed_infos_from_lvmetad(cmd); - if (!(pvslist = get_pvs(cmd))) - return_0; - dm_list_iterate_items(pvl, pvslist) if (pvl->pv->dev == dev) pv = pvl->pv; @@ -765,26 +761,18 @@ static int pvremove_check(struct cmd_context *cmd, const char *name, r = 1; out: - if (pvslist) - dm_list_iterate_items(pvl, pvslist) - free_pv_fid(pvl->pv); return r; } int pvremove_single(struct cmd_context *cmd, const char *pv_name, void *handle __attribute__((unused)), unsigned force_count, - unsigned prompt) + unsigned prompt, struct dm_list *pvslist) { struct device *dev; struct lvmcache_info *info; int r = 0; - if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) { - log_error("Can't get lock for orphan PVs"); - return 0; - } - - if (!pvremove_check(cmd, pv_name, force_count, prompt)) + if (!pvremove_check(cmd, pv_name, force_count, prompt, pvslist)) goto out; if (!(dev = dev_cache_get(pv_name, cmd->filter))) { @@ -819,10 +807,49 @@ int pvremove_single(struct cmd_context *cmd, const char *pv_name, r = 1; +out: + return r; +} + +int pvremove_many(struct cmd_context *cmd, struct dm_list *pv_names, + unsigned force_count, unsigned prompt) +{ + int ret = 1; + struct dm_list *pvslist = NULL; + struct pv_list *pvl; + const struct dm_str_list *pv_name; + + if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) { + log_error("Can't get lock for orphan PVs"); + return 0; + } + + lvmcache_seed_infos_from_lvmetad(cmd); + + if (!(pvslist = get_pvs(cmd))) { + ret = 0; + goto_out; + } + + dm_list_iterate_items(pv_name, pv_names) { + if (!pvremove_single(cmd, pv_name->str, NULL, force_count, prompt, pvslist)) { + stack; + ret = 0; + } + if (sigint_caught()) { + ret = 0; + goto_out; + } + } + out: unlock_vg(cmd, VG_ORPHANS); - return r; + if (pvslist) + dm_list_iterate_items(pvl, pvslist) + free_pv_fid(pvl->pv); + + return ret; } int pvcreate_single(struct cmd_context *cmd, const char *pv_name, diff --git a/liblvm/lvm_pv.c b/liblvm/lvm_pv.c index 64b01d500..24b27327f 100644 --- a/liblvm/lvm_pv.c +++ b/liblvm/lvm_pv.c @@ -16,6 +16,7 @@ #include "lib.h" #include "metadata.h" #include "lvm-string.h" +#include "str_list.h" #include "lvm_misc.h" #include "lvm2app.h" #include "locking.h" @@ -118,8 +119,14 @@ int lvm_pv_remove(lvm_t libh, const char *pv_name) int rc = 0; struct cmd_context *cmd = (struct cmd_context *)libh; struct saved_env e = store_user_env(cmd); + struct dm_list pv_names; - if (!pvremove_single(cmd, pv_name, NULL, 0, 0)) + dm_list_init(&pv_names); + + if (!str_list_add(cmd->mem, &pv_names, pv_name)) + rc = -1; + + if (rc >= 0 && !pvremove_many(cmd, &pv_names, 0, 0)) rc = -1; restore_user_env(&e); diff --git a/test/shell/pvremove-warnings.sh b/test/shell/pvremove-warnings.sh index f9d273729..865a31eaa 100644 --- a/test/shell/pvremove-warnings.sh +++ b/test/shell/pvremove-warnings.sh @@ -14,3 +14,8 @@ aux prepare_devs 2 pvcreate "$dev1" "$dev2" pvremove "$dev1" "$dev2" 2>&1 | tee pvremove.txt not grep "No physical" pvremove.txt + +pvcreate "$dev1" "$dev2" +vgcreate bla $dev1 $dev2 +pvremove -ff -y $dev1 $dev2 2>&1 | tee pvremove.txt +not grep "device missing" pvremove.txt diff --git a/tools/pvremove.c b/tools/pvremove.c index 035d4fd4e..b40ff794a 100644 --- a/tools/pvremove.c +++ b/tools/pvremove.c @@ -18,9 +18,9 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv) { int i; - int ret = ECMD_PROCESSED; unsigned force_count; unsigned prompt; + struct dm_list pv_names; if (!argc) { log_error("Please enter a physical volume path"); @@ -30,15 +30,16 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv) force_count = arg_count(cmd, force_ARG); prompt = arg_count(cmd, yes_ARG); + dm_list_init(&pv_names); + for (i = 0; i < argc; i++) { dm_unescape_colons_and_at_signs(argv[i], NULL, NULL); - if (!pvremove_single(cmd, argv[i], NULL, force_count, prompt)) { - stack; - ret = ECMD_FAILED; - } - if (sigint_caught()) + if (!str_list_add(cmd->mem, &pv_names, argv[i])) return_ECMD_FAILED; } - return ret; + if (!pvremove_many(cmd, &pv_names, force_count, prompt)) + return_ECMD_FAILED; + + return ECMD_PROCESSED; }