diff options
author | David Teigland <teigland@redhat.com> | 2014-06-18 15:25:46 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2014-06-20 14:40:57 -0500 |
commit | 5084bbca50281eeab2a1e64ec60fd2745a11b656 (patch) | |
tree | c331c9158f2098b7698e0b77a6e2d20ce1f83a18 | |
parent | 394ed9cf44c3d92169610232d9db60c67f9d05c3 (diff) | |
download | lvm2-dev-dct-process-v20.tar.gz |
toollib: process_each_pv workaround for no mda pvsdev-dct-process-v20
Add a workaround for a bug somewhere that can cause
a pv with no mda to appear in both its real vg and
in the orphan vg when not using lvmetad.
-rw-r--r-- | tools/toollib.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/tools/toollib.c b/tools/toollib.c index aed352cd1..9ae29327f 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -1858,17 +1858,17 @@ static int get_all_devs(struct cmd_context *cmd, struct dm_list *all_devs) return ECMD_PROCESSED; } -static void device_list_remove(struct dm_list *all_devs, struct device *dev) +static int device_list_remove(struct dm_list *all_devs, struct device *dev) { struct device_list *devl; dm_list_iterate_items(devl, all_devs) { if (devl->dev == dev) { dm_list_del(&devl->list); - return; + return 1; } } - log_error(INTERNAL_ERROR "device_list_remove %s not found", dev_name(dev)); + return 0; } static int process_dev_list(struct cmd_context *cmd, struct dm_list *all_devs, @@ -1914,6 +1914,7 @@ static int process_pvs_in_vg(struct cmd_context *cmd, struct pv_list *pvl; const char *pv_name; int process_pv; + int dev_found; int ret_max = ECMD_PROCESSED; int ret = 0; @@ -1948,8 +1949,23 @@ static int process_pvs_in_vg(struct cmd_context *cmd, else log_very_verbose("Processing PV %s in VG %s", pv_name, vg->name); - if (all_devs) - device_list_remove(all_devs, pv->dev); + dev_found = device_list_remove(all_devs, pv->dev); + + /* + * There's a bug somewhere that can cause pvs with no mdas + * to appear in both their real vg and the orphan vg when + * not using lvmetad. + * + * These pvs are not missing and they will not be found in + * all_devs the second time they are encountered here. + * + * Missing pvs will also not be found in all_devs, but we + * do want to process missing pvs. + */ + if (!dev_found && !is_missing_pv(pv)) { + log_verbose("Skipping PV %s in VG %s not in device list", pv_name, vg->name); + continue; + } if (!skip) ret = process_single_pv(cmd, vg, pv, handle); @@ -2084,18 +2100,15 @@ int process_each_pv(struct cmd_context *cmd, * from all vgs are processed first, removing each from all_devs. Then * any devs remaining in all_devs are processed. */ - if (process_all_devs) { - ret = get_all_devs(cmd, &all_devs); - if (ret != ECMD_PROCESSED) - return ret; - } + ret = get_all_devs(cmd, &all_devs); + if (ret != ECMD_PROCESSED) + return ret; ret = get_all_vgnames(cmd, &all_vgnames, vg_name, 1); if (ret != ECMD_PROCESSED) return ret; - ret = process_pvs_in_vgs(cmd, flags, &all_vgnames, - process_all_devs ? &all_devs : NULL, + ret = process_pvs_in_vgs(cmd, flags, &all_vgnames, &all_devs, &arg_pvnames, &arg_tags, process_all_pvs, handle, process_single_pv); if (ret > ret_max) @@ -2104,7 +2117,7 @@ int process_each_pv(struct cmd_context *cmd, if (sigint_caught()) goto out; - if (dm_list_empty(&all_devs)) + if (!process_all_devs) goto out; ret = process_dev_list(cmd, &all_devs, handle, process_single_pv); |