1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

handle duplicate vgids

The approach to duplicate VGIDs has been that it is not possible
or not allowed, so the behavior has been undefined.  The actual
result was unpredictable and/or broken, and generally unhelpful.

Improve this by recognizing the problem, displaying the VGs,
and printing a warning to fix the problem.  Beyond this,
using VGs with duplicate VGIDs remains undefined, but should
work well enough to correct the problem with vgchange -u.

It's possible to create this condition without too much difficulty
by cloning PVs, followed by an incomplete attempt at making the two
VGs unique (vgrename and pvchange -u, but missing vgchange -u.)
This commit is contained in:
David Teigland 2022-01-06 10:15:16 -06:00
parent 42a16aa6f3
commit bd2baeaaa6
2 changed files with 68 additions and 4 deletions

20
lib/cache/lvmcache.c vendored
View File

@ -354,9 +354,11 @@ static struct lvmcache_vginfo *_vginfo_lookup(const char *vgname, const char *vg
if (vgid_arg) { if (vgid_arg) {
if ((vginfo = dm_hash_lookup(_vgid_hash, vgid))) { if ((vginfo = dm_hash_lookup(_vgid_hash, vgid))) {
if (vgname && strcmp(vginfo->vgname, vgname)) { if (vgname && strcmp(vginfo->vgname, vgname)) {
/* should never happen */ log_warn("WARNING: lookup found duplicate VGID %s for VGs %s and %s.", vgid, vginfo->vgname, vgname);
log_error(INTERNAL_ERROR "vginfo_lookup vgid %s has two names %s %s", if ((vginfo = dm_hash_lookup(_vgname_hash, vgname))) {
vgid, vginfo->vgname, vgname); if (!memcmp(vginfo->vgid, vgid, ID_LEN))
return vginfo;
}
return NULL; return NULL;
} }
return vginfo; return vginfo;
@ -1884,7 +1886,17 @@ static int _lvmcache_update_vgname(struct cmd_context *cmd,
_drop_vginfo(info, info->vginfo); _drop_vginfo(info, info->vginfo);
if (!(vginfo = lvmcache_vginfo_from_vgid(vgid))) { vginfo = lvmcache_vginfo_from_vgid(vgid);
if (vginfo && strcmp(vginfo->vgname, vgname)) {
log_warn("WARNING: fix duplicate VGID %s for VGs %s and %s (see vgchange -u).", vgid_dashed, vgname, vginfo->vgname);
vginfo = lvmcache_vginfo_from_vgname(vgname, NULL);
if (vginfo && memcmp(vginfo->vgid, vgid, ID_LEN)) {
log_error("Ignoring %s with conflicting VG info %s %s.", dev_name(info->dev), vgid_dashed, vgname);
return_0;
}
}
if (!vginfo) {
/* /*
* Create a vginfo struct for this VG and put the vginfo * Create a vginfo struct for this VG and put the vginfo
* into the hash table. * into the hash table.

View File

@ -0,0 +1,52 @@
#!/usr/bin/env bash
# Copyright (C) 2008-2013 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
SKIP_WITH_LVMLOCKD=1
SKIP_WITH_LVMPOLLD=1
. lib/inittest
aux prepare_devs 2
vgcreate $vg1 "$dev1"
vgchange --setautoactivation n $vg1
UUID1=$(vgs --noheading -o vg_uuid $vg1 | xargs)
lvcreate -l1 -an -n $lv1 $vg1
dd if="$dev1" of="$dev2" bs=1M count=1
aux disable_dev "$dev1"
vgrename $vg1 $vg2
pvchange -u "$dev2"
aux enable_dev "$dev1"
vgs -o+uuid |tee out
grep $vg1 out | tee out1
grep $UUID1 out1
grep $vg2 out | tee out2
grep $UUID1 out2
vgs $vg1
vgs $vg2
lvs $vg1/$lv1
lvs $vg2/$lv1
lvremove $vg1/$lv1
lvremove $vg2/$lv1
lvcreate -l1 -an -n $lv2 $vg1
lvcreate -l1 -an -n $lv3 $vg2
vgchange -u $vg2
vgs -o uuid $vg1 |tee out
grep $UUID1 out
vgs -o uuid $vg2 |tee out
not grep $UUID1 out
vgremove -ff $vg1
vgremove -ff $vg2