summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2015-09-18 09:42:38 -0500
committerDavid Teigland <teigland@redhat.com>2015-10-14 14:42:50 -0500
commit367bd9f058216fbae18288e168fce97c63b377d5 (patch)
treea7f28402d2210976886d2a1373214ca217ba19af
parentdf34fcdafd20ac195e588a06c8fc5a904fa71669 (diff)
downloadlvm2-367bd9f058216fbae18288e168fce97c63b377d5.tar.gz
lvmetad: fix update_metadata with new vgid
When vgchange -u changes the vgid in an existing VG, it invokes update_metadata() in lvmetad with the existing VG name but a new vgid. update_metadata() doesn't recognize this condition, and ends up with in correct state, e.g. the existing name is missing in the vgname_to_vgid hash table. This fixes update_metadata() to recognize when an existing VG name is being updated with a new vgid, and in that case first calls remove_metadata() on the old vgid, before continuing with update_metadata() which will add the updated VG as if it were new. One known shortcoming of this approach is that the VG is missing from lvmetad hash tables completely in the short time between the remove and adding it again. Other commands that look up the VG in that window will not find it.
-rw-r--r--daemons/lvmetad/lvmetad-core.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 89aaaf84c..f8c712978 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -843,13 +843,26 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid
int seq;
int haveseq = -1;
const char *oldname = NULL;
+ const char *oldvgid = NULL;
const char *vgid;
char *cfgname;
lock_vgid_to_metadata(s);
old = dm_hash_lookup(s->vgid_to_metadata, _vgid);
oldname = dm_hash_lookup(s->vgid_to_vgname, _vgid);
+ /* If _vgid is unknown, it may be a new vgid for an existing vg. */
+ if (!oldname)
+ oldvgid = dm_hash_lookup(s->vgname_to_vgid, name);
unlock_vgid_to_metadata(s);
+
+ if (oldvgid) {
+ DEBUGLOG(s, "Existing name %s with vgid %s has new vgid %s",
+ name, oldvgid, _vgid);
+ remove_metadata(s, oldvgid, 1);
+ oldname = NULL;
+ oldvgid = NULL;
+ }
+
lock_vg(s, _vgid);
seq = dm_config_find_int(metadata, "metadata/seqno", -1);