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-21 16:27:43 -0500
commite2a645fe3d31c29dd9feb9f598b4bbbe4a7afa92 (patch)
tree6117d3c0c7586826ffdeaeed469bbaff2e7087d2
parent73e679f33f411c65c9b7c7e4e501d97245f0bf5d (diff)
downloadlvm2-e2a645fe3d31c29dd9feb9f598b4bbbe4a7afa92.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 64d998ec3..16045f51e 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -845,13 +845,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);