public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2 lib/format_text/format-text.c lib/metadat ...
@ 2011-06-15 17:45 mornfall
  0 siblings, 0 replies; 4+ messages in thread
From: mornfall @ 2011-06-15 17:45 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	mornfall@sourceware.org	2011-06-15 17:45:04

Modified files:
	lib/format_text: format-text.c 
	lib/metadata   : metadata.c metadata.h 
	test           : t-lvconvert-repair-transient-dmeventd.sh 

Log message:
	Fix RHBZ 651590 (failure to lock LV results in failure to repair mirror after
	transient error), stemming from the following sequence of events:
	
	1) devices fail IO, triggering repair
	2) dmeventd starts fixing up the mirror
	3) during the downconversion, a new metadata version is written
	
	--> the devices come back online here
	
	4) the mirror device suspend/resume is called to update DM tables
	5) during the suspend/resume cycle, *pre*-commit metadata is read;
	however, since the failed devices are now back online, we get back
	inconsistent set of precommit metadata and the whole operation fails
	
	The patch relaxes the check that fails in step 5 above, namely by ignoring
	inconsistencies coming from PVs that are marked MISSING.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/format-text.c.diff?cvsroot=lvm2&r1=1.181&r2=1.182
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.457&r2=1.458
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.244&r2=1.245
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/t-lvconvert-repair-transient-dmeventd.sh.diff?cvsroot=lvm2&r1=1.1&r2=1.2

--- LVM2/lib/format_text/format-text.c	2011/06/01 19:29:33	1.181
+++ LVM2/lib/format_text/format-text.c	2011/06/15 17:45:02	1.182
@@ -127,6 +127,12 @@
 	return 0;
 }
 
+static struct device *_mda_get_device_raw(struct metadata_area *mda)
+{
+	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
+	return mdac->area.dev;
+}
+
 /*
  * For circular region between region_start and region_start + region_size,
  * back up one SECTOR_SIZE from 'region_ptr' and return the value.
@@ -1629,7 +1635,8 @@
 	.mda_total_sectors = _mda_total_sectors_raw,
 	.mda_in_vg = _mda_in_vg_raw,
 	.pv_analyze_mda = _pv_analyze_mda_raw,
-	.mda_locns_match = _mda_locns_match_raw
+	.mda_locns_match = _mda_locns_match_raw,
+	.mda_get_device = _mda_get_device_raw
 };
 
 static int _text_pv_setup(const struct format_type *fmt,
--- LVM2/lib/metadata/metadata.c	2011/06/01 19:29:33	1.457
+++ LVM2/lib/metadata/metadata.c	2011/06/15 17:45:03	1.458
@@ -2837,6 +2837,7 @@
 	int inconsistent_pvs = 0;
 	int inconsistent_seqno = 0;
 	int inconsistent_mdas = 0;
+	int inconsistent_mda_count = 0;
 	unsigned use_precommitted = precommitted;
 	unsigned saved_handles_missing_pvs = cmd->handles_missing_pvs;
 	struct dm_list *pvids;
@@ -2913,6 +2914,7 @@
 		return_NULL;
 
 	/* Ensure contents of all metadata areas match - else do recovery */
+	inconsistent_mda_count=0;
 	dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
 		if ((use_precommitted &&
 		     !(vg = mda->ops->vg_read_precommit(fid, vgname, mda))) ||
@@ -2922,6 +2924,7 @@
 			free_vg(vg);
 			continue;
 		}
+
 		if (!correct_vg) {
 			correct_vg = vg;
 			continue;
@@ -2940,6 +2943,9 @@
 			if (vg->seqno > correct_vg->seqno) {
 				free_vg(correct_vg);
 				correct_vg = vg;
+			} else {
+				mda->status |= MDA_INCONSISTENT;
+				++inconsistent_mda_count;
 			}
 		}
 
@@ -3067,6 +3073,7 @@
 		}
 
 		/* Ensure contents of all metadata areas match - else recover */
+		inconsistent_mda_count=0;
 		dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
 			if ((use_precommitted &&
 			     !(vg = mda->ops->vg_read_precommit(fid, vgname,
@@ -3111,6 +3118,9 @@
 				if (vg->seqno > correct_vg->seqno) {
 					free_vg(correct_vg);
 					correct_vg = vg;
+				} else {
+					mda->status |= MDA_INCONSISTENT;
+					++inconsistent_mda_count;
 				}
 			}
 
@@ -3137,13 +3147,26 @@
 		if (use_precommitted) {
 			log_error("Inconsistent pre-commit metadata copies "
 				  "for volume group %s", vgname);
-			/* FIXME: during repair, there is inconsistent flag set because some metadata areas
-			 * are missing (on missing PVs). Code should create list of missing PVs, compare it
-			 * with PV marked missing in metadata and if equals, use it as consistent vg.
-			 * For now, return precommited metadata if remainng seq match here to allow
-			 * preloading table in suspend call.
+
+			/*
+			 * Check whether all of the inconsistent MDAs were on
+			 * MISSING PVs -- in that case, we should be safe.
 			 */
-			if (!inconsistent_seqno) {
+			dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
+				if (mda->status & MDA_INCONSISTENT) {
+					log_debug("Checking inconsistent MDA: %s", dev_name(mda_get_device(mda)));
+					dm_list_iterate_items(pvl, &correct_vg->pvs) {
+						if (mda_get_device(mda) == pvl->pv->dev &&
+						    (pvl->pv->status & MISSING_PV))
+							--inconsistent_mda_count;
+					}
+				}
+			}
+
+			if (inconsistent_mda_count < 0)
+				log_error(INTERNAL_ERROR "Too many inconsistent MDAs.");
+
+			if (!inconsistent_mda_count) {
 				*consistent = 0;
 				_free_pv_list(&all_pvs);
 				return correct_vg;
@@ -4285,6 +4308,13 @@
 	return mda1->ops->mda_locns_match(mda1, mda2);
 }
 
+struct device *mda_get_device(struct metadata_area *mda)
+{
+	if (!mda->ops->mda_get_device)
+		return NULL;
+	return mda->ops->mda_get_device(mda);
+}
+
 unsigned mda_is_ignored(struct metadata_area *mda)
 {
 	return (mda->status & MDA_IGNORED);
--- LVM2/lib/metadata/metadata.h	2011/06/01 19:29:33	1.244
+++ LVM2/lib/metadata/metadata.h	2011/06/15 17:45:03	1.245
@@ -175,9 +175,12 @@
 	 */
 	unsigned (*mda_locns_match)(struct metadata_area *mda1,
 				    struct metadata_area *mda2);
+
+	struct device *(*mda_get_device)(struct metadata_area *mda);
 };
 
-#define MDA_IGNORED 0x00000001
+#define MDA_IGNORED      0x00000001
+#define MDA_INCONSISTENT 0x00000002
 
 struct metadata_area {
 	struct dm_list list;
@@ -191,6 +194,7 @@
 unsigned mda_is_ignored(struct metadata_area *mda);
 void mda_set_ignored(struct metadata_area *mda, unsigned ignored);
 unsigned mda_locns_match(struct metadata_area *mda1, struct metadata_area *mda2);
+struct device *mda_get_device(struct metadata_area *mda);
 
 struct format_instance_ctx {
 	uint32_t type;
--- LVM2/test/t-lvconvert-repair-transient-dmeventd.sh	2011/01/07 14:56:10	1.1
+++ LVM2/test/t-lvconvert-repair-transient-dmeventd.sh	2011/06/15 17:45:03	1.2
@@ -19,9 +19,9 @@
 aux disable_dev $dev2 $dev4
 mkfs.ext3 $DM_DEV_DIR/$vg/4way
 aux enable_dev $dev2 $dev4
-sleep 10
+sleep 3
 lvs -a -o +devices | not grep unknown
 check mirror $vg 4way
 check mirror_legs $vg 4way 2
-lvs -a -o +devices | should not grep mimage_1
-lvs -a -o +devices | should not grep mimage_3
+lvs -a -o +devices | not grep mimage_1
+lvs -a -o +devices | not grep mimage_3


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

* LVM2 lib/format_text/format-text.c lib/metadat ...
@ 2011-02-21 12:31 prajnoha
  0 siblings, 0 replies; 4+ messages in thread
From: prajnoha @ 2011-02-21 12:31 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	prajnoha@sourceware.org	2011-02-21 12:31:28

Modified files:
	lib/format_text: format-text.c 
	lib/metadata   : pv.h 
	tools          : pvchange.c 

Log message:
	Add old_uuid field to struct physical_volume so we can still reference a PV
	with its old UUID when we're changig it (the cache as well as metadata area
	index has the old uuid that we need to use to access the information!)

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/format-text.c.diff?cvsroot=lvm2&r1=1.165&r2=1.166
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/pv.h.diff?cvsroot=lvm2&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/pvchange.c.diff?cvsroot=lvm2&r1=1.89&r2=1.90

--- LVM2/lib/format_text/format-text.c	2011/02/21 12:27:26	1.165
+++ LVM2/lib/format_text/format-text.c	2011/02/21 12:31:28	1.166
@@ -1260,6 +1260,7 @@
 {
 	struct text_fid_pv_context *fid_pv_tc;
 	struct format_instance *fid = pv->fid;
+	const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);
 	struct label *label;
 	int64_t label_sector;
 	struct lvmcache_info *info;
@@ -1303,8 +1304,7 @@
 	 * just pass the right format_instance in.
 	 */
 	for (mda_index = 0; mda_index < FMT_TEXT_MAX_MDAS_PER_PV; mda_index++) {
-		if (!(mda = fid_get_mda_indexed(fid, (const char *) &pv->id,
-							ID_LEN, mda_index)))
+		if (!(mda = fid_get_mda_indexed(fid, pvid, ID_LEN, mda_index)))
 			continue;
 
 		mdac = (struct mda_context *) mda->metadata_locn;
@@ -1644,7 +1644,7 @@
 			  struct volume_group *vg)
 {
 	struct format_instance *fid = pv->fid;
-	const char *pvid = (const char *) &pv->id;
+	const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);
 	unsigned mda_index;
 	struct metadata_area *pv_mda;
 	struct mda_context *pv_mdac;
@@ -1879,7 +1879,7 @@
 				      unsigned mda_ignored)
 {
 	struct format_instance *fid = pv->fid;
-	const char *pvid = (char *) &pv->id;
+	const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);
 	uint64_t pe_start, pe_end;
 	uint64_t alignment, alignment_offset;
 	uint64_t disk_size;
@@ -2099,7 +2099,7 @@
 			   uint64_t size)
 {
 	struct format_instance *fid = pv->fid;
-	const char *pvid = (const char *) &pv->id;
+	const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);
 	struct metadata_area *mda;
 	struct mda_context *mdac;
 	uint64_t size_reduction;
--- LVM2/lib/metadata/pv.h	2011/02/21 12:12:32	1.9
+++ LVM2/lib/metadata/pv.h	2011/02/21 12:31:28	1.10
@@ -22,6 +22,7 @@
 
 struct physical_volume {
 	struct id id;
+	struct id old_id;		/* Set during pvchange -u. */
 	struct device *dev;
 	const struct format_type *fmt;
 	struct format_instance *fid;
--- LVM2/tools/pvchange.c	2011/02/21 12:26:28	1.89
+++ LVM2/tools/pvchange.c	2011/02/21 12:31:28	1.90
@@ -120,6 +120,7 @@
 
 	if (arg_count(cmd, uuid_ARG)) {
 		/* --uuid: Change PV ID randomly */
+		memcpy(&pv->old_id, &pv->id, sizeof(pv->id));
 		if (!id_create(&pv->id)) {
 			log_error("Failed to generate new random UUID for %s.",
 				  pv_name);


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

* LVM2 lib/format_text/format-text.c lib/metadat ...
@ 2011-02-21 12:27 prajnoha
  0 siblings, 0 replies; 4+ messages in thread
From: prajnoha @ 2011-02-21 12:27 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	prajnoha@sourceware.org	2011-02-21 12:27:26

Modified files:
	lib/format_text: format-text.c 
	lib/metadata   : metadata-exported.h metadata.h pv_manip.c 
	tools          : pvresize.c 

Log message:
	Change pvresize code to work with new metadata handling interface and allow
	resizing a PV with two metadata areas.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/format-text.c.diff?cvsroot=lvm2&r1=1.164&r2=1.165
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.180&r2=1.181
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.238&r2=1.239
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/pv_manip.c.diff?cvsroot=lvm2&r1=1.25&r2=1.26
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/pvresize.c.diff?cvsroot=lvm2&r1=1.40&r2=1.41

--- LVM2/lib/format_text/format-text.c	2011/02/21 12:26:27	1.164
+++ LVM2/lib/format_text/format-text.c	2011/02/21 12:27:26	1.165
@@ -2093,6 +2093,55 @@
 	return remove_metadata_area_from_pv(pv, mda_index);
 }
 
+static int _text_pv_resize(const struct format_type *fmt,
+			   struct physical_volume *pv,
+			   struct volume_group *vg,
+			   uint64_t size)
+{
+	struct format_instance *fid = pv->fid;
+	const char *pvid = (const char *) &pv->id;
+	struct metadata_area *mda;
+	struct mda_context *mdac;
+	uint64_t size_reduction;
+	uint64_t mda_size;
+	unsigned mda_ignored;
+
+	/*
+	 * First, set the new size and update the cache and reset pe_count.
+	 * (pe_count must be reset otherwise it would be considered as
+	 * a limiting factor while moving the mda!)
+	 */
+	pv->size = size;
+	pv->pe_count = 0;
+
+	/* If there's an mda at the end, move it to a new position. */
+	if ((mda = fid_get_mda_indexed(fid, pvid, ID_LEN, 1)) &&
+	    (mdac = mda->metadata_locn)) {
+		/* FIXME: Maybe MDA0 size would be better? */
+		mda_size = mdac->area.size >> SECTOR_SHIFT;
+		mda_ignored = mda_is_ignored(mda);
+
+		if (!_text_pv_remove_metadata_area(fmt, pv, 1) ||
+		    !_text_pv_add_metadata_area(fmt, pv, 1, 1, mda_size,
+						mda_ignored)) {
+			log_error("Failed to move metadata area with index 1 "
+				  "while resizing PV %s.", pv_dev_name(pv));
+			return 0;
+		}
+	}
+
+	/* If there's a VG, reduce size by counting in pe_start and metadata areas. */
+	if (vg) {
+		size_reduction = pv_pe_start(pv);
+		if ((mda = fid_get_mda_indexed(fid, pvid, ID_LEN, 1)) &&
+		    (mdac = mda->metadata_locn))
+			size_reduction += mdac->area.size >> SECTOR_SHIFT;
+		pv->size -= size_reduction;
+	}
+
+	return 1;
+}
+
 /* NULL vgname means use only the supplied context e.g. an archive file */
 static struct format_instance *_text_create_text_instance(const struct format_type *fmt,
 							   const struct format_instance_ctx *fic)
@@ -2170,6 +2219,7 @@
 	.pv_setup = _text_pv_setup,
 	.pv_add_metadata_area = _text_pv_add_metadata_area,
 	.pv_remove_metadata_area = _text_pv_remove_metadata_area,
+	.pv_resize = _text_pv_resize,
 	.pv_write = _text_pv_write,
 	.vg_setup = _text_vg_setup,
 	.lv_setup = _text_lv_setup,
--- LVM2/lib/metadata/metadata-exported.h	2011/02/21 12:26:27	1.180
+++ LVM2/lib/metadata/metadata-exported.h	2011/02/21 12:27:26	1.181
@@ -428,7 +428,7 @@
 				  uint64_t pvmetadatasize,
 				  unsigned metadataignore);
 int pv_resize(struct physical_volume *pv, struct volume_group *vg,
-             uint32_t new_pe_count);
+             uint64_t size);
 int pv_analyze(struct cmd_context *cmd, const char *pv_name,
 	       uint64_t label_sector);
 
--- LVM2/lib/metadata/metadata.h	2011/02/21 12:26:27	1.238
+++ LVM2/lib/metadata/metadata.h	2011/02/21 12:27:26	1.239
@@ -293,6 +293,14 @@
 					unsigned metadata_index);
 
 	/*
+	 * Recalculate the PV size taking into account any existing metadata areas.
+	 */
+	int (*pv_resize) (const struct format_type *fmt,
+			  struct physical_volume *pv,
+			  struct volume_group *vg,
+			  uint64_t size);
+
+	/*
 	 * Write a PV structure to disk. Fails if the PV is in a VG ie
 	 * pv->vg_name must be a valid orphan VG name
 	 */
--- LVM2/lib/metadata/pv_manip.c	2010/03/31 17:23:19	1.25
+++ LVM2/lib/metadata/pv_manip.c	2011/02/21 12:27:26	1.26
@@ -357,10 +357,10 @@
 	return ret;
 }
 
-static int _reduce_pv(struct physical_volume *pv, struct volume_group *vg, uint32_t new_pe_count)
+static int _reduce_pv(struct physical_volume *pv, struct volume_group *vg,
+		      uint32_t old_pe_count, uint32_t new_pe_count)
 {
 	struct pv_segment *peg, *pegt;
-	uint32_t old_pe_count = pv->pe_count;
 
 	if (new_pe_count < pv->pe_alloc_count) {
 		log_error("%s: cannot resize to %" PRIu32 " extents "
@@ -400,10 +400,9 @@
 }
 
 static int _extend_pv(struct physical_volume *pv, struct volume_group *vg,
-		      uint32_t new_pe_count)
+		      uint32_t old_pe_count, uint32_t new_pe_count)
 {
 	struct pv_segment *peg;
-	uint32_t old_pe_count = pv->pe_count;
 
 	if ((uint64_t) new_pe_count * pv->pe_size > pv->size ) {
 		log_error("%s: cannot resize to %" PRIu32 " extents as there "
@@ -432,20 +431,59 @@
  */
 int pv_resize(struct physical_volume *pv,
 	      struct volume_group *vg,
-	      uint32_t new_pe_count)
+	      uint64_t size)
 {
-	if ((new_pe_count == pv->pe_count)) {
-		log_verbose("No change to size of physical volume %s.",
-			    pv_dev_name(pv));
-		return 1;
+	uint32_t old_pe_count, new_pe_count = 0;
+
+	if (size < pv_min_size()) {
+		log_error("Size must exceed minimum of %ld sectors on PV %s.",
+			   pv_min_size(), pv_dev_name(pv));
+		return 0;
 	}
 
-	log_verbose("Resizing physical volume %s from %" PRIu32
-		    " to %" PRIu32 " extents.",
-		    pv_dev_name(pv), pv->pe_count, new_pe_count);
-
-	if (new_pe_count > pv->pe_count)
-		return _extend_pv(pv, vg, new_pe_count);
-	else
-		return _reduce_pv(pv, vg, new_pe_count);
+	if (size < pv_pe_start(pv)) {
+		log_error("Size must exceed physical extent start "
+			  "of %" PRIu64 " sectors on PV %s.",
+			  pv_pe_start(pv), pv_dev_name(pv));
+	}
+
+	old_pe_count = pv->pe_count;
+
+	if (!pv->fmt->ops->pv_resize(pv->fmt, pv, vg, size)) {
+		log_error("Format specific resize of PV %s failed.",
+			   pv_dev_name(pv));
+		return 0;
+	}
+
+	/* pv->pe_count is 0 now! We need to recalculate! */
+
+	/* If there's a VG, calculate new PE count value. */
+	if (vg) {
+		/* FIXME: Maybe PE calculation should go into pv->fmt->resize?
+		          (like it is for pv->fmt->setup) */
+		if (!(new_pe_count = pv_size(pv) / vg->extent_size)) {
+			log_error("Size must leave space for at least one physical "
+				  "extent of %" PRIu32 " sectors on PV %s.",
+				   pv_pe_size(pv), pv_dev_name(pv));
+			return 0;
+		}
+
+		if ((new_pe_count == old_pe_count)) {
+			pv->pe_count = old_pe_count;
+			log_verbose("No change to size of physical volume %s.",
+				    pv_dev_name(pv));
+			return 1;
+		}
+
+		log_verbose("Resizing physical volume %s from %" PRIu32
+			    " to %" PRIu32 " extents.",
+			    pv_dev_name(pv), pv->pe_count, new_pe_count);
+
+		if (new_pe_count > old_pe_count)
+			return _extend_pv(pv, vg, old_pe_count, new_pe_count);
+		else
+			return _reduce_pv(pv, vg, old_pe_count, new_pe_count);
+	}
+
+	return 1;
 }
--- LVM2/tools/pvresize.c	2011/02/21 12:26:28	1.40
+++ LVM2/tools/pvresize.c	2011/02/21 12:27:26	1.41
@@ -30,12 +30,9 @@
 {
 	struct pv_list *pvl;
 	uint64_t size = 0;
-	uint32_t new_pe_count = 0;
 	int r = 0;
 	const char *pv_name = pv_dev_name(pv);
 	const char *vg_name = pv_vg_name(pv);
-	struct lvmcache_info *info;
-	int mda_count = 0;
 	struct volume_group *old_vg = vg;
 
 	if (is_orphan_vg(vg_name)) {
@@ -49,9 +46,6 @@
 			log_error("Unable to read PV \"%s\"", pv_name);
 			return 0;
 		}
-
-		mda_count = dm_list_size(&pv->fid->metadata_areas_in_use) +
-			    dm_list_size(&pv->fid->metadata_areas_ignored);
 	} else {
 		vg = vg_read_for_update(cmd, vg_name, NULL, 0);
 
@@ -70,24 +64,10 @@
 
 		pv = pvl->pv;
 
-		if (!(info = info_from_pvid(pv->dev->pvid, 0))) {
-			log_error("Can't get info for PV %s in volume group %s",
-				  pv_name, vg->name);
-			goto out;
-		}
-
-		mda_count = dm_list_size(&info->mdas);
-
 		if (!archive(vg))
 			goto out;
 	}
 
-	/* FIXME Create function to test compatibility properly */
-	if (mda_count > 1) {
-		log_error("%s: too many metadata areas for pvresize", pv_name);
-		goto out;
-	}
-
 	if (!(pv->fmt->features & FMT_RESIZE_PV)) {
 		log_error("Physical volume %s format does not support resizing.",
 			  pv_name);
@@ -109,39 +89,12 @@
 		size = new_size;
 	}
 
-	if (size < pv_min_size()) {
-		log_error("%s: Size must exceed minimum of %" PRIu64 " sectors.",
-			  pv_name, pv_min_size());
-		goto out;
-	}
-
-	if (size < pv_pe_start(pv)) {
-		log_error("%s: Size must exceed physical extent start of "
-			  "%" PRIu64 " sectors.", pv_name, pv_pe_start(pv));
-		goto out;
-	}
-
-	pv->size = size;
-
-	if (vg) {
-		pv->size -= pv_pe_start(pv);
-		new_pe_count = pv_size(pv) / vg->extent_size;
-
- 		if (!new_pe_count) {
-			log_error("%s: Size must leave space for at "
-				  "least one physical extent of "
-				  "%" PRIu32 " sectors.", pv_name,
-				  pv_pe_size(pv));
-			goto out;
-		}
-
-		if (!pv_resize(pv, vg, new_pe_count))
-			goto_out;
-	}
-
 	log_verbose("Resizing volume \"%s\" to %" PRIu64 " sectors.",
 		    pv_name, pv_size(pv));
 
+	if (!pv_resize(pv, vg, size))
+		goto_out;
+
 	log_verbose("Updating physical volume \"%s\"", pv_name);
 	if (!is_orphan_vg(vg_name)) {
 		if (!vg_write(vg) || !vg_commit(vg)) {


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

* LVM2 lib/format_text/format-text.c lib/metadat ...
@ 2009-01-09 22:44 wysochanski
  0 siblings, 0 replies; 4+ messages in thread
From: wysochanski @ 2009-01-09 22:44 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	wysochanski@sourceware.org	2009-01-09 22:44:34

Modified files:
	lib/format_text: format-text.c 
	lib/metadata   : metadata.h 
	lib/report     : columns.h report.c 
	man            : pvs.8.in vgs.8.in 

Log message:
	Add pv_mda_size to 'pvs' and vg_mda_size to 'vgs'.
	
	Reports the size of the smallest metadata area in a PV or a VG.
	Useful to confirm pvcreate --metadatasize or pvmetadatasize setting in
	/etc/lvm/lvm.conf file.
	
	NOTE: Actual value in these fields will most always differ from that
	given in pvcreate options due to rounding and alignment effects.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/format-text.c.diff?cvsroot=lvm2&r1=1.99&r2=1.100
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.186&r2=1.187
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/columns.h.diff?cvsroot=lvm2&r1=1.28&r2=1.29
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/report.c.diff?cvsroot=lvm2&r1=1.91&r2=1.92
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/pvs.8.in.diff?cvsroot=lvm2&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/vgs.8.in.diff?cvsroot=lvm2&r1=1.3&r2=1.4

--- LVM2/lib/format_text/format-text.c	2008/12/07 04:27:57	1.99
+++ LVM2/lib/format_text/format-text.c	2009/01/09 22:44:33	1.100
@@ -87,6 +87,13 @@
 	return mdac->free_sectors;
 }
 
+static uint64_t _mda_total_sectors_raw(struct metadata_area *mda)
+{
+	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
+
+	return mdac->area.size >> SECTOR_SHIFT;
+}
+
 /*
  * Check if metadata area belongs to vg
  */
@@ -1559,6 +1566,7 @@
 	.vg_commit = _vg_commit_raw,
 	.vg_revert = _vg_revert_raw,
 	.mda_free_sectors = _mda_free_sectors_raw,
+	.mda_total_sectors = _mda_total_sectors_raw,
 	.mda_in_vg = _mda_in_vg_raw,
 	.pv_analyze_mda = _pv_analyze_mda_raw,
 };
--- LVM2/lib/metadata/metadata.h	2008/12/19 15:24:53	1.186
+++ LVM2/lib/metadata/metadata.h	2009/01/09 22:44:33	1.187
@@ -139,6 +139,11 @@
 	uint64_t (*mda_free_sectors) (struct metadata_area *mda);
 
 	/*
+	 * Returns number of total sectors in given metadata area.
+	 */
+	uint64_t (*mda_total_sectors) (struct metadata_area *mda);
+
+	/*
 	 * Check if metadata area belongs to vg
 	 */
 	int (*mda_in_vg) (struct format_instance * fi,
--- LVM2/lib/report/columns.h	2008/04/10 17:19:02	1.28
+++ LVM2/lib/report/columns.h	2009/01/09 22:44:34	1.29
@@ -51,7 +51,8 @@
 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, "#PMdaFree", id, 9, pvmdafree, "pv_mda_free", "Free metadata area space on this device in current units.")
+FIELD(PVS, pv, NUM, "PMdaFree", id, 9, pvmdafree, "pv_mda_free", "Free metadata area space on this device in current units.")
+FIELD(PVS, pv, NUM, "PMdaSize", id, 9, pvmdasize, "pv_mda_size", "Size of smallest metadata area on this device in current units.")
 
 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.")
@@ -71,7 +72,8 @@
 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, "#VMdaFree", cmd, 9, vgmdafree, "vg_mda_free", "Free metadata area space for this VG in current units.")
+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(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.")
--- LVM2/lib/report/report.c	2008/12/15 13:30:46	1.91
+++ LVM2/lib/report/report.c	2009/01/09 22:44:34	1.92
@@ -884,6 +884,53 @@
 	return _size64_disp(rh, mem, field, &freespace, private);
 }
 
+static uint64_t _find_min_mda_size(struct dm_list *mdas)
+{
+	uint64_t min_mda_size = UINT64_MAX, mda_size;
+	struct metadata_area *mda;
+
+	dm_list_iterate_items(mda, mdas) {
+		if (!mda->ops->mda_total_sectors)
+			continue;
+		mda_size = mda->ops->mda_total_sectors(mda);
+		if (mda_size < min_mda_size)
+			min_mda_size = mda_size;
+	}
+
+	if (min_mda_size == UINT64_MAX)
+		min_mda_size = UINT64_C(0);
+
+	return min_mda_size;
+}
+
+static int _pvmdasize_disp(struct dm_report *rh, struct dm_pool *mem,
+			   struct dm_report_field *field,
+			   const void *data, void *private)
+{
+	struct lvmcache_info *info;
+	uint64_t min_mda_size;
+	const char *pvid = (const char *)(&((struct id *) data)->uuid);
+
+	info = info_from_pvid(pvid, 0);
+
+	/* PVs could have 2 mdas of different sizes (rounding effect) */
+	min_mda_size = _find_min_mda_size(&info->mdas);
+
+	return _size64_disp(rh, mem, field, &min_mda_size, private);
+}
+
+static int _vgmdasize_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;
+	uint64_t min_mda_size;
+
+	min_mda_size = _find_min_mda_size(&vg->fid->metadata_areas);
+
+	return _size64_disp(rh, mem, field, &min_mda_size, private);
+}
+
 static int _vgmdafree_disp(struct dm_report *rh, struct dm_pool *mem,
 			   struct dm_report_field *field,
 			   const void *data, void *private)
--- LVM2/man/pvs.8.in	2008/11/12 15:16:58	1.3
+++ LVM2/man/pvs.8.in	2009/01/09 22:44:34	1.4
@@ -31,7 +31,8 @@
 Comma-separated ordered list of columns.  Precede the list with '+' to append
 to the default selection of columns.  Column names are: pv_fmt, pv_uuid,
 pv_size, dev_size, pv_free, pv_used, pv_name, pv_attr, pv_pe_count, 
-pv_pe_alloc_count, pv_tags, pvseg_start, pvseg_size, pe_start.
+pv_pe_alloc_count, pv_tags, pvseg_start, pvseg_size, pe_start,
+pv_mda_count, pv_mda_free, and pv_mda_size.
 With --segments, any "pvseg_" prefixes are optional; otherwise any
 "pv_" prefixes are optional.  Columns mentioned in \fBvgs (8)\fP can also
 be chosen. The pv_attr bits are: (a)llocatable and e(x)ported.
--- LVM2/man/vgs.8.in	2008/11/12 15:16:58	1.3
+++ LVM2/man/vgs.8.in	2009/01/09 22:44:34	1.4
@@ -33,7 +33,7 @@
 to the default selection of columns.  Column names are: 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_tags, vg_mda_count, vg_mda_free, and vg_mda_size.
 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
 at the same time.  


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

end of thread, other threads:[~2011-06-15 17:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-15 17:45 LVM2 lib/format_text/format-text.c lib/metadat mornfall
  -- strict thread matches above, loose matches on Subject: below --
2011-02-21 12:31 prajnoha
2011-02-21 12:27 prajnoha
2009-01-09 22:44 wysochanski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).