diff options
author | David Teigland <teigland@redhat.com> | 2015-09-18 09:42:38 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2015-09-18 09:42:38 -0500 |
commit | f82c499dfee90f16cd2a1352d05afae7ae830c14 (patch) | |
tree | ddd86e75a29d0d3c4fbf7c762ad1c51891342c70 | |
parent | 90ad817a43a8c2ef6ca9d6797d5b9e50c6a87cfd (diff) | |
download | lvm2-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.c | 13 |
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); |