summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2014-06-18 15:25:46 -0500
committerDavid Teigland <teigland@redhat.com>2014-06-20 14:40:57 -0500
commit5084bbca50281eeab2a1e64ec60fd2745a11b656 (patch)
treec331c9158f2098b7698e0b77a6e2d20ce1f83a18
parent394ed9cf44c3d92169610232d9db60c67f9d05c3 (diff)
downloadlvm2-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.c39
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);