summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2015-09-18 09:42:38 -0500
committerDavid Teigland <teigland@redhat.com>2015-09-18 09:42:38 -0500
commitf82c499dfee90f16cd2a1352d05afae7ae830c14 (patch)
treeddd86e75a29d0d3c4fbf7c762ad1c51891342c70
parent90ad817a43a8c2ef6ca9d6797d5b9e50c6a87cfd (diff)
downloadlvm2-dev-dct-vgchange-uuid.tar.gz
lvmetad: fix update_metadata with new vgiddev-dct-vgchange-uuid
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);