All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Add pvck ability to scan for labels on any area of disk
@ 2007-04-20 17:42 Dave Wysochanski
  0 siblings, 0 replies; 3+ messages in thread
From: Dave Wysochanski @ 2007-04-20 17:42 UTC (permalink / raw)
  To: lvm-devel

Add 'start_sector' parameter to label_read and _find_labeller to add
flexibility in searching for disk labels.
Should not change functional behavior.

Index: LVM2/lib/cache/lvmcache.c
===================================================================
--- LVM2.orig/lib/cache/lvmcache.c	2007-04-20 11:26:52.000000000 -0400
+++ LVM2/lib/cache/lvmcache.c	2007-04-20 13:20:28.000000000 -0400
@@ -135,7 +135,7 @@ const struct format_type *fmt_from_vgnam
 
 	list_iterate_safe(devh, tmp, &devs) {
 		devl = list_item(devh, struct device_list);
-		label_read(devl->dev, &label);
+		label_read(devl->dev, &label, UINT64_C(0));
 		list_del(&devl->list);
 		dm_free(devl);
 	}
@@ -205,7 +205,7 @@ static void _rescan_entry(struct lvmcach
 	struct label *label;
 
 	if (info->status & CACHE_INVALID)
-		label_read(info->dev, &label);
+		label_read(info->dev, &label, UINT64_C(0));
 }
 
 static int _scan_invalid(void)
@@ -247,7 +247,7 @@ int lvmcache_label_scan(struct cmd_conte
 	}
 
 	while ((dev = dev_iter_get(iter)))
-		label_read(dev, &label);
+		label_read(dev, &label, UINT64_C(0));
 
 	dev_iter_destroy(iter);
 
@@ -346,7 +346,7 @@ struct device *device_from_pvid(struct c
 
 	/* Already cached ? */
 	if ((info = info_from_pvid((char *) pvid))) {
-		if (label_read(info->dev, &label)) {
+		if (label_read(info->dev, &label, UINT64_C(0))) {
 			info = (struct lvmcache_info *) label->info;
 			if (id_equal(pvid, (struct id *) &info->dev->pvid))
 				return info->dev;
@@ -357,7 +357,7 @@ struct device *device_from_pvid(struct c
 
 	/* Try again */
 	if ((info = info_from_pvid((char *) pvid))) {
-		if (label_read(info->dev, &label)) {
+		if (label_read(info->dev, &label, UINT64_C(0))) {
 			info = (struct lvmcache_info *) label->info;
 			if (id_equal(pvid, (struct id *) &info->dev->pvid))
 				return info->dev;
@@ -371,7 +371,7 @@ struct device *device_from_pvid(struct c
 
 	/* Try again */
 	if ((info = info_from_pvid((char *) pvid))) {
-		if (label_read(info->dev, &label)) {
+		if (label_read(info->dev, &label, UINT64_C(0))) {
 			info = (struct lvmcache_info *) label->info;
 			if (id_equal(pvid, (struct id *) &info->dev->pvid))
 				return info->dev;
Index: LVM2/lib/format_text/format-text.c
===================================================================
--- LVM2.orig/lib/format_text/format-text.c	2007-04-20 11:26:52.000000000 -0400
+++ LVM2/lib/format_text/format-text.c	2007-04-20 13:20:28.000000000 -0400
@@ -1287,7 +1287,7 @@ static int _text_pv_read(const struct fo
 	}
 
 	/* FIXME Optimise out repeated reading when cache lock held */
-	if (!(label_read(dev, &label))) {
+	if (!(label_read(dev, &label, UINT64_C(0)))) {
 		stack;
 		return 0;
 	}
Index: LVM2/lib/label/label.c
===================================================================
--- LVM2.orig/lib/label/label.c	2007-04-20 11:26:52.000000000 -0400
+++ LVM2/lib/label/label.c	2007-04-20 13:24:47.000000000 -0400
@@ -107,7 +107,8 @@ struct labeller *label_get_handler(const
 }
 
 static struct labeller *_find_labeller(struct device *dev, char *buf,
-				       uint64_t *label_sector)
+				       uint64_t *label_sector,
+				       uint64_t start_sector)
 {
 	struct labeller_i *li;
 	struct labeller *r = NULL;
@@ -117,12 +118,13 @@ static struct labeller *_find_labeller(s
 	int found = 0;
 	char readbuf[LABEL_SCAN_SIZE] __attribute((aligned(8)));
 
-	if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, readbuf)) {
+	if (!dev_read(dev, start_sector << SECTOR_SHIFT,
+		      LABEL_SCAN_SIZE, readbuf)) {
 		log_debug("%s: Failed to read label area", dev_name(dev));
 		goto out;
 	}
 
-	/* Scan first few sectors for a valid label */
+	/* Scan a few sectors for a valid label */
 	for (sector = 0; sector < LABEL_SCAN_SECTORS;
 	     sector += LABEL_SIZE >> SECTOR_SHIFT) {
 		lh = (struct label_header *) (readbuf +
@@ -132,13 +134,14 @@ static struct labeller *_find_labeller(s
 			if (found) {
 				log_error("Ignoring additional label on %s at "
 					  "sector %" PRIu64, dev_name(dev),
-					  sector);
+					  sector + start_sector);
 			}
-			if (xlate64(lh->sector_xl) != sector) {
+			if (xlate64(lh->sector_xl) != sector + start_sector) {
 				log_info("%s: Label for sector %" PRIu64
 					 " found at sector %" PRIu64
 					 " - ignoring", dev_name(dev),
-					 xlate64(lh->sector_xl), sector);
+					 xlate64(lh->sector_xl),
+					 sector + start_sector);
 				continue;
 			}
 			if (calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
@@ -153,19 +156,21 @@ static struct labeller *_find_labeller(s
 		}
 
 		list_iterate_items(li, &_labellers) {
-			if (li->l->ops->can_handle(li->l, (char *) lh, sector)) {
+			if (li->l->ops->can_handle(li->l, (char *) lh,
+						   sector + start_sector)) {
 				log_very_verbose("%s: %s label detected",
 						 dev_name(dev), li->name);
 				if (found) {
 					log_error("Ignoring additional label "
 						  "on %s at sector %" PRIu64,
-						  dev_name(dev), sector);
+						  dev_name(dev),
+						  sector + start_sector);
 					continue;
 				}
 				r = li->l;
 				memcpy(buf, lh, LABEL_SIZE);
 				if (label_sector)
-					*label_sector = sector;
+					*label_sector = sector + start_sector;
 				found = 1;
 				break;
 			}
@@ -256,7 +261,8 @@ int label_remove(struct device *dev)
 }
 
 /* FIXME Avoid repeated re-reading if cache lock held */
-int label_read(struct device *dev, struct label **result)
+int label_read(struct device *dev, struct label **result,
+		uint64_t start_sector)
 {
 	char buf[LABEL_SIZE] __attribute((aligned(8)));
 	struct labeller *l;
@@ -274,7 +280,7 @@ int label_read(struct device *dev, struc
 		return r;
 	}
 
-	if (!(l = _find_labeller(dev, buf, &sector)))
+	if (!(l = _find_labeller(dev, buf, &sector, start_sector)))
 		goto_out;
 
 	if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result)
@@ -354,7 +360,7 @@ int label_verify(struct device *dev)
 		return_0;
 	}
 
-	if (!(l = _find_labeller(dev, buf, &sector)))
+	if (!(l = _find_labeller(dev, buf, &sector, UINT64_C(0))))
 		goto_out;
 
 	r = l->ops->verify ? l->ops->verify(l, buf, sector) : 1;
Index: LVM2/lib/label/label.h
===================================================================
--- LVM2.orig/lib/label/label.h	2007-04-20 11:26:52.000000000 -0400
+++ LVM2/lib/label/label.h	2007-04-20 13:20:28.000000000 -0400
@@ -96,7 +96,8 @@ int label_register_handler(const char *n
 struct labeller *label_get_handler(const char *name);
 
 int label_remove(struct device *dev);
-int label_read(struct device *dev, struct label **result);
+int label_read(struct device *dev, struct label **result,
+		uint64_t start_sector);
 int label_write(struct device *dev, struct label *label);
 int label_verify(struct device *dev);
 struct label *label_create(struct labeller *labeller);
Index: LVM2/lib/metadata/metadata.c
===================================================================
--- LVM2.orig/lib/metadata/metadata.c	2007-04-20 11:26:52.000000000 -0400
+++ LVM2/lib/metadata/metadata.c	2007-04-20 13:26:59.000000000 -0400
@@ -1403,7 +1403,7 @@ struct physical_volume *pv_read(struct c
 		return NULL;
 	}
 
-	if (!(label_read(dev, &label))) {
+	if (!(label_read(dev, &label, UINT64_C(0)))) {
 		if (warnings)
 			log_error("No physical volume label read from %s",
 				  pv_name);
Index: LVM2/tools/lvmdiskscan.c
===================================================================
--- LVM2.orig/tools/lvmdiskscan.c	2007-04-20 11:26:52.000000000 -0400
+++ LVM2/tools/lvmdiskscan.c	2007-04-20 13:20:28.000000000 -0400
@@ -112,7 +112,7 @@ int lvmdiskscan(struct cmd_context *cmd,
 	/* Do scan */
 	for (dev = dev_iter_get(iter); dev; dev = dev_iter_get(iter)) {
 		/* Try if it is a PV first */
-		if ((label_read(dev, &label))) {
+		if ((label_read(dev, &label, UINT64_C(0)))) {
 			if (!dev_get_size(dev, &size)) {
 				log_error("Couldn't get size of \"%s\"",
 					  dev_name(dev));
Index: LVM2/WHATS_NEW
===================================================================
--- LVM2.orig/WHATS_NEW	2007-04-20 13:19:01.000000000 -0400
+++ LVM2/WHATS_NEW	2007-04-20 13:21:17.000000000 -0400
@@ -1,5 +1,6 @@
 Version 2.02.25 -
 =================================
+  Add start_sector param to label_read and _find_labeller.
   Add lib/config support functions.
   Add count_chars_null and count_chars_len.
   Add dev_read_circular.




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

* [PATCH 1/2] Add pvck ability to scan for labels on any area of disk
@ 2007-04-20 17:45 Dave Wysochanski
  2007-04-23 22:04 ` [REPOST PATCH " Dave Wysochanski
  0 siblings, 1 reply; 3+ messages in thread
From: Dave Wysochanski @ 2007-04-20 17:45 UTC (permalink / raw)
  To: lvm-devel

Update pvck to read labels on disk, with flexible --labelsector
parameter.

Index: LVM2/lib/metadata/metadata.c
===================================================================
--- LVM2.orig/lib/metadata/metadata.c	2007-04-20 13:39:28.000000000 -0400
+++ LVM2/lib/metadata/metadata.c	2007-04-20 13:43:03.000000000 -0400
@@ -1555,3 +1555,39 @@ int pv_write_orphan(struct cmd_context *
 
 	return 1;
 }
+/*
+ * Returns:
+ *  0 - fail
+ *  1 - success
+ */
+int pv_analyze(struct cmd_context *cmd, const char *pv_name,
+	       int64_t label_sector)
+{
+	struct label *label;
+	struct device *dev;
+
+	/*
+	 * Take the pv directly, and ignore any filters.  We do this
+	 * because we're often in recovery mode here, and side-effects
+	 * with things like filters would probably be unexpected.
+	 */
+	dev = dev_cache_get(pv_name, NULL);
+	if (!dev)
+		goto error;
+
+	/*
+	 * First, scan for LVM labels.
+	 */
+	if (label_read(dev, &label, label_sector)) {
+		log_print("Found label on %s, sector %"PRIu64", type=%s",
+			  pv_name, label->sector, label->type);
+	} else {
+		log_error("Could not find LVM label on %s - "
+			  "try --labelsector option?", pv_name);
+		goto error;
+	}
+
+	return 1;
+ error:
+	return 0;
+}
Index: LVM2/lib/metadata/metadata.h
===================================================================
--- LVM2.orig/lib/metadata/metadata.h	2007-04-20 13:39:28.000000000 -0400
+++ LVM2/lib/metadata/metadata.h	2007-04-20 13:43:03.000000000 -0400
@@ -443,6 +443,8 @@ struct physical_volume *pv_create(const 
 				  uint64_t pvmetadatasize, struct list *mdas);
 int pv_resize(struct physical_volume *pv, struct volume_group *vg,
               uint32_t new_pe_count);
+int pv_analyze(struct cmd_context *cmd, const char *pv_name,
+	       int64_t label_sector);
 
 struct volume_group *vg_create(struct cmd_context *cmd, const char *name,
 			       uint32_t extent_size, uint32_t max_pv,
Index: LVM2/man/pvck.8
===================================================================
--- LVM2.orig/man/pvck.8	2007-04-20 13:39:28.000000000 -0400
+++ LVM2/man/pvck.8	2007-04-20 13:43:03.000000000 -0400
@@ -3,11 +3,27 @@
 pvck \- check physical volume metadata
 .SH SYNOPSIS
 .B pvck
-[\-d/\-\-debug] [\-h/\-?/\-\-help] [\-v/\-\-verbose] [PhysicalVolume...]
+.RB [ \-d | \-\-debug ]
+.RB [ \-h | \-\-help ]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-\-labelsector ]
+.IR PhysicalVolume " [" PhysicalVolume ...]
 .SH DESCRIPTION
 pvck checks physical volume LVM metadata for consistency.
 .SH OPTIONS
 See \fBlvm\fP for common options.
+.TP
+.BR \-\-labelsector " sector"
+By default the PV(s) are scanned for an LVM identifier (label) in its second
+sector (sector 1).  This lets you scan a different sector for an LVM label,
+and is useful for recovery situations.  For example, suppose the partition
+table is corrupted or lost on /dev/sda, but you know there were LVM partitions
+on it.  You can guess at the location of the partition, and pass this sector
+offset to pvck /dev/sda as the \fB--labelsector\fP parameter.  (With a script, you
+can automate this process if you are unsure about the location.)  Note that
+pvck scans a few sectors starting at labelsector (see LABEL_SCAN_SECTORS in
+the source) so you don't need to specify the exact sector for the label.
+For LVM1, you should use \fB--labelsector\fP 0.
 .SH SEE ALSO
 .BR lvm (8),
 .BR pvcreate (8),
Index: LVM2/tools/commands.h
===================================================================
--- LVM2.orig/tools/commands.h	2007-04-20 13:39:28.000000000 -0400
+++ LVM2/tools/commands.h	2007-04-20 13:43:03.000000000 -0400
@@ -412,9 +412,11 @@ xx(pvck,
    "pvck "
    "\t[-d|--debug]\n"
    "\t[-h|--help]\n"
-   "\t[-v|--verbose]\n"
+    "\t[--labelsector sector] " "\n"
+  "\t[-v|--verbose]\n"
    "\t[--version]" "\n"
-   "\tPhysicalVolume [PhysicalVolume...]\n" )
+   "\tPhysicalVolume [PhysicalVolume...]\n",
+   labelsector_ARG)
 
 xx(pvcreate,
    "Initialize physical volume(s) for use by LVM",
Index: LVM2/tools/pvck.c
===================================================================
--- LVM2.orig/tools/pvck.c	2007-04-20 13:39:28.000000000 -0400
+++ LVM2/tools/pvck.c	2007-04-20 13:43:03.000000000 -0400
@@ -15,16 +15,29 @@
 
 #include "tools.h"
 
-static int _pvck_single(struct cmd_context * cmd,
-			struct volume_group * vg,
-			struct physical_volume * pv,
-			void *handle)
-{
-	return ECMD_PROCESSED;
-}
-
 int pvck(struct cmd_context *cmd, int argc, char **argv)
 {
-	/* FIXME: Correlate findings of each PV */
-	return process_each_pv(cmd, argc, argv, NULL, NULL, _pvck_single);
+	int i;
+
+	/* FIXME: validate cmdline options */
+	/* FIXME: what does the cmdline look like? */
+	/*
+	 * Use what's on the cmdline directly, and avoid calling into
+	 * some of the other infrastructure functions, so as to avoid
+	 * hitting some of the lvmcache behavior, scanning other devices,
+	 * etc.
+	 */
+	for (i = 0; i < argc; i++) {
+		/* FIXME: warning and/or check if in use? */
+		log_verbose("Scanning %s", argv[i]);
+
+		if (!pv_analyze(cmd, argv[i],
+				arg_int64_value(cmd, labelsector_ARG,
+						DEFAULT_LABELSECTOR)))
+			goto error;
+	}
+
+	return ECMD_PROCESSED;
+ error:
+	return ECMD_FAILED;
 }
Index: LVM2/WHATS_NEW
===================================================================
--- LVM2.orig/WHATS_NEW	2007-04-20 13:39:28.000000000 -0400
+++ LVM2/WHATS_NEW	2007-04-20 13:43:03.000000000 -0400
@@ -1,5 +1,6 @@
 Version 2.02.25 -
 =================================
+  Add ability for pvck to detect LVM2 and LVM1 labels.
   Add start_sector param to label_read and _find_labeller.
   Add lib/config support functions.
   Add count_chars_null and count_chars_len.




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

* [REPOST PATCH 1/2] Add pvck ability to scan for labels on any area of disk
  2007-04-20 17:45 [PATCH 1/2] Add pvck ability to scan for labels on any area of disk Dave Wysochanski
@ 2007-04-23 22:04 ` Dave Wysochanski
  0 siblings, 0 replies; 3+ messages in thread
From: Dave Wysochanski @ 2007-04-23 22:04 UTC (permalink / raw)
  To: lvm-devel

I think all comments incorporated / addressed.

Update pvck to read labels on disk, with flexible --labelsector
parameter.

Index: LVM2-label-read/lib/metadata/metadata.c
===================================================================
--- LVM2-label-read.orig/lib/metadata/metadata.c	2007-04-23 14:21:01.000000000 -0400
+++ LVM2-label-read/lib/metadata/metadata.c	2007-04-23 17:53:02.000000000 -0400
@@ -1555,3 +1555,35 @@ int pv_write_orphan(struct cmd_context *
 
 	return 1;
 }
+/*
+ * Returns:
+ *  0 - fail
+ *  1 - success
+ */
+int pv_analyze(struct cmd_context *cmd, const char *pv_name,
+	       int64_t label_sector)
+{
+	struct label *label;
+	struct device *dev;
+
+	dev = dev_cache_get(pv_name, cmd->filter);
+	if (!dev) {
+		log_error("Device %s not found (or ignored by filtering).",
+			  pv_name);
+		return 0;
+	}
+
+	/*
+	 * First, scan for LVM labels.
+	 */
+	if (!label_read(dev, &label, label_sector)) {
+		log_error("Could not find LVM label on %s",
+			  pv_name);
+		return 0;
+	}
+
+	log_print("Found label on %s, sector %"PRIu64", type=%s",
+		  pv_name, label->sector, label->type);
+
+	return 1;
+}
Index: LVM2-label-read/lib/metadata/metadata.h
===================================================================
--- LVM2-label-read.orig/lib/metadata/metadata.h	2007-03-23 08:43:17.000000000 -0400
+++ LVM2-label-read/lib/metadata/metadata.h	2007-04-23 15:13:43.000000000 -0400
@@ -443,6 +443,8 @@ struct physical_volume *pv_create(const 
 				  uint64_t pvmetadatasize, struct list *mdas);
 int pv_resize(struct physical_volume *pv, struct volume_group *vg,
               uint32_t new_pe_count);
+int pv_analyze(struct cmd_context *cmd, const char *pv_name,
+	       int64_t label_sector);
 
 struct volume_group *vg_create(struct cmd_context *cmd, const char *name,
 			       uint32_t extent_size, uint32_t max_pv,
Index: LVM2-label-read/man/pvck.8
===================================================================
--- LVM2-label-read.orig/man/pvck.8	2007-03-30 17:00:25.000000000 -0400
+++ LVM2-label-read/man/pvck.8	2007-04-23 17:31:28.000000000 -0400
@@ -3,11 +3,29 @@
 pvck \- check physical volume metadata
 .SH SYNOPSIS
 .B pvck
-[\-d/\-\-debug] [\-h/\-?/\-\-help] [\-v/\-\-verbose] [PhysicalVolume...]
+.RB [ \-d | \-\-debug ]
+.RB [ \-h | \-\-help ]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-\-labelsector ]
+.IR PhysicalVolume " [" PhysicalVolume ...]
 .SH DESCRIPTION
 pvck checks physical volume LVM metadata for consistency.
 .SH OPTIONS
 See \fBlvm\fP for common options.
+.TP
+.BR \-\-labelsector " sector"
+By default, 4 sectors of \fBPhysicalVolume\fP are scanned for an LVM label,
+starting at sector 0.  This parameter allows you to specify a different
+starting sector for the scan and is useful for recovery situations.  For
+example, suppose the partition table is corrupted or lost on /dev/sda,
+but you suspect there was an LVM partition at approximately 100 MB.  This
+area of the disk may be scanned by using the \fB--labelsector\fP parameter
+with a value of 204800 (100 * 1024 * 1024 / 512 = 204800):
+.sp
+.BI "pvck --labelsector 204800 /dev/sda"
+.sp
+Note that a script can be used with \fB--labelsector\fP to automate the
+process of finding LVM labels.
 .SH SEE ALSO
 .BR lvm (8),
 .BR pvcreate (8),
Index: LVM2-label-read/tools/commands.h
===================================================================
--- LVM2-label-read.orig/tools/commands.h	2007-03-30 17:00:26.000000000 -0400
+++ LVM2-label-read/tools/commands.h	2007-04-23 17:57:03.000000000 -0400
@@ -412,9 +412,12 @@ xx(pvck,
    "pvck "
    "\t[-d|--debug]\n"
    "\t[-h|--help]\n"
+   "\t[--labelsector sector] " "\n"
    "\t[-v|--verbose]\n"
    "\t[--version]" "\n"
-   "\tPhysicalVolume [PhysicalVolume...]\n" )
+   "\tPhysicalVolume [PhysicalVolume...]\n",
+
+   labelsector_ARG)
 
 xx(pvcreate,
    "Initialize physical volume(s) for use by LVM",
Index: LVM2-label-read/tools/pvck.c
===================================================================
--- LVM2-label-read.orig/tools/pvck.c	2007-03-30 17:00:26.000000000 -0400
+++ LVM2-label-read/tools/pvck.c	2007-04-23 17:33:00.000000000 -0400
@@ -15,16 +15,26 @@
 
 #include "tools.h"
 
-static int _pvck_single(struct cmd_context * cmd,
-			struct volume_group * vg,
-			struct physical_volume * pv,
-			void *handle)
-{
-	return ECMD_PROCESSED;
-}
-
 int pvck(struct cmd_context *cmd, int argc, char **argv)
 {
-	/* FIXME: Correlate findings of each PV */
-	return process_each_pv(cmd, argc, argv, NULL, NULL, _pvck_single);
+	int i;
+
+	/* FIXME: validate cmdline options */
+	/* FIXME: what does the cmdline look like? */
+	/*
+	 * Use what's on the cmdline directly, and avoid calling into
+	 * some of the other infrastructure functions, so as to avoid
+	 * hitting some of the lvmcache behavior, scanning other devices,
+	 * etc.
+	 */
+	for (i = 0; i < argc; i++) {
+		/* FIXME: warning and/or check if in use? */
+		log_verbose("Scanning %s", argv[i]);
+
+		pv_analyze(cmd, argv[i],
+			   arg_int64_value(cmd, labelsector_ARG,
+					   UINT64_C(0)));
+	}
+
+	return ECMD_PROCESSED;
 }






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

end of thread, other threads:[~2007-04-23 22:04 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-20 17:45 [PATCH 1/2] Add pvck ability to scan for labels on any area of disk Dave Wysochanski
2007-04-23 22:04 ` [REPOST PATCH " Dave Wysochanski
  -- strict thread matches above, loose matches on Subject: below --
2007-04-20 17:42 [PATCH " Dave Wysochanski

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.