diff options
-rw-r--r-- | WHATS_NEW | 1 | ||||
-rw-r--r-- | lib/metadata/metadata-exported.h | 1 | ||||
-rw-r--r-- | lib/metadata/metadata.c | 53 | ||||
-rw-r--r-- | tools/lvmcmdline.c | 1 | ||||
-rw-r--r-- | tools/pvcreate.c | 3 | ||||
-rw-r--r-- | tools/pvdisplay.c | 2 | ||||
-rw-r--r-- | tools/toollib.c | 25 |
7 files changed, 72 insertions, 14 deletions
@@ -1,5 +1,6 @@ Version 2.02.30 - =================================== + Fix process_all_pvs to detect non-orphans with no MDAs correctly. Don't use block_on_error with mirror targets version 1.12 and above. Update vgsplit to include vgcreate-style options when new VG is destination. Update vgsplit to accept existing VG as destination. diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 3d57b6ff..b415b794 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -310,6 +310,7 @@ struct list *get_pvs(struct cmd_context *cmd); /* Set full_scan to 1 to re-read every (filtered) device label */ struct list *get_vgs(struct cmd_context *cmd, int full_scan); struct list *get_vgids(struct cmd_context *cmd, int full_scan); +int scan_vgs_for_pvs(struct cmd_context *cmd); int pv_write(struct cmd_context *cmd, struct physical_volume *pv, struct list *mdas, int64_t label_sector); diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index 5d42ded9..f54a5d16 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -1015,7 +1015,16 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd, return NULL; } - /* FIXME Can fail when no PV mda */ + if (is_orphan_vg(pv->vg_name)) { + /* If a PV has no MDAs - need to search all VGs for it */ + if (!scan_vgs_for_pvs(cmd)) + return_NULL; + if (!(pv = _pv_read(cmd, pv_name, NULL, NULL, 1))) { + log_error("Physical volume %s not found", pv_name); + return NULL; + } + } + if (is_orphan_vg(pv->vg_name)) { log_error("Physical volume %s not in a volume group", pv_name); return NULL; @@ -1788,7 +1797,7 @@ struct list *get_vgids(struct cmd_context *cmd, int full_scan) return lvmcache_get_vgids(cmd, full_scan); } -struct list *get_pvs(struct cmd_context *cmd) +static int _get_pvs(struct cmd_context *cmd, struct list **pvslist) { struct str_list *strl; struct list *results; @@ -1802,17 +1811,19 @@ struct list *get_pvs(struct cmd_context *cmd) lvmcache_label_scan(cmd, 0); - if (!(results = dm_pool_alloc(cmd->mem, sizeof(*results)))) { - log_error("PV list allocation failed"); - return NULL; - } + if (pvslist) { + if (!(results = dm_pool_alloc(cmd->mem, sizeof(*results)))) { + log_error("PV list allocation failed"); + return NULL; + } - list_init(results); + list_init(results); + } /* Get list of VGs */ if (!(vgids = get_vgids(cmd, 0))) { log_error("get_pvs: get_vgs failed"); - return NULL; + return 0; } /* Read every VG to ensure cache consistency */ @@ -1839,16 +1850,36 @@ struct list *get_pvs(struct cmd_context *cmd) vgname); /* Move PVs onto results list */ - list_iterate_safe(pvh, tmp, &vg->pvs) { - list_add(results, pvh); - } + if (pvslist) + list_iterate_safe(pvh, tmp, &vg->pvs) + list_add(results, pvh); } init_pvmove(old_pvmove); init_partial(old_partial); + if (pvslist) + *pvslist = results; + else + dm_pool_free(cmd->mem, vgids); + + return 1; +} + +struct list *get_pvs(struct cmd_context *cmd) +{ + struct list *results; + + if (!_get_pvs(cmd, &results)) + return NULL; + return results; } +int scan_vgs_for_pvs(struct cmd_context *cmd) +{ + return _get_pvs(cmd, NULL); +} + /* FIXME: liblvm todo - make into function that takes handle */ int pv_write(struct cmd_context *cmd __attribute((unused)), struct physical_volume *pv, diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c index 99a406fb..8c74c5a5 100644 --- a/tools/lvmcmdline.c +++ b/tools/lvmcmdline.c @@ -584,7 +584,6 @@ static int _process_command_line(struct cmd_context *cmd, int *argc, a->ui64_value = 0; } - memset(str, 0, sizeof(str)); /* fill in the short and long opts */ for (i = 0; i < cmd->command->num_args; i++) _add_getopt_arg(cmd->command->valid_args[i], &ptr, &o); diff --git a/tools/pvcreate.c b/tools/pvcreate.c index 3e12c5c7..b7932316 100644 --- a/tools/pvcreate.c +++ b/tools/pvcreate.c @@ -51,7 +51,8 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name) * system. */ if (pv && is_orphan(pv)) { - (void) get_vgs(cmd, 1); + if (!scan_vgs_for_pvs(cmd)) + return_0; pv = pv_read(cmd, name, NULL, NULL, 0); } diff --git a/tools/pvdisplay.c b/tools/pvdisplay.c index 7862629c..a2dacf40 100644 --- a/tools/pvdisplay.c +++ b/tools/pvdisplay.c @@ -26,7 +26,7 @@ static int _pvdisplay_single(struct cmd_context *cmd, const char *pv_name = pv_dev_name(pv); const char *vg_name = NULL; - if (!is_orphan(pv) && !vg) { + if (!is_orphan(pv) && !vg) { vg_name = pv_vg_name(pv); if (!(vg = vg_lock_and_read(cmd, vg_name, (char *)&pv->vgid, LCK_VG_READ, CLUSTERED, 0))) { diff --git a/tools/toollib.c b/tools/toollib.c index ab33e4b2..30c7dce3 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -696,6 +696,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, struct str_list *sll; char *tagname; int consistent = 1; + int scanned = 0; list_init(&tags); @@ -738,6 +739,30 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, ret_max = ECMD_FAILED; continue; } + + /* + * If a PV has no MDAs it may appear to be an + * orphan until the metadata is read off + * another PV in the same VG. Detecting this + * means checking every VG by scanning every + * PV on the system. + */ + if (!scanned && is_orphan(pv)) { + if (!scan_vgs_for_pvs(cmd)) { + stack; + ret_max = ECMD_FAILED; + continue; + } + scanned = 1; + if (!(pv = pv_read(cmd, argv[opt], + NULL, NULL, 1))) { + log_error("Failed to read " + "physical volume " + "\"%s\"", argv[opt]); + ret_max = ECMD_FAILED; + continue; + } + } } ret = process_single(cmd, vg, pv, handle); |