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

Re: [lvm-devel] [PATCH] Allow incomplete mirror repairs in lvconvert --repair.



Hi,

re-sending the patch against current CVS, and with a minor bug fixed.

Petr Rockai <prockai redhat com> writes:
> the attached patch should address RHBZ 560105 and 560111. This changes
> lvconvert --repair as follows:
>
> - downconvert (like before)
> - try to replace everything (like before)
> - if the second step fails, try to reduce number of mirror images (one
>   at a time) until only 2 remain
> - if this still fails and we used to have a disk log, try 2-way + corelog
>
> This should basically give you an LV that is closest to the original
> mirror, in the space constraints of free PV areas.
>
> Please note that this patch also changes the failure/success returns of
> (manual) lvconvert --repair. As far as the initial downconversion
> succeeds -- i.e. the resulting LV is not partial, we report success.
>
> Failures to replace (part of) the failed devices are now reported as
> warnings.

Tue Mar 23 19:28:58 CET 2010  Petr Rockai <me mornfall net>
  * lvconvert --repair: Partial repair is better than none.
diff -rN -u -p old-upstream/test/t-lvconvert-repair-policy.sh new-upstream/test/t-lvconvert-repair-policy.sh
--- old-upstream/test/t-lvconvert-repair-policy.sh	2010-03-23 19:32:18.000000000 +0100
+++ new-upstream/test/t-lvconvert-repair-policy.sh	2010-03-23 19:32:18.000000000 +0100
@@ -47,9 +47,9 @@ lvs | grep mirror_mlog
 cleanup $dev1
 
 disable_dev $dev2 $dev4
-# no room for repair, downconversion should happen
+# no room for repair, corelog conversion should happen
 repair 'activation { mirror_image_fault_policy = "replace" }'
-lvs | grep -- -wi-a-
+lvs | grep -- mwi-a-
 cleanup $dev2 $dev4
 
 disable_dev $dev2 $dev4
diff -rN -u -p old-upstream/test/t-lvconvert-repair.sh new-upstream/test/t-lvconvert-repair.sh
--- old-upstream/test/t-lvconvert-repair.sh	2010-03-23 19:32:18.000000000 +0100
+++ new-upstream/test/t-lvconvert-repair.sh	2010-03-23 19:32:18.000000000 +0100
@@ -69,5 +69,5 @@ vgextend $vg $dev3
 lvcreate -m 2 -l 1 -n mirror2 $vg $dev1 $dev2 $dev3 $dev4
 vgchange -a n $vg
 pvremove -ff -y $dev4
-echo 'y' | not lvconvert -y -i 1 --repair $vg/mirror2
+echo 'y' | lvconvert -y -i 1 --repair $vg/mirror2
 vgs
diff -rN -u -p old-upstream/tools/lvconvert.c new-upstream/tools/lvconvert.c
--- old-upstream/tools/lvconvert.c	2010-03-23 19:32:18.000000000 +0100
+++ new-upstream/tools/lvconvert.c	2010-03-23 19:32:18.000000000 +0100
@@ -721,12 +721,11 @@ static int _lvconvert_mirrors(struct cmd
 	unsigned log_count = 1;
 	int r = 0;
 	struct logical_volume *log_lv, *layer_lv;
-	int failed_mirrors = 0, failed_log = 0;
+	int failed_mirrors = 0, failed_log = 0, original_log = 0;
 	struct dm_list *old_pvh = NULL, *remove_pvs = NULL, *failed_pvs = NULL;
 
-	int repair = arg_count(cmd, repair_ARG);
+	int repair = arg_is_set(cmd, repair_ARG);
 	int replace_log = 1, replace_mirrors = 1;
-	int failure_code = 0;
 
 	seg = first_seg(lv);
 	existing_mirrors = lv_mirror_count(lv);
@@ -802,6 +801,7 @@ static int _lvconvert_mirrors(struct cmd
 			failed_log = 1;
 			log_count = 0;
 		}
+		original_log = log_count;
 	} else {
 		/*
 		 * Did the user try to subtract more legs than available?
@@ -887,15 +887,15 @@ static int _lvconvert_mirrors(struct cmd
 			if (!lv_split_mirror_images(lv, lp->lv_split_name,
 						    existing_mirrors - lp->mirrors,
 						    remove_pvs))
-				return 0;
+				goto out;
 		} else if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,
 					      (!log_count || lp->mirrors == 1) ? 1U : 0U,
 					      remove_pvs, 0))
-			return_0;
+			goto_out;
 
 		if (lp->mirrors > 1 &&
 		    !_lv_update_log_type(cmd, lp, lv, log_count))
-			return_0;
+			goto_out;
 	} else if (!(lv->status & MIRRORED)) {
 		/*
 		 * Converting from linear to mirror
@@ -923,8 +923,7 @@ static int _lvconvert_mirrors(struct cmd
 						lp->region_size),
 				    log_count, lp->pvh, lp->alloc,
 				    MIRROR_BY_LV)) {
-			stack;
-			return failure_code;
+			goto_out;
 		}
 		if (lp->wait_completion)
 			lp->need_polling = 1;
@@ -945,7 +944,7 @@ static int _lvconvert_mirrors(struct cmd
 		if (lv_is_origin(lv)) {
 			log_error("Can't add additional mirror images to "
 				  "mirrors that are under snapshots");
-			return failure_code;
+			goto_out;
 		}
 
 		/*
@@ -953,10 +952,8 @@ static int _lvconvert_mirrors(struct cmd
 		 * insertion to make the end result consistent with
 		 * linear-to-mirror conversion.
 		 */
-		if (!_lv_update_log_type(cmd, lp, lv, log_count)) {
-			stack;
-			return failure_code;
-		}
+		if (!_lv_update_log_type(cmd, lp, lv, log_count))
+			goto_out;
 		/* Insert a temporary layer for syncing,
 		 * only if the original lv is using disk log. */
 		if (seg->log_lv && !_insert_lvconvert_layer(cmd, lv)) {
@@ -983,8 +980,7 @@ static int _lvconvert_mirrors(struct cmd
 					  "and dmsetup may be required.");
 				return 0;
 			}
-			stack;
-			return failure_code;
+			goto_out;
 		}
 		if (seg->log_lv)
 			lv->status |= CONVERTING;
@@ -993,10 +989,8 @@ static int _lvconvert_mirrors(struct cmd
 
 	if (lp->mirrors == existing_mirrors) {
 		if (_using_corelog(lv) != !log_count) {
-			if (!_lv_update_log_type(cmd, lp, lv, log_count)) {
-				stack;
-				return failure_code;
-			}
+			if (!_lv_update_log_type(cmd, lp, lv, log_count))
+				goto_out;
 		} else {
 			log_error("Logical volume %s already has %"
 				  PRIu32 " mirror(s).", lv->name,
@@ -1041,23 +1035,39 @@ static int _lvconvert_mirrors(struct cmd
 			lp->mirrors += failed_mirrors;
 		failed_mirrors = 0;
 		existing_mirrors = lv_mirror_count(lv);
-		/*
-		 * Ignore failure in upconversion if this is a policy-driven
-		 * action. If we got this far, only unexpected failures are
-		 * reported.
-		 */
-		if (arg_count(cmd, use_policies_ARG))
-			failure_code = 1;
+		repair = 2;
 		/* Now replace missing devices. */
 		if (replace_log || replace_mirrors)
 			goto restart;
 	}
 
+	if (repair)
+		repair = 1; /* all done */
+
 	if (!lp->need_polling)
 		log_print("Logical volume %s converted.", lv->name);
 
 	r = 1;
 out:
+	if (repair > 1 && r == 0) {
+		if (lp->mirrors > 2) {
+			lp->mirrors--;
+			goto restart;
+		} else if (log_count) {
+			log_count = 0;
+			goto restart;
+		} else
+			r = 1; /* downconvert went OK, consider this a success */
+	}
+
+	if (repair == 1 && r == 1) {
+		if (lp->mirrors != existing_mirrors)
+			log_warn("WARNING: Failed to replace %d of %d images in volume %s",
+				 existing_mirrors - lp->mirrors, existing_mirrors, lv->name);
+		if (log_count != original_log)
+			log_warn("WARNING: Failed to replace mirror log in volume %s", lv->name);
+	}
+
 	backup(lv->vg);
 	return r;
 }

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