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

[lvm-devel] [PATCH] (3/6) partial activation



User documentation should be no longer TBD, as the example config and manual
page have been updated for this incarnation of the patch. It is still way more
verbose than anyone would like, when you have "invalid" configuration. That
should be addressed separately in 6/6, where we rework the --partial flag
handling.

(The table names have been fixed to be unique in presence of multiple segments
as well, since the last incarnation of the patch.)

Mon Jul 28 14:54:57 CEST 2008  me mornfall net
  * Add a segment number to the error table.
Mon Jul 28 15:16:31 CEST 2008  me mornfall net
  * Update lvm.conf manpage to reflect new missing_stripe_filler status.
Mon Jul 28 15:06:03 CEST 2008  me mornfall net
  tagged base 3
Tue Jul 22 16:27:30 CEST 2008  me mornfall net
  * Update default (example) configuration file.
Tue Jul 15 17:12:15 CEST 2008  me mornfall net
  * Remove the redundant dm->stripe_filler field.
Tue Jul 15 16:46:22 CEST 2008  me mornfall net
  * Explain the **tree hack.
Tue Jul 15 16:46:11 CEST 2008  me mornfall net
  * Use return_NULL instead of return_0 where appropriate.
Tue Jul 15 16:45:46 CEST 2008  me mornfall net
  * Don't forget to actually compute the error area size.
Mon Jul 14 16:36:24 CEST 2008  me mornfall net
  * Missed return and error handling.
Mon Jul 14 16:36:05 CEST 2008  me mornfall net
  * Missed static keywords.
Mon Jul 14 15:43:56 CEST 2008  me mornfall net
  * Backward-compatibility with missing_stripe_filler. Warn user if it does not exist.
Fri Jul 11 14:44:56 CEST 2008  me mornfall net
  tagged hotspare: partial activation 1
Sun Jun  8 13:12:30 CEST 2008  me mornfall net
  * It's better when it compiles.
Sun Jun  8 13:11:14 CEST 2008  me mornfall net
  * Use human-readable names in error tables + coding style.
Sun Jun  8 13:09:56 CEST 2008  me mornfall net
  * First working iteration of /dev/ioerror-less activation.
Sun May 11 14:11:49 CEST 2008  me mornfall net
  * Sketch out how partial activation should work without /dev/ioerror.
diff -rN -p -u old-lib-partial_activation/doc/example.conf new-lib-partial_activation/doc/example.conf
--- old-lib-partial_activation/doc/example.conf	2008-07-29 15:26:45.037489947 +0200
+++ new-lib-partial_activation/doc/example.conf	2008-07-29 15:26:45.381491048 +0200
@@ -266,11 +266,13 @@ global {
 }
 
 activation {
-    # Device used in place of missing stripes if activating incomplete volume.
-    # For now, you need to set this up yourself first (e.g. with 'dmsetup')
-    # For example, you could make it return I/O errors using the 'error' 
-    # target or make it return zeros.
-    missing_stripe_filler = "/dev/ioerror"
+    # How to fill in missing stripes if activating incomplete volume. Using
+    # "error" will make inaccessible parts of the device return I/O errors on
+    # access. You can instead use a device path -- in that case, that device
+    # will be used to substitute missing stripes. However, note that using
+    # anything else than "error" with mirrored or snapshotted volumes is
+    # likely to result in data corruption.
+    missing_stripe_filler = "error"
 
     # How much stack (in KB) to reserve for use while devices suspended
     reserved_stack = 256
diff -rN -p -u old-lib-partial_activation/lib/activate/dev_manager.c new-lib-partial_activation/lib/activate/dev_manager.c
--- old-lib-partial_activation/lib/activate/dev_manager.c	2008-07-29 15:26:45.041490334 +0200
+++ new-lib-partial_activation/lib/activate/dev_manager.c	2008-07-29 15:26:45.305491095 +0200
@@ -47,7 +47,6 @@ struct dev_manager {
 
 	struct cmd_context *cmd;
 
-	const char *stripe_filler;
 	void *target_state;
 	uint32_t pvmove_mirror_count;
 
@@ -59,8 +58,6 @@ struct lv_layer {
 	const char *old_name;
 };
 
-static const char *stripe_filler = NULL;
-
 static char *_build_dlid(struct dm_pool *mem, const char *lvid, const char *layer)
 {
 	char *dlid;
@@ -443,13 +440,6 @@ struct dev_manager *dev_manager_create(s
 	dm->cmd = cmd;
 	dm->mem = mem;
 
-	if (!stripe_filler) {
-		stripe_filler = find_config_tree_str(cmd,
-						"activation/missing_stripe_filler",
-						DEFAULT_STRIPE_FILLER);
-	}
-	dm->stripe_filler = stripe_filler;
-
 	if (!(dm->vg_name = dm_pool_strdup(dm->mem, vg_name)))
 		goto_bad;
 
@@ -699,6 +689,68 @@ bad:
 	return NULL;
 }
 
+static char *_add_error_device(struct dev_manager *dm, struct dm_tree *dtree,
+			       struct lv_segment *seg, int s)
+{
+	char *id, *name;
+	char errid[32];
+	struct dm_tree_node *node;
+	struct lv_segment *seg_i;
+	int segno = -1, i = 0;;
+	uint64_t size = seg->len * seg->lv->vg->extent_size;
+
+	list_iterate_items(seg_i, &seg->lv->segments) {
+		if (seg == seg_i)
+			segno = i;
+		++i;
+	}
+
+	if (segno < 0) {
+		log_error("_add_error_device called with bad segment");
+		return_NULL;
+	}
+
+	sprintf(errid, "missing_%d_%d", segno, s);
+
+	if (!(id = build_dlid(dm, seg->lv->lvid.s, errid))) 
+		return_NULL;
+
+	if (!(name = build_dm_name(dm->mem, seg->lv->vg->name,
+				   seg->lv->name, errid)))
+		return_NULL;
+	if (!(node = dm_tree_add_new_dev(dtree, name, id, 0, 0, 0, 0, 0)))
+		return_NULL;
+	if (!dm_tree_node_add_error_target(node, size))
+		return_NULL;
+
+	return id;
+}
+
+static int _add_error_area(struct dev_manager *dm, struct dm_tree_node *node,
+			   struct lv_segment *seg, int s)
+{
+	char *dlid;
+	uint64_t extent_size = seg->lv->vg->extent_size;
+
+	if (!strcmp(dm->cmd->stripe_filler, "error")) {
+		/*
+		 * FIXME, the tree pointer is first field of dm_tree_node, but
+		 * we don't have the struct definition available.
+		 */
+		struct dm_tree **tree = (struct dm_tree **) node;
+		dlid = _add_error_device(dm, *tree, seg, s);
+		if (!dlid)
+			return_0;
+		dm_tree_node_add_target_area(node, NULL, dlid,
+					     extent_size * seg_le(seg, s));
+	} else {
+		dm_tree_node_add_target_area(node,
+					     dm->cmd->stripe_filler,
+					     NULL, UINT64_C(0));
+	}
+	return 1;
+}
+
 int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
 		   struct dm_tree_node *node, uint32_t start_area,
 		   uint32_t areas)
@@ -712,11 +764,10 @@ int add_areas_line(struct dev_manager *d
 		     (!seg_pvseg(seg, s) ||
 		      !seg_pv(seg, s) ||
 		      !seg_dev(seg, s))) ||
-		    (seg_type(seg, s) == AREA_LV && !seg_lv(seg, s)))
-			dm_tree_node_add_target_area(node,
-							dm->stripe_filler,
-							NULL, UINT64_C(0));
-		else if (seg_type(seg, s) == AREA_PV)
+		    (seg_type(seg, s) == AREA_LV && !seg_lv(seg, s))) {
+			if (!_add_error_area(dm, node, seg, s))
+				return_0;
+		} else if (seg_type(seg, s) == AREA_PV)
 			dm_tree_node_add_target_area(node,
 							dev_name(seg_dev(seg, s)),
 							NULL,
diff -rN -p -u old-lib-partial_activation/lib/commands/toolcontext.c new-lib-partial_activation/lib/commands/toolcontext.c
--- old-lib-partial_activation/lib/commands/toolcontext.c	2008-07-29 15:26:45.041490334 +0200
+++ new-lib-partial_activation/lib/commands/toolcontext.c	2008-07-29 15:26:45.197499079 +0200
@@ -154,6 +154,7 @@ static int _process_config(struct cmd_co
 {
 	mode_t old_umask;
 	const char *read_ahead;
+	struct stat st;
 
 	/* umask */
 	cmd->default_settings.umask = find_config_tree_int(cmd,
@@ -218,6 +219,24 @@ static int _process_config(struct cmd_co
 		return 0;
 	}
 
+	cmd->stripe_filler = find_config_tree_str(cmd,
+						  "activation/missing_stripe_filler",
+						  DEFAULT_STRIPE_FILLER);
+	if (strcmp(cmd->stripe_filler, "error")) {
+		if (stat(cmd->stripe_filler, &st)) {
+			log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
+				 "is invalid,", cmd->stripe_filler);
+			log_warn("         stat failed: %s", strerror(errno));
+			log_warn("Falling back to \"error\" missing_stripe_filler.");
+			cmd->stripe_filler = "error";
+		} else if (!S_ISBLK(st.st_mode)) {
+			log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
+				 "is not a block device.", cmd->stripe_filler);
+			log_warn("Falling back to \"error\" missing_stripe_filler.");
+			cmd->stripe_filler = "error";
+		}
+	}
+
 	return 1;
 }
 
diff -rN -p -u old-lib-partial_activation/lib/commands/toolcontext.h new-lib-partial_activation/lib/commands/toolcontext.h
--- old-lib-partial_activation/lib/commands/toolcontext.h	2008-07-29 15:26:45.041490334 +0200
+++ new-lib-partial_activation/lib/commands/toolcontext.h	2008-07-29 15:26:45.197499079 +0200
@@ -81,6 +81,7 @@ struct cmd_context {
 
 	struct archive_params *archive_params;
 	struct backup_params *backup_params;
+	const char *stripe_filler;
 
 	/* List of defined tags */
 	struct list tags;
diff -rN -p -u old-lib-partial_activation/lib/config/defaults.h new-lib-partial_activation/lib/config/defaults.h
--- old-lib-partial_activation/lib/config/defaults.h	2008-07-29 15:26:45.041490334 +0200
+++ new-lib-partial_activation/lib/config/defaults.h	2008-07-29 15:26:45.381491048 +0200
@@ -91,7 +91,7 @@
 #  define DEFAULT_ACTIVATION 0
 #endif
 
-#define DEFAULT_STRIPE_FILLER "/dev/ioerror"
+#define DEFAULT_STRIPE_FILLER "error"
 #define DEFAULT_MIRROR_REGION_SIZE 512	/* KB */
 #define DEFAULT_INTERVAL 15
 
diff -rN -p -u old-lib-partial_activation/man/lvm.conf.5 new-lib-partial_activation/man/lvm.conf.5
--- old-lib-partial_activation/man/lvm.conf.5	2008-07-29 15:26:45.037489947 +0200
+++ new-lib-partial_activation/man/lvm.conf.5	2008-07-29 15:26:45.093494110 +0200
@@ -300,12 +300,16 @@ in \fBlvm\fP (8).
 .TP
 \fBactivation\fP \(em Settings affecting device-mapper activation
 .IP
-\fBmissing_stripe_filler\fP \(em When activating an incomplete
-logical volume in partial mode, this missing data is replaced
-with this device.  It could perhaps be a block device that always
-returns an error when it is accessed, or one that always
-returns zeros.  See \fBlvcreate\fP (8) for how to create
-such devices.
+\fBmissing_stripe_filler\fP \(em When activating an incomplete logical
+volume in partial mode, this option dictates how the missing data is
+replaced.  Value of "error" will cause activation to create error
+mappings for the missing data, meaning that read access to missing
+portions of the volume will result in I/O errors. You can instead also
+use a device path, and in that case, this device will be used to
+substitute missing stripes. However, note that using anything else than
+"error" with mirrored or snapshotted volumes is likely to result in data
+corruption.  For instructions on how to create a device that always
+returns zeros, see \fBlvcreate\fP (8).
 .IP
 \fBmirror_region_size\fP \(em Unit size in KB for copy operations
 when mirroring.

-- 
Peter Rockai | me()mornfall!net | prockai()redhat!com
 http://blog.mornfall.net | http://web.mornfall.net

"In My Egotistical Opinion, most people's C programs should be
 indented six feet downward and covered with dirt."
     -- Blair P. Houghton on the subject of C program indentation

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