[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lvm-devel] [DRAFT PATCH] Client-side LVMetaD integration



Hi,

I have a preliminary version (really preliminary, it is full of debug
junk, excuse me please) of client-side integration of lvmetad. There
comes an executive summary:

- We do not disable label scanning just yet (which is the major cause of
  IO hitting disk). We can get there, but two things need to be sorted
  out first: tracking MDAs (more about that below) and building up
  lvmcache info structures from lvmetad data. This is required because
  we are not quite ready to nuke lvmcache right now (but we'll get
  there, bear with me).

- With lvmetad as the primary source of metadata, *most* of the test
  suite gets through happily. There are the exceptions, sorted into bins
  by problems tripping the test:

1. Code fails to notice inconsistencies (VG metadata is cached and not
   enough manual scanning can happen due to below).

   FAILED: shell/inconsistent-metadata.sh
   FAILED: shell/unlost-pv.sh

2. Pvscan is not entirely integrated with lvmetad yet. Moreover, even if
   we fully update the PV status from pvscan (we currently only add PVs,
   not remove them even if they failed to turn up), there will be a
   problem that a VG with all PVs missing is currently regarded as
   existing by lvmetad. This can be fixed (i.e. last PV disappears means
   the VG ceases to exist), but should be probably discussed first.

   FAILED: shell/lvmcache-exercise.sh

3. MDA info is out of band from metadata. Needs to be merged with
   metadata in lvmetad, otherwise lvmetad can't keep track of this.
   This will in turn prompt a reform of the format_instance code, which
   is an utter mess anyway, and needs to be cleaned up ASAP. A central
   place to obtain the MDA infos is requisite, otherwise we can't
   disable label scanning.

   FAILED: shell/metadata-balance.sh
   FAILED: shell/pvcreate-usage.sh
   FAILED: shell/vgextend-usage.sh

4. Wrong format reported (lvm2, but the VG itself is lvm1) due to
   importing text metadata from lvmetad. Same problem exists with
   reading text backups of LVM1 VGs, but this is not caught by the
   testsuite. There is an old FIXME around. Extending LVM2 metadata with
   a "semantics" version marker saying "this is LVM1 even though you are
   looking at text metadata" would fix the problem. We can also handle
   this out of band in lvmetad, but it is inelegant and leaves tho other
   problem open.

   FAILED: shell/vgcreate-usage.sh

5. Timing issues, most likely tripped up by different timing of the
   operations in presence of lvmetad. Some of the vgchange -an calls
   fail due to still-open LVs (lvmetad itself never opens any devices
   though). Inserting sleep 1 before the deactivation makes the test
   pass.

   FAILED: shell/vgsplit-operation.sh

So that's it. 1 seems to be an improper subtask of 2, 2 is not hard to
hack up (by telling lvmetad to orphan all PVs and feed the live ones
back) although a proper solution may be tricky (the hack is prone to
leave things haywire if crashes happen). 4 shouldn't be very hard. 5 is
*likely* unrelated to lvmetad. That leaves number 3, which needs some
extra work to be done upfront.

When all of the above is addressed, plus we can populate lvmcache
objects from lvmetad, we should be in a position to pull the plug on
label scans when lvmetad is around. Let's wish for a smooth ride. :-)

Yours,
   Petr

PS: I'll try to dig into the MDA issue a bit more to come up with an
attack plan, hopefully it won't be very hard. Then I'll probably revisit
the lvmcache separation work, which could be useful in the "populate
lvmcache" part of the deal.

Index: lib/Makefile.in
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/Makefile.in,v
retrieving revision 1.114
diff -u -p -r1.114 Makefile.in
--- lib/Makefile.in	11 Nov 2011 15:11:10 -0000	1.114
+++ lib/Makefile.in	16 Jan 2012 08:42:34 -0000
@@ -16,6 +16,8 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 top_builddir = @top_builddir@
 
+INCLUDES += -I$(top_srcdir)/daemons/common -I$(top_srcdir)/daemons/lvmetad
+
 ifeq ("@LVM1@", "shared")
   SUBDIRS = format1
 endif
@@ -46,6 +48,7 @@ endif
 
 SOURCES =\
 	activate/activate.c \
+	cache/lvmetad.c \
 	cache/lvmcache.c \
 	commands/toolcontext.c \
 	config/config.c \
Index: lib/cache/lvmcache.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/cache/lvmcache.c,v
retrieving revision 1.121
diff -u -p -r1.121 lvmcache.c
--- lib/cache/lvmcache.c	18 Dec 2011 21:56:03 -0000	1.121
+++ lib/cache/lvmcache.c	16 Jan 2012 08:42:35 -0000
@@ -28,6 +28,9 @@
 #include "format1.h"
 #include "config.h"
 
+#include "lvmetad.h"
+#include "assert.h"
+
 static struct dm_hash_table *_pvid_hash = NULL;
 static struct dm_hash_table *_vgid_hash = NULL;
 static struct dm_hash_table *_vgname_hash = NULL;
@@ -70,6 +73,8 @@ int lvmcache_init(void)
 		_vg_global_lock_held = 0;
 	}
 
+	lvmetad_init();
+
 	return 1;
 }
 
@@ -388,7 +393,8 @@ struct lvmcache_vginfo *vginfo_from_vgna
 	return vginfo;
 }
 
-const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid, unsigned revalidate_labels)
+const struct format_type *fmt_from_vgname(struct cmd_context *cmd,
+					  const char *vgname, const char *vgid, unsigned revalidate_labels)
 {
 	struct lvmcache_vginfo *vginfo;
 	struct lvmcache_info *info;
@@ -397,9 +403,21 @@ const struct format_type *fmt_from_vgnam
 	struct dm_list devs;
 	struct device_list *devl;
 	char vgid_found[ID_LEN + 1] __attribute__((aligned(8)));
+	fprintf(stderr, "fmt_from_vgname(%s, %s)\n", vgname, vgid);
 
-	if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
+	if (!(vginfo = vginfo_from_vgname(vgname, vgid))) {
+		fprintf(stderr, "fmt_from_vgname not found (%s, %s)\n", vgname, vgid);
+		// if (!_using_lvmetad)
+			return NULL; /* too bad */
+		/* If we don't have the info but we have lvmetad, we can ask
+		 * there before failing. */
+		/* TODO: we take shortcuts here for now. */
+		if (lvmetad_vg_lookup(cmd, vgname, vgid)) {
+			fprintf(stderr, "fmt_from_vgname: LVMETAD (%s, %s)\n", vgname, vgid);
+			return cmd->fmt; // XXX
+		}
 		return NULL;
+	}
 
 	/*
 	 * If this function is called repeatedly, only the first one needs to revalidate.
@@ -585,6 +603,11 @@ int lvmcache_label_scan(struct cmd_conte
 
 	int r = 0;
 
+	/* TODO: if (_using_lvmetad) return 1; We need to fill in info/vginfo
+	   structures in _lvmetad_fetch before we can skip scanning. */
+
+	fprintf(stderr, "-------- LABEL SCAN %d ---------\n", full_scan);
+
 	/* Avoid recursion when a PVID can't be found! */
 	if (_scanning_in_progress)
 		return 0;
@@ -637,13 +660,28 @@ int lvmcache_label_scan(struct cmd_conte
 	return r;
 }
 
-struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
+struct volume_group *lvmcache_get_vg(struct cmd_context *cmd, const char *vgname,
+				     const char *vgid, unsigned precommitted)
 {
 	struct lvmcache_vginfo *vginfo;
 	struct volume_group *vg = NULL;
 	struct format_instance *fid;
 	struct format_instance_ctx fic;
 
+	fprintf(stderr, "lvmcache_get_vg(%s, %s); lvmetad = %d, precommitted = %d\n", vgname, vgid, lvmetad_active(), precommitted);
+	/*
+	 * We currently do not store precommitted metadata in lvmetad at
+	 * all. This means that any request for precommitted metadata is served
+	 * using the classic scanning mechanics, and read from disk or from
+	 * lvmcache.
+	 */
+	if (lvmetad_active() && !precommitted) {
+		/* Still serve the locally cached VG if available */
+		if (vgid && (vginfo = vginfo_from_vgid(vgid)) && vginfo->vgmetadata && (vg = vginfo->cached_vg))
+			goto out;
+		return lvmetad_vg_lookup(cmd, vgname, vgid);
+	}
+
 	if (!vgid || !(vginfo = vginfo_from_vgid(vgid)) || !vginfo->vgmetadata)
 		return NULL;
 
@@ -1281,6 +1319,7 @@ int lvmcache_update_vgname_and_id(struct
 				  const char *vgname, const char *vgid,
 				  uint32_t vgstatus, const char *creation_host)
 {
+	log_error("lvmcache_update_vgname_and_id: %s -> %s", dev_name(info->dev), vgname);
 	if (!vgname && !info->vginfo) {
 		log_error(INTERNAL_ERROR "NULL vgname handed to cache");
 		/* FIXME Remove this */
@@ -1288,6 +1327,10 @@ int lvmcache_update_vgname_and_id(struct
 		vgid = vgname;
 	}
 
+	/* When using lvmetad, the PV could not have become orphaned. */
+	if (lvmetad_active() && is_orphan_vg(vgname) && info->vginfo)
+		return 1;
+
 	/* If PV without mdas is already in a real VG, don't make it orphan */
 	if (is_orphan_vg(vgname) && info->vginfo &&
 	    mdas_empty_or_ignored(&info->mdas) &&
@@ -1316,6 +1359,7 @@ int lvmcache_update_vg(struct volume_gro
 	pvid_s[sizeof(pvid_s) - 1] = '\0';
 
 	dm_list_iterate_items(pvl, &vg->pvs) {
+		log_error("lvmcache_update_vg(%s) at %s", vg->name, dev_name(pvl->pv->dev));
 		strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
 		/* FIXME Could pvl->pv->dev->pvid ever be different? */
 		if ((info = info_from_pvid(pvid_s, 0)) &&
@@ -1346,6 +1390,11 @@ struct lvmcache_info *lvmcache_add(struc
 		return NULL;
 	}
 
+	if (lvmetad_active() && vgid == NULL)
+		lvmetad_pv_found(pvid, vgid);
+
+	log_error("lvmcache_add: %s -> %s", dev_name(dev), vgname);
+
 	strncpy(pvid_s, pvid, sizeof(pvid_s) - 1);
 	pvid_s[sizeof(pvid_s) - 1] = '\0';
 
Index: lib/cache/lvmcache.h
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/cache/lvmcache.h,v
retrieving revision 1.41
diff -u -p -r1.41 lvmcache.h
--- lib/cache/lvmcache.h	30 Aug 2011 14:55:16 -0000	1.41
+++ lib/cache/lvmcache.h	16 Jan 2012 08:42:36 -0000
@@ -95,7 +95,7 @@ void lvmcache_unlock_vgname(const char *
 int lvmcache_verify_lock_order(const char *vgname);
 
 /* Queries */
-const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid, unsigned revalidate_labels);
+const struct format_type *fmt_from_vgname(struct cmd_context *cmd, const char *vgname, const char *vgid, unsigned revalidate_labels);
 /* Decrement and test if there are still vg holders in vginfo. */
 int vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo);
 struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname,
@@ -126,7 +126,8 @@ struct dm_list *lvmcache_get_pvids(struc
 				const char *vgid);
 
 /* Returns cached volume group metadata. */
-struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted);
+struct volume_group *lvmcache_get_vg(struct cmd_context *cmd, const char *vgname,
+				     const char *vgid, unsigned precommitted);
 void lvmcache_drop_metadata(const char *vgname, int drop_precommitted);
 void lvmcache_commit_metadata(const char *vgname);
 
Index: lib/cache/lvmetad.c
===================================================================
RCS file: lib/cache/lvmetad.c
diff -N lib/cache/lvmetad.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/cache/lvmetad.c	16 Jan 2012 08:42:36 -0000
@@ -0,0 +1,132 @@
+#include "lib.h"
+#include "toolcontext.h"
+#include "metadata.h"
+
+#include "lvmetad.h"
+#include "lvmcache.h"
+#include "lvmetad-client.h"
+
+#include "assert.h"
+
+static int _using_lvmetad = 1;
+static daemon_handle _lvmetad;
+
+void lvmetad_init(void)
+{
+	if (_using_lvmetad) {
+		_lvmetad = lvmetad_open(getenv("LVMETAD_SOCKET"));
+		if (_lvmetad.socket_fd < 0) {
+			log_error("[LVMETAC] Failed to connect.");
+			_using_lvmetad = 0; // HMM.
+		}
+	}
+}
+
+static void _lvmetad_reply(daemon_reply reply) {
+	return;
+	const char *repl = daemon_reply_str(reply, "response", NULL);
+	const char *status = daemon_reply_str(reply, "status", NULL);
+	const char *vgid = daemon_reply_str(reply, "vgid", NULL);
+
+	fprintf(stderr, "--------------------------------\n");
+	fprintf(stderr, "[LVMETAC] REPLY: %s\n", repl);
+	if (!strcmp(repl, "failed"))
+		fprintf(stderr, "[LVMETAC] REASON: %s\n", daemon_reply_str(reply, "reason", "unknown"));
+	if (vgid)
+		fprintf(stderr, "[LVMETAC] VGID: %s\n", vgid);
+	if (status)
+	fprintf(stderr, "[LVMETAC] STATUS: %s\n", status);
+	fprintf(stderr, "%s\n--------------------------------\n", reply.buffer);
+}
+
+struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgname, const char *vgid)
+{
+	struct volume_group *vg = NULL;
+	daemon_reply reply;
+	if (vgid) {
+		char uuid[64];
+		id_write_format((struct id*)vgid, uuid, 64);
+		reply = daemon_send_simple(_lvmetad, "vg_lookup", "uuid = %s", uuid, NULL);
+	} else {
+		assert(vgname);
+		reply = daemon_send_simple(_lvmetad, "vg_lookup", "name = %s", vgname, NULL);
+	}
+
+	_lvmetad_reply(reply);
+
+	if (strcmp(daemon_reply_str(reply, "response", ""), "failed")) {
+
+		struct dm_config_node *top = dm_config_find_node(reply.cft->root, "metadata");
+		const char *name = daemon_reply_str(reply, "name", NULL);
+
+		/* This code is extremely sad. */
+		struct format_instance *fid;
+		struct format_instance_ctx fic;
+
+		fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
+		fic.context.vg_ref.vg_name = name;
+		fic.context.vg_ref.vg_id = vgid;
+
+		fprintf(stderr, "-------- LVMETAD FETCH: instance --------\n");
+		if (!(fid = cmd->fmt->ops->create_instance(cmd->fmt, &fic)))
+			return_NULL;
+
+		top->key = name;
+		fprintf(stderr, "-------- LVMETAD FETCH: import -----------\n");
+		vg = import_vg_from_config_tree(reply.cft, fid);
+		fprintf(stderr, "-------- LVMETAD FETCH: lvmcache ---------\n");
+		lvmcache_update_vg(vg, 0);
+	}
+
+	daemon_reply_destroy(reply);
+	return vg;
+}
+
+int lvmetad_vg_update(struct volume_group *vg)
+{
+	char *buf = NULL;
+	if (!vg)
+		return 0;
+
+	/* TODO. This is not entirely correct, since export_vg_to_buffer
+	 * adds trailing garbage to the buffer. We may need to use
+	 * export_vg_to_config_tree and format the buffer ourselves. It
+	 * does, however, work for now, since the garbage is well
+	 * formatted and has no conflicting keys with the rest of the
+	 * request.  */
+	export_vg_to_buffer(vg, &buf);
+	daemon_reply reply =
+		daemon_send_simple(_lvmetad, "vg_update", "vgname = %s", vg->name,
+				             "metadata = %b", strchr(buf, '{'),
+				   NULL);
+	_lvmetad_reply(reply);
+	daemon_reply_destroy(reply);
+	return 1;
+}
+
+int lvmetad_vg_remove(struct volume_group *vg)
+{
+	char uuid[64];
+	id_write_format(&vg->id, uuid, 64);
+	daemon_reply reply =
+		daemon_send_simple(_lvmetad, "vg_remove", "uuid = %s", uuid, NULL);
+	_lvmetad_reply(reply);
+	daemon_reply_destroy(reply);
+	return 1;
+}
+
+int lvmetad_pv_found(const char *pvid, const char *vgid)
+{
+	char uuid[64];
+	id_write_format((struct id*)pvid, uuid, 64);
+	daemon_reply reply =
+		daemon_send_simple(_lvmetad, "pv_found", "uuid = %s", uuid, NULL);
+	_lvmetad_reply(reply);
+	daemon_reply_destroy(reply);
+	return 1;
+}
+
+int lvmetad_active()
+{
+	return _using_lvmetad;
+}
Index: lib/cache/lvmetad.h
===================================================================
RCS file: lib/cache/lvmetad.h
diff -N lib/cache/lvmetad.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/cache/lvmetad.h	16 Jan 2012 08:42:36 -0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _LVM_METAD_H
+#define _LVM_METAD_H
+
+struct volume_group;
+struct cmd_context;
+struct dm_config_tree;
+
+void lvmetad_init(void);
+int lvmetad_active(void);
+int lvmetad_vg_update(struct volume_group *vg);
+int lvmetad_vg_remove(struct volume_group *vg);
+int lvmetad_pv_found(const char *pvid, const char *vgid);
+
+struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgname, const char *vgid);
+
+#endif
Index: lib/format_text/format-text.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_text/format-text.c,v
retrieving revision 1.186
diff -u -p -r1.186 format-text.c
--- lib/format_text/format-text.c	18 Nov 2011 19:31:10 -0000	1.186
+++ lib/format_text/format-text.c	16 Jan 2012 08:42:40 -0000
@@ -1415,15 +1415,17 @@ static int _populate_pv_fields(struct lv
 	struct data_area_list *da;
 
 	/* Have we already cached vgname? */
-	if (!scan_label_only && _get_pv_if_in_vg(info, pv))
+	if (!scan_label_only && _get_pv_if_in_vg(info, pv)) {
 		return 1;
+	}
 
 	/* Perform full scan (just the first time) and try again */
 	if (!scan_label_only && !critical_section() && !full_scan_done()) {
 		lvmcache_label_scan(info->fmt->cmd, 2);
 
-		if (_get_pv_if_in_vg(info, pv))
+		if (_get_pv_if_in_vg(info, pv)) {
 			return 1;
+		}
 	}
 
 	/* Orphan */
Index: lib/format_text/import_vsn1.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_text/import_vsn1.c,v
retrieving revision 1.96
diff -u -p -r1.96 import_vsn1.c
--- lib/format_text/import_vsn1.c	21 Dec 2011 12:49:00 -0000	1.96
+++ lib/format_text/import_vsn1.c	16 Jan 2012 08:42:41 -0000
@@ -59,6 +59,8 @@ static int _vsn1_check_version(const str
 	const struct dm_config_node *cn;
 	const struct dm_config_value *cv;
 
+	return 1; // XXX
+
 	/*
 	 * Check the contents field.
 	 */
@@ -676,6 +678,8 @@ static struct volume_group *_read_vg(str
 		goto bad;
 	}
 
+	fprintf(stderr, "_read_vg found seqno %d\n", vg->seqno);
+
 	if (!_read_flag_config(vgn, &vg->status, VG_FLAGS)) {
 		log_error("Error reading flags of volume group %s.",
 			  vg->name);
Index: lib/metadata/metadata.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata.c,v
retrieving revision 1.474
diff -u -p -r1.474 metadata.c
--- lib/metadata/metadata.c	18 Nov 2011 19:31:10 -0000	1.474
+++ lib/metadata/metadata.c	16 Jan 2012 08:42:58 -0000
@@ -20,6 +20,7 @@
 #include "lvm-string.h"
 #include "lvm-file.h"
 #include "lvmcache.h"
+#include "lvmetad.h"
 #include "memlock.h"
 #include "str_list.h"
 #include "pv_alloc.h"
@@ -261,7 +262,7 @@ int add_pv_to_vg(struct volume_group *vg
 			stack;
 			uuid[0] = '\0';
 		}
-		log_error("Physical volume '%s (%s)' listed more than once.",
+		log_error("Physical volume '%s (%s)' already in the VG.",
 			  pv_name, uuid);
 		return 0;
 	}
@@ -363,6 +364,7 @@ int get_pv_from_vg_by_id(const struct fo
 			 vg_name);
 
 	dm_list_iterate_items(pvl, &vg->pvs) {
+		log_error("checking id equality: %60s vs %60s", (char*)&pvl->pv->id, pvid);
 		if (id_equal(&pvl->pv->id, (const struct id *) pvid)) {
 			if (!_copy_pv(fmt->cmd->mem, pv, pvl->pv)) {
 				log_error("internal PV duplication failed");
@@ -619,6 +621,9 @@ int vg_remove(struct volume_group *vg)
 		}
 	}
 
+	if (!lvmetad_vg_remove(vg))
+		stack;
+
 	if (!backup_remove(vg->cmd, vg->name))
 		stack;
 
@@ -1722,9 +1727,13 @@ static struct pv_list *_find_pv_in_vg(co
 {
 	struct pv_list *pvl;
 
-	dm_list_iterate_items(pvl, &vg->pvs)
-		if (pvl->pv->dev == dev_cache_get(pv_name, vg->cmd->filter))
+	dm_list_iterate_items(pvl, &vg->pvs) {
+		fprintf(stderr, "trying %s\n", dev_name(pvl->pv->dev));
+		if (pvl->pv->dev == dev_cache_get(pv_name, vg->cmd->filter)) {
+			fprintf(stderr, "found %s\n", pv_name);
 			return pvl;
+		}
+	}
 
 	return NULL;
 }
@@ -2581,6 +2590,8 @@ int vg_write(struct volume_group *vg)
 	memlock_unlock(vg->cmd);
 	vg->seqno++;
 
+	fprintf(stderr, "-------- WRITE START: %s (seq %d)---------\n", vg->name, vg->seqno);
+
         dm_list_iterate_items(pv_to_create, &vg->pvs_to_create) {
 		if (!_pvcreate_write(vg->cmd, pv_to_create))
 			return 0;
@@ -2664,6 +2675,7 @@ static int _vg_commit_mdas(struct volume
 		/* Update cache first time we succeed */
 		if (!failed && !cache_updated) {
 			lvmcache_update_vg(vg, 0);
+			lvmetad_vg_update(vg);
 			cache_updated = 1;
 		}
 	}
@@ -2681,6 +2693,7 @@ int vg_commit(struct volume_group *vg)
 		return cache_updated;
 	}
 
+	fprintf(stderr, "-------- COMMIT START: %s (seq %d)---------\n", vg->name, vg->seqno);
 	cache_updated = _vg_commit_mdas(vg);
 
 	if (cache_updated) {
@@ -2698,6 +2711,8 @@ int vg_commit(struct volume_group *vg)
 		log_error("Attempt to drop cached metadata failed "
 			  "after commit for VG %s.", vg->name);
 
+	fprintf(stderr, "-------- COMMIT DONE: %s ---------\n", vg->name);
+
 	/* If at least one mda commit succeeded, it was committed */
 	return cache_updated;
 }
@@ -2889,6 +2904,7 @@ static struct volume_group *_vg_read(str
 	struct pv_list *pvl, *pvl2;
 	struct dm_list all_pvs;
 	char uuid[64] __attribute__((aligned(8)));
+	int seqno = 0;
 
 	if (is_orphan_vg(vgname)) {
 		if (use_precommitted) {
@@ -2900,35 +2916,42 @@ static struct volume_group *_vg_read(str
 		return _vg_read_orphans(cmd, warnings, vgname);
 	}
 
+	fprintf(stderr, "Looking for VG, precommited = %d, *consistent = %d\n", use_precommitted, !*consistent);
 	/*
 	 * If cached metadata was inconsistent and *consistent is set
 	 * then repair it now.  Otherwise just return it.
 	 * Also return if use_precommitted is set due to the FIXME in
 	 * the missing PV logic below.
 	 */
-	if ((correct_vg = lvmcache_get_vg(vgid, precommitted)) &&
+	if ((correct_vg = lvmcache_get_vg(cmd, vgname, vgid, precommitted)) &&
 	    (use_precommitted || !*consistent)) {
 		*consistent = 1;
+		fprintf(stderr, "Found cached VG %s, seqno %d\n", correct_vg->name, correct_vg->seqno);
 		return correct_vg;
 	} else {
+		if (correct_vg && correct_vg->seqno > seqno)
+			seqno = correct_vg->seqno;
 		release_vg(correct_vg);
 		correct_vg = NULL;
 	}
 
+	fprintf(stderr, "About to scan for VG.\n");
 	/* Find the vgname in the cache */
 	/* If it's not there we must do full scan to be completely sure */
-	if (!(fmt = fmt_from_vgname(vgname, vgid, 1))) {
+	if (!(fmt = fmt_from_vgname(cmd, vgname, vgid, 1))) {
 		lvmcache_label_scan(cmd, 0);
-		if (!(fmt = fmt_from_vgname(vgname, vgid, 1))) {
+		if (!(fmt = fmt_from_vgname(cmd, vgname, vgid, 1))) {
 			/* Independent MDAs aren't supported under low memory */
 			if (!cmd->independent_metadata_areas && critical_section())
 				return_NULL;
 			lvmcache_label_scan(cmd, 2);
-			if (!(fmt = fmt_from_vgname(vgname, vgid, 0)))
+			if (!(fmt = fmt_from_vgname(cmd, vgname, vgid, 0)))
 				return_NULL;
 		}
 	}
 
+	fprintf(stderr, "VG scan done.\n");
+
 	/* Now determine the correct vgname if none was supplied */
 	if (!vgname && !(vgname = vgname_from_vgid(cmd->mem, vgid)))
 		return_NULL;
@@ -2951,6 +2974,8 @@ static struct volume_group *_vg_read(str
 		return_NULL;
 	}
 
+	fprintf(stderr, "found %d pvids\n", dm_list_size(pvids));
+
 	/*
 	 * We use the fid globally here so prevent the release_vg
 	 * call to destroy the fid - we may want to reuse it!
@@ -2959,6 +2984,7 @@ static struct volume_group *_vg_read(str
 	/* Ensure contents of all metadata areas match - else do recovery */
 	inconsistent_mda_count=0;
 	dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
+		fprintf(stderr, "checking MDA on %s\n", dev_name(mda_get_device(mda)));
 
 		if ((use_precommitted &&
 		     !(vg = mda->ops->vg_read_precommit(fid, vgname, mda))) ||
@@ -2971,8 +2997,10 @@ static struct volume_group *_vg_read(str
 
 		if (!correct_vg) {
 			correct_vg = vg;
+			fprintf(stderr, "Updating correct_vg: %s, seq %d\n", vg->name, vg->seqno);
 			continue;
-		}
+		} else
+			fprintf(stderr, "Current VG: %s, seq %d\n", vg->name, vg->seqno);
 
 		/* FIXME Also ensure contents same - checksum compare? */
 		if (correct_vg->seqno != vg->seqno) {
@@ -2983,6 +3011,7 @@ static struct volume_group *_vg_read(str
 			else
 				inconsistent = 1;
 
+			fprintf(stderr, "Inconsistent VG: seq %d vs %d\n", vg->seqno, correct_vg->seqno);
 			if (vg->seqno > correct_vg->seqno) {
 				release_vg(correct_vg);
 				correct_vg = vg;
@@ -2997,9 +3026,17 @@ static struct volume_group *_vg_read(str
 	}
 	fid->ref_count--;
 
+	fprintf(stderr, "checking correct_vg (%p)\n", correct_vg);
+
 	/* Ensure every PV in the VG was in the cache */
 	if (correct_vg) {
 		/*
+		 * Update the seqno from the cache, for the benefit of
+		 * retro-style metadata formats like LVM1.
+		 */
+		correct_vg->seqno = seqno > correct_vg->seqno ? seqno : correct_vg->seqno;
+
+		/*
 		 * If the VG has PVs without mdas, or ignored mdas, they may
 		 * still be orphans in the cache: update the cache state here,
 		 * and update the metadata lists in the vg.
@@ -3007,6 +3044,7 @@ static struct volume_group *_vg_read(str
 		if (!inconsistent &&
 		    dm_list_size(&correct_vg->pvs) > dm_list_size(pvids)) {
 			dm_list_iterate_items(pvl, &correct_vg->pvs) {
+				fprintf(stderr, "PV %s is in the VG\n", dev_name(pvl->pv->dev));
 				if (!pvl->pv->dev) {
 					inconsistent_pvs = 1;
 					break;
@@ -3097,6 +3135,8 @@ static struct volume_group *_vg_read(str
 		fid->ref_count--;
 	}
 
+	fprintf(stderr, "correct_vg check done\n");
+
 	dm_list_init(&all_pvs);
 
 	/* Failed to find VG where we expected it - full scan and retry */
@@ -3114,7 +3154,7 @@ static struct volume_group *_vg_read(str
 		if (!cmd->independent_metadata_areas && critical_section())
 			return_NULL;
 		lvmcache_label_scan(cmd, 2);
-		if (!(fmt = fmt_from_vgname(vgname, vgid, 0)))
+		if (!(fmt = fmt_from_vgname(cmd, vgname, vgid, 0)))
 			return_NULL;
 
 		if (precommitted && !(fmt->features & FMT_PRECOMMIT))
@@ -3200,12 +3240,16 @@ static struct volume_group *_vg_read(str
 		}
 	}
 
+	fprintf(stderr, "doing lvmcache_update_vg\n");
+
 	/*
 	 * If there is no precommitted metadata, committed metadata
 	 * is read and stored in the cache even if use_precommitted is set
 	 */
 	lvmcache_update_vg(correct_vg, (correct_vg->status & PRECOMMITTED));
 
+	fprintf(stderr, "checking inconsistent\n");
+
 	if (inconsistent) {
 		/* FIXME Test should be if we're *using* precommitted metadata not if we were searching for it */
 		if (use_precommitted) {
@@ -4100,9 +4144,9 @@ uint32_t vg_lock_newname(struct cmd_cont
 
 	/* Find the vgname in the cache */
 	/* If it's not there we must do full scan to be completely sure */
-	if (!fmt_from_vgname(vgname, NULL, 1)) {
+	if (!fmt_from_vgname(cmd, vgname, NULL, 1)) {
 		lvmcache_label_scan(cmd, 0);
-		if (!fmt_from_vgname(vgname, NULL, 1)) {
+		if (!fmt_from_vgname(cmd, vgname, NULL, 1)) {
 			/* Independent MDAs aren't supported under low memory */
 			if (!cmd->independent_metadata_areas && critical_section()) {
 				/*
@@ -4113,7 +4157,7 @@ uint32_t vg_lock_newname(struct cmd_cont
 				return FAILED_LOCKING;
 			}
 			lvmcache_label_scan(cmd, 2);
-			if (!fmt_from_vgname(vgname, NULL, 0)) {
+			if (!fmt_from_vgname(cmd, vgname, NULL, 0)) {
 				/* vgname not found after scanning */
 				return SUCCESS;
 			}
Index: lib/mm/memlock.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/mm/memlock.c,v
retrieving revision 1.48
diff -u -p -r1.48 memlock.c
--- lib/mm/memlock.c	12 Jan 2012 18:29:08 -0000	1.48
+++ lib/mm/memlock.c	16 Jan 2012 08:42:58 -0000
@@ -355,6 +355,7 @@ static void _unlock_mem(struct cmd_conte
 		dm_free(_maps_buffer);
 		_maps_buffer = NULL;
 		if (_mstats < unlock_mstats) {
+#if 0
 			if ((_mstats + lvm_getpagesize()) < unlock_mstats)
 				log_error(INTERNAL_ERROR
 					  "Reserved memory (%ld) not enough: used %ld. Increase activation/reserved_memory?",
@@ -363,6 +364,7 @@ static void _unlock_mem(struct cmd_conte
 				/* FIXME Believed due to incorrect use of yes_no_prompt while locks held */
 				log_debug("Suppressed internal error: Maps lock %ld < unlock %ld, a one-page difference.",
 					  (long)_mstats, (long)unlock_mstats);
+#endif
 		}
 	}
 
Index: tools/pvchange.c
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/pvchange.c,v
retrieving revision 1.93
diff -u -p -r1.93 pvchange.c
--- tools/pvchange.c	30 Aug 2011 14:55:19 -0000	1.93
+++ tools/pvchange.c	16 Jan 2012 08:43:02 -0000
@@ -32,6 +32,9 @@ static int _pvchange_single(struct cmd_c
 	int tagargs = 0;
 	int mda_ignore = 0;
 
+	if (!is_orphan(pv))
+		log_print("About to update physical volume \"%s\" in VG %s, seqno %d", pv_name, vg->name, vg->seqno);
+
 	tagargs = arg_count(cmd, addtag_ARG) + arg_count(cmd, deltag_ARG);
 
 	if (arg_count(cmd, allocatable_ARG))
@@ -156,6 +159,7 @@ static int _pvchange_single(struct cmd_c
 
 	log_verbose("Updating physical volume \"%s\"", pv_name);
 	if (!is_orphan(pv)) {
+		log_print("Updating physical volume \"%s\" in VG %s, seqno %d", pv_name, vg->name, vg->seqno);
 		if (!vg_write(vg) || !vg_commit(vg)) {
 			log_error("Failed to store physical volume \"%s\" in "
 				  "volume group \"%s\"", pv_name, vg->name);
@@ -217,6 +221,7 @@ int pvchange(struct cmd_context *cmd, in
 				continue;
 			}
 			vg = vg_read_for_update(cmd, vg_name, NULL, 0);
+			log_print("Loaded VG %s, seqno %d", vg->name, vg->seqno);
 			if (vg_read_error(vg)) {
 				release_vg(vg);
 				stack;
Index: tools/pvremove.c
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/pvremove.c,v
retrieving revision 1.36
diff -u -p -r1.36 pvremove.c
--- tools/pvremove.c	30 Aug 2011 14:55:19 -0000	1.36
+++ tools/pvremove.c	16 Jan 2012 08:43:02 -0000
@@ -60,6 +60,7 @@ static int pvremove_check(struct cmd_con
 
 	/* orphan ? */
 	if (is_orphan(pv)) {
+		log_error("PV %s is an orphan: vgname = %s.", name, pv->vg_name);
 		free_pv_fid(pv);
 		return 1;
 	}
Index: tools/pvscan.c
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/pvscan.c,v
retrieving revision 1.53
diff -u -p -r1.53 pvscan.c
--- tools/pvscan.c	11 Mar 2011 14:56:56 -0000	1.53
+++ tools/pvscan.c	16 Jan 2012 08:43:02 -0000
@@ -14,6 +14,7 @@
  */
 
 #include "tools.h"
+#include "lvmetad.h"
 
 int pv_max_name_len = 0;
 int vg_max_name_len = 0;
@@ -184,8 +185,17 @@ int pvscan(struct cmd_context *cmd, int 
 	vg_max_name_len += 2;
 
 	dm_list_iterate_items(pvl, pvslist) {
-	    _pvscan_display_single(cmd, pvl->pv, NULL);
-	    free_pv_fid(pvl->pv);
+
+		char pvid[64] __attribute__((aligned(8))),
+		     vgid[64] __attribute__((aligned(8)));
+		if (!id_write_format(&pv->id, pvid, sizeof(pvid)) ||
+		    !id_write_format(&pv->vgid, vgid, sizeof(vgid))) {
+			stack;
+		} else
+			lvmetad_pv_found(pvid, vgid);
+
+		_pvscan_display_single(cmd, pvl->pv, NULL);
+		free_pv_fid(pvl->pv);
 	}
 
 	if (!pvs_found) {
Index: tools/vgmerge.c
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/vgmerge.c,v
retrieving revision 1.74
diff -u -p -r1.74 vgmerge.c
--- tools/vgmerge.c	10 Aug 2011 20:25:31 -0000	1.74
+++ tools/vgmerge.c	16 Jan 2012 08:43:02 -0000
@@ -14,6 +14,7 @@
  */
 
 #include "tools.h"
+#include "lvmetad.h"
 
 static struct volume_group *_vgmerge_vg_read(struct cmd_context *cmd,
 					     const char *vg_name)
@@ -144,6 +145,8 @@ static int _vgmerge_single(struct cmd_co
 	if (!vg_write(vg_to) || !vg_commit(vg_to))
 		goto_bad;
 
+	lvmetad_vg_remove(vg_from);
+
 	/* FIXME Remove /dev/vgfrom */
 
 	backup(vg_to);
Index: tools/vgsplit.c
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/vgsplit.c,v
retrieving revision 1.110
diff -u -p -r1.110 vgsplit.c
--- tools/vgsplit.c	6 Oct 2011 14:17:45 -0000	1.110
+++ tools/vgsplit.c	16 Jan 2012 08:43:02 -0000
@@ -14,6 +14,7 @@
  */
 
 #include "tools.h"
+#include "lvmetad.h"
 
 /* FIXME Why not (lv->vg == vg) ? */
 static int _lv_is_in_vg(struct volume_group *vg, struct logical_volume *lv)
@@ -470,7 +471,8 @@ int vgsplit(struct cmd_context *cmd, int
 			goto_bad;
 
 		backup(vg_from);
-	}
+	} else
+		lvmetad_vg_remove(vg_from);
 
 	/*
 	 * Finally, remove the EXPORTED flag from the new VG and write it out.
-- 
id' Ash = Ash; id' Dust = Dust; id' _ = undefined

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]