summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2014-11-06 14:01:12 -0600
committerDavid Teigland <teigland@redhat.com>2014-11-07 12:52:54 -0600
commit9da53f0d7853a5d1ebe6bb98256a9dc5b17a8b1b (patch)
treee5700128d8ca20413b7a422c2edcf1a5428299f5
parentd5ad2a15f43e7246490baa208faf32682b3044cd (diff)
downloadlvm2-dev-dct-lvmetad-3.tar.gz
lvmcache: reread vg if the lvmetad copy is staledev-dct-lvmetad-3
-rw-r--r--lib/cache/lvmetad.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index ccdf63a35..30ebd916c 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -34,6 +34,8 @@ static char *_lvmetad_token = NULL;
static const char *_lvmetad_socket = NULL;
static struct cmd_context *_lvmetad_cmd = NULL;
+static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg);
+
void lvmetad_disconnect(void)
{
if (_lvmetad_connected)
@@ -442,6 +444,15 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
pvl->pv->status |= MISSING_PV; /* probably missing */
}
+ /*
+ * locking may have detected a newer vg version and
+ * invalidated the cached vg.
+ */
+ if (dm_config_find_node(reply.cft->root, "vg_invalid")) {
+ log_debug_lvmetad("Update invalid lvmetad cache for VG %s", vgname);
+ vg = lvmetad_pvscan_vg(cmd, vg);
+ }
+
lvmcache_update_vg(vg, 0);
vg_mark_partial_lvs(vg, 1);
}
@@ -902,6 +913,67 @@ static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
return 1;
}
+/*
+ * The lock manager may detect that the vg cached in lvmetad is out of date,
+ * 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.
+ */
+
+static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg)
+{
+ struct volume_group *vg_ret = NULL;
+ struct pv_list *pvl;
+ struct device *dev;
+ struct label *label;
+ struct lvmcache_info *info;
+ struct _lvmetad_pvscan_baton baton;
+ /* Create a dummy instance. */
+ struct format_instance_ctx fic = { .type = 0 };
+
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ /* missing pv */
+ if (!pvl->pv->dev)
+ continue;
+
+ dev = pvl->pv->dev;
+
+ if (!label_read(dev, &label, 0)) {
+ log_print_unless_silent("No PV label found on %s.", dev_name(dev));
+ continue;
+ }
+
+ info = (struct lvmcache_info *) label->info;
+
+ baton.vg = NULL;
+ baton.fid = lvmcache_fmt(info)->ops->create_instance(lvmcache_fmt(info), &fic);
+
+ if (!baton.fid)
+ return NULL;
+
+ if (baton.fid->fmt->features & FMT_OBSOLETE) {
+ log_error("WARNING: Ignoring obsolete format of metadata (%s) on device %s when using lvmetad",
+ baton.fid->fmt->name, dev_name(dev));
+ lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
+ return NULL;
+ }
+
+ lvmcache_foreach_mda(info, _lvmetad_pvscan_single, &baton);
+
+ if (!baton.vg) {
+ lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
+ return NULL;
+ }
+
+ if (!vg_ret)
+ vg_ret = baton.vg;
+ else
+ release_vg(baton.vg);
+ }
+
+ return vg_ret;
+}
+
int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
activation_handler handler)
{