summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2023-02-09 17:14:19 -0600
committerDavid Teigland <teigland@redhat.com>2023-02-09 17:37:22 -0600
commitbe124ae81027e8736106e4958bd2dfab971d6764 (patch)
tree281729764d22b78a132d76e9ac669a8d2c0862f2
parent94f77a4d8d9737fca05fb4e451678ec440c68670 (diff)
downloadlvm2-be124ae81027e8736106e4958bd2dfab971d6764.tar.gz
vgimportclone: fix non-duplicate PV with non-unique basevgname arg
Fix hang of vgimportclone command when: the PV(s) being imported are not actually clones/duplicates, and the -n vgname arg is the same as the current vgname. (Not the intended use of the command, but it should still work.) In this case, the old and new vgnames ended up being the same, when the code expected they would be different. A file lock on both the old and new vgnames is used, so when both flocks are on the same file, the second blocks indefinitely. Fix the new vgname to be the old name plus a numeric suffix, which is the expected result.
-rw-r--r--test/shell/vgimportclone.sh20
-rw-r--r--tools/vgimportclone.c15
2 files changed, 33 insertions, 2 deletions
diff --git a/test/shell/vgimportclone.sh b/test/shell/vgimportclone.sh
index e1b9d3832..13924c3dd 100644
--- a/test/shell/vgimportclone.sh
+++ b/test/shell/vgimportclone.sh
@@ -104,6 +104,26 @@ pvremove "$dev1"
pvremove "$dev2"
pvremove "$dev3"
+# Test importing a non-duplicate pv using the existing vg name
+vgcreate $vg1 "$dev1"
+vgimportclone -n $vg1 "$dev1"
+vgs ${vg1}1
+not vgs $vg1
+vgremove ${vg1}1
+
+# Test importing a non-duplicate pv using the existing vg name
+# Another existing VG is using the initial generated vgname with
+# the "1" suffix, so "2" is used.
+vgcreate $vg1 "$dev1"
+vgcreate ${vg1}1 "$dev2"
+vgimportclone -n $vg1 "$dev1"
+vgs ${vg1}1
+vgs ${vg1}2
+vgremove ${vg1}1
+vgremove ${vg1}2
+pvremove "$dev1"
+pvremove "$dev2"
+
# Verify that if we provide the -n|--basevgname,
# the number suffix is not added unnecessarily.
vgcreate $SHARED --metadatasize 128k A${vg1}B "$dev1"
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
index 93fa3b18d..a6d055f7f 100644
--- a/tools/vgimportclone.c
+++ b/tools/vgimportclone.c
@@ -407,8 +407,19 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
log_error("Base vg name %s is too long.", vgname);
goto out;
}
- (void) dm_strncpy(tmp_vgname, base_vgname, NAME_LEN);
- vgname_count = 0;
+ if (strcmp(vgname, vp.old_vgname)) {
+ (void) dm_strncpy(tmp_vgname, base_vgname, NAME_LEN);
+ vgname_count = 0;
+ } else {
+ /* Needed when basename matches old name, and PV is not a duplicate
+ which means old name is not found on other devs, and is not seen
+ in the vgnames search below, causing old and new names to match. */
+ if (dm_snprintf(tmp_vgname, sizeof(tmp_vgname), "%s1", vp.old_vgname) < 0) {
+ log_error("Temporary vg name %s1 is too long.", vp.old_vgname);
+ goto out;
+ }
+ vgname_count = 1;
+ }
} else {
if (dm_snprintf(base_vgname, sizeof(base_vgname), "%s", vp.old_vgname) < 0) {
log_error(INTERNAL_ERROR "Old vg name %s is too long.", vp.old_vgname);