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

[lvm-devel] [PATCH] Handle transient errors for mirrored log in lvconvert --repair



Hi again,

Takahiro Yasui <takahiro yasui hds com> writes:
> Yes, this solution is acceptable to me. As a long term, we can introduce
> a kind of logic to keep the information of a bad segment or device and
> extend cases for 'allocate' policy.
great. I am attaching a patch proposal that would implement the outlined
policy. I have tucked in a warning for a good measure.

The patch still needs some testing, which I'd appreciate if you could
carry out. I will be away from internet starting tomorrow noon CEST and
should be back approximately Tuesday evening next week (still CEST). I
am afraid I won't have more time for this until after I return.

Yours,
   Petr.

Index: tools/lvconvert.c
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/lvconvert.c,v
retrieving revision 1.140
diff -u -p -r1.140 lvconvert.c
--- tools/lvconvert.c	13 Jul 2010 22:04:36 -0000	1.140
+++ tools/lvconvert.c	29 Jul 2010 19:50:55 -0000
@@ -625,14 +625,21 @@ static struct logical_volume *_original_
 
 static void _lvconvert_mirrors_repair_ask(struct cmd_context *cmd,
 					  int failed_log, int failed_mirrors,
-					  int *replace_log, int *replace_mirrors)
+					  int *replace_log, int *replace_mirrors,
+					  int transient_errors)
 {
 	const char *leg_policy = NULL, *log_policy = NULL;
 
 	int force = arg_count(cmd, force_ARG);
 	int yes = arg_count(cmd, yes_ARG);
 
-	*replace_log = *replace_mirrors = 1;
+	*replace_log = *replace_mirrors = 0;
+
+	if (transient_errors) {
+		log_warn("WARNING: Transient device errors encountered.\n"
+			 "Mirror image and log replacement is now forbidden.");
+		return;
+	}
 
 	if (arg_count(cmd, use_policies_ARG)) {
 		leg_policy = find_config_tree_str(cmd,
@@ -649,13 +656,13 @@ static void _lvconvert_mirrors_repair_as
 		return;
 	}
 
-	if (yes)
+	if (force != PROMPT)
 		return;
 
-	if (force != PROMPT) {
-		*replace_log = *replace_mirrors = 0;
+	*replace_log = *replace_mirrors = 1;
+
+	if (yes)
 		return;
-	}
 
 	if (failed_log &&
 	    yes_no_prompt("Attempt to replace failed mirror log? [y/n]: ") == 'n') {
@@ -696,6 +703,13 @@ static int _lv_update_mirrored_log(struc
 	int old_log_count;
 	struct logical_volume *log_lv;
 
+	/*
+	 * When log_count is 0, mirrored log doesn't need to be
+	 * updated here but it will be removed later.
+	 */
+	if (!log_count)
+		return 1;
+
 	log_lv = first_seg(_original_lv(lv))->log_lv;
 	if (!log_lv || !(log_lv->status & MIRRORED))
 		return 1;
@@ -705,12 +719,9 @@ static int _lv_update_mirrored_log(struc
 		return 1;
 
 	/* Reducing redundancy of the log */
-	if (log_count)
-		return remove_mirror_images(log_lv, log_count,
-					    is_mirror_image_removable,
-					    operable_pvs, 0U);
-
-	return remove_mirror_log(lv->vg->cmd, lv, operable_pvs);
+	return remove_mirror_images(log_lv, log_count,
+				    is_mirror_image_removable,
+				    operable_pvs, 0U);
 }
 
 static int _lv_update_log_type(struct cmd_context *cmd,
@@ -1159,6 +1170,17 @@ out_skip_log_convert:
 	return 1;
 }
 
+static int _partial_lv_count(struct volume_group *vg)
+{
+	int count = 0;
+	struct lv_list *lvl;
+	dm_list_iterate_items(lvl, &vg->lvs) {
+		if (lvl->lv->status & PARTIAL_LV)
+			++ count;
+	}
+	return count;
+}
+
 /*
  * _lvconvert_mirrors_repair
  *
@@ -1179,14 +1201,22 @@ static int _lvconvert_mirrors_repair(str
 	int failed_mirrors = 0;
 	int replace_log = 0;
 	int replace_mirrors = 0;
+	int partial_count = 0;
 	uint32_t new_log_count, log_count;
 	struct logical_volume *log_lv;
 
 	cmd->handles_missing_pvs = 1;
 	cmd->partial_activation = 1;
 	lp->need_polling = 0;
+	log_lv = first_seg(lv)->log_lv;
+
+	partial_count = -_partial_lv_count(lv->vg);
 
 	lv_check_transient(lv); /* TODO check this in lib for all commands? */
+	if (log_lv)
+		lv_check_transient(log_lv);
+
+	partial_count += _partial_lv_count(lv->vg);
 
 	if (!(lv->status & PARTIAL_LV)) {
 		log_error("%s is consistent. Nothing to repair.", lv->name);
@@ -1209,7 +1239,6 @@ static int _lvconvert_mirrors_repair(str
 	 * Count the failed log devices
 	 */
 	new_log_count = old_log_count;
-	log_lv = first_seg(lv)->log_lv;
 	if (log_lv) {
 		new_log_count = lv_mirror_count(log_lv);
 		if (log_lv->status & PARTIAL_LV) {
@@ -1229,7 +1258,7 @@ static int _lvconvert_mirrors_repair(str
 	 * Find out our policies
 	 */
 	_lvconvert_mirrors_repair_ask(cmd, failed_log, failed_mirrors,
-				      &replace_log, &replace_mirrors);
+				      &replace_log, &replace_mirrors, partial_count);
 
 	/*
 	 * First phase - remove faulty devices

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