diff options
author | David Teigland <teigland@redhat.com> | 2015-09-29 11:07:59 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2015-09-29 11:28:48 -0500 |
commit | 634bf8c953caba4550463281fc0a90ee43c80c8d (patch) | |
tree | f46208d41db2a4bd8cf1f0e34d2294f6a7c65f39 | |
parent | be393f6722bd89f3fe98ab1be2f1dd41609a0172 (diff) | |
download | lvm2-634bf8c953caba4550463281fc0a90ee43c80c8d.tar.gz |
lockd: fix rescanning VG metadata
One host changes a VG, making the cached VG on another
host invalid. The other host then rereads the VG from
disk to get the latest copy. If the first host removed
a PV from the VG, the second host attempts to reread the
VG from old PV when rescanning. Reading the VG from the
removed PV fails, causing vg_read to return "VG not found".
The fix is to simply not fail when a VG is not found while
rereading a PV and continue without it.
(This doesn't happen if the second host happens to first
run a command like 'vgs' that triggers a global revalidation
of metadata.)
-rw-r--r-- | lib/cache/lvmetad.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c index 0fff65a1c..721c4a29b 100644 --- a/lib/cache/lvmetad.c +++ b/lib/cache/lvmetad.c @@ -1122,6 +1122,8 @@ static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton) * due to something like an lvcreate from another host. * This is limited to changes that only affect the vg (not global state like * orphan PVs), so we only need to reread mdas on the vg's existing pvs. + * But, a previous PV in the VG may have been removed since we last read + * the VG, and that PV may have been reused for another VG. */ static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg) @@ -1160,9 +1162,25 @@ static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct vo lvmcache_foreach_mda(info, _lvmetad_pvscan_single, &baton); + /* + * The PV may have been removed from the VG by another host + * since we last read the VG. + */ if (!baton.vg) { + log_debug_lvmetad("Did not find VG %s in scan of PV %s", vg->name, dev_name(pvl->pv->dev)); lvmcache_fmt(info)->ops->destroy_instance(baton.fid); - return NULL; + continue; + } + + /* + * The PV may have been removed from the VG and used for a + * different VG since we last read the VG. + */ + if (strcmp(baton.vg->name, vg->name)) { + log_debug_lvmetad("Did not find VG %s in scan of PV %s which is now VG %s", + vg->name, dev_name(pvl->pv->dev), baton.vg->name); + release_vg(baton.vg); + continue; } if (!(vgmeta = export_vg_to_config_tree(baton.vg))) { |