summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WHATS_NEW1
-rw-r--r--lib/metadata/metadata-exported.h1
-rw-r--r--lib/metadata/metadata.c53
-rw-r--r--tools/lvmcmdline.c1
-rw-r--r--tools/pvcreate.c3
-rw-r--r--tools/pvdisplay.c2
-rw-r--r--tools/toollib.c25
7 files changed, 72 insertions, 14 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 40ee7a75..19094c9b 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -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);