]> sourceware.org Git - lvm2.git/commitdiff
Use lvconvert --repair instead of vgreduce in mirror dmeventd DSO (mornfall)
authorMilan Broz <mbroz@redhat.com>
Thu, 4 Jun 2009 12:01:15 +0000 (12:01 +0000)
committerMilan Broz <mbroz@redhat.com>
Thu, 4 Jun 2009 12:01:15 +0000 (12:01 +0000)
Introduce lvconvert --use_policies (mornfall)

WHATS_NEW
daemons/dmeventd/plugins/mirror/dmeventd_mirror.c
doc/example.conf
lib/config/defaults.h
man/lvconvert.8.in
test/t-lvconvert-repair.sh
tools/args.h
tools/commands.h
tools/lvconvert.c

index 8844c6435d9c4e28a4c3b39d177569de9b5b7ffa..f6e04f227d573fadec90a801e629f2573b25c56d 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
 Version 2.02.48 - 
 ===============================
+  Use lvconvert --repair instead of vgreduce in mirror dmeventd DSO.
+  Introduce lvconvert --use_policies (repair policy according to lvm.conf).
   Fix clvmd-corosync to match new corosync API.
   Fix makefile to build also shared libraries when running plain make.
   Fix rename of active snapshot with virtual origin.
index fc610aea8b4794d0fe0114cb1418e91d184fcf51..4c9fcf5c4537f34ea65348fbd9c8fe3ae485cd74 100644 (file)
@@ -152,7 +152,7 @@ static int _remove_failed_devices(const char *device)
        }
 
        /* 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 */
index e06a32906695558e290e61c76f1348788647ca34..73f17c27935d91718ac2bfcc755b2a8b30779e66 100644 (file)
@@ -317,8 +317,10 @@ activation {
     # A disk log ensures that a mirror does not need to be re-synced
     # (all copies made the same) every time a machine reboots or crashes.
     #
-    # In the event of a failure, the specified policy will be used to
-    # determine what happens:
+    # In the event of a failure, the specified policy will be used to determine
+    # what happens. This applies to automatic repairs (when the mirror is being
+    # monitored by dmeventd) and to manual lvconvert --repair when
+    # --use-policies is given.
     #
     # "remove" - Simply remove the faulty device and run without it.  If
     #            the log device fails, the mirror would convert to using
@@ -338,20 +340,13 @@ activation {
     #            will preserve the mirror characteristic of the device.
     #            This policy acts like "remove" if no suitable device and
     #            space can be allocated for the replacement.
-    #            Currently this is not implemented properly and behaves
-    #            similarly to:
     #
-    # "allocate_anywhere" - Operates like "allocate", but it does not
-    #            require that the new space being allocated be on a
-    #            device is not part of the mirror.  For a log device
-    #            failure, this could mean that the log is allocated on
-    #            the same device as a mirror device.  For a mirror
-    #            device, this could mean that the mirror device is
-    #            allocated on the same device as another mirror device.
-    #            This policy would not be wise for mirror devices
-    #            because it would break the redundant nature of the
-    #            mirror.  This policy acts like "remove" if no suitable
-    #            device and space can be allocated for the replacement.
+    # "allocate_anywhere" - Not yet implemented. Useful to place the log device
+    #            temporarily on same physical volume as one of the mirror
+    #            images. This policy is not recommended for mirror devices
+    #            since it would break the redundant nature of the mirror. This
+    #            policy acts like "remove" if no suitable device and space can
+    #            be allocated for the replacement.
 
     mirror_log_fault_policy = "allocate"
     mirror_device_fault_policy = "remove"
index 605bc497576c18e711e16f46d816695b24e99561..98c023acfd3b4177091ae3f18cb01e110c29c805 100644 (file)
 #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 */
index 6c9a2ce882ed86774c72eefbd8011b3c4cf449c4..1375729e182b8466c657e2bbac4a00928d7f11c6 100644 (file)
@@ -63,8 +63,14 @@ Report progress as a percentage at regular intervals.
 .TP
 .I \-\-repair
 Repair a mirror that has suffered a disk failure. The mirror will be brought
-back into a consistent state, and if possible, the original number of
-mirrors will be restored.
+back into a consistent state, and if possible, the original number of mirrors
+will be restored, if so desired. By default, lvconvert will prompt you whether
+to perform the replacement. If you instead wish to unconditionally replace
+missing devices, you may specify \-y on the commandline and if you instead want
+no replacement to happen at all, you may provide \-f. Additionally, you may use
+"--use-policies" - this option will use the device replacement policy specified
+in lvm.conf, specifically "activation/mirror_log_fault_policy" and
+"activation/mirror_device_fault_policy".
 .br
 .TP
 .I \-s, \-\-snapshot
index 1ec927e935f3a615996bc321a44d26e52e246575..a40cd276774b4a432f380e610fda86fa94359ca4 100644 (file)
@@ -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
index f8dc02c606bd61d24301357648e573399d0e3641..846b6c2efe49be8ac03813e0242f0c5e6916b2ef 100644 (file)
@@ -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)
index eec62e3bba8af62c8f8108ae5d20f99de8656858..ee39bf917bfda34616902459ff2e9fc95cd53aea 100644 (file)
@@ -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",
index c5e63a390b1755d3e15a6c2327632d0d0107b346..47f5de751f5eba3f45be87e1c2372a6d0ac74b47 100644 (file)
@@ -457,6 +457,49 @@ static struct logical_volume *_original_lv(struct logical_volume *lv)
        return next_lv;
 }
 
+static void _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;
+       }
+
+       if (yes)
+               return;
+
+       if (force != PROMPT) {
+               *replace_log = *replace_mirrors = 0;
+               return;
+       }
+
+       if (failed_log &&
+           yes_no_prompt("Attempt to replace failed mirror log? [y/n]: ") == 'n') {
+               *replace_log = 0;
+       }
+
+       if (failed_mirrors &&
+           yes_no_prompt("Attempt to replace failed mirror images "
+                         "(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)
 {
@@ -470,18 +513,21 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
        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;
        }
@@ -503,7 +549,7 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
        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;
@@ -514,7 +560,7 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
                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 images failed.",
                          failed_mirrors, existing_mirrors);
                old_pvh = lp->pvh;
                if (!(lp->pvh = _failed_pv_list(lv->vg)))
@@ -577,6 +623,10 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
                return 0;
        }
 
+       if (repair)
+               _lvconvert_mirrors_repair_ask(cmd, failed_log, failed_mirrors,
+                                             &replace_log, &replace_mirrors);
+
  restart:
        /*
         * Converting from mirror to linear
@@ -594,7 +644,7 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
         */
        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,
@@ -727,13 +777,15 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
 
        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)
This page took 0.060581 seconds and 5 git commands to generate.