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

[lvm-devel] [PATCH] lvconvert --repair prompts and policies



Hi,

this is a new iteration of the patch, that hopefully addresses everyone's
concerns. For "normal" use (manual), it will prompt whether replacement of
devices is desired, with -y and -f to select yes and no respectively. Moreover,
--use-policies is provided that will read and use the lvm.conf mirror policy
settings.

We use --use-policies for dmeventd.

Yours,
   Petr.

diff -rN -u -p old-upstream/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c new-upstream/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c
--- old-upstream/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c	2009-06-02 20:50:15.580980414 +0200
+++ new-upstream/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c	2009-06-02 20:50:15.908981250 +0200
@@ -152,7 +152,7 @@ static int _remove_failed_devices(const 
 	}
 
 	/* FIXME Is any sanity-checking required on %s? */
-	if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "vgreduce --config devices{ignore_suspended_devices=1} --removemissing --force %s", vg)) {
+	if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "lvconvert --config devices{ignore_suspended_devices=1} --repair --use-policies %s/%s", vg, lv)) {
 		/* this error should be caught above, but doesn't hurt to check again */
 		syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
 		dm_pool_empty(_mem_pool);  /* FIXME: not safe with multiple threads */
diff -rN -u -p old-upstream/lib/config/defaults.h new-upstream/lib/config/defaults.h
--- old-upstream/lib/config/defaults.h	2009-06-02 20:50:15.608978525 +0200
+++ new-upstream/lib/config/defaults.h	2009-06-02 20:50:15.912981968 +0200
@@ -126,4 +126,7 @@
 #define DEFAULT_SEGS_SORT "vg_name,lv_name,seg_start"
 #define DEFAULT_PVSEGS_SORT "pv_name,pvseg_start"
 
+#define DEFAULT_MIRROR_DEVICE_FAULT_POLICY "remove"
+#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
+
 #endif				/* _LVM_DEFAULTS_H */
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	2009-06-02 20:50:15.808978596 +0200
+++ new-upstream/test/t-lvconvert-repair.sh	2009-06-02 20:50:15.964981244 +0200
@@ -22,19 +22,19 @@ disable_dev $dev1
 lvchange --partial -a y $vg/mirror
 
 not vgreduce -v --removemissing $vg
-lvconvert -i 1 --repair $vg/mirror
+lvconvert -y -i 1 --repair $vg/mirror
 vgreduce --removemissing $vg
 
 enable_dev $dev1
 vgextend $vg $dev1
 disable_dev $dev2
-lvconvert -i 1 --repair $vg/mirror
+lvconvert -y -i 1 --repair $vg/mirror
 vgreduce --removemissing $vg
 
 enable_dev $dev2
 vgextend $vg $dev2
 disable_dev $dev3
-lvconvert -i 1 --repair $vg/mirror
+lvconvert -y -i 1 --repair $vg/mirror
 vgreduce --removemissing $vg
 
 enable_dev $dev3
@@ -42,5 +42,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 -i 1 --repair $vg/mirror2
+echo 'y' | not lvconvert -y -i 1 --repair $vg/mirror2
 vgs
diff -rN -u -p old-upstream/tools/args.h new-upstream/tools/args.h
--- old-upstream/tools/args.h	2009-06-02 20:50:15.820978096 +0200
+++ new-upstream/tools/args.h	2009-06-02 20:50:15.968980565 +0200
@@ -50,6 +50,7 @@ arg(resync_ARG, '\0', "resync", NULL, 0)
 arg(corelog_ARG, '\0', "corelog", NULL, 0)
 arg(mirrorlog_ARG, '\0', "mirrorlog", string_arg, 0)
 arg(repair_ARG, '\0', "repair", NULL, 0)
+arg(use_policies_ARG, '\0', "use-policies", NULL, 0)
 arg(monitor_ARG, '\0', "monitor", yes_no_arg, 0)
 arg(config_ARG, '\0', "config", string_arg, 0)
 arg(trustcache_ARG, '\0', "trustcache", NULL, 0)
diff -rN -u -p old-upstream/tools/commands.h new-upstream/tools/commands.h
--- old-upstream/tools/commands.h	2009-06-02 20:50:15.824979722 +0200
+++ new-upstream/tools/commands.h	2009-06-02 20:50:15.968980565 +0200
@@ -94,7 +94,7 @@ xx(lvconvert,
    0,
    "lvconvert "
    "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n"
-   "\t[--repair]\n"
+   "\t[--repair [--use-policies]]\n"
    "\t[-R|--regionsize MirrorLogRegionSize]\n"
    "\t[--alloc AllocationPolicy]\n"
    "\t[-b|--background]\n"
@@ -117,7 +117,7 @@ xx(lvconvert,
 
    alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG, interval_ARG,
    mirrorlog_ARG, mirrors_ARG, regionsize_ARG, repair_ARG, snapshot_ARG,
-   test_ARG, zero_ARG)
+   test_ARG, use_policies_ARG, yes_ARG, force_ARG, zero_ARG)
 
 xx(lvcreate,
    "Create a logical volume",
diff -rN -u -p old-upstream/tools/lvconvert.c new-upstream/tools/lvconvert.c
--- old-upstream/tools/lvconvert.c	2009-06-02 20:50:15.828979183 +0200
+++ new-upstream/tools/lvconvert.c	2009-06-02 20:50:15.972982889 +0200
@@ -436,6 +436,49 @@ static struct logical_volume *_original_
 	return next_lv;
 }
 
+static int _lvconvert_mirrors_repair_ask(struct cmd_context *cmd,
+					 int failed_log, int failed_mirrors,
+					 int *replace_log, int *replace_mirrors)
+{
+	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;
+
+	if (arg_count(cmd, use_policies_ARG)) {
+		leg_policy = find_config_tree_str(cmd,
+					"activation/mirror_device_fault_policy",
+					DEFAULT_MIRROR_DEVICE_FAULT_POLICY);
+		log_policy = find_config_tree_str(cmd,
+					"activation/mirror_log_fault_policy",
+					DEFAULT_MIRROR_LOG_FAULT_POLICY);
+		*replace_mirrors = strcmp(leg_policy, "remove");
+		*replace_log = strcmp(log_policy, "remove");
+		return 1;
+	}
+
+	if (yes)
+		return 1;
+
+	if (force != PROMPT) {
+		*replace_log = *replace_mirrors = 0;
+		return 1;
+	}
+
+	if (failed_log &&
+	    yes_no_prompt("Attempt to replace failed log device? [y/n]: ") == 'n') {
+		*replace_log = 0;
+	}
+
+	if (failed_mirrors &&
+	    yes_no_prompt("Attempt to replace failed mirror devices "
+			  "(requires full device resync)? [y/n]: ") == 'n') {
+		*replace_mirrors = 0;
+	}
+}
+
 static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
 			      struct lvconvert_params *lp)
 {
@@ -449,18 +492,21 @@ static int _lvconvert_mirrors(struct cmd
 	int failed_mirrors = 0, failed_log = 0;
 	struct dm_list *old_pvh = NULL, *remove_pvs = NULL;
 
+	int repair = arg_count(cmd, repair_ARG);
+	int replace_log = 1, replace_mirrors = 1;
+
 	seg = first_seg(lv);
 	existing_mirrors = lv_mirror_count(lv);
 
 	/* If called with no argument, try collapsing the resync layers */
 	if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG) &&
 	    !arg_count(cmd, corelog_ARG) && !arg_count(cmd, regionsize_ARG) &&
-	    !arg_count(cmd, repair_ARG)) {
+	    !repair) {
 		lp->need_polling = 1;
 		return 1;
 	}
 
-	if (arg_count(cmd, mirrors_ARG) && arg_count(cmd, repair_ARG)) {
+	if (arg_count(cmd, mirrors_ARG) && repair) {
 		log_error("You can only use one of -m, --repair.");
 		return 0;
 	}
@@ -482,7 +528,7 @@ static int _lvconvert_mirrors(struct cmd
 	else
 		lp->mirrors += 1;
 
-	if (arg_count(cmd,repair_ARG)) {
+	if (repair) {
 		cmd->handles_missing_pvs = 1;
 		cmd->partial_activation = 1;
 		lp->need_polling = 0;
@@ -493,7 +539,7 @@ static int _lvconvert_mirrors(struct cmd
 		if ((failed_mirrors = _failed_mirrors_count(lv)) < 0)
 			return_0;
 		lp->mirrors -= failed_mirrors;
-		log_error("Mirror status: %d/%d legs failed.",
+		log_error("Mirror status: %d/%d mirrors failed.",
 			  failed_mirrors, existing_mirrors);
 		old_pvh = lp->pvh;
 		if (!(lp->pvh = _failed_pv_list(lv->vg)))
@@ -556,6 +602,10 @@ static int _lvconvert_mirrors(struct cmd
 		return 0;
 	}
 
+	if (repair)
+		_lvconvert_mirrors_repair_ask(cmd, failed_log, failed_mirrors,
+					      &replace_log, &replace_mirrors);
+
  restart:
 	/*
 	 * Converting from mirror to linear
@@ -573,7 +623,7 @@ static int _lvconvert_mirrors(struct cmd
 	 */
 	if (lp->mirrors < existing_mirrors) {
 		/* Reduce number of mirrors */
-		if (arg_count(cmd, repair_ARG) || lp->pv_count)
+		if (repair || lp->pv_count)
 			remove_pvs = lp->pvh;
 		if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,
 				       (corelog || lp->mirrors == 1) ? 1U : 0U,
@@ -706,13 +756,15 @@ static int _lvconvert_mirrors(struct cmd
 
 	if (failed_log || failed_mirrors) {
 		lp->pvh = old_pvh;
-		if (failed_log)
+		if (failed_log && replace_log)
 			failed_log = corelog = 0;
-		lp->mirrors += failed_mirrors;
+		if (replace_mirrors)
+			lp->mirrors += failed_mirrors;
 		failed_mirrors = 0;
 		existing_mirrors = lv_mirror_count(lv);
 		/* Now replace missing devices. */
-		goto restart;
+		if (replace_log || replace_mirrors)
+			goto restart;
 	}
 
 	if (!lp->need_polling)
-- 
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]