summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2015-05-06 14:49:44 -0500
committerDavid Teigland <teigland@redhat.com>2015-05-06 15:18:43 -0500
commit6b7ec65c6cbb142338f1efbf083b40e1abe47b1d (patch)
treeff1df2dd27d38a66299b406ac13d2b72910e21d6
parentc9cc86fd6eee750a4b10cab35c426a50c6fd97b0 (diff)
downloadlvm2-dev-dct-lvmcache.tar.gz
lvmcache: choose preferred device oncedev-dct-lvmcache
A command may call vg_lookup to get VG info from lvmetad multiple times. The first time, it copies the VG info into lvmcache, and lvmcache sets the preferred device for PVs (among duplicates). The second time, it copies the VG into lvmcache, we want to leave the previous preferred device selection unchanged. Otherwise, the preferred device for the PV changes each time lvmcache is updated.
-rw-r--r--lib/cache/lvmcache.c33
-rw-r--r--lib/cache/lvmcache.h3
-rw-r--r--lib/cache/lvmetad.c19
3 files changed, 44 insertions, 11 deletions
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 90e7b2843..5c5a9ab2d 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -67,6 +67,7 @@ struct lvmcache_vginfo {
unsigned vg_use_count; /* Counter of vg reusage */
unsigned precommitted; /* Is vgmetadata live or precommitted? */
unsigned cached_vg_invalidated; /* Signal to regenerate cached_vg */
+ unsigned updated_from_lvmetad; /* lvmetad data has been copied to lvmcache */
};
static struct dm_hash_table *_pvid_hash = NULL;
@@ -115,6 +116,27 @@ int lvmcache_init(void)
return 1;
}
+/*
+ * A command may call vg_lookup to get VG info from lvmetad multiple times.
+ * The first time, it copies the VG info into lvmcache, and lvmcache sets the
+ * preferred device for PVs. The second time, it copies the VG into lvmcache,
+ * and we want to leave the previous preferred device selection unchanged.
+ * This flag allows lvmcache to know that lvmcache_add() is being called the
+ * first time.
+ */
+
+void lvmcache_set_updated_from_lvmetad(struct volume_group *vg)
+{
+ struct lvmcache_vginfo *vginfo;
+
+ if (!(vginfo = lvmcache_vginfo_from_vgid((const char *)&vg->id))) {
+ stack;
+ return;
+ }
+
+ vginfo->updated_from_lvmetad = 1;
+}
+
void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd)
{
if (!lvmetad_active() || _has_scanned)
@@ -1689,6 +1711,13 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
dev_name(dev));
}
+ if (existing->vginfo->updated_from_lvmetad) {
+ log_warn("Found duplicate PV %s: using existing dev %s",
+ pvid_s,
+ dev_name(existing->dev));
+ return NULL;
+ }
+
if (old_in_subsystem && !new_in_subsystem) {
/* Use old, ignore new. */
log_warn("Found duplicate PV %s: using %s not %s",
@@ -1741,7 +1770,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
pvid_s,
dev_name(dev),
dev_name(existing->dev));
- log_warn("Using duplicate PV %s which is more recent, replacing %s",
+ log_warn("Using duplicate PV %s which is last seen, replacing %s",
dev_name(dev),
dev_name(existing->dev));
@@ -1754,7 +1783,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
pvid_s,
dev_name(dev),
dev_name(existing->dev));
- log_warn("Using duplicate PV %s which is more recent, replacing %s",
+ log_warn("Using duplicate PV %s which is last seen, replacing %s",
dev_name(dev),
dev_name(existing->dev));
}
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 6c4c927ed..015f650a7 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -171,4 +171,7 @@ void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv,
int lvmcache_found_duplicate_pvs(void);
+void lvmcache_set_updated_from_lvmetad(struct volume_group *vg);
+
+
#endif
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 00a84b51e..0894c791c 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -265,9 +265,9 @@ static int _read_mda(struct lvmcache_info *info,
return 0;
}
-static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
- struct dm_config_node *cn,
- struct format_type *fmt, dev_t fallback)
+static int _pv_populate_lvmcache(struct cmd_context *cmd,
+ struct dm_config_node *cn,
+ struct format_type *fmt, dev_t fallback)
{
struct device *dev, *dev_alternate, *dev_alternate_cache = NULL;
struct label *label;
@@ -293,7 +293,7 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
if (!fmt) {
log_error("PV %s not recognised. Is the device missing?", pvid_txt);
- return NULL;
+ return 0;
}
dev = dev_cache_get_by_devt(devt, cmd->filter);
@@ -302,17 +302,17 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
if (!dev) {
log_warn("WARNING: Device for PV %s not found or rejected by a filter.", pvid_txt);
- return NULL;
+ return 0;
}
if (!pvid_txt || !id_read_format(&pvid, pvid_txt)) {
log_error("Missing or ill-formatted PVID for PV: %s.", pvid_txt);
- return NULL;
+ return 0;
}
if (vgid_txt) {
if (!id_read_format(&vgid, vgid_txt))
- return_NULL;
+ return_0;
} else
strcpy((char*)&vgid, fmt->orphan_vg_name);
@@ -321,7 +321,7 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
if (!(info = lvmcache_add(fmt->labeller, (const char *)&pvid, dev,
vgname, (const char *)&vgid, 0)))
- return_NULL;
+ return_0;
lvmcache_get_label(info)->sector = label_sector;
lvmcache_get_label(info)->dev = dev;
@@ -390,7 +390,7 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
}
}
- return info;
+ return 1;
}
struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgname, const char *vgid)
@@ -478,6 +478,7 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
lvmcache_update_vg(vg, 0);
vg_mark_partial_lvs(vg, 1);
+ lvmcache_set_updated_from_lvmetad(vg);
}
out: