All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/35] Add full metadata balancing support, v5.
@ 2010-06-22  3:05 Dave Wysochanski
  2010-06-22  3:05 ` [PATCH 01/35] Change 'filler' to 'flags' in on-disk 'raw_locn' structure Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

This patchset is a fifth round of the metadata balancing support,
makes minor revisions and builds on the fourth round of patches
submitted (5/26/2010).  There are still some definite warts and
FIXMEs in the code but this is now a complete patchset for the
metadata balance feature.

Changes from the fourth round start around patch 19 and include:
1) Sort mdas so that ignored mdas get committed to disk first.
This reduces the time that we may get an inconsistent on-disk
state that would require auto-repair.
2) Fixed a few bugs in pv-based metadata balance patchset.
3) Add "phase 2" (vg-based) of metadata balance.  Define one
function which implements the metadata balancing and call it from
the vg_write() path.  In most cases, this works just fine, but
there are a few checks that need updated for the new 'fid' list
of ignored mdas.
4) Update nightly test cases to include all "phase 2" commands
such as vgcreate, vgchange, vgsplit, etc.




^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 01/35] Change 'filler' to 'flags' in on-disk 'raw_locn' structure.
  2010-06-22  3:05 [PATCH 00/35] Add full metadata balancing support, v5 Dave Wysochanski
@ 2010-06-22  3:05 ` Dave Wysochanski
  2010-06-22  3:05   ` [PATCH 02/35] Add text format specific 'rlocn' ignore flag and access functions Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Future patches will make use of a specific flag in the on-disk 'raw_locn'
structure to enable/disable metadata areas, and facilitate metadata
balancing.

Note that 'filler' is always set to '0' (see add_mda() - memset),
so use of this area as a non-zero flags field is a safe way to
provide future code features.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/layout.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
index b023e92..444a500 100644
--- a/lib/format_text/layout.h
+++ b/lib/format_text/layout.h
@@ -51,7 +51,7 @@ struct raw_locn {
 	uint64_t offset;	/* Offset in bytes to start sector */
 	uint64_t size;		/* Bytes */
 	uint32_t checksum;
-	uint32_t filler;
+	uint32_t flags;
 } __attribute__ ((packed));
 
 /* On disk */
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 02/35] Add text format specific 'rlocn' ignore flag and access functions.
  2010-06-22  3:05 ` [PATCH 01/35] Change 'filler' to 'flags' in on-disk 'raw_locn' structure Dave Wysochanski
@ 2010-06-22  3:05   ` Dave Wysochanski
  2010-06-22  3:05     ` [PATCH 03/35] Add location independent flag and functions to ignore mdas Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Adding a flag to the 'rlocn' structure in the mda header of the
text format allows us to flip a bit to ignore an area on disk that
stores the metadata via the text format specific mda_header.
This patch defines the flag and access functions to manage the flag.
Other patches will manage the ignore on a format-independent basis,
by using a flag in the metadata_area structure.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 include/.symlinks.in          |    1 +
 lib/format_text/format-text.c |   13 +++++++++++++
 lib/format_text/format-text.h |    1 +
 lib/format_text/layout.h      |   10 ++++++++++
 4 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/include/.symlinks.in b/include/.symlinks.in
index 5a7e556..415bf82 100644
--- a/include/.symlinks.in
+++ b/include/.symlinks.in
@@ -26,6 +26,7 @@
 @top_srcdir@/lib/format_text/format-text.h
 @top_srcdir@/lib/format_text/text_export.h
 @top_srcdir@/lib/format_text/text_import.h
+ at top_srcdir@/lib/format_text/layout.h
 @top_srcdir@/lib/label/label.h
 @top_srcdir@/lib/locking/locking.h
 @top_srcdir@/lib/log/log.h
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 6e02f12..9599626 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -66,6 +66,19 @@ struct text_context {
 	char *desc;		/* Description placed inside file */
 };
 
+int rlocn_is_ignored(const struct raw_locn *rlocn)
+{
+	return (rlocn->flags & RAW_LOCN_IGNORED ? 1 : 0);
+}
+
+void rlocn_set_ignored(struct raw_locn *rlocn, int value)
+{
+	if (value)
+		rlocn->flags |= RAW_LOCN_IGNORED;
+	else
+		rlocn->flags &= ~RAW_LOCN_IGNORED;
+}
+
 /*
  * NOTE: Currently there can be only one vg per text file.
  */
diff --git a/lib/format_text/format-text.h b/lib/format_text/format-text.h
index 9750ffa..17997cc 100644
--- a/lib/format_text/format-text.h
+++ b/lib/format_text/format-text.h
@@ -17,6 +17,7 @@
 #define _LVM_FORMAT_TEXT_H
 
 #include "lvm-types.h"
+#include "layout.h"
 #include "metadata.h"
 
 #define FMT_TEXT_NAME "lvm2"
diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
index 444a500..b7b2f2b 100644
--- a/lib/format_text/layout.h
+++ b/lib/format_text/layout.h
@@ -46,6 +46,13 @@ struct pv_header {
 	struct disk_locn disk_areas_xl[0];	/* Two lists */
 } __attribute__ ((packed));
 
+/*
+ * Ignore this raw location.  This allows us to
+ * ignored metadata areas easily, and thus balance
+ * metadata across VGs with many PVs.
+ */
+#define RAW_LOCN_IGNORED 0x00000001
+
 /* On disk */
 struct raw_locn {
 	uint64_t offset;	/* Offset in bytes to start sector */
@@ -54,6 +61,9 @@ struct raw_locn {
 	uint32_t flags;
 } __attribute__ ((packed));
 
+int rlocn_is_ignored(const struct raw_locn *rlocn);
+void rlocn_set_ignored(struct raw_locn *rlocn, int value);
+
 /* On disk */
 /* Structure size limited to one sector */
 struct mda_header {
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 03/35] Add location independent flag and functions to ignore mdas.
  2010-06-22  3:05   ` [PATCH 02/35] Add text format specific 'rlocn' ignore flag and access functions Dave Wysochanski
@ 2010-06-22  3:05     ` Dave Wysochanski
  2010-06-22  3:05       ` [PATCH 04/35] Move dev_open / dev_close outside _vg_read_raw_area() Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

First we add a 'flags' field to the location independent
metadata_area structure, and a MDA_IGNORE flag.  The
mda_is_ignored and mda_set_ignored functions are added to
manage the flag.  Adding the flag and functions gives a
library interface to ignore metadata areas independent of
the underlying location (disk, file, etc).  The location
specific read/write functions must then handle the specifics
of what this flag means to the location.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/text_label.c |    1 +
 lib/metadata/metadata.c      |   13 +++++++++++++
 lib/metadata/metadata.h      |    6 ++++++
 3 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index 7f02fc6..15758d6 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -215,6 +215,7 @@ int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct dm_list *
 
 	mdal->ops = mda_lists->raw_ops;
 	mdal->metadata_locn = mdac;
+	mdal->flags = 0;
 
 	mdac->area.dev = dev;
 	mdac->area.start = start;
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index d76a910..68f7436 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3855,6 +3855,19 @@ uint32_t pv_pe_alloc_count(const struct physical_volume *pv)
 	return pv_field(pv, pe_alloc_count);
 }
 
+int mda_is_ignored(struct metadata_area *mda)
+{
+	return (mda->flags & MDA_IGNORED);
+}
+
+void mda_set_ignored(struct metadata_area *mda, int value)
+{
+	if (value)
+		mda->flags |= MDA_IGNORED;
+	else
+		mda->flags &= ~MDA_IGNORED;
+}
+
 uint32_t pv_mda_count(const struct physical_volume *pv)
 {
 	struct lvmcache_info *info;
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 3a3979d..71c562a 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -158,12 +158,18 @@ struct metadata_area_ops {
 
 };
 
+#define MDA_IGNORED 0x00000001
+
 struct metadata_area {
 	struct dm_list list;
 	struct metadata_area_ops *ops;
 	void *metadata_locn;
+	uint32_t flags;
 };
 
+int mda_is_ignored(struct metadata_area *mda);
+void mda_set_ignored(struct metadata_area *mda, int value);
+
 #define seg_pvseg(seg, s)	(seg)->areas[(s)].u.pv.pvseg
 #define seg_dev(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pv->dev
 #define seg_pe(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pe
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 04/35] Move dev_open / dev_close outside _vg_read_raw_area().
  2010-06-22  3:05     ` [PATCH 03/35] Add location independent flag and functions to ignore mdas Dave Wysochanski
@ 2010-06-22  3:05       ` Dave Wysochanski
  2010-06-22  3:05         ` [PATCH 05/35] Move dev_open/dev_close outside vgname_from_mda() Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

This refactoring moves the device open/close up one level to the caller of
_vg_read_raw_area().  Should be no functional change and facilitate future
changes related to metadata balancing.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/format-text.c |   40 ++++++++++++++++++++++++++++++----------
 1 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 9599626..9411f93 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -477,9 +477,6 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
 	char *desc;
 	uint32_t wrap = 0;
 
-	if (!dev_open(area->dev))
-		return_NULL;
-
 	if (!(mdah = _raw_read_mda_header(fid->fmt, area)))
 		goto_out;
 
@@ -514,9 +511,6 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
 		vg->status |= PRECOMMITTED;
 
       out:
-	if (!dev_close(area->dev))
-		stack;
-
 	return vg;
 }
 
@@ -525,8 +519,17 @@ static struct volume_group *_vg_read_raw(struct format_instance *fid,
 					 struct metadata_area *mda)
 {
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
+	struct volume_group *vg;
 
-	return _vg_read_raw_area(fid, vgname, &mdac->area, 0);
+	if (!dev_open(mdac->area.dev))
+		return_NULL;
+
+	vg = _vg_read_raw_area(fid, vgname, &mdac->area, 0);
+
+	if (!dev_close(mdac->area.dev))
+		stack;
+
+	return vg;
 }
 
 static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
@@ -534,8 +537,17 @@ static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
 						   struct metadata_area *mda)
 {
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
+	struct volume_group *vg;
+
+	if (!dev_open(mdac->area.dev))
+		return_NULL;
+
+	vg = _vg_read_raw_area(fid, vgname, &mdac->area, 1);
+
+	if (!dev_close(mdac->area.dev))
+		stack;
 
-	return _vg_read_raw_area(fid, vgname, &mdac->area, 1);
+	return vg;
 }
 
 static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
@@ -1186,9 +1198,17 @@ static int _scan_raw(const struct format_type *fmt)
 		/* FIXME We're reading mdah twice here... */
 		if ((vgname = vgname_from_mda(fmt, &rl->dev_area, &vgid, &vgstatus,
 					      NULL, NULL))) {
-			if ((vg = _vg_read_raw_area(&fid, vgname,
-						    &rl->dev_area, 0)))
+			if (!dev_open(rl->dev_area.dev)) {
+				stack;
+				continue;
+			}
+
+			vg = _vg_read_raw_area(&fid, vgname, &rl->dev_area, 0);
+			if (vg)
 				lvmcache_update_vg(vg, 0);
+
+			if (!dev_close(rl->dev_area.dev))
+				stack;
 		}
 	}
 
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 05/35] Move dev_open/dev_close outside vgname_from_mda().
  2010-06-22  3:05       ` [PATCH 04/35] Move dev_open / dev_close outside _vg_read_raw_area() Dave Wysochanski
@ 2010-06-22  3:05         ` Dave Wysochanski
  2010-06-22  3:05           ` [PATCH 06/35] Allow raw_read_mda_header to be called from text_label.c Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Refactor vgname_from_mda() so caller must open/close the device.
Should be no functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/format-text.c |   20 +++++++-------------
 lib/format_text/text_label.c  |    6 ++++++
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 9411f93..fa9d2d1 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1093,9 +1093,6 @@ const char *vgname_from_mda(const struct format_type *fmt,
 	if (mda_free_sectors)
 		*mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
 
-	if (!dev_open(dev_area->dev))
-		return_NULL;
-
 	if (!(mdah = _raw_read_mda_header(fmt, dev_area)))
 		goto_out;
 
@@ -1173,9 +1170,6 @@ const char *vgname_from_mda(const struct format_type *fmt,
 	}
 
       out:
-	if (!dev_close(dev_area->dev))
-		stack;
-
 	return vgname;
 }
 
@@ -1196,20 +1190,20 @@ static int _scan_raw(const struct format_type *fmt)
 
 	dm_list_iterate_items(rl, raw_list) {
 		/* FIXME We're reading mdah twice here... */
+		if (!dev_open(rl->dev_area.dev)) {
+			stack;
+			continue;
+		}
+
 		if ((vgname = vgname_from_mda(fmt, &rl->dev_area, &vgid, &vgstatus,
 					      NULL, NULL))) {
-			if (!dev_open(rl->dev_area.dev)) {
-				stack;
-				continue;
-			}
-
 			vg = _vg_read_raw_area(&fid, vgname, &rl->dev_area, 0);
 			if (vg)
 				lvmcache_update_vg(vg, 0);
 
-			if (!dev_close(rl->dev_area.dev))
-				stack;
 		}
+		if (!dev_close(rl->dev_area.dev))
+			stack;
 	}
 
 	return 1;
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index 15758d6..6f897e1 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -299,6 +299,10 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
 
 	dm_list_iterate_items(mda, &info->mdas) {
 		mdac = (struct mda_context *) mda->metadata_locn;
+		if (!dev_open(mdac->area.dev)) {
+			stack;
+			continue;
+		}
 		if ((vgname = vgname_from_mda(info->fmt, &mdac->area,
 					      &vgid, &vgstatus, &creation_host,
 					      &mdac->free_sectors)) &&
@@ -306,6 +310,8 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
 						   (char *) &vgid, vgstatus,
 						   creation_host))
 			return_0;
+		if (!dev_close(mdac->area.dev))
+			stack;
 	}
 
 	info->status &= ~CACHE_INVALID;
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 06/35] Allow raw_read_mda_header to be called from text_label.c.
  2010-06-22  3:05         ` [PATCH 05/35] Move dev_open/dev_close outside vgname_from_mda() Dave Wysochanski
@ 2010-06-22  3:05           ` Dave Wysochanski
  2010-06-22  3:05             ` [PATCH 07/35] Ensure in-memory state matches on-disk state of mda ignore bit Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

We'd like to pass in mda_header to vgname_from_mda().  In order to
do this, we need to call raw_read_mda_header() from text_label.c,
_text_read(), which gets called from the label_read() path, and
peers into the metadata and update vginfo cache.  We should check
the disable bit here, and if set, not peer into the vg metadata,
thus reducing the I/O to disk.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/format-text.c |   33 +++++++++++++++++++--------------
 lib/format_text/format-text.h |    1 +
 lib/format_text/layout.h      |    4 ++++
 lib/format_text/text_label.c  |   15 +++++++++++++--
 4 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index fa9d2d1..577d681 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -37,9 +37,6 @@
 #include <dirent.h>
 #include <ctype.h>
 
-static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
-					       struct device_area *dev_area);
-
 static struct format_instance *_text_create_text_instance(const struct format_type
 						     *fmt, const char *vgname,
 						     const char *vgid,
@@ -181,7 +178,7 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
 	if (!dev_open(area->dev))
 		return_0;
 
-	if (!(mdah = _raw_read_mda_header(fmt, area)))
+	if (!(mdah = raw_read_mda_header(fmt, area)))
 		goto_out;
 
 	rlocn = mdah->raw_locns;
@@ -308,8 +305,8 @@ static void _xlate_mdah(struct mda_header *mdah)
 	}
 }
 
-static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
-					       struct device_area *dev_area)
+struct mda_header *raw_read_mda_header(const struct format_type *fmt,
+				       struct device_area *dev_area)
 {
 	struct mda_header *mdah;
 
@@ -453,7 +450,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
 	if (!dev_open(dev_area->dev))
 		return_0;
 
-	if (!(mdah = _raw_read_mda_header(fid->fmt, dev_area)))
+	if (!(mdah = raw_read_mda_header(fid->fmt, dev_area)))
 		return_0;
 
 	if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit))
@@ -477,7 +474,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
 	char *desc;
 	uint32_t wrap = 0;
 
-	if (!(mdah = _raw_read_mda_header(fid->fmt, area)))
+	if (!(mdah = raw_read_mda_header(fid->fmt, area)))
 		goto_out;
 
 	if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &precommitted))) {
@@ -577,7 +574,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
 	if (!dev_open(mdac->area.dev))
 		return_0;
 
-	if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
+	if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area)))
 		goto_out;
 
 	rlocn = _find_vg_rlocn(&mdac->area, mdah,
@@ -683,7 +680,7 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
 	if (!found)
 		return 1;
 
-	if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
+	if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area)))
 		goto_out;
 
 	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah,
@@ -794,7 +791,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
 	if (!dev_open(mdac->area.dev))
 		return_0;
 
-	if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
+	if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area)))
 		goto_out;
 
 	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
@@ -1077,12 +1074,12 @@ static int _scan_file(const struct format_type *fmt)
 }
 
 const char *vgname_from_mda(const struct format_type *fmt,
+			    struct mda_header *mdah,
 			    struct device_area *dev_area, struct id *vgid,
 			    uint64_t *vgstatus, char **creation_host,
 			    uint64_t *mda_free_sectors)
 {
 	struct raw_locn *rlocn;
-	struct mda_header *mdah;
 	uint32_t wrap = 0;
 	const char *vgname = NULL;
 	unsigned int len = 0;
@@ -1093,7 +1090,7 @@ const char *vgname_from_mda(const struct format_type *fmt,
 	if (mda_free_sectors)
 		*mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
 
-	if (!(mdah = _raw_read_mda_header(fmt, dev_area)))
+	if (!mdah)
 		goto_out;
 
 	/* FIXME Cope with returning a list */
@@ -1182,6 +1179,7 @@ static int _scan_raw(const struct format_type *fmt)
 	struct format_instance fid;
 	struct id vgid;
 	uint64_t vgstatus;
+	struct mda_header *mdah;
 
 	raw_list = &((struct mda_lists *) fmt->private)->raws;
 
@@ -1195,13 +1193,20 @@ static int _scan_raw(const struct format_type *fmt)
 			continue;
 		}
 
-		if ((vgname = vgname_from_mda(fmt, &rl->dev_area, &vgid, &vgstatus,
+		if (!(mdah = raw_read_mda_header(fmt, &rl->dev_area))) {
+			stack;
+			goto close_dev;
+		}
+
+		if ((vgname = vgname_from_mda(fmt, mdah,
+					      &rl->dev_area, &vgid, &vgstatus,
 					      NULL, NULL))) {
 			vg = _vg_read_raw_area(&fid, vgname, &rl->dev_area, 0);
 			if (vg)
 				lvmcache_update_vg(vg, 0);
 
 		}
+	close_dev:
 		if (!dev_close(rl->dev_area.dev))
 			stack;
 	}
diff --git a/lib/format_text/format-text.h b/lib/format_text/format-text.h
index 17997cc..9e1bdd7 100644
--- a/lib/format_text/format-text.h
+++ b/lib/format_text/format-text.h
@@ -61,6 +61,7 @@ int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct dm_list *
 void del_mdas(struct dm_list *mdas);
 
 const char *vgname_from_mda(const struct format_type *fmt,
+			    struct mda_header *mdah,
 			    struct device_area *dev_area, struct id *vgid,
 			    uint64_t *vgstatus, char **creation_host,
 			    uint64_t *mda_free_sectors);
diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
index b7b2f2b..f23719a 100644
--- a/lib/format_text/layout.h
+++ b/lib/format_text/layout.h
@@ -76,6 +76,9 @@ struct mda_header {
 	struct raw_locn raw_locns[0];	/* NULL-terminated list */
 } __attribute__ ((packed));
 
+struct mda_header *raw_read_mda_header(const struct format_type *fmt,
+				       struct device_area *dev_area);
+
 struct mda_lists {
 	struct dm_list dirs;
 	struct dm_list raws;
@@ -86,6 +89,7 @@ struct mda_lists {
 struct mda_context {
 	struct device_area area;
 	uint64_t free_sectors;
+	struct mda_header *mdah; /* copy of the on-disk mdah */
 	struct raw_locn rlocn;	/* Store inbetween write and commit */
 };
 
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index 6f897e1..7083b89 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -262,6 +262,7 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
 	const char *vgname;
 	uint64_t vgstatus;
 	char *creation_host;
+	struct mda_header *mdah;
 
 	pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl));
 
@@ -303,13 +304,23 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
 			stack;
 			continue;
 		}
-		if ((vgname = vgname_from_mda(info->fmt, &mdac->area,
+		if (!(mdah = raw_read_mda_header(info->fmt, &mdac->area))) {
+			stack;
+			goto close_dev;
+		}
+
+		if ((vgname = vgname_from_mda(info->fmt, mdah,
+					      &mdac->area,
 					      &vgid, &vgstatus, &creation_host,
 					      &mdac->free_sectors)) &&
 		    !lvmcache_update_vgname_and_id(info, vgname,
 						   (char *) &vgid, vgstatus,
-						   creation_host))
+						   creation_host)) {
+			if (!dev_close(mdac->area.dev))
+					stack;
 			return_0;
+		}
+	close_dev:
 		if (!dev_close(mdac->area.dev))
 			stack;
 	}
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 07/35] Ensure in-memory state matches on-disk state of mda ignore bit.
  2010-06-22  3:05           ` [PATCH 06/35] Allow raw_read_mda_header to be called from text_label.c Dave Wysochanski
@ 2010-06-22  3:05             ` Dave Wysochanski
  2010-06-22  3:05               ` [PATCH 08/35] Add mda_locn_match() internal library function for mapping pv/device to VG mda Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/format-text.c |    3 +++
 lib/format_text/text_label.c  |    2 ++
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 577d681..f983c42 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -720,6 +720,7 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
 			  "header at %" PRIu64, vg->name,
 			  dev_name(mdac->area.dev), mdac->area.start);
 
+	rlocn_set_ignored(mdah->raw_locns, mda_is_ignored(mda));
 	if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
 				   mdah)) {
 		dm_pool_free(fid->fmt->cmd->mem, mdah);
@@ -802,6 +803,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
 	rlocn->offset = 0;
 	rlocn->size = 0;
 	rlocn->checksum = 0;
+	rlocn_set_ignored(mdah->raw_locns, mda_is_ignored(mda));
 
 	if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
 				   mdah)) {
@@ -1505,6 +1507,7 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
 		mdac = mda->metadata_locn;
 		memset(&buf, 0, sizeof(buf));
 		mdah->size = mdac->area.size;
+		rlocn_set_ignored(mdah->raw_locns, mda_is_ignored(mda));
 		if (!_raw_write_mda_header(fmt, mdac->area.dev,
 					   mdac->area.start, mdah)) {
 			if (!dev_close(pv->dev))
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index 7083b89..ab9f595 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -301,6 +301,7 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
 	dm_list_iterate_items(mda, &info->mdas) {
 		mdac = (struct mda_context *) mda->metadata_locn;
 		if (!dev_open(mdac->area.dev)) {
+			mda_set_ignored(mda, 1);
 			stack;
 			continue;
 		}
@@ -308,6 +309,7 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
 			stack;
 			goto close_dev;
 		}
+		mda_set_ignored(mda, rlocn_is_ignored(mdah->raw_locns));
 
 		if ((vgname = vgname_from_mda(info->fmt, mdah,
 					      &mdac->area,
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 08/35] Add mda_locn_match() internal library function for mapping pv/device to VG mda.
  2010-06-22  3:05             ` [PATCH 07/35] Ensure in-memory state matches on-disk state of mda ignore bit Dave Wysochanski
@ 2010-06-22  3:05               ` Dave Wysochanski
  2010-06-22  3:05                 ` [PATCH 09/35] Add mda location specific mda_copy constructor Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

A metadata_area is defined independent of the location.  One downside
is that there is no obvious mapping from a pv to an mda.  For a PV in
a VG, we need a way to start with a PV and end up with an MDA, if we
are to manage mdas starting with a device/pv.  This function provides
us a way to go down the list of PVs on a VG, and identify which ones
match a particular PV.

I'm not entirely happy with this approach, but it does fit into the
existing structures in a reasonable way.

An alternative solution might be to refactor the VG - PV interface such
that mdas are a list tied to a PV.  However, this seemed a bit tricky since
a PV does not come into existence until after the list of mdas is
constructed (see _vg_read() - we create a 'fid' and attach mdas to it,
then we go through them and attach pvs).

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/format-text.c |   15 +++++++++++++++
 lib/metadata/metadata.c       |   30 ++++++++++++++++++++++++++++++
 lib/metadata/metadata.h       |    7 +++++++
 3 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index f983c42..2dc51ee 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -121,6 +121,20 @@ static int _mda_in_vg_raw(struct format_instance *fid __attribute((unused)),
 	return 0;
 }
 
+static int _mda_locn_match_raw(struct metadata_area *mda1,
+			       struct metadata_area *mda2)
+{
+	struct mda_context *mda1c = (struct mda_context *) mda1->metadata_locn;
+	struct mda_context *mda2c = (struct mda_context *) mda2->metadata_locn;
+
+	if ((mda1c->area.dev == mda2c->area.dev) &&
+	    (mda1c->area.start == mda2c->area.start) &&
+	    (mda1c->area.size == mda2c->area.size))
+		return 1;
+
+	return 0;
+}
+
 /*
  * For circular region between region_start and region_start + region_size,
  * back up one SECTOR_SIZE from 'region_ptr' and return the value.
@@ -1724,6 +1738,7 @@ static struct metadata_area_ops _metadata_text_raw_ops = {
 	.mda_total_sectors = _mda_total_sectors_raw,
 	.mda_in_vg = _mda_in_vg_raw,
 	.pv_analyze_mda = _pv_analyze_mda_raw,
+	.mda_locn_match = _mda_locn_match_raw
 };
 
 /* pvmetadatasize in sectors */
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 68f7436..3a673da 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3855,6 +3855,36 @@ uint32_t pv_pe_alloc_count(const struct physical_volume *pv)
 	return pv_field(pv, pe_alloc_count);
 }
 
+/*
+ * This function provides a way to answer the question on a format specific
+ * basis - does the format specfic context of these two metadata areas
+ * match?
+ *
+ * A metatdata_area is defined to be independent of the underlying context.
+ * This has the benefit that we can use the same abstraction to read disks
+ * (see _metadata_text_raw_ops) or files (see _metadata_text_file_ops).
+ * However, one downside is there is no format-independent way to determine
+ * whether a given metadata_area is attached to a specific device - in fact,
+ * it may not be attached to a device at all.
+ *
+ * Thus, LVM is structured such that an mda is not a member of struct
+ * physical_volume.  The location of the mda depends on whether
+ * the PV is in a volume group.  A PV not in a VG has an mda on the
+ * 'info->mda' list in lvmcache, while a PV in a VG has an mda on
+ * the vg->fid->metadata_areas list.  For further details, see _vg_read(),
+ * and the sequence of creating the format_instance with fid->metadata_areas
+ * list, as well as the construction of the VG, with list of PVs (comes
+ * after the construction of the fid and list of mdas).
+ */
+int mda_locn_match(struct metadata_area *mda1, struct metadata_area *mda2)
+{
+	if (!mda1->ops->mda_locn_match || !mda2->ops->mda_locn_match ||
+	    mda1->ops->mda_locn_match != mda2->ops->mda_locn_match)
+		return 0;
+
+	return mda1->ops->mda_locn_match(mda1, mda2);
+}
+
 int mda_is_ignored(struct metadata_area *mda)
 {
 	return (mda->flags & MDA_IGNORED);
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 71c562a..6f6236f 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -156,6 +156,12 @@ struct metadata_area_ops {
 	int (*pv_analyze_mda) (const struct format_type * fmt,
 			       struct metadata_area *mda);
 
+	/*
+	 * Do these two metadata_areas match with respect to their underlying
+	 * location?
+	 */
+	int (*mda_locn_match)(struct metadata_area *mda1,
+			      struct metadata_area *mda2);
 };
 
 #define MDA_IGNORED 0x00000001
@@ -169,6 +175,7 @@ struct metadata_area {
 
 int mda_is_ignored(struct metadata_area *mda);
 void mda_set_ignored(struct metadata_area *mda, int value);
+int mda_locn_match(struct metadata_area *mda1, struct metadata_area *mda2);
 
 #define seg_pvseg(seg, s)	(seg)->areas[(s)].u.pv.pvseg
 #define seg_dev(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pv->dev
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 09/35] Add mda location specific mda_copy constructor.
  2010-06-22  3:05               ` [PATCH 08/35] Add mda_locn_match() internal library function for mapping pv/device to VG mda Dave Wysochanski
@ 2010-06-22  3:05                 ` Dave Wysochanski
  2010-06-22  3:05                   ` [PATCH 10/35] Use vg_mda_count() in vgdisplay Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Because of the way mdas are handled internally, where a PV in a VG
has mdas on both info->mdas and vg->fid->metadata_areas list, we
need a location independent copy constructor for struct
metadata_area.  Break up the existing format-text specific copy
constructor into a format independent piece and a format dependent
piece.

This function is necessary to properly implement pv_set_mda_ignored().

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/format-text.c |   28 ++++++++++------------------
 lib/metadata/metadata.c       |   25 +++++++++++++++++++++++++
 lib/metadata/metadata.h       |    7 +++++++
 3 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 2dc51ee..be221ee 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1614,32 +1614,23 @@ static int _populate_pv_fields(struct lvmcache_info *info,
 }
 
 /*
- * Copy constructor for a metadata_area.
+ * Copy constructor for a metadata_locn.
  */
-static struct metadata_area *_mda_copy(struct dm_pool *mem,
-				       struct metadata_area *mda)
+static void *_mda_copy_raw(struct dm_pool *mem,
+			   struct metadata_area *mda)
 {
-	struct metadata_area *mda_new;
 	struct mda_context *mdac, *mdac_new;
 
-	if (!(mda_new = dm_pool_alloc(mem, sizeof(*mda_new)))) {
-		log_error("metadata_area allocation failed");
-		return NULL;
-	}
-	/* FIXME: Should have a per-format constructor here */
 	mdac = (struct mda_context *) mda->metadata_locn;
+	if (!mdac)
+		return NULL;
 	if (!(mdac_new = dm_pool_alloc(mem, sizeof(*mdac_new)))) {
 		log_error("mda_context allocation failed");
-		dm_pool_free(mem, mda_new);
 		return NULL;
 	}
-	memcpy(mda_new, mda, sizeof(*mda));
 	memcpy(mdac_new, mdac, sizeof(*mdac));
-	mda_new->metadata_locn = mdac_new;
-
-	/* FIXME mda 'list' left invalid here */
 
-	return mda_new;
+	return mdac_new;
 }
 
 
@@ -1667,7 +1658,7 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
 
 	/* Add copy of mdas to supplied list */
 	dm_list_iterate_items(mda, &info->mdas) {
-		mda_new = _mda_copy(fmt->cmd->mem, mda);
+		mda_new = mda_copy(fmt->cmd->mem, mda);
 		if (!mda_new)
 			return 0;
 		dm_list_add(mdas, &mda_new->list);
@@ -1734,6 +1725,7 @@ static struct metadata_area_ops _metadata_text_raw_ops = {
 	.vg_precommit = _vg_precommit_raw,
 	.vg_commit = _vg_commit_raw,
 	.vg_revert = _vg_revert_raw,
+	.mda_copy = _mda_copy_raw,
 	.mda_free_sectors = _mda_free_sectors_raw,
 	.mda_total_sectors = _mda_total_sectors_raw,
 	.mda_in_vg = _mda_in_vg_raw,
@@ -1804,7 +1796,7 @@ static int _text_pv_setup(const struct format_type *fmt,
 				if (found)
 					continue;
 
-				mda_new = _mda_copy(fmt->cmd->mem, mda);
+				mda_new = mda_copy(fmt->cmd->mem, mda);
 				if (!mda_new)
 					return_0;
 				dm_list_add(mdas, &mda_new->list);
@@ -1972,7 +1964,7 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
 			mdas = &info->mdas;
 			dm_list_iterate_items(mda, mdas) {
 				/* FIXME Check it holds this VG */
-				mda_new = _mda_copy(fmt->cmd->mem, mda);
+				mda_new = mda_copy(fmt->cmd->mem, mda);
 				if (!mda_new)
 					return_NULL;
 				dm_list_add(&fid->metadata_areas, &mda_new->list);
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 3a673da..20a51e9 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3856,6 +3856,31 @@ uint32_t pv_pe_alloc_count(const struct physical_volume *pv)
 }
 
 /*
+ * Copy constructor for a metadata_area.
+ */
+struct metadata_area *mda_copy(struct dm_pool *mem,
+			       struct metadata_area *mda)
+{
+	struct metadata_area *mda_new;
+
+	if (!(mda_new = dm_pool_alloc(mem, sizeof(*mda_new)))) {
+		log_error("metadata_area allocation failed");
+		return NULL;
+	}
+	memcpy(mda_new, mda, sizeof(*mda));
+	if (mda->ops->mda_copy && mda->metadata_locn) {
+		mda_new->metadata_locn = mda->ops->mda_copy(mem, mda);
+		if (!mda_new->metadata_locn) {
+			dm_pool_free(mem, mda_new);
+			return NULL;
+		}
+	}
+
+	/* FIXME mda 'list' left invalid here */
+
+	return mda_new;
+}
+/*
  * This function provides a way to answer the question on a format specific
  * basis - does the format specfic context of these two metadata areas
  * match?
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 6f6236f..86314b2 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -136,6 +136,11 @@ struct metadata_area_ops {
 			  struct metadata_area * mda);
 
 	/*
+	 * Per location copy constructor.
+	 */
+	void *(*mda_copy) (struct dm_pool *mem, struct metadata_area *mda);
+
+	/*
 	 * Returns number of free sectors in given metadata area.
 	 */
 	uint64_t (*mda_free_sectors) (struct metadata_area *mda);
@@ -172,6 +177,8 @@ struct metadata_area {
 	void *metadata_locn;
 	uint32_t flags;
 };
+struct metadata_area *mda_copy(struct dm_pool *mem,
+			       struct metadata_area *mda);
 
 int mda_is_ignored(struct metadata_area *mda);
 void mda_set_ignored(struct metadata_area *mda, int value);
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 10/35] Use vg_mda_count() in vgdisplay.
  2010-06-22  3:05                 ` [PATCH 09/35] Add mda location specific mda_copy constructor Dave Wysochanski
@ 2010-06-22  3:05                   ` Dave Wysochanski
  2010-06-22  3:05                     ` [PATCH 11/35] Add metadata_areas_ignored list and functions to manage ignored mdas Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel


Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/display/display.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/display/display.c b/lib/display/display.c
index a835327..7a8e325 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -664,7 +664,7 @@ void vgdisplay_full(const struct volume_group *vg)
 	log_print("Format                %s", vg->fid->fmt->name);
 	if (vg->fid->fmt->features & FMT_MDAS) {
 		log_print("Metadata Areas        %d",
-			  dm_list_size(&vg->fid->metadata_areas));
+			  vg_mda_count(vg));
 		log_print("Metadata Sequence No  %d", vg->seqno);
 	}
 	access_str = vg->status & (LVM_READ | LVM_WRITE);
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 11/35] Add metadata_areas_ignored list and functions to manage ignored mdas.
  2010-06-22  3:05                   ` [PATCH 10/35] Use vg_mda_count() in vgdisplay Dave Wysochanski
@ 2010-06-22  3:05                     ` Dave Wysochanski
  2010-06-22  3:05                       ` [PATCH 12/35] Define new functions and vgs/pvs fields related to mda ignore Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Add a second mda list, metadata_areas_ignored to fid, and a couple
functions, fid_add_mda() and fid_add_mdas() to help manage the lists.

These functions are needed to properly count the ignored mdas and
manage the lists attached to the 'fid' and ultimately the 'vg'.

Ensure metadata_areas_ignored is initialized in other formats, even
if the list is never used.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format1/format1.c            |    1 +
 lib/format_pool/format_pool.c    |    1 +
 lib/format_text/format-text.c    |    2 ++
 lib/metadata/metadata-exported.h |    1 +
 lib/metadata/metadata.c          |   23 +++++++++++++++++++++++
 lib/metadata/metadata.h          |    2 ++
 lib/report/report.c              |    1 +
 7 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/lib/format1/format1.c b/lib/format1/format1.c
index 1167e04..f0b323c 100644
--- a/lib/format1/format1.c
+++ b/lib/format1/format1.c
@@ -464,6 +464,7 @@ static struct format_instance *_format1_create_instance(const struct format_type
 
 	fid->fmt = fmt;
 	dm_list_init(&fid->metadata_areas);
+	dm_list_init(&fid->metadata_areas_ignored);
 
 	/* Define a NULL metadata area */
 	if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
diff --git a/lib/format_pool/format_pool.c b/lib/format_pool/format_pool.c
index d8a09ec..d3f5fd6 100644
--- a/lib/format_pool/format_pool.c
+++ b/lib/format_pool/format_pool.c
@@ -263,6 +263,7 @@ static struct format_instance *_pool_create_instance(const struct format_type *f
 
 	fid->fmt = fmt;
 	dm_list_init(&fid->metadata_areas);
+	dm_list_init(&fid->metadata_areas_ignored);
 
 	/* Define a NULL metadata area */
 	if (!(mda = dm_pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) {
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index be221ee..bbee7f0 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1201,6 +1201,7 @@ static int _scan_raw(const struct format_type *fmt)
 
 	fid.fmt = fmt;
 	dm_list_init(&fid.metadata_areas);
+	dm_list_init(&fid.metadata_areas_ignored);
 
 	dm_list_iterate_items(rl, raw_list) {
 		/* FIXME We're reading mdah twice here... */
@@ -1910,6 +1911,7 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
 
 	fid->fmt = fmt;
 	dm_list_init(&fid->metadata_areas);
+	dm_list_init(&fid->metadata_areas_ignored);
 
 	if (!vgname) {
 		if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index dbac0f2..d0e10e6 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -216,6 +216,7 @@ struct physical_volume {
 struct format_instance {
 	const struct format_type *fmt;
 	struct dm_list metadata_areas;	/* e.g. metadata locations */
+	struct dm_list metadata_areas_ignored;
 	void *private;
 };
 
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 20a51e9..c7b829f 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3855,6 +3855,29 @@ uint32_t pv_pe_alloc_count(const struct physical_volume *pv)
 	return pv_field(pv, pe_alloc_count);
 }
 
+void fid_add_mda(struct format_instance *fid, struct metadata_area *mda)
+{
+	if (mda_is_ignored(mda))
+		dm_list_add(&fid->metadata_areas_ignored,
+			    &mda->list);
+	else
+		dm_list_add(&fid->metadata_areas,
+			    &mda->list);
+}
+
+int fid_add_mdas(struct format_instance *fid, struct dm_list *mdas)
+{
+	struct metadata_area *mda, *mda_new;
+
+	dm_list_iterate_items(mda, mdas) {
+		mda_new = mda_copy(fid->fmt->cmd->mem, mda);
+		if (!mda_new)
+			return_0;
+		fid_add_mda(fid, mda_new);
+	}
+	return 1;
+}
+
 /*
  * Copy constructor for a metadata_area.
  */
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 86314b2..fd89423 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -183,6 +183,8 @@ struct metadata_area *mda_copy(struct dm_pool *mem,
 int mda_is_ignored(struct metadata_area *mda);
 void mda_set_ignored(struct metadata_area *mda, int value);
 int mda_locn_match(struct metadata_area *mda1, struct metadata_area *mda2);
+void fid_add_mda(struct format_instance *fid, struct metadata_area *mda);
+int fid_add_mdas(struct format_instance *fid, struct dm_list *mdas);
 
 #define seg_pvseg(seg, s)	(seg)->areas[(s)].u.pv.pvseg
 #define seg_dev(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pv->dev
diff --git a/lib/report/report.c b/lib/report/report.c
index 063db07..d912758 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1103,6 +1103,7 @@ static int _copypercent_disp(struct dm_report *rh __attribute((unused)),
 /* necessary for displaying something for PVs not belonging to VG */
 static struct format_instance _dummy_fid = {
 	.metadata_areas = { &(_dummy_fid.metadata_areas), &(_dummy_fid.metadata_areas) },
+	.metadata_areas_ignored = { &(_dummy_fid.metadata_areas_ignored), &(_dummy_fid.metadata_areas_ignored) },
 };
 
 static struct volume_group _dummy_vg = {
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 12/35] Define new functions and vgs/pvs fields related to mda ignore.
  2010-06-22  3:05                     ` [PATCH 11/35] Add metadata_areas_ignored list and functions to manage ignored mdas Dave Wysochanski
@ 2010-06-22  3:05                       ` Dave Wysochanski
  2010-06-22  3:05                         ` [PATCH 13/35] Add --metadataignore to pvchange, allowing for ignoring of metadata areas Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Define a new pvs field, pv_mda_count_ignored, and a new vgs field,
vg_mda_count_ignored to match the existing pv_mda_count and vg_mda_count.
Also define various supporting functions to implement the counting as
well as setting the ignored flag and determining if an mda is ignored.
These high level functions call into the lower level location independent
mda ignore functions defined by earlier patches.

Note that counting ignored mdas in a vg requires traversing both lists
and checking for the ignored bit on the mda.  The count of 'ignored'
mdas then is defined by having the bit set, not by which list the mda
is on.  The list does determine whether LVM actually does read/write to
the mda, though we must count the bits in order to return accurate numbers
for the various counts.  Also, pv_mda_set_ignored must search both vg
lists for ignored mda.  If the state changes and needs to be committed
to disk, the ignored mda will be on the non-ignored list.

Note also in pv_mda_set_ignored(), we must properly manage the mda lists.
If we change the ignored state of an mda, we must change any mdas on
vg->fid->metadata_areas that correspond to this pv.  Also, we may
need to allocate a copy of the mda, as is done when fid->metadata_areas
is populated from _vg_read(), if we are un-ignoring an ignored mda.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/metadata/metadata-exported.h |    4 +
 lib/metadata/metadata.c          |  116 +++++++++++++++++++++++++++++++++++++-
 lib/report/columns.h             |    2 +
 lib/report/report.c              |   25 ++++++++
 4 files changed, 146 insertions(+), 1 deletions(-)

diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index d0e10e6..8c12f36 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -857,6 +857,9 @@ uint64_t pv_pe_start(const struct physical_volume *pv);
 uint32_t pv_pe_count(const struct physical_volume *pv);
 uint32_t pv_pe_alloc_count(const struct physical_volume *pv);
 uint32_t pv_mda_count(const struct physical_volume *pv);
+uint32_t pv_mda_count_ignored(const struct physical_volume *pv);
+uint32_t pv_mda_is_ignored(const struct physical_volume *pv);
+int pv_mda_set_ignored(const struct physical_volume *pv, int value);
 
 uint64_t lv_size(const struct logical_volume *lv);
 
@@ -872,6 +875,7 @@ uint64_t vg_pv_count(const struct volume_group *vg);
 uint64_t vg_max_pv(const struct volume_group *vg);
 uint64_t vg_max_lv(const struct volume_group *vg);
 uint32_t vg_mda_count(const struct volume_group *vg);
+uint32_t vg_mda_count_ignored(const struct volume_group *vg);
 int vg_check_write_mode(struct volume_group *vg);
 #define vg_is_clustered(vg) (vg_status((vg)) & CLUSTERED)
 #define vg_is_exported(vg) (vg_status((vg)) & EXPORTED_VG)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index c7b829f..b52447a 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3954,6 +3954,97 @@ uint32_t pv_mda_count(const struct physical_volume *pv)
 	return info ? dm_list_size(&info->mdas) : UINT64_C(0);
 }
 
+uint32_t pv_mda_count_ignored(const struct physical_volume *pv)
+{
+	struct lvmcache_info *info;
+	struct metadata_area *mda;
+	uint32_t count=0;
+
+	info = info_from_pvid((const char *)&pv->id.uuid, 0);
+	if (!info)
+		return 0;
+	dm_list_iterate_items(mda, &info->mdas) {
+		if (mda_is_ignored(mda))
+			count++;
+	}
+	return count;
+}
+
+uint32_t pv_mda_is_ignored(const struct physical_volume *pv)
+{
+	return pv_mda_count_ignored(pv) ? 1 : 0;
+}
+
+int pv_mda_set_ignored(const struct physical_volume *pv, int value)
+{
+	struct lvmcache_info *info;
+	struct metadata_area *mda, *mda_vg, *tmda;
+	struct dm_list *mdas_vg, *mdas_vg_ignored;
+
+	info = info_from_pvid((const char *)&pv->id.uuid, 0);
+	if (!info)
+		return_0;
+
+	if (is_orphan(pv)) {
+		dm_list_iterate_items(mda, &info->mdas) {
+			mda_set_ignored(mda, value);
+		}
+		return 1;
+	}
+
+	/*
+	 * Do not allow disabling of the the last PV in a VG.
+	 */
+	if (!pv_mda_count_ignored(pv) &&
+	    (pv_mda_count(pv) ==
+	     vg_mda_count(pv->vg) - vg_mda_count_ignored(pv->vg))) {
+		log_error("Cannot disable metadata - volume group "
+			  "needs at least one enabled physical volume.\n");
+		return 0;
+	}
+
+	/*
+	 * Non-orphan case is more complex.
+	 * If the PV's mdas are ignored, and we wish to un-ignore,
+	 * we clear the bit and move them from the ignored mda list to the
+	 * non-ignored list, ensuring the new state will get written to disk
+	 * in the vg_write() path.
+	 * If the PV's mdas are not ignored, and we are setting
+	 * them to ignored, we set the bit but leave them on the non-ignored
+	 * list, ensuring the new state will get written to disk in the
+	 * vg_write() path.
+	 */
+	mdas_vg = &pv->vg->fid->metadata_areas;
+	mdas_vg_ignored = &pv->vg->fid->metadata_areas_ignored;
+	dm_list_iterate_items(mda, &info->mdas) {
+		if (mda_is_ignored(mda) && !value) {
+			/* If the mda is ignored, it could be on either list */
+			dm_list_iterate_items_safe(mda_vg, tmda, mdas_vg_ignored) {
+				if (mda_locn_match(mda, mda_vg)) {
+					mda_set_ignored(mda_vg, value);
+					dm_list_move(mdas_vg, &mda_vg->list);
+				}
+			}
+			dm_list_iterate_items_safe(mda_vg, tmda, mdas_vg) {
+				if (mda_locn_match(mda, mda_vg)) {
+					mda_set_ignored(mda_vg, value);
+					dm_list_move(mdas_vg, &mda_vg->list);
+				}
+			}
+		} else if (!mda_is_ignored(mda) && value) {
+			dm_list_iterate_items_safe(mda_vg, tmda, mdas_vg) {
+				if (mda_locn_match(mda, mda_vg)) {
+					mda_set_ignored(mda_vg, value);
+					/* don't move mda - needs written to
+					   disk */
+				}
+			}
+		}
+		mda_set_ignored(mda, value);
+	}
+	return 1;
+}
+
 uint32_t vg_seqno(const struct volume_group *vg)
 {
 	return vg->seqno;
@@ -4006,7 +4097,30 @@ uint64_t vg_max_lv(const struct volume_group *vg)
 
 uint32_t vg_mda_count(const struct volume_group *vg)
 {
-	return dm_list_size(&vg->fid->metadata_areas);
+	return dm_list_size(&vg->fid->metadata_areas) +
+		dm_list_size(&vg->fid->metadata_areas_ignored);
+}
+
+uint32_t vg_mda_count_ignored(const struct volume_group *vg)
+{
+       uint32_t count = 0;
+       struct metadata_area *mda;
+
+       /*
+	* Ignored mdas could be on either list - the reason being the state
+	* may have changed from ignored to un-ignored and we need to write
+	* the state to disk.
+	*/
+       dm_list_iterate_items(mda, &vg->fid->metadata_areas) {
+	       if (mda_is_ignored(mda))
+		       count++;
+       }
+       dm_list_iterate_items(mda, &vg->fid->metadata_areas_ignored) {
+	       if (mda_is_ignored(mda))
+		       count++;
+       }
+
+       return count;
 }
 
 uint64_t lv_size(const struct logical_volume *lv)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 1414971..9cc5cb1 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -92,6 +92,7 @@ FIELD(PVS, pv, NUM, "PE", pe_count, 3, uint32, "pv_pe_count", "Total number of P
 FIELD(PVS, pv, NUM, "Alloc", pe_alloc_count, 5, uint32, "pv_pe_alloc_count", "Total number of allocated Physical Extents.")
 FIELD(PVS, pv, STR, "PV Tags", tags, 7, tags, "pv_tags", "Tags, if any.")
 FIELD(PVS, pv, NUM, "#PMda", id, 5, pvmdas, "pv_mda_count", "Number of metadata areas on this device.")
+FIELD(PVS, pv, NUM, "#PMdaIgn", id, 8, pvmdas_ignored, "pv_mda_count_ignored", "Number of metadata areas ignored on this device.")
 
 FIELD(VGS, vg, STR, "Fmt", cmd, 3, vgfmt, "vg_fmt", "Type of metadata.")
 FIELD(VGS, vg, STR, "VG UUID", id, 38, uuid, "vg_uuid", "Unique identifier.")
@@ -111,6 +112,7 @@ FIELD(VGS, vg, NUM, "#SN", cmd, 3, snapcount, "snap_count", "Number of snapshots
 FIELD(VGS, vg, NUM, "Seq", seqno, 3, uint32, "vg_seqno", "Revision number of internal metadata.  Incremented whenever it changes.")
 FIELD(VGS, vg, STR, "VG Tags", tags, 7, tags, "vg_tags", "Tags, if any.")
 FIELD(VGS, vg, NUM, "#VMda", cmd, 5, vgmdas, "vg_mda_count", "Number of metadata areas in use by this VG.")
+FIELD(VGS, vg, NUM, "#VMdaIgn", cmd, 8, vgmdas_ignored, "vg_mda_count_ignored", "Number of metadata areas ignored in this VG.")
 FIELD(VGS, vg, NUM, "VMdaFree", cmd, 9, vgmdafree, "vg_mda_free", "Free metadata area space for this VG in current units.")
 FIELD(VGS, vg, NUM, "VMdaSize", cmd, 9, vgmdasize, "vg_mda_size", "Size of smallest metadata area for this VG in current units.")
 
diff --git a/lib/report/report.c b/lib/report/report.c
index d912758..9196531 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -856,6 +856,19 @@ static int _pvmdas_disp(struct dm_report *rh, struct dm_pool *mem,
 	return _uint32_disp(rh, mem, field, &count, private);
 }
 
+static int _pvmdas_ignored_disp(struct dm_report *rh, struct dm_pool *mem,
+				 struct dm_report_field *field,
+				 const void *data, void *private)
+{
+	uint32_t count;
+	const struct physical_volume *pv =
+	    (const struct physical_volume *) data;
+
+	count = pv_mda_count_ignored(pv);
+
+	return _uint32_disp(rh, mem, field, &count, private);
+}
+
 static int _vgmdas_disp(struct dm_report *rh, struct dm_pool *mem,
 			struct dm_report_field *field,
 			const void *data, void *private)
@@ -868,6 +881,18 @@ static int _vgmdas_disp(struct dm_report *rh, struct dm_pool *mem,
 	return _uint32_disp(rh, mem, field, &count, private);
 }
 
+static int _vgmdas_ignored_disp(struct dm_report *rh, struct dm_pool *mem,
+				 struct dm_report_field *field,
+				 const void *data, void *private)
+{
+	const struct volume_group *vg = (const struct volume_group *) data;
+	uint32_t count;
+
+	count = vg_mda_count_ignored(vg);
+
+	return _uint32_disp(rh, mem, field, &count, private);
+}
+
 static int _pvmdafree_disp(struct dm_report *rh, struct dm_pool *mem,
 			   struct dm_report_field *field,
 			   const void *data, void *private)
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 13/35] Add --metadataignore to pvchange, allowing for ignoring of metadata areas.
  2010-06-22  3:05                       ` [PATCH 12/35] Define new functions and vgs/pvs fields related to mda ignore Dave Wysochanski
@ 2010-06-22  3:05                         ` Dave Wysochanski
  2010-06-22  3:05                           ` [PATCH 14/35] Update pvchange, pvs and vgs man pages for metadata ignore Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

This patch just modifies pvchange to call the underlying ignore
functions for mdas.  Ensure special cases do not reflect changes
in metadata (PVs with 0 mdas, setting ignored when already ignored,
clearing ignored when not ignored).

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 tools/args.h     |    1 +
 tools/commands.h |    3 ++-
 tools/pvchange.c |   33 ++++++++++++++++++++++++++++++++-
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/tools/args.h b/tools/args.h
index 76146ee..d343689 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -25,6 +25,7 @@ arg(nolocking_ARG, '\0', "nolocking", NULL, 0)
 arg(pvmetadatacopies_ARG, '\0', "pvmetadatacopies", int_arg, 0)
 arg(metadatacopies_ARG, '\0', "metadatacopies", int_arg, 0)
 arg(metadatasize_ARG, '\0', "metadatasize", size_mb_arg, 0)
+arg(metadataignore_ARG, '\0', "metadataignore", yes_no_arg, 0)
 arg(restorefile_ARG, '\0', "restorefile", string_arg, 0)
 arg(labelsector_ARG, '\0', "labelsector", int_arg, 0)
 arg(driverloaded_ARG, '\0', "driverloaded", yes_no_arg, 0)
diff --git a/tools/commands.h b/tools/commands.h
index e33cadc..6d8d2c0 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -455,6 +455,7 @@ xx(pvchange,
    "\t[-t|--test]\n"
    "\t[-u|--uuid]\n"
    "\t[-x|--allocatable y|n]\n"
+   "\t[--metadataignore y|n]\n"
    "\t[-v|--verbose]\n"
    "\t[--addtag Tag]\n"
    "\t[--deltag Tag]\n"
@@ -462,7 +463,7 @@ xx(pvchange,
    "\t[PhysicalVolumePath...]\n",
 
    all_ARG, allocatable_ARG, allocation_ARG, autobackup_ARG, deltag_ARG,
-   addtag_ARG, test_ARG, uuid_ARG)
+   addtag_ARG, metadataignore_ARG, test_ARG, uuid_ARG)
 
 xx(pvresize,
    "Resize physical volume(s)",
diff --git a/tools/pvchange.c b/tools/pvchange.c
index 5486b73..ba196d6 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -34,6 +34,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
 	int allocatable = 0;
 	int tagarg = 0;
 	int r = 0;
+	int mda_ignore = 0;
 
 	if (arg_count(cmd, addtag_ARG))
 		tagarg = addtag_ARG;
@@ -43,6 +44,9 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
 	if (arg_count(cmd, allocatable_ARG))
 		allocatable = !strcmp(arg_str_value(cmd, allocatable_ARG, "n"),
 				      "y");
+	if (arg_count(cmd, metadataignore_ARG))
+		mda_ignore = !strcmp(arg_str_value(cmd, metadataignore_ARG, "n"),
+				      "y");
 	else if (tagarg && !(tag = arg_str_value(cmd, tagarg, NULL))) {
 		log_error("Failed to get tag");
 		return 0;
@@ -117,6 +121,32 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
 				goto out;
 			}
 		}
+	} else if (arg_count(cmd, metadataignore_ARG)) {
+		if (mda_ignore && pv_mda_is_ignored(pv)) {
+			log_error("Physical volume \"%s\" metadata already "
+				  "ignored", pv_name);
+			goto out;
+		}
+		if (!mda_ignore && !pv_mda_is_ignored(pv)) {
+			log_error("Physical volume \"%s\" metadata already "
+				  "not ignored", pv_name);
+			goto out;
+		}
+		if (!pv_mda_count(pv)) {
+			log_error("Physical volume \"%s\" has no metadata "
+				  "areas ", pv_name);
+			goto out;
+		}
+		if (mda_ignore) {
+			log_verbose("Setting physical volume \"%s\" "
+				    "metadata ignored", pv_name);
+		} else {
+			log_verbose("Setting physical volume \"%s\" "
+				    "metadata not ignored", pv_name);
+		}
+		if (!pv_mda_set_ignored(pv, mda_ignore)) {
+			goto out;
+		}
 	} else {
 		/* --uuid: Change PV ID randomly */
 		if (!id_create(&pv->id)) {
@@ -187,7 +217,8 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
 	struct str_list *sll;
 
 	if (arg_count(cmd, allocatable_ARG) + arg_count(cmd, addtag_ARG) +
-	    arg_count(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) != 1) {
+	    arg_count(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) +
+	    arg_count(cmd, metadataignore_ARG) != 1) {
 		log_error("Please give exactly one option of -x, -uuid, "
 			  "--addtag or --deltag");
 		return EINVALID_CMD_LINE;
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 14/35] Update pvchange, pvs and vgs man pages for metadata ignore.
  2010-06-22  3:05                         ` [PATCH 13/35] Add --metadataignore to pvchange, allowing for ignoring of metadata areas Dave Wysochanski
@ 2010-06-22  3:05                           ` Dave Wysochanski
  2010-06-22  3:05                             ` [PATCH 15/35] Implement ignore of mda if bit set by skipping r/w of metadata Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Explain --metadataignore argument to pvchange, add new fields to pvs / vgs.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 man/pvchange.8.in |   10 +++++++++-
 man/pvs.8.in      |    3 ++-
 man/vgs.8.in      |    2 +-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/man/pvchange.8.in b/man/pvchange.8.in
index 00c94a6..7585306 100644
--- a/man/pvchange.8.in
+++ b/man/pvchange.8.in
@@ -6,6 +6,7 @@ pvchange \- change attributes of a physical volume
 [\-\-addtag Tag]
 [\-A|\-\-autobackup y|n] [\-d|\-\-debug] 
 [\-\-deltag Tag]
+[\-\-metadataignore y|n]
 [\-h|\-?|\-\-help]
 [\-t|\-\-test]
 [\-v|\-\-verbose] [\-a|\-\-all] [\-x|\-\-allocatable y|n]
@@ -25,10 +26,17 @@ Generate new random UUID for specified physical volumes.
 .TP
 .I \-x, \-\-allocatable y|n
 Enable or disable allocation of physical extents on this physical volume.
+.TP
+.I \-\-metadataignore y|n
+Ingore or un-ignore metadata areas on this physical volume.  If metadata
+areas on a physical volume are ignored, LVM will treat the physical volume
+as though it has been created with \fB\-\-pvmetadatacopies\fP of 0.  LVM
+operations that would normally result in reading or writing of metadata
+will skip over any ignored metadata areas on physical volumes.
 .SH Example
 "pvchange -x n /dev/sdk1" disallows the allocation of physical extents
 on this physical volume (possibly because of disk errors, or because it will
 be removed after freeing it.
 .SH SEE ALSO
-.BR lvm (8), 
+.BR lvm (8),
 .BR pvcreate (8)
diff --git a/man/pvs.8.in b/man/pvs.8.in
index fe00d2a..55892cc 100644
--- a/man/pvs.8.in
+++ b/man/pvs.8.in
@@ -54,7 +54,8 @@ Use \fb-o help\fP to view the full list of columns available.
 .IP
 Column names include: pv_fmt, pv_uuid, dev_size, pv_name, pv_mda_free,
 pv_mda_size, pe_start, pv_size, pv_free, pv_used, pv_attr, pv_pe_count,
-pv_pe_alloc_count, pv_tags, pv_mda_count, pvseg_start, and pvseg_size.
+pv_pe_alloc_count, pv_tags, pv_mda_count, pv_mda_count_ignored,
+pvseg_start, and pvseg_size.
 .IP
 With --segments, any "pvseg_" prefixes are optional; otherwise any
 "pv_" prefixes are optional.  Columns mentioned in \fBvgs (8)\fP can also
diff --git a/man/vgs.8.in b/man/vgs.8.in
index b22d08b..7475f77 100644
--- a/man/vgs.8.in
+++ b/man/vgs.8.in
@@ -49,7 +49,7 @@ Use \fb-o help\fP to view the full list of columns available.
 Column names include: vg_fmt, vg_uuid, vg_name, vg_attr, vg_size, vg_free,
 vg_sysid, vg_extent_size, vg_extent_count, vg_free_count, max_lv, max_pv,
 pv_count, lv_count, snap_count, vg_seqno, vg_tags, vg_mda_count, vg_mda_free,
-and vg_mda_size.
+and vg_mda_size, vg_mda_count_ignored.
 .IP
 Any "vg_" prefixes are optional.  Columns mentioned in either \fBpvs (8)\fP 
 or \fBlvs (8)\fP can also be chosen, but columns cannot be taken from both
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 15/35] Implement ignore of mda if bit set by skipping r/w of metadata.
  2010-06-22  3:05                           ` [PATCH 14/35] Update pvchange, pvs and vgs man pages for metadata ignore Dave Wysochanski
@ 2010-06-22  3:05                             ` Dave Wysochanski
  2010-06-22  3:05                               ` [PATCH 16/35] Add mdas_empty_or_ignored() helper function Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

We implement ignore of an mda at label_read time by checking for
the ignore bit, and then skipping the reading of the vgname and
other information in the metadata.  This will have an effect similar
to a PV found with no mdas.  Thus, it will look like an orphan in the
cache until we scan the rest of the system and find a PV with
metadata, and the mda will not be on the vg->fid->metadata_areas
list so no read/writes will be done to the metadata area.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/text_label.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index ab9f595..70aba3f 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -311,6 +311,12 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
 		}
 		mda_set_ignored(mda, rlocn_is_ignored(mdah->raw_locns));
 
+		if (mda_is_ignored(mda)) {
+			if (!dev_close(mdac->area.dev))
+				stack;
+			continue;
+		}
+
 		if ((vgname = vgname_from_mda(info->fmt, mdah,
 					      &mdac->area,
 					      &vgid, &vgstatus, &creation_host,
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 16/35] Add mdas_empty_or_ignored() helper function.
  2010-06-22  3:05                             ` [PATCH 15/35] Implement ignore of mda if bit set by skipping r/w of metadata Dave Wysochanski
@ 2010-06-22  3:05                               ` Dave Wysochanski
  2010-06-22  3:05                                 ` [PATCH 17/35] Use mdas_empty_or_ignored() in place of checks for empty mda list Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Add a helper function to consolidate checking for an empty mdas list
or ignored mdas.  Ignored mdas should behave almost identically to
an empty mda list - the metadata areas should not be read or written
to.  This function will make it easier to implement metadata balancing
and easier to track pvs with an empty mda list or ignored mdas.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/metadata/metadata.c |   13 +++++++++++++
 lib/metadata/metadata.h |    1 +
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index b52447a..6b7931e 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -4045,6 +4045,19 @@ int pv_mda_set_ignored(const struct physical_volume *pv, int value)
 	return 1;
 }
 
+int mdas_empty_or_ignored(struct dm_list *mdas)
+{
+	struct metadata_area *mda;
+
+	if (!dm_list_size(mdas))
+		return 1;
+	dm_list_iterate_items(mda, mdas) {
+		if (mda_is_ignored(mda))
+			return 1;
+	}
+	return 0;
+}
+
 uint32_t vg_seqno(const struct volume_group *vg)
 {
 	return vg->seqno;
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index fd89423..63f9f72 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -185,6 +185,7 @@ void mda_set_ignored(struct metadata_area *mda, int value);
 int mda_locn_match(struct metadata_area *mda1, struct metadata_area *mda2);
 void fid_add_mda(struct format_instance *fid, struct metadata_area *mda);
 int fid_add_mdas(struct format_instance *fid, struct dm_list *mdas);
+int mdas_empty_or_ignored(struct dm_list *mdas);
 
 #define seg_pvseg(seg, s)	(seg)->areas[(s)].u.pv.pvseg
 #define seg_dev(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pv->dev
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 17/35] Use mdas_empty_or_ignored() in place of checks for empty mda list.
  2010-06-22  3:05                               ` [PATCH 16/35] Add mdas_empty_or_ignored() helper function Dave Wysochanski
@ 2010-06-22  3:05                                 ` Dave Wysochanski
  2010-06-22  3:05                                   ` [PATCH 18/35] Update _vg_read and _text_create_text_instance to use fid_add_mda[s] Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

With the addition of ignored mdas, we replace all checks for an empty
mda list with a new function to look for either an empty mda list or
ignored mdas.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/cache/lvmcache.c    |    3 ++-
 lib/metadata/metadata.c |   31 ++++++++++++++++++-------------
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 213f3cf..a7b11cc 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1197,7 +1197,8 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
 	}
 
 	/* If PV without mdas is already in a real VG, don't make it orphan */
-	if (is_orphan_vg(vgname) && info->vginfo && !dm_list_size(&info->mdas) &&
+	if (is_orphan_vg(vgname) && info->vginfo &&
+	    mdas_empty_or_ignored(&info->mdas) &&
 	    !is_orphan_vg(info->vginfo->vgname) && memlock())
 		return 1;
 
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 6b7931e..d1d2fed 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1305,7 +1305,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name,
 	 * this means checking every VG by scanning every PV on the
 	 * system.
 	 */
-	if (pv && is_orphan(pv) && !dm_list_size(&mdas)) {
+	if (pv && is_orphan(pv) && mdas_empty_or_ignored(&mdas)) {
 		if (!scan_vgs_for_pvs(cmd))
 			return_0;
 		pv = pv_read(cmd, name, NULL, NULL, 0, 0);
@@ -1798,7 +1798,7 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,
 		return NULL;
 	}
 
-	if (is_orphan_vg(pv->vg_name) && !dm_list_size(&mdas)) {
+	if (is_orphan_vg(pv->vg_name) && mdas_empty_or_ignored(&mdas)) {
 		/* If a PV has no MDAs - need to search all VGs for it */
 		if (!scan_vgs_for_pvs(cmd))
 			return_NULL;
@@ -2722,8 +2722,8 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
 	/* Ensure every PV in the VG was in the cache */
 	if (correct_vg) {
 		/*
-		 * If the VG has PVs without mdas, they may still be
-		 * orphans in the cache: update the cache state here.
+		 * If the VG has PVs without mdas, or ignored mdas, they may
+		 * still be orphans in the cache: update the cache state here.
 		 */
 		if (!inconsistent &&
 		    dm_list_size(&correct_vg->pvs) > dm_list_size(pvids)) {
@@ -2738,11 +2738,12 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
 
 				/*
 				 * PV not marked as belonging to this VG in cache.
-				 * Check it's an orphan without metadata area.
+				 * Check it's an orphan without metadata area
+				 * not ignored.
 				 */
 				if (!(info = info_from_pvid(pvl->pv->dev->pvid, 1)) ||
 				   !info->vginfo || !is_orphan_vg(info->vginfo->vgname) ||
-				   dm_list_size(&info->mdas)) {
+				   !mdas_empty_or_ignored(&info->mdas)) {
 					inconsistent_pvs = 1;
 					break;
 				}
@@ -3128,20 +3129,24 @@ const char *find_vgname_from_pvid(struct cmd_context *cmd,
 			return_NULL;
 		}
 		/*
-		 * If an orphan PV has no MDAs it may appear to be an
-		 * orphan until the metadata is read off another PV in
-		 * the same VG.  Detecting this means checking every VG
-		 * by scanning every PV on the system.
+		 * If an orphan PV has no MDAs, or it has MDAs but the
+		 * MDA is ignored, it may appear to be an orphan until
+		 * the metadata is read off another PV in the same VG.
+		 * Detecting this means checking every VG by scanning
+		 * every PV on the system.
 		 */
-		if (!dm_list_size(&info->mdas)) {
+		if (mdas_empty_or_ignored(&info->mdas)) {
 			if (!scan_vgs_for_pvs(cmd)) {
 				log_error("Rescan for PVs without "
 					  "metadata areas failed.");
 				return NULL;
 			}
+			/*
+			 * Ask lvmcache again - we may have a non-orphan
+			 * name now
+			 */
+			vgname = lvmcache_vgname_from_pvid(cmd, pvid);
 		}
-		/* Ask lvmcache again - we may have a non-orphan name now */
-		vgname = lvmcache_vgname_from_pvid(cmd, pvid);
 	}
 	return vgname;
 }
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 18/35] Update _vg_read and _text_create_text_instance to use fid_add_mda[s].
  2010-06-22  3:05                                 ` [PATCH 17/35] Use mdas_empty_or_ignored() in place of checks for empty mda list Dave Wysochanski
@ 2010-06-22  3:05                                   ` Dave Wysochanski
  2010-06-22  3:05                                     ` [PATCH 19/35] Refactor vg_commit() to add _vg_commit_mdas() Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

When we are constructing the vg, we may need to adjust the list of
metadata_areas if there are ignored mdas.  At label read time, we
do not read the metadata of ignored mdas, and as a result, they do
not get placed on vg->fid->metadata_areas inside _text_create_text_instance
since lvmcache does not have these areas attached to vginfo->infos.
However, when we're checking the pvids inside _vg_read, after having
read another metadata area from another PV, we do have the opportunity
to update the metadata_area and metadata_areas_ignored lists based
on the read metadata_area.  We need accurate mda lists for the reporting
functions that count the ignored mdas, as well as general correctness
of mda balancing.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/format-text.c |   20 +++++++-------------
 lib/metadata/metadata.c       |    6 +++++-
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index bbee7f0..cb91992 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1886,11 +1886,11 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
 {
 	struct format_instance *fid;
 	struct text_fid_context *fidtc;
-	struct metadata_area *mda, *mda_new;
+	struct metadata_area *mda;
 	struct mda_context *mdac;
 	struct dir_list *dl;
 	struct raw_list *rl;
-	struct dm_list *dir_list, *raw_list, *mdas;
+	struct dm_list *dir_list, *raw_list;
 	char path[PATH_MAX];
 	struct lvmcache_vginfo *vginfo;
 	struct lvmcache_info *info;
@@ -1918,7 +1918,7 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
 			return_NULL;
 		mda->ops = &_metadata_text_file_backup_ops;
 		mda->metadata_locn = context;
-		dm_list_add(&fid->metadata_areas, &mda->list);
+		fid_add_mda(fid, mda);
 	} else {
 		dir_list = &((struct mda_lists *) fmt->private)->dirs;
 
@@ -1935,7 +1935,7 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
 				return_NULL;
 			mda->ops = &_metadata_text_file_ops;
 			mda->metadata_locn = context;
-			dm_list_add(&fid->metadata_areas, &mda->list);
+			fid_add_mda(fid, mda);
 		}
 
 		raw_list = &((struct mda_lists *) fmt->private)->raws;
@@ -1955,7 +1955,7 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
 			memcpy(&mdac->area, &rl->dev_area, sizeof(mdac->area));
 			mda->ops = &_metadata_text_raw_ops;
 			/* FIXME MISTAKE? mda->metadata_locn = context; */
-			dm_list_add(&fid->metadata_areas, &mda->list);
+			fid_add_mda(fid, mda);
 		}
 
 		/* Scan PVs in VG for any further MDAs */
@@ -1963,14 +1963,8 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
 		if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
 			goto_out;
 		dm_list_iterate_items(info, &vginfo->infos) {
-			mdas = &info->mdas;
-			dm_list_iterate_items(mda, mdas) {
-				/* FIXME Check it holds this VG */
-				mda_new = mda_copy(fmt->cmd->mem, mda);
-				if (!mda_new)
-					return_NULL;
-				dm_list_add(&fid->metadata_areas, &mda_new->list);
-			}
+			if (!fid_add_mdas(fid, &info->mdas))
+				return_NULL;
 		}
 		/* FIXME Check raw metadata area count - rescan if required */
 	}
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index d1d2fed..99b4147 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2723,7 +2723,8 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
 	if (correct_vg) {
 		/*
 		 * If the VG has PVs without mdas, or ignored mdas, they may
-		 * still be orphans in the cache: update the cache state here.
+		 * still be orphans in the cache: update the cache state here,
+		 * and update the metadata lists in the vg.
 		 */
 		if (!inconsistent &&
 		    dm_list_size(&correct_vg->pvs) > dm_list_size(pvids)) {
@@ -2747,6 +2748,9 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
 					inconsistent_pvs = 1;
 					break;
 				}
+				if (dm_list_size(&info->mdas) &&
+				    !fid_add_mdas(fid, &info->mdas))
+					return_NULL;
 			}
 
 			/* If the check passed, let's update VG and recalculate pvids */
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 19/35] Refactor vg_commit() to add _vg_commit_mdas().
  2010-06-22  3:05                                   ` [PATCH 18/35] Update _vg_read and _text_create_text_instance to use fid_add_mda[s] Dave Wysochanski
@ 2010-06-22  3:05                                     ` Dave Wysochanski
  2010-06-22  3:05                                       ` [PATCH 20/35] Before committing each mda, arrange mdas so ignored mdas get committed first Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Factor out calling mda->ops->vg_commit() for each mda.
No functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/metadata/metadata.c |   26 +++++++++++++++++---------
 1 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 99b4147..304522d 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2424,18 +2424,11 @@ int vg_write(struct volume_group *vg)
 	return 1;
 }
 
-/* Commit pending changes */
-int vg_commit(struct volume_group *vg)
+static int _vg_commit_mdas(struct volume_group *vg)
 {
 	struct metadata_area *mda;
-	int cache_updated = 0;
 	int failed = 0;
-
-	if (!vgname_is_locked(vg->name)) {
-		log_error(INTERNAL_ERROR "Attempt to write new VG metadata "
-			  "without locking %s", vg->name);
-		return cache_updated;
-	}
+	int cache_updated = 0;
 
 	/* Commit to each copy of the metadata area */
 	dm_list_iterate_items(mda, &vg->fid->metadata_areas) {
@@ -2451,6 +2444,21 @@ int vg_commit(struct volume_group *vg)
 			cache_updated = 1;
 		}
 	}
+	return cache_updated;
+}
+
+/* Commit pending changes */
+int vg_commit(struct volume_group *vg)
+{
+	int cache_updated = 0;
+
+	if (!vgname_is_locked(vg->name)) {
+		log_error(INTERNAL_ERROR "Attempt to write new VG metadata "
+			  "without locking %s", vg->name);
+		return cache_updated;
+	}
+
+	cache_updated = _vg_commit_mdas(vg);
 
 	if (cache_updated) {
 		/* Instruct remote nodes to upgrade cached metadata. */
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 20/35] Before committing each mda, arrange mdas so ignored mdas get committed first.
  2010-06-22  3:05                                     ` [PATCH 19/35] Refactor vg_commit() to add _vg_commit_mdas() Dave Wysochanski
@ 2010-06-22  3:05                                       ` Dave Wysochanski
  2010-06-22  3:05                                         ` [PATCH 21/35] Add tests for phase 1 of metadata balance - manage per-PV ignore bit Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Arrange mdas so mdas that are to be ignored come first.  This is an
optimization that ensures consistency on disk for the longest period of time.
This was noted by agk in review of the v4 patchset of pvchange-based mda
balance.

Note the following example for an explanation of the background:
Assume the initial state on disk is as follows:
PV0 (v1, non-ignored)
PV1 (v1, non-ignored)
PV2 (v1, non-ignored)
PV3 (v1, non-ignored)

If we did not sort the list, we would have a commit sequence something like
this:
PV0 (v2, non-ignored)
PV1 (v2, ignored)
PV2 (v2, ignored)
PV3 (v2, non-ignored)

After the commit of PV0's mdas, we'd have an on-disk state like this:
PV0 (v2, non-ignored)
PV1 (v1, non-ignored)
PV2 (v1, non-ignored)
PV3 (v1, non-ignored)

This is an inconsistent state of the disk. If the machine fails, the next
time it was brought back up, the auto-correct mechanism in vg_read would
update the metadata on PV1-PV3.  However, if possible we try to avoid
inconsistent on-disk states.  Clearly, because we did not sort, we have
a greater chance of on-disk inconsistency - from the time the commit of
PV0 is complete until the time PV3 is complete.

We could improve the amount of time the on-disk state is consistent by simply
sorting the commit order as follows:
PV1 (v2, ignored)
PV2 (v2, ignored)
PV0 (v2, non-ignored)
PV3 (v2, non-ignored)

Thus, after the first PV is committed (in this case PV1), on-disk we would
have:
PV0 (v1, non-ignored)
PV1 (v2, ignored)
PV2 (v1, non-ignored)
PV3 (v1, non-ignored)

This is clearly a consistent state.  PV1 will be read but the mda will be
ignored.  All other PVs contain v1 metadata, and no auto-correct will be
required.  In fact, if we commit all PVs with ignored mdas first, we'll
only have an inconsistent state when we start writing non-ignored PVs,
and thus the chances we'll get an inconsistent state on disk is much
less with the sorted method.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/metadata/metadata.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 304522d..51356b9 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2426,10 +2426,21 @@ int vg_write(struct volume_group *vg)
 
 static int _vg_commit_mdas(struct volume_group *vg)
 {
-	struct metadata_area *mda;
+	struct metadata_area *mda, *tmda;
+	struct dm_list ignored;
 	int failed = 0;
 	int cache_updated = 0;
 
+	/* Rearrange the metadata_areas list so ignored mdas come first */
+	dm_list_init(&ignored);
+	dm_list_iterate_items_safe(mda, tmda, &vg->fid->metadata_areas) {
+		if (mda_is_ignored(mda))
+			dm_list_move(&ignored, &mda->list);
+	}
+	dm_list_iterate_items_safe(mda, tmda, &ignored) {
+		dm_list_move(&vg->fid->metadata_areas, &mda->list);
+	}
+
 	/* Commit to each copy of the metadata area */
 	dm_list_iterate_items(mda, &vg->fid->metadata_areas) {
 		failed = 0;
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 21/35] Add tests for phase 1 of metadata balance - manage per-PV ignore bit.
  2010-06-22  3:05                                       ` [PATCH 20/35] Before committing each mda, arrange mdas so ignored mdas get committed first Dave Wysochanski
@ 2010-06-22  3:05                                         ` Dave Wysochanski
  2010-06-22  3:05                                           ` [PATCH 22/35] Define vgmetadatacopies in vgchange man page Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 test/t-metadata-balance.sh |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)
 create mode 100755 test/t-metadata-balance.sh

diff --git a/test/t-metadata-balance.sh b/test/t-metadata-balance.sh
new file mode 100755
index 0000000..2321771
--- /dev/null
+++ b/test/t-metadata-balance.sh
@@ -0,0 +1,41 @@
+# Copyright (C) 2008 Red Hat, Inc. All rights reserved.
+#
+# 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 General Public License v.2.
+#
+# You should have received a copy of the GNU 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
+
+. ./test-utils.sh
+
+aux prepare_devs 5
+
+#  Make sure we can ignore / un-ignore mdas on a per-PV basis
+for pv_in_vg in 1 0; do
+for mdacp in 1 2; do
+	pvcreate --metadatacopies $mdacp $dev1 $dev2
+        pvcreate --metadatacopies 0 $dev3
+	if [ $pv_in_vg = 1 ]; then
+		vgcreate -c n "$vg" $dev1 $dev2 $dev3
+	fi
+	pvchange --metadataignore y $dev1
+	check_pv_field_ $dev1 pv_mda_count $mdacp
+	check_pv_field_ $dev1 pv_mda_count_ignored $mdacp
+	check_pv_field_ $dev2 pv_mda_count $mdacp
+	check_pv_field_ $dev2 pv_mda_count_ignored 0
+	if [ $pv_in_vg = 1 ]; then
+		check_vg_field_ $vg vg_mda_count $(($mdacp * 2))
+		check_vg_field_ $vg vg_mda_count_ignored $mdacp
+	fi
+	pvchange --metadataignore n $dev1
+	check_pv_field_ $dev1 pv_mda_count $mdacp
+	check_pv_field_ $dev1 pv_mda_count_ignored 0
+	if [ $pv_in_vg = 1 ]; then
+		check_vg_field_ $vg vg_mda_count $(($mdacp * 2))
+		check_vg_field_ $vg vg_mda_count_ignored 0
+		vgremove -f $vg
+	fi
+done
+done
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 22/35] Define vgmetadatacopies in vgchange man page.
  2010-06-22  3:05                                         ` [PATCH 21/35] Add tests for phase 1 of metadata balance - manage per-PV ignore bit Dave Wysochanski
@ 2010-06-22  3:05                                           ` Dave Wysochanski
  2010-06-22  3:05                                             ` [PATCH 23/35] Add mda_copies to VG structures and initialization Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

This patch adds a vgmetadatacopies parameter for metadata balancing.
This parameter provides a simple way for users to create a policy for
placing metadata on PVs automatically by LVM.  The behavior is implemented
inside LVM by managing the 'ignore' mda bits.  We chose the name
'vgmetadatacopies' as this is a natural extension to the existing parameter
'pvmetadatacopies' / 'metadatacopies' in pvcreate.

This is a first step at VG parameter based metadata balancing.  Most users
will probably want to state that they want a certain number of PVs to contai
metadata, and they may be less concerned about a specific number of metadata
copies in the volume group.  However, for default values (pvmetadatacopies
is 1 by default), the number of metadatacopies in the volume group, and the
number of PVs with metadata are the same.  In the future we could add
vgmetadatacopiespvs to define more specifically the number of pvs in the
VG that contain metadata, but for now we start with this parameter.

Another possible future extension would be to define a specific pv tag
to mark the set of PVs that should be used for metadata balancing.  This
tag based approach could be used in conjunction with 'vgmetadatacopies'.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 man/vgchange.8.in |   27 ++++++++++++++++++++-------
 1 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/man/vgchange.8.in b/man/vgchange.8.in
index 2fc0f8b..eb4e4b9 100644
--- a/man/vgchange.8.in
+++ b/man/vgchange.8.in
@@ -25,6 +25,8 @@ vgchange \- change attributes of a volume group
 .IR MaxLogicalVolumes ]
 .RB [ -p | \-\-maxphysicalvolumes
 .IR MaxPhysicalVolumes ]
+.RB [ \-\-[vg]metadatacopies ]
+.IR copies ]
 .RB [ \-P | \-\-partial]
 .RB [ \-s | \-\-physicalextentsize
 .IR PhysicalExtentSize [ \fBbBsSkKmMgGtTpPeE\fR ]]
@@ -127,13 +129,24 @@ volume group.
 Changes the maximum number of physical volumes that can belong
 to this volume group.
 For volume groups with metadata in lvm1 format, the limit is 255.
-If the metadata uses lvm2 format, the value 0
-removes this restriction: there is then no limit.
-If you have a large number of physical volumes in
-a volume group with metadata in lvm2 format,
-for tool performance reasons, you should consider
-some use of \fB--pvmetadatacopies 0\fP
-as described in \fBpvcreate(8)\fP.
+If the metadata uses lvm2 format, the value 0 removes this restriction:
+there is then no limit.  If you have a large number of physical volumes in
+a volume group with metadata in lvm2 format, for tool performance reasons,
+you should consider some use of \fB--pvmetadatacopies 0\fP as described in
+\fBpvcreate(8)\fP, and/or use \fB--vgmetadatacopies\fP.
+.TP
+.BR \-\-vgmetadatacopies " " \fI#copies\fR
+Sets the targetted number of metadata copies in the volume group.
+If set to a non-zero value, LVM will attempt to use \fB#copies\fP to
+determine the set of physical volumes on which to read and write metadata.
+LVM manages the set automatically by setting or clearing the 'metadataignore'
+flag on the physical volumes (see \fBpvchange\fP), and in this way balances
+metadata across PVs in the volume group.  Only physical volumes created
+with a non-zero value of \fBmetadatacopies\fP are used in the set of physical
+volumes.  This option is useful for volume groups containing large numbers
+of physical volumes containing metadata as it may be used to minimize metadata
+read and write overhead.
+Setting \fB--vgmetadatacopies\fP to 0 disables LVM metadata balancing.
 .TP
 .BR \-s ", " \-\-physicalextentsize " " \fIPhysicalExtentSize\fR[\fBbBsSkKmMgGtTpPeE\fR]
 Changes the physical extent size on physical volumes of this volume group.
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 23/35] Add mda_copies to VG structures and initialization.
  2010-06-22  3:05                                           ` [PATCH 22/35] Define vgmetadatacopies in vgchange man page Dave Wysochanski
@ 2010-06-22  3:05                                             ` Dave Wysochanski
  2010-06-22  3:05                                               ` [PATCH 24/35] Add vg get/set methods for VG metadata copies Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

Add a field to struct volume_group to later implement metadata
balancing:
- mda_copies: target # of non-ignored mdas in the VG; default 0 (do
not control pv 'ignore mdas' bit.

This patch just adds the parameter to the structures with the default
values but does not modify any commands.  Should be no functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/config/defaults.h            |    1 +
 lib/metadata/metadata-exported.h |    2 ++
 lib/metadata/metadata.c          |    1 +
 tools/toollib.c                  |    2 ++
 4 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 3c383d0..0d8cb9c 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -61,6 +61,7 @@
 #define DEFAULT_STRIPESIZE 64	/* KB */
 #define DEFAULT_PVMETADATASIZE 255
 #define DEFAULT_PVMETADATACOPIES 1
+#define DEFAULT_VGMETADATACOPIES 0
 #define DEFAULT_LABELSECTOR UINT64_C(1)
 #define DEFAULT_READ_AHEAD "auto"
 #define DEFAULT_UDEV_RULES 1
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 8c12f36..4388587 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -281,6 +281,7 @@ struct volume_group {
 	 * 0 for success else appropriate FAILURE_* bits set.
 	 */
 	uint32_t read_status;
+	uint32_t mda_copies; /* target number of mdas for this VG */
 };
 
 /* There will be one area for each stripe */
@@ -891,6 +892,7 @@ struct vgcreate_params {
 	size_t max_lv;
 	alloc_policy_t alloc;
 	int clustered; /* FIXME: put this into a 'status' variable instead? */
+	uint32_t metadata_copies;
 };
 
 int vgcreate_params_validate(struct cmd_context *cmd,
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 51356b9..5c74893 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -910,6 +910,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
 	vg->max_pv = DEFAULT_MAX_PV;
 
 	vg->alloc = DEFAULT_ALLOC_POLICY;
+	vg->mda_copies = DEFAULT_VGMETADATACOPIES;
 
 	vg->pv_count = 0;
 	dm_list_init(&vg->pvs);
diff --git a/tools/toollib.c b/tools/toollib.c
index e6791e2..02b06fd 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1187,6 +1187,7 @@ void vgcreate_params_set_defaults(struct vgcreate_params *vp_def,
 		vp_def->max_lv = vg->max_lv;
 		vp_def->alloc = vg->alloc;
 		vp_def->clustered = vg_is_clustered(vg);
+		vp_def->metadata_copies = vg->mda_copies;
 	} else {
 		vp_def->vg_name = NULL;
 		vp_def->extent_size = DEFAULT_EXTENT_SIZE * 2;
@@ -1194,6 +1195,7 @@ void vgcreate_params_set_defaults(struct vgcreate_params *vp_def,
 		vp_def->max_lv = DEFAULT_MAX_LV;
 		vp_def->alloc = DEFAULT_ALLOC_POLICY;
 		vp_def->clustered = DEFAULT_CLUSTERED;
+		vp_def->metadata_copies = DEFAULT_VGMETADATACOPIES;
 	}
 }
 
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 24/35] Add vg get/set methods for VG metadata copies.
  2010-06-22  3:05                                             ` [PATCH 23/35] Add mda_copies to VG structures and initialization Dave Wysochanski
@ 2010-06-22  3:05                                               ` Dave Wysochanski
  2010-06-22  3:05                                                 ` [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

This patch adds the get and partially implemented set function.
The 'set' function should probably ignore or un-ignore metadata areas
based on new values.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/metadata/metadata-exported.h |    2 ++
 lib/metadata/metadata.c          |   16 ++++++++++++++++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 4388587..b444e34 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -877,6 +877,8 @@ uint64_t vg_max_pv(const struct volume_group *vg);
 uint64_t vg_max_lv(const struct volume_group *vg);
 uint32_t vg_mda_count(const struct volume_group *vg);
 uint32_t vg_mda_count_ignored(const struct volume_group *vg);
+uint32_t vg_mda_copies(const struct volume_group *vg);
+int vg_set_mda_copies(struct volume_group *vg, uint32_t value);
 int vg_check_write_mode(struct volume_group *vg);
 #define vg_is_clustered(vg) (vg_status((vg)) & CLUSTERED)
 #define vg_is_exported(vg) (vg_status((vg)) & EXPORTED_VG)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 5c74893..a597f3c 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -989,6 +989,22 @@ static int _recalc_extents(uint32_t *extents, const char *desc1,
 	return 1;
 }
 
+uint32_t vg_mda_copies(const struct volume_group *vg)
+{
+	return vg->mda_copies;
+}
+
+int vg_set_mda_copies(struct volume_group *vg, uint32_t value)
+{
+	/* FIXME: add checks, etc, and set the value */
+	/*
+	 * FIXME: Before we set a larger value, we may need to
+	 * enable some mdas on PVS
+	 */
+	vg->mda_copies = value;
+	return 1;
+}
+
 int vg_set_extent_size(struct volume_group *vg, uint32_t new_size)
 {
 	uint32_t old_size = vg->extent_size;
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata.
  2010-06-22  3:05                                               ` [PATCH 24/35] Add vg get/set methods for VG metadata copies Dave Wysochanski
@ 2010-06-22  3:05                                                 ` Dave Wysochanski
  2010-06-22  3:05                                                   ` [PATCH 26/35] Add vg_mda_copies display field to 'vgs' command Dave Wysochanski
  2010-06-22  8:18                                                   ` [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata Zdenek Kabelac
  0 siblings, 2 replies; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel

This patch adds the ability to read/write the vg->mda_copies values
from/to the vg metadata.

If we read the VG metadata and this field does not exist, we set
mda_copies to the default value of 0.  Later in the code, we use
this special '0' value to indicate a disable of metadata balancing.
This should preserve existing LVM behavior and ensure metadata balancing
can be turned off should the need arise.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/format_text/export.c      |    1 +
 lib/format_text/import_vsn1.c |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index 5f02b5d..52ae11c 100644
--- a/lib/format_text/export.c
+++ b/lib/format_text/export.c
@@ -397,6 +397,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
 		outf(f, "allocation_policy = \"%s\"",
 		     get_alloc_string(vg->alloc));
 	}
+	outf(f, "metadata_copies = %u", vg->mda_copies);
 
 	return 1;
 }
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 316adb5..62bcbec 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -23,6 +23,7 @@
 #include "pv_alloc.h"
 #include "segtype.h"
 #include "text_import.h"
+#include "defaults.h"
 
 typedef int (*section_fn) (struct format_instance * fid, struct dm_pool * mem,
 			   struct volume_group * vg, struct config_node * pvn,
@@ -745,6 +746,10 @@ static struct volume_group *_read_vg(struct format_instance *fid,
 			return_0;
 	}
 
+	if (!_read_uint32(vgn, "metadata_copies", &vg->mda_copies)) {
+		vg->mda_copies = DEFAULT_VGMETADATACOPIES;
+	}
+
 	/*
 	 * The pv hash memorises the pv section names -> pv
 	 * structures.
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 26/35] Add vg_mda_copies display field to 'vgs' command.
  2010-06-22  3:05                                                 ` [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata Dave Wysochanski
@ 2010-06-22  3:05                                                   ` Dave Wysochanski
  2010-06-22  3:06                                                     ` [PATCH 27/35] Update vgchange tool to accept --vgmetadatacopies Dave Wysochanski
  2010-06-22  8:18                                                   ` [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata Zdenek Kabelac
  1 sibling, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:05 UTC (permalink / raw)
  To: lvm-devel


Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/report/columns.h |    1 +
 lib/report/report.c  |   12 ++++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/lib/report/columns.h b/lib/report/columns.h
index 9cc5cb1..2f32528 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -115,6 +115,7 @@ FIELD(VGS, vg, NUM, "#VMda", cmd, 5, vgmdas, "vg_mda_count", "Number of metadata
 FIELD(VGS, vg, NUM, "#VMdaIgn", cmd, 8, vgmdas_ignored, "vg_mda_count_ignored", "Number of metadata areas ignored in this VG.")
 FIELD(VGS, vg, NUM, "VMdaFree", cmd, 9, vgmdafree, "vg_mda_free", "Free metadata area space for this VG in current units.")
 FIELD(VGS, vg, NUM, "VMdaSize", cmd, 9, vgmdasize, "vg_mda_size", "Size of smallest metadata area for this VG in current units.")
+FIELD(VGS, vg, NUM, "#VMdaCps", cmd, 8, vgmda_copies, "vg_mda_copies", "Target number of non-ignored metadata areas in the VG.")
 
 FIELD(SEGS, seg, STR, "Type", list, 4, segtype, "segtype", "Type of LV segment.")
 FIELD(SEGS, seg, NUM, "#Str", area_count, 4, uint32, "stripes", "Number of stripes or mirror legs.")
diff --git a/lib/report/report.c b/lib/report/report.c
index 9196531..84afc88 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -893,6 +893,18 @@ static int _vgmdas_ignored_disp(struct dm_report *rh, struct dm_pool *mem,
 	return _uint32_disp(rh, mem, field, &count, private);
 }
 
+static int _vgmda_copies_disp(struct dm_report *rh, struct dm_pool *mem,
+				   struct dm_report_field *field,
+				   const void *data, void *private)
+{
+	const struct volume_group *vg = (const struct volume_group *) data;
+	uint32_t count;
+
+	count = vg_mda_copies(vg);
+
+	return _uint32_disp(rh, mem, field, &count, private);
+}
+
 static int _pvmdafree_disp(struct dm_report *rh, struct dm_pool *mem,
 			   struct dm_report_field *field,
 			   const void *data, void *private)
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 27/35] Update vgchange tool to accept --vgmetadatacopies.
  2010-06-22  3:05                                                   ` [PATCH 26/35] Add vg_mda_copies display field to 'vgs' command Dave Wysochanski
@ 2010-06-22  3:06                                                     ` Dave Wysochanski
  2010-06-22  3:06                                                       ` [PATCH 28/35] Implement _vg_metadata_balance and call from vg_write() path Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:06 UTC (permalink / raw)
  To: lvm-devel

Update logic in vgchange to handle --vgmetadatacopies, allow
--metadatacopies as a synonym to --vgmetadatacopies,
and add these parameters to args.h and commands.h

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 tools/args.h     |    1 +
 tools/commands.h |    4 +++-
 tools/vgchange.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/tools/args.h b/tools/args.h
index d343689..60d99d1 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -23,6 +23,7 @@ arg(physicalvolumesize_ARG, '\0', "setphysicalvolumesize", size_mb_arg, 0)
 arg(ignorelockingfailure_ARG, '\0', "ignorelockingfailure", NULL, 0)
 arg(nolocking_ARG, '\0', "nolocking", NULL, 0)
 arg(pvmetadatacopies_ARG, '\0', "pvmetadatacopies", int_arg, 0)
+arg(vgmetadatacopies_ARG, '\0', "vgmetadatacopies", int_arg, 0)
 arg(metadatacopies_ARG, '\0', "metadatacopies", int_arg, 0)
 arg(metadatasize_ARG, '\0', "metadatasize", size_mb_arg, 0)
 arg(metadataignore_ARG, '\0', "metadataignore", yes_no_arg, 0)
diff --git a/tools/commands.h b/tools/commands.h
index 6d8d2c0..62a684b 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -710,6 +710,7 @@ xx(vgchange,
    "\t[--ignorelockingfailure]\n"
    "\t[--ignoremonitoring]\n"
    "\t[--monitor {y|n}]\n"
+   "\t[--[vg]metadatacopies #copies] " "\n"
    "\t[--poll {y|n}]\n"
    "\t[--noudevsync]\n"
    "\t[--refresh]\n"
@@ -731,7 +732,8 @@ xx(vgchange,
    addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, available_ARG,
    clustered_ARG, deltag_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG,
    logicalvolume_ARG, maxphysicalvolumes_ARG, monitor_ARG, noudevsync_ARG,
-   partial_ARG, physicalextentsize_ARG, poll_ARG, refresh_ARG, resizeable_ARG,
+   metadatacopies_ARG, vgmetadatacopies_ARG, partial_ARG,
+   physicalextentsize_ARG, poll_ARG, refresh_ARG, resizeable_ARG,
    resizable_ARG, sysinit_ARG, test_ARG, uuid_ARG)
 
 xx(vgck,
diff --git a/tools/vgchange.c b/tools/vgchange.c
index e2fbaeb..fc2f44d 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -525,6 +525,45 @@ static int _vgchange_refresh(struct cmd_context *cmd, struct volume_group *vg)
 	return ECMD_PROCESSED;
 }
 
+static int _vgchange_metadata_copies(struct cmd_context *cmd,
+				     struct volume_group *vg)
+{
+	uint32_t value;
+
+	if (arg_count(cmd, vgmetadatacopies_ARG))
+		value = arg_uint_value(cmd, vgmetadatacopies_ARG,
+			DEFAULT_VGMETADATACOPIES);
+	else if (arg_count(cmd, metadatacopies_ARG))
+		value = arg_uint_value(cmd, metadatacopies_ARG,
+			DEFAULT_VGMETADATACOPIES);
+	if (value == vg_mda_copies(vg)) {
+		log_error("Metadata copies of VG %s is already %u",
+			  vg->name, value);
+		return ECMD_PROCESSED;
+	}
+
+	if (!archive(vg)) {
+		stack;
+		return ECMD_FAILED;
+	}
+
+	if (!vg_set_mda_copies(vg, value)) {
+		stack;
+		return EINVALID_CMD_LINE;
+	}
+
+	if (!vg_write(vg) || !vg_commit(vg)) {
+		stack;
+		return ECMD_FAILED;
+	}
+
+	backup(vg);
+
+	log_print("Volume group \"%s\" successfully changed", vg->name);
+
+	return ECMD_PROCESSED;
+}
+
 static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
 			   struct volume_group *vg,
 			   void *handle __attribute((unused)))
@@ -593,6 +632,10 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
 	else if (arg_count(cmd, refresh_ARG))
 		r = _vgchange_refresh(cmd, vg);
 
+	else if (arg_count(cmd, vgmetadatacopies_ARG) ||
+		 arg_count(cmd, metadatacopies_ARG))
+		r = _vgchange_metadata_copies(cmd, vg);
+
 	return r;
 }
 
@@ -606,10 +649,12 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
 	     arg_count(cmd, physicalextentsize_ARG) +
 	     arg_count(cmd, clustered_ARG) + arg_count(cmd, alloc_ARG) +
 	     arg_count(cmd, monitor_ARG) + arg_count(cmd, poll_ARG) +
-	     arg_count(cmd, refresh_ARG))) {
+	     arg_count(cmd, refresh_ARG) + arg_count(cmd, metadatacopies_ARG) +
+	     arg_count(cmd, vgmetadatacopies_ARG))) {
 		log_error("Need 1 or more of -a, -c, -l, -p, -s, -x, "
 			  "--refresh, --uuid, --alloc, --addtag, --deltag, "
-			  "--monitor or --poll");
+			  "--monitor, --poll, --vgmetadatacopies or "
+			  "--metadatacopies");
 		return EINVALID_CMD_LINE;
 	}
 
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 28/35] Implement _vg_metadata_balance and call from vg_write() path.
  2010-06-22  3:06                                                     ` [PATCH 27/35] Update vgchange tool to accept --vgmetadatacopies Dave Wysochanski
@ 2010-06-22  3:06                                                       ` Dave Wysochanski
  2010-06-22  3:06                                                         ` [PATCH 29/35] Set vg_mda_copies when pvchange --metadataignore is given Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:06 UTC (permalink / raw)
  To: lvm-devel

Implement metadata balancing by comparing the value of the
newly added vg_mda_copies field (--vgmetadatacopies parameter)
with the current count of of non-ignored mdas and ignoring or
unignoring mdas as necessary to get to the target count.
Also, as a safety check before returning, ensure we have at
least one mda enabled.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/metadata/metadata.c |   88 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index a597f3c..6f4cf60 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -58,6 +58,8 @@ static struct pv_list *_find_pv_in_vg_by_uuid(const struct volume_group *vg,
 static uint32_t _vg_bad_status_bits(const struct volume_group *vg,
 				    uint64_t status);
 
+static int _vg_metadata_balance(struct volume_group *vg);
+
 const char _really_init[] =
     "Really INITIALIZE physical volume \"%s\" of volume group \"%s\" [y/n]? ";
 
@@ -989,6 +991,91 @@ static int _recalc_extents(uint32_t *extents, const char *desc1,
 	return 1;
 }
 
+static int _vg_ignore_mdas(struct volume_group *vg, uint32_t count)
+{
+	struct metadata_area *mda;
+
+	if (!count)
+		return 1;
+	/* FIXME: flip bits on random mdas */
+	dm_list_iterate_items(mda, &vg->fid->metadata_areas) {
+		if (!mda_is_ignored(mda)) {
+			mda_set_ignored(mda, 1);
+			count--;
+		}
+		if (!count)
+			return 1;
+	}
+	log_error("Unable to find %"PRIu32" metadata areas to ignore "
+		  "on volume group %s", count, vg->name);
+	return 0;
+}
+
+static int _vg_unignore_mdas(struct volume_group *vg, uint32_t count)
+{
+	struct metadata_area *mda, *tmda;
+
+	if (!count)
+		return 1;
+	/* FIXME: flip bits on random mdas */
+	dm_list_iterate_items_safe(mda, tmda, &vg->fid->metadata_areas_ignored) {
+		if (mda_is_ignored(mda)) {
+			mda_set_ignored(mda, 0);
+			dm_list_move(&vg->fid->metadata_areas, &mda->list);
+			count--;
+		}
+		if (!count)
+			return 1;
+	}
+	dm_list_iterate_items(mda, &vg->fid->metadata_areas) {
+		if (mda_is_ignored(mda)) {
+			mda_set_ignored(mda, 0);
+			count--;
+		}
+		if (!count)
+			return 1;
+	}
+	log_error("Unable to find %"PRIu32" metadata areas to un-ignore "
+		  "on volume group %s", count, vg->name);
+	return 0;
+}
+
+static int _vg_metadata_balance(struct volume_group *vg)
+{
+	uint32_t mda_copies, count;
+	int ret = 1;
+
+	mda_copies = vg_mda_count(vg) - vg_mda_count_ignored(vg);
+	if (!vg->mda_copies)
+		goto skip_balance;
+
+	if (mda_copies > vg->mda_copies) {
+		ret = _vg_ignore_mdas(vg, mda_copies - vg->mda_copies);
+	} else if (mda_copies < vg->mda_copies) {
+		/* not an error to have vg_mda_count larger than total mdas */
+		if (vg->mda_copies >= vg_mda_count(vg))
+			count = vg_mda_count_ignored(vg);
+		else
+			count = vg->mda_copies - mda_copies;
+		ret = _vg_unignore_mdas(vg, count);
+	}
+	if (!ret)
+		return ret;
+
+skip_balance:
+	/*
+	 * Ensure at least one enabled mda.
+	 * FIXME: check size of fid->metadata_areas; reason is because of how
+	 * pv_setup works in the case of a pv with 2 mdas, one ignored and
+	 * another not ignored; function needs refactoring to be correct.
+	 */
+	if (!dm_list_size(&vg->fid->metadata_areas) ||
+	    vg_mda_count(vg) == vg_mda_count_ignored(vg)) {
+		ret = _vg_unignore_mdas(vg, 1);
+	}
+	return ret;
+}
+
 uint32_t vg_mda_copies(const struct volume_group *vg)
 {
 	return vg->mda_copies;
@@ -2378,6 +2465,7 @@ int vg_write(struct volume_group *vg)
 		return 0;
 	}
 
+	_vg_metadata_balance(vg);
 
 	if (dm_list_empty(&vg->fid->metadata_areas)) {
 		log_error("Aborting vg_write: No metadata areas to write to!");
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 29/35] Set vg_mda_copies when pvchange --metadataignore is given.
  2010-06-22  3:06                                                       ` [PATCH 28/35] Implement _vg_metadata_balance and call from vg_write() path Dave Wysochanski
@ 2010-06-22  3:06                                                         ` Dave Wysochanski
  2010-06-22  3:06                                                           ` [PATCH 30/35] Add --vgmetadatacopies to vgcreate man page, command, and lvm.conf Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:06 UTC (permalink / raw)
  To: lvm-devel

When a user explicitly sets a new mda ignore value for a PV, we
should update vg_mda_copies accordingly.  When the VG is written
out, the user would not want the new ignore state to get lost as
a result of the metadata balancing policy.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 tools/pvchange.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/tools/pvchange.c b/tools/pvchange.c
index ba196d6..7f02073 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -147,6 +147,18 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
 		if (!pv_mda_set_ignored(pv, mda_ignore)) {
 			goto out;
 		}
+		/*
+		 * Update vg_mda_copies based on the mdas in this PV.
+		 * This is most likely what the usre would expect - if they
+		 * specify a specific PV to be ignored/un-ignored, they will
+		 * most likely not want LVM to turn around and change the
+		 * ignore / un-ignore value when it writes the VG to disk.
+		 * This does not guarantee this PV's ignore bits will be
+		 * preserved in future operations.
+		 */
+		if (!is_orphan(pv) && vg_mda_copies(vg)) {
+			vg_set_mda_copies(vg, vg_mda_copies(vg));
+		}
 	} else {
 		/* --uuid: Change PV ID randomly */
 		if (!id_create(&pv->id)) {
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 30/35] Add --vgmetadatacopies to vgcreate man page, command, and lvm.conf.
  2010-06-22  3:06                                                         ` [PATCH 29/35] Set vg_mda_copies when pvchange --metadataignore is given Dave Wysochanski
@ 2010-06-22  3:06                                                           ` Dave Wysochanski
  2010-06-22  3:06                                                             ` [PATCH 31/35] Ensure fid mda lists are populated correctly during vgextend Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:06 UTC (permalink / raw)
  To: lvm-devel

Allow parsing of --vgmetadatacopies for vgcreate.  Accept
--metadatacopies as a synonym for --vgmetadatacopies.  Other
patches will add balancing algorithm before the metadata is
written in vg_write().

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 man/lvm.conf.5.in |   23 +++++++++++++++++++++++
 man/vgcreate.8.in |   15 +++++++++++++++
 tools/commands.h  |    5 +++--
 tools/toollib.c   |   12 ++++++++++++
 tools/vgcreate.c  |    8 ++------
 5 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/man/lvm.conf.5.in b/man/lvm.conf.5.in
index 02ebb2a..ff0c35e 100644
--- a/man/lvm.conf.5.in
+++ b/man/lvm.conf.5.in
@@ -406,6 +406,29 @@ The metadata areas are treated as circular buffers, so
 unused space becomes filled with an archive of the most recent
 previous versions of the metadata.
 .IP
+\fBvgmetadatacopies\fP \(em When creating a volume group using the
+LVM2 metadata format, this is the default number of copies of metadata
+desired across all the physical volumes in the volume group.  If set to
+a non-zero value, LVM will attempt to balance metadata areas across
+the physical volumes in the volume group to achieve the number
+of metadata copies specified.  LVM implements the balancing through
+automatically setting and clearing metadata ignore
+(See \fBpvchange --metadataignore\fP) on physical volumes created with
+a non-zero value of \fBpvmetadatacopies\fP. Balancing may be triggered
+by an LVM command that adds or removes physical volumes (\fBvgextend\fP
+or \fBvgreduce\fP, \fBvgsplit\fP, \fBvgmerge\fP), when physical
+volumes go missing or reappear, or when a new value is explicity set
+(See \fBvgchange --vgmetadatacopies\fP).
+Setting \fBvgmetadatacopies\fP to 0 disables metadata balancing.  It
+is not an error to set a value larger than the sum of all metadata areas
+on all physical volumes.  The value can be overridden on the command line
+with \fB--vgmetadatacopies\fP.  This option may be useful for volume groups
+containing large numbers of physical volumes.   It offers a simple way
+to specify a reasonable number of metadata copies (for example 5) without
+having to know ahead of time which physical volumes should have metadata.
+Having a smaller number of metadata areas offers better performance
+than the default of reading and writing metadata on all physical volumes.
+.IP
 \fBdirs\fP \(em List of directories holding live copies of LVM2
 metadata as text files.  These directories must not be on logical
 volumes.  It is possible to use LVM2 with a couple of directories
diff --git a/man/vgcreate.8.in b/man/vgcreate.8.in
index 24d1642..2c8ce34 100644
--- a/man/vgcreate.8.in
+++ b/man/vgcreate.8.in
@@ -16,6 +16,8 @@ vgcreate \- create a volume group
 .RB [ -M | \-\-metadatatype type]
 .RB [ -p | \-\-maxphysicalvolumes
 .IR MaxPhysicalVolumes ]
+.RB [ \-\-[vg]metadatacopies ]
+.IR copies ]
 .RB [ \-s | \-\-physicalextentsize
 .IR PhysicalExtentSize [ \fBbBsSkKmMgGtTpPeE\fR ]]
 .RB [ \-t | \-\-test ]
@@ -74,6 +76,19 @@ for tool performance reasons, you should consider
 some use of \fB--pvmetadatacopies 0\fP
 as described in \fBpvcreate(8)\fP.
 .TP
+.BR \-\-vgmetadatacopies " " \fI#copies\fR
+Sets the targetted number of metadata copies in the volume group.
+If set to a non-zero value, LVM will attempt to use \fB#copies\fP to
+determine the set of physical volumes on which to read and write metadata.
+LVM manages the set automatically by setting or clearing the 'metadataignore'
+flag on the physical volumes (see \fBpvchange\fP), and in this way balances
+metadata across PVs in the volume group.  Only physical volumes created
+with a non-zero value of \fBmetadatacopies\fP are used in the set of physical
+volumes.  This option is useful for volume groups containing large numbers
+of physical volumes containing metadata as it may be used to minimize metadata
+read and write overhead.
+The default value is 0, which disables LVM metadata balancing.
+.TP
 .BR \-s ", " \-\-physicalextentsize " " \fIPhysicalExtentSize\fR[\fBbBsSkKmMgGtTpPeE\fR]
 Sets the physical extent size on physical volumes of this volume group.
 A size suffix (k for kilobytes up to t for terabytes) is optional, megabytes
diff --git a/tools/commands.h b/tools/commands.h
index 62a684b..8f5ff3a 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -776,6 +776,7 @@ xx(vgcreate,
    "\t[-h|--help]" "\n"
    "\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
    "\t[-M|--metadatatype 1|2] " "\n"
+   "\t[--[vg]metadatacopies #copies] " "\n"
    "\t[-p|--maxphysicalvolumes MaxPhysicalVolumes] " "\n"
    "\t[-s|--physicalextentsize PhysicalExtentSize[bBsSkKmMgGtTpPeE]] " "\n"
    "\t[-t|--test] " "\n"
@@ -787,8 +788,8 @@ xx(vgcreate,
    addtag_ARG, alloc_ARG, autobackup_ARG, clustered_ARG, maxlogicalvolumes_ARG,
    maxphysicalvolumes_ARG, metadatatype_ARG, physicalextentsize_ARG, test_ARG,
    force_ARG, yes_ARG, zero_ARG, labelsector_ARG, metadatasize_ARG,
-   pvmetadatacopies_ARG, metadatacopies_ARG, dataalignment_ARG,
-   dataalignmentoffset_ARG)
+   pvmetadatacopies_ARG, metadatacopies_ARG, vgmetadatacopies_ARG,
+   dataalignment_ARG, dataalignmentoffset_ARG)
 
 xx(vgdisplay,
    "Display volume group information",
diff --git a/tools/toollib.c b/tools/toollib.c
index 02b06fd..e56a3e5 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1243,6 +1243,18 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
 		return 1;
 	}
 
+	if (arg_count(cmd, metadatacopies_ARG)) {
+		vp_new->metadata_copies = arg_int_value(cmd, metadatacopies_ARG,
+							DEFAULT_VGMETADATACOPIES);
+	} else if (arg_count(cmd, vgmetadatacopies_ARG)) {
+		vp_new->metadata_copies = arg_int_value(cmd, vgmetadatacopies_ARG,
+							DEFAULT_VGMETADATACOPIES);
+	} else {
+		vp_new->metadata_copies = find_config_tree_int(cmd,
+						   "metadata/vgmetadatacopies",
+						   DEFAULT_VGMETADATACOPIES);
+	}
+
 	return 0;
 }
 
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 6087145..3bb500f 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -35,11 +35,6 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
 	argc--;
 	argv++;
 
-	if (arg_count(cmd, metadatacopies_ARG)) {
-		log_error("Invalid option --metadatacopies, "
-			  "use --pvmetadatacopies instead.");
-		return EINVALID_CMD_LINE;
-	}
 	pvcreate_params_set_defaults(&pp);
 	if (!pvcreate_params_validate(cmd, argc, argv, &pp)) {
 		return EINVALID_CMD_LINE;
@@ -68,7 +63,8 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
 	    !vg_set_max_lv(vg, vp_new.max_lv) ||
 	    !vg_set_max_pv(vg, vp_new.max_pv) ||
 	    !vg_set_alloc_policy(vg, vp_new.alloc) ||
-	    !vg_set_clustered(vg, vp_new.clustered))
+	    !vg_set_clustered(vg, vp_new.clustered) ||
+	    !vg_set_mda_copies(vg, vp_new.metadata_copies))
 		goto bad_orphan;
 
 	if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 31/35] Ensure fid mda lists are populated correctly during vgextend.
  2010-06-22  3:06                                                           ` [PATCH 30/35] Add --vgmetadatacopies to vgcreate man page, command, and lvm.conf Dave Wysochanski
@ 2010-06-22  3:06                                                             ` Dave Wysochanski
  2010-06-22  3:06                                                               ` [PATCH 32/35] Update check in vg_split_mdas to account for ignored mdas list Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:06 UTC (permalink / raw)
  To: lvm-devel

The vgextend path calls add_pv_to_vg().  Inside add_pv_to_vg(),
we must ensure we pass the correct mdas list into pv_setup(), as
copies of mdas are placed on the vg->fid list.  If we don't place
the mdas on the correct vg->fid list, the various counts may be
incorrect and the metadata balance algorithm will not work when
called from vg_write() path.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/metadata/metadata.c |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 6f4cf60..855b8af 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -174,6 +174,7 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
 	struct format_instance *fid = vg->fid;
 	struct dm_pool *mem = vg->vgmem;
 	char uuid[64] __attribute((aligned(8)));
+	struct dm_list *mdas;
 
 	log_verbose("Adding physical volume '%s' to volume group '%s'",
 		    pv_name, vg->name);
@@ -217,9 +218,24 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
 	 */
 	pv->pe_alloc_count = 0;
 
+	/*
+	 * FIXME: this does not work entirely correctly in the case where a PV
+	 * has 2 mdas and only one is ignored; ideally all non-ignored mdas
+	 * should be placed on metadata_areas list and ignored on the
+	 * metadata_areas_ignored list; however this requires another
+	 * fairly complex refactoring to remove the 'mdas' parameter from both
+	 * pv_setup and pv_write.  For now, we only put ignored mdas on the
+	 * metadata_areas_ignored list if all mdas in the PV are ignored;
+	 * otherwise, we use the non-ignored list.
+	 */
+	if (pv_mda_is_ignored(pv) == pv_mda_count(pv))
+		mdas = &fid->metadata_areas_ignored;
+	else
+		mdas = &fid->metadata_areas;
+
 	if (!fid->fmt->ops->pv_setup(fid->fmt, UINT64_C(0), 0,
 				     vg->extent_size, 0, 0, 0UL, UINT64_C(0),
-				     &fid->metadata_areas, pv, vg)) {
+				     mdas, pv, vg)) {
 		log_error("Format-specific setup of physical volume '%s' "
 			  "failed.", pv_name);
 		return 0;
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 32/35] Update check in vg_split_mdas to account for ignored mdas list.
  2010-06-22  3:06                                                             ` [PATCH 31/35] Ensure fid mda lists are populated correctly during vgextend Dave Wysochanski
@ 2010-06-22  3:06                                                               ` Dave Wysochanski
  2010-06-22  3:06                                                                 ` [PATCH 33/35] Update _vgmerge_single() to move fid->metadata_areas_ignored Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:06 UTC (permalink / raw)
  To: lvm-devel

The check in vg_split_mdas will trigger an error if the 'from' vg
list is empty.  However, this might be ok in some instances now
that we have ignored mdas.  Relax this check so an error is triggered
only in the case where there's truly no more mdas in the 'from'
vg.

One example of where this makes a difference is with vgreduce.
If we try to vgreduce a PV with un-ignored mdas, this should trigger
the balancing function to un-ignore mdas on another PV in the VG.
However, we don't get to vg_write() before we fail because this
list size check fails, and we see an error message indicating:
"Cannot remove final metadata area ..."

Another example is with vgsplit into a new VG, where the PVs
being moved contain all ignored mdas.  We must move the mdas on
fid->metadata_areas_ignored from 'vg_from' to 'vg_to'.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 lib/metadata/metadata.c |   40 ++++++++++++++++++++++++++++------------
 1 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 855b8af..27a9a3a 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1364,20 +1364,12 @@ int vg_set_clustered(struct volume_group *vg, int clustered)
 	return 1;
 }
 
-/*
- * Separate metadata areas after splitting a VG.
- * Also accepts orphan VG as destination (for vgreduce).
- */
-int vg_split_mdas(struct cmd_context *cmd __attribute((unused)),
-		  struct volume_group *vg_from, struct volume_group *vg_to)
+static int _move_mdas(struct volume_group *vg_from, struct volume_group *vg_to,
+		      struct dm_list *mdas_from, struct dm_list *mdas_to)
 {
 	struct metadata_area *mda, *mda2;
-	struct dm_list *mdas_from, *mdas_to;
 	int common_mda = 0;
 
-	mdas_from = &vg_from->fid->metadata_areas;
-	mdas_to = &vg_to->fid->metadata_areas;
-
 	dm_list_iterate_items_safe(mda, mda2, mdas_from) {
 		if (!mda->ops->mda_in_vg) {
 			common_mda = 1;
@@ -1391,9 +1383,33 @@ int vg_split_mdas(struct cmd_context *cmd __attribute((unused)),
 				dm_list_move(mdas_to, &mda->list);
 		}
 	}
+	return common_mda;
+}
+
+/*
+ * Separate metadata areas after splitting a VG.
+ * Also accepts orphan VG as destination (for vgreduce).
+ */
+int vg_split_mdas(struct cmd_context *cmd __attribute((unused)),
+		  struct volume_group *vg_from, struct volume_group *vg_to)
+{
+	struct dm_list *mdas_from, *mdas_to;
+	struct dm_list *mdas_from_ignored, *mdas_to_ignored;
+	int common_mda = 0;
+
+	mdas_from = &vg_from->fid->metadata_areas;
+	mdas_from_ignored = &vg_from->fid->metadata_areas_ignored;
+	mdas_to = &vg_to->fid->metadata_areas;
+	mdas_to_ignored = &vg_to->fid->metadata_areas_ignored;
+
+	common_mda = _move_mdas(vg_from, vg_to,
+				mdas_from, mdas_to);
+	common_mda = _move_mdas(vg_from, vg_to,
+				mdas_from_ignored, mdas_to_ignored);
 
-	if (dm_list_empty(mdas_from) ||
-	    (!is_orphan_vg(vg_to->name) && dm_list_empty(mdas_to)))
+	if ((dm_list_empty(mdas_from) && dm_list_empty(mdas_from_ignored)) ||
+	    ((!is_orphan_vg(vg_to->name) && dm_list_empty(mdas_to) &&
+	      dm_list_empty(mdas_to_ignored))))
 		return common_mda;
 
 	return 1;
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 33/35] Update _vgmerge_single() to move fid->metadata_areas_ignored.
  2010-06-22  3:06                                                               ` [PATCH 32/35] Update check in vg_split_mdas to account for ignored mdas list Dave Wysochanski
@ 2010-06-22  3:06                                                                 ` Dave Wysochanski
  2010-06-22  3:06                                                                   ` [PATCH 34/35] Add --vgmetadatacopies to vgsplit man page and command Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:06 UTC (permalink / raw)
  To: lvm-devel

When vgmerge is called we move the mdas from the source to the
destination.  With metadata balancing we now have another mda
list, fid->metadata_areas_ignored, so move the mdas on this list
as well.

This patch should not matter as the code is written today.  However
we include it for completeness in the case that _vgmerge_single()
is refactored and/or moved into a library function.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 tools/vgmerge.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/tools/vgmerge.c b/tools/vgmerge.c
index 299bed7..ff74705 100644
--- a/tools/vgmerge.c
+++ b/tools/vgmerge.c
@@ -126,6 +126,12 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
 		dm_list_move(&vg_to->fid->metadata_areas, mdah);
 	}
 
+	while (!dm_list_empty(&vg_from->fid->metadata_areas_ignored)) {
+		struct dm_list *mdah = vg_from->fid->metadata_areas_ignored.n;
+
+		dm_list_move(&vg_to->fid->metadata_areas_ignored, mdah);
+	}
+
 	vg_to->extent_count += vg_from->extent_count;
 	vg_to->free_count += vg_from->free_count;
 
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 34/35] Add --vgmetadatacopies to vgsplit man page and command.
  2010-06-22  3:06                                                                 ` [PATCH 33/35] Update _vgmerge_single() to move fid->metadata_areas_ignored Dave Wysochanski
@ 2010-06-22  3:06                                                                   ` Dave Wysochanski
  2010-06-22  3:06                                                                     ` [PATCH 35/35] Update tests to handle phase 2 (vg based) metadata balance Dave Wysochanski
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:06 UTC (permalink / raw)
  To: lvm-devel


Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 tools/commands.h |    3 ++-
 tools/vgsplit.c  |    6 ++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/tools/commands.h b/tools/commands.h
index 8f5ff3a..aa012a7 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -1007,6 +1007,7 @@ xx(vgsplit,
    "\t[-h|--help] " "\n"
    "\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
    "\t[-M|--metadatatype 1|2] " "\n"
+   "\t[--[vg]metadatacopies #copies] " "\n"
    "\t[-n|--name LogicalVolumeName]\n"
    "\t[-p|--maxphysicalvolumes MaxPhysicalVolumes] " "\n"
    "\t[-t|--test] " "\n"
@@ -1017,7 +1018,7 @@ xx(vgsplit,
 
    alloc_ARG, autobackup_ARG, clustered_ARG,
    maxlogicalvolumes_ARG, maxphysicalvolumes_ARG,
-   metadatatype_ARG, name_ARG, test_ARG)
+   metadatatype_ARG, vgmetadatacopies_ARG, name_ARG, test_ARG)
 
 xx(version,
    "Display software and driver version information",
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index 1fa3d00..988c334 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -272,7 +272,8 @@ static int new_vg_option_specified(struct cmd_context *cmd)
 	return(arg_count(cmd, clustered_ARG) ||
 	       arg_count(cmd, alloc_ARG) ||
 	       arg_count(cmd, maxphysicalvolumes_ARG) ||
-	       arg_count(cmd, maxlogicalvolumes_ARG));
+	       arg_count(cmd, maxlogicalvolumes_ARG) ||
+	       arg_count(cmd, vgmetadatacopies_ARG));
 }
 
 int vgsplit(struct cmd_context *cmd, int argc, char **argv)
@@ -382,7 +383,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
 		    !vg_set_max_lv(vg_to, vp_new.max_lv) ||
 		    !vg_set_max_pv(vg_to, vp_new.max_pv) ||
 		    !vg_set_alloc_policy(vg_to, vp_new.alloc) ||
-		    !vg_set_clustered(vg_to, vp_new.clustered))
+		    !vg_set_clustered(vg_to, vp_new.clustered) ||
+		    !vg_set_mda_copies(vg_to, vp_new.metadata_copies))
 			goto_bad;
 	}
 
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 35/35] Update tests to handle phase 2 (vg based) metadata balance.
  2010-06-22  3:06                                                                   ` [PATCH 34/35] Add --vgmetadatacopies to vgsplit man page and command Dave Wysochanski
@ 2010-06-22  3:06                                                                     ` Dave Wysochanski
  0 siblings, 0 replies; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22  3:06 UTC (permalink / raw)
  To: lvm-devel

Test vgcreate/vgchange --vgmetadatacopies, vgextend, vgreduce,
vgsplit, vgmerge.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
---
 test/t-metadata-balance.sh |  153 +++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 151 insertions(+), 2 deletions(-)

diff --git a/test/t-metadata-balance.sh b/test/t-metadata-balance.sh
index 2321771..95764a8 100755
--- a/test/t-metadata-balance.sh
+++ b/test/t-metadata-balance.sh
@@ -10,9 +10,9 @@
 
 . ./test-utils.sh
 
-aux prepare_devs 5
+aux prepare_devs 6
 
-#  Make sure we can ignore / un-ignore mdas on a per-PV basis
+echo Make sure we can ignore / un-ignore mdas on a per-PV basis
 for pv_in_vg in 1 0; do
 for mdacp in 1 2; do
 	pvcreate --metadatacopies $mdacp $dev1 $dev2
@@ -28,6 +28,7 @@ for mdacp in 1 2; do
 	if [ $pv_in_vg = 1 ]; then
 		check_vg_field_ $vg vg_mda_count $(($mdacp * 2))
 		check_vg_field_ $vg vg_mda_count_ignored $mdacp
+		check_vg_field_ $vg vg_mda_copies 0
 	fi
 	pvchange --metadataignore n $dev1
 	check_pv_field_ $dev1 pv_mda_count $mdacp
@@ -35,7 +36,155 @@ for mdacp in 1 2; do
 	if [ $pv_in_vg = 1 ]; then
 		check_vg_field_ $vg vg_mda_count $(($mdacp * 2))
 		check_vg_field_ $vg vg_mda_count_ignored 0
+		check_vg_field_ $vg vg_mda_copies 0
 		vgremove -f $vg
 	fi
 done
 done
+
+# Check if a PV has non-ignored mdas, and if so, ignore
+pvignore_ () {
+	pv_ignored=$(get_pv_field "$1" pv_mda_count_ignored)
+	if [ $pv_ignored = 0 ]; then
+	    pvchange --metadataignore y $1
+	fi
+}
+
+pvunignore_ () {
+	pv_ignored=$(get_pv_field "$1" pv_mda_count_ignored)
+	if [ $pv_ignored != 0 ]; then
+	    pvchange --metadataignore n $1
+	fi
+}
+
+echo Test of vgmetadatacopies with vgcreate and vgchange
+for mdacp in 1 2; do
+	pvcreate --metadatacopies $mdacp $dev1 $dev2 $dev4 $dev5
+	check_pv_field_ $dev1 pv_mda_count_ignored 0
+	check_pv_field_ $dev2 pv_mda_count_ignored 0
+	check_pv_field_ $dev4 pv_mda_count_ignored 0
+	check_pv_field_ $dev5 pv_mda_count_ignored 0
+	pvcreate --metadatacopies 0 $dev3
+	vgcreate -c n "$vg" $dev1 $dev2 $dev3
+	check_vg_field_ $vg vg_mda_copies 0
+	echo ensure both --vgmetadatacopies and --metadatacopies accepted
+	vgchange --metadatacopies $(($mdacp * 1)) $vg
+	echo --vgmetadatacopies is persistent on disk
+	echo --vgmetadatacopies affects underlying pv mda ignore
+	check_vg_field_ $vg vg_mda_copies $(($mdacp * 1))
+	check_vg_field_ $vg vg_mda_count_ignored $(($mdacp * 1))
+	vgchange --vgmetadatacopies $(($mdacp * 2)) $vg
+	check_vg_field_ $vg vg_mda_copies $(($mdacp * 2))
+	check_vg_field_ $vg vg_mda_count_ignored 0
+	echo allow setting metadatacopies larger than number of PVs
+	vgchange --vgmetadatacopies $(($mdacp * 5)) $vg
+	check_vg_field_ $vg vg_mda_copies $(($mdacp * 5))
+	check_vg_field_ $vg vg_mda_count_ignored 0
+	echo setting to 0 disables automatic balancing
+	vgchange --vgmetadatacopies 0 $vg
+	check_vg_field_ $vg vg_mda_copies 0
+	vgremove -f $vg
+	echo vgcreate succeeds even when creating a VG w/all ignored mdas
+	pvchange --metadataignore y $dev1 $dev2
+	check_pv_field_ $dev1 pv_mda_count $mdacp
+	check_pv_field_ $dev2 pv_mda_count_ignored $mdacp
+	vgcreate -c n "$vg" $dev1 $dev2
+	check_vg_field_ $vg vg_mda_copies 0
+	vgremove -f $vg
+	echo vgcreate succeeds with a specific number of metadata copies
+	vgcreate -c n --vgmetadatacopies $(($mdacp * 2)) "$vg" $dev1 $dev2
+	check_vg_field_ $vg vg_mda_copies $(($mdacp * 2))
+	vgremove -f $vg
+	vgcreate -c n --vgmetadatacopies $(($mdacp * 1)) "$vg" $dev1 $dev2
+	check_vg_field_ $vg vg_mda_copies $(($mdacp * 1))
+	vgremove -f $vg
+	echo vgcreate succeeds with a larger value than total metadatacopies
+	vgcreate -c n --vgmetadatacopies $(($mdacp * 5)) "$vg" $dev1 $dev2
+	check_vg_field_ $vg vg_mda_copies $(($mdacp * 5))
+	vgremove -f $vg
+	echo vgcreate succeeds with --vgmetadatacopies 0
+	vgcreate -c n --vgmetadatacopies 0 "$vg" $dev1 $dev2
+	check_vg_field_ $vg vg_mda_copies 0
+	vgremove -f $vg
+	pvunignore_ $dev1
+	pvunignore_ $dev2
+	pvunignore_ $dev4
+	pvunignore_ $dev5
+	echo vgcreate succeds with small value of --metadatacopies, ignores mdas
+	vgcreate -c n --vgmetadatacopies 1 "$vg" $dev1 $dev2 $dev4 $dev5
+	check_vg_field_ $vg vg_mda_copies 1
+	check_vg_field_ $vg vg_mda_count $(($mdacp * 4))
+	check_vg_field_ $vg vg_mda_count_ignored $(($mdacp * 4 - 1))
+	echo Setting a larger value should trigger non-ignore of mdas
+	vgchange --metadatacopies 3 $vg
+	check_vg_field_ $vg vg_mda_copies 3
+	check_vg_field_ $vg vg_mda_count_ignored $(($mdacp * 4 - 3))
+	echo Setting a smaller value should trigger ignore of mdas
+	vgremove -f $vg
+done
+
+echo Test vgextend / vgreduce with vgmetadatacopies
+for mdacp in 1 2; do
+	pvcreate --metadatacopies $mdacp $dev1 $dev2 $dev4 $dev5
+	pvcreate --metadatacopies 0 $dev3
+	echo Set a large value of vgmetadatacopies
+	vgcreate -c n --vgmetadatacopies $(($mdacp * 5)) "$vg" $dev1 $dev2 $dev3
+	check_vg_field_ $vg vg_mda_copies $(($mdacp * 5))
+	echo Ignore mdas on devices to be used for vgextend
+	echo Large value of vgetadatacopies should automatically un-ignore mdas
+	pvchange --metadataignore y $dev4 $dev5
+	check_pv_field_ $dev4 pv_mda_count_ignored $mdacp
+	vgextend $vg $dev4 $dev5
+	check_pv_field_ $dev4 pv_mda_count_ignored 0
+	check_pv_field_ $dev5 pv_mda_count_ignored 0
+	vgremove -f $vg
+	echo Set a small value of vgmetadatacopies
+	vgcreate -c n --vgmetadatacopies $(($mdacp * 1)) "$vg" $dev1 $dev2 $dev3
+	check_vg_field_ $vg vg_mda_copies $(($mdacp * 1))
+	echo Ignore mdas on devices to be used for vgextend
+	echo Small value of vgetadatacopies should leave mdas as ignored
+	pvchange --metadataignore y $dev4 $dev5
+	check_pv_field_ $dev4 pv_mda_count_ignored $mdacp
+	vgextend $vg $dev4 $dev5
+	check_pv_field_ $dev4 pv_mda_count_ignored $mdacp
+	check_pv_field_ $dev5 pv_mda_count_ignored $mdacp
+	echo vgreduce of ignored pv w/mda should not trigger any change to ignore bits
+	vgreduce $vg $dev4
+	check_pv_field_ $dev4 pv_mda_count_ignored $mdacp
+	check_pv_field_ $dev5 pv_mda_count_ignored $mdacp
+	echo vgreduce of un-ignored pv w/mda should trigger un-ignore on an mda
+	vgreduce $vg $dev1 $dev2 $dev3
+	check_pv_field_ $dev5 pv_mda_count_ignored 0
+	check_vg_field_ $vg vg_mda_copies $(($mdacp * 1))
+	pvunignore_ $dev1
+	pvunignore_ $dev2
+	echo setting vgmetadatacopies to 0 should allow vgextend to add w/out balancing
+	vgchange --vgmetadatacopies 0 $vg
+	vgextend $vg $dev1 $dev2
+	check_vg_field_ $vg vg_mda_copies 0
+	check_vg_field_ $vg vg_mda_count $(($mdacp * 3))
+	check_vg_field_ $vg vg_mda_count_ignored 0
+	check_pv_field_ $dev1 pv_mda_count_ignored 0
+	check_pv_field_ $dev2 pv_mda_count_ignored 0
+	vgremove -f $vg
+done
+
+echo Test special situations, vgsplit, vgmerge, etc
+for mdacp in 1 2; do
+	pvcreate --metadatacopies $mdacp $dev1 $dev2 $dev3 $dev4 $dev5
+	vgcreate -c n --vgmetadatacopies 2 $vg1 $dev1 $dev2 $dev3
+	vgcreate -c n --vgmetadatacopies $(($mdacp * 1)) $vg2 $dev4 $dev5
+	echo vgsplit/vgmerge preserves value of metadata copies
+	check_vg_field_ $vg1 vg_mda_copies 2
+	check_vg_field_ $vg2 vg_mda_copies $(($mdacp * 1))
+	vgsplit $vg1 $vg2 $dev1
+	check_vg_field_ $vg2 vg_mda_copies $(($mdacp * 1))
+	vgmerge $vg1 $vg2
+	check_vg_field_ $vg1 vg_mda_copies 2
+	check_vg_field_ $vg1 vg_mda_count $(($mdacp * 5))
+	echo vgsplit into new vg sets proper value of vgmetadatacopies
+	vgsplit --vgmetadatacopies $(($mdacp * 2)) $vg1 $vg2 $dev1 $dev2
+	check_vg_field_ $vg2 vg_mda_copies $(($mdacp * 2))
+	vgremove -f $vg1
+	vgremove -f $vg2
+done
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata.
  2010-06-22  3:05                                                 ` [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata Dave Wysochanski
  2010-06-22  3:05                                                   ` [PATCH 26/35] Add vg_mda_copies display field to 'vgs' command Dave Wysochanski
@ 2010-06-22  8:18                                                   ` Zdenek Kabelac
  2010-06-22 10:36                                                     ` Dave Wysochanski
  1 sibling, 1 reply; 39+ messages in thread
From: Zdenek Kabelac @ 2010-06-22  8:18 UTC (permalink / raw)
  To: lvm-devel

Dne 22.6.2010 05:05, Dave Wysochanski napsal(a):
> This patch adds the ability to read/write the vg->mda_copies values
> from/to the vg metadata.
>
> If we read the VG metadata and this field does not exist, we set
> mda_copies to the default value of 0.  Later in the code, we use
> this special '0' value to indicate a disable of metadata balancing.
> This should preserve existing LVM behavior and ensure metadata balancing
> can be turned off should the need arise.
>
> Signed-off-by: Dave Wysochanski<dwysocha@redhat.com>
> ---
>   lib/format_text/export.c      |    1 +
>   lib/format_text/import_vsn1.c |    5 +++++
>   2 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/lib/format_text/export.c b/lib/format_text/export.c
> index 5f02b5d..52ae11c 100644
> --- a/lib/format_text/export.c
> +++ b/lib/format_text/export.c
> @@ -397,6 +397,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
>   		outf(f, "allocation_policy = \"%s\"",
>   		     get_alloc_string(vg->alloc));
>   	}
> +	outf(f, "metadata_copies = %u", vg->mda_copies);
>
>   	return 1;


Hmm - so we add a new element to the metadata format with the same version 
number? If the user will update metadata with older tools which do not know 
about this parameter - will he get at least a warning that he will miss some 
information ?

Zdenek



^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata.
  2010-06-22  8:18                                                   ` [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata Zdenek Kabelac
@ 2010-06-22 10:36                                                     ` Dave Wysochanski
  2010-06-22 14:04                                                       ` Alasdair G Kergon
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Wysochanski @ 2010-06-22 10:36 UTC (permalink / raw)
  To: lvm-devel

On Tue, 2010-06-22 at 10:18 +0200, Zdenek Kabelac wrote:
> Dne 22.6.2010 05:05, Dave Wysochanski napsal(a):
> > This patch adds the ability to read/write the vg->mda_copies values
> > from/to the vg metadata.
> >
> > If we read the VG metadata and this field does not exist, we set
> > mda_copies to the default value of 0.  Later in the code, we use
> > this special '0' value to indicate a disable of metadata balancing.
> > This should preserve existing LVM behavior and ensure metadata balancing
> > can be turned off should the need arise.
> >
> > Signed-off-by: Dave Wysochanski<dwysocha@redhat.com>
> > ---
> >   lib/format_text/export.c      |    1 +
> >   lib/format_text/import_vsn1.c |    5 +++++
> >   2 files changed, 6 insertions(+), 0 deletions(-)
> >
> > diff --git a/lib/format_text/export.c b/lib/format_text/export.c
> > index 5f02b5d..52ae11c 100644
> > --- a/lib/format_text/export.c
> > +++ b/lib/format_text/export.c
> > @@ -397,6 +397,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
> >   		outf(f, "allocation_policy = \"%s\"",
> >   		     get_alloc_string(vg->alloc));
> >   	}
> > +	outf(f, "metadata_copies = %u", vg->mda_copies);
> >
> >   	return 1;
> 
> 
> Hmm - so we add a new element to the metadata format with the same version 
> number? If the user will update metadata with older tools which do not know 
> about this parameter - will he get at least a warning that he will miss some 
> information ?
> 

LVM ignores unknown fields in the vg metadata, and if older tools are
used after metadata is written with new tools and this value, yes,
you'll lose this field (it will go back to default value of "disabled
metadata balance").

If we update FORMAT_VERSION_VALUE, older tools will just refuse to parse
the metadata completely and the tools are useless.  I don't think this
is what users would want.  Perhaps there should be a warning of sorts
when unknown fields are encountered, though I've not looked into such a
patch.

It's not clear what process (if any) we are using when updating on-disk
metadata and fields.  Another case is my first few patches, where I take
a previously unused area of the LVM header area and use it for flags.  I
have not tested whether older tools would wipe the value of the
"ignored" flag or whether it would be preserved.

Was someone working on patches or rules for updating on-disk
fields/metadata?  It does not seem like we test these types of scenarios
but I guess so far it has "just worked".



^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata.
  2010-06-22 10:36                                                     ` Dave Wysochanski
@ 2010-06-22 14:04                                                       ` Alasdair G Kergon
  0 siblings, 0 replies; 39+ messages in thread
From: Alasdair G Kergon @ 2010-06-22 14:04 UTC (permalink / raw)
  To: lvm-devel

Indeed, that version number would only be changed if chose to make a major
change that broke compatibility.

Generally, if people access LVM metadata with older tools than the ones
used to write it they can expect any new features in the metadata to get
dropped - but the code should still work OK.  Sometimes there'll be
warning messages; other times not.

We do try to phase-in new features, so code goes in that recognises the
new feature several releases before the feature can be enabled by default.

So for now, this new feature will require positive action by the
sysadmin to enable.  (E.g. editing lvm.conf or using new cmdline
options.)

Alasdair



^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2010-06-22 14:04 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-22  3:05 [PATCH 00/35] Add full metadata balancing support, v5 Dave Wysochanski
2010-06-22  3:05 ` [PATCH 01/35] Change 'filler' to 'flags' in on-disk 'raw_locn' structure Dave Wysochanski
2010-06-22  3:05   ` [PATCH 02/35] Add text format specific 'rlocn' ignore flag and access functions Dave Wysochanski
2010-06-22  3:05     ` [PATCH 03/35] Add location independent flag and functions to ignore mdas Dave Wysochanski
2010-06-22  3:05       ` [PATCH 04/35] Move dev_open / dev_close outside _vg_read_raw_area() Dave Wysochanski
2010-06-22  3:05         ` [PATCH 05/35] Move dev_open/dev_close outside vgname_from_mda() Dave Wysochanski
2010-06-22  3:05           ` [PATCH 06/35] Allow raw_read_mda_header to be called from text_label.c Dave Wysochanski
2010-06-22  3:05             ` [PATCH 07/35] Ensure in-memory state matches on-disk state of mda ignore bit Dave Wysochanski
2010-06-22  3:05               ` [PATCH 08/35] Add mda_locn_match() internal library function for mapping pv/device to VG mda Dave Wysochanski
2010-06-22  3:05                 ` [PATCH 09/35] Add mda location specific mda_copy constructor Dave Wysochanski
2010-06-22  3:05                   ` [PATCH 10/35] Use vg_mda_count() in vgdisplay Dave Wysochanski
2010-06-22  3:05                     ` [PATCH 11/35] Add metadata_areas_ignored list and functions to manage ignored mdas Dave Wysochanski
2010-06-22  3:05                       ` [PATCH 12/35] Define new functions and vgs/pvs fields related to mda ignore Dave Wysochanski
2010-06-22  3:05                         ` [PATCH 13/35] Add --metadataignore to pvchange, allowing for ignoring of metadata areas Dave Wysochanski
2010-06-22  3:05                           ` [PATCH 14/35] Update pvchange, pvs and vgs man pages for metadata ignore Dave Wysochanski
2010-06-22  3:05                             ` [PATCH 15/35] Implement ignore of mda if bit set by skipping r/w of metadata Dave Wysochanski
2010-06-22  3:05                               ` [PATCH 16/35] Add mdas_empty_or_ignored() helper function Dave Wysochanski
2010-06-22  3:05                                 ` [PATCH 17/35] Use mdas_empty_or_ignored() in place of checks for empty mda list Dave Wysochanski
2010-06-22  3:05                                   ` [PATCH 18/35] Update _vg_read and _text_create_text_instance to use fid_add_mda[s] Dave Wysochanski
2010-06-22  3:05                                     ` [PATCH 19/35] Refactor vg_commit() to add _vg_commit_mdas() Dave Wysochanski
2010-06-22  3:05                                       ` [PATCH 20/35] Before committing each mda, arrange mdas so ignored mdas get committed first Dave Wysochanski
2010-06-22  3:05                                         ` [PATCH 21/35] Add tests for phase 1 of metadata balance - manage per-PV ignore bit Dave Wysochanski
2010-06-22  3:05                                           ` [PATCH 22/35] Define vgmetadatacopies in vgchange man page Dave Wysochanski
2010-06-22  3:05                                             ` [PATCH 23/35] Add mda_copies to VG structures and initialization Dave Wysochanski
2010-06-22  3:05                                               ` [PATCH 24/35] Add vg get/set methods for VG metadata copies Dave Wysochanski
2010-06-22  3:05                                                 ` [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata Dave Wysochanski
2010-06-22  3:05                                                   ` [PATCH 26/35] Add vg_mda_copies display field to 'vgs' command Dave Wysochanski
2010-06-22  3:06                                                     ` [PATCH 27/35] Update vgchange tool to accept --vgmetadatacopies Dave Wysochanski
2010-06-22  3:06                                                       ` [PATCH 28/35] Implement _vg_metadata_balance and call from vg_write() path Dave Wysochanski
2010-06-22  3:06                                                         ` [PATCH 29/35] Set vg_mda_copies when pvchange --metadataignore is given Dave Wysochanski
2010-06-22  3:06                                                           ` [PATCH 30/35] Add --vgmetadatacopies to vgcreate man page, command, and lvm.conf Dave Wysochanski
2010-06-22  3:06                                                             ` [PATCH 31/35] Ensure fid mda lists are populated correctly during vgextend Dave Wysochanski
2010-06-22  3:06                                                               ` [PATCH 32/35] Update check in vg_split_mdas to account for ignored mdas list Dave Wysochanski
2010-06-22  3:06                                                                 ` [PATCH 33/35] Update _vgmerge_single() to move fid->metadata_areas_ignored Dave Wysochanski
2010-06-22  3:06                                                                   ` [PATCH 34/35] Add --vgmetadatacopies to vgsplit man page and command Dave Wysochanski
2010-06-22  3:06                                                                     ` [PATCH 35/35] Update tests to handle phase 2 (vg based) metadata balance Dave Wysochanski
2010-06-22  8:18                                                   ` [PATCH 25/35] Make vg->mda_copies persistent in on disk vg metadata Zdenek Kabelac
2010-06-22 10:36                                                     ` Dave Wysochanski
2010-06-22 14:04                                                       ` Alasdair G Kergon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.