]> sourceware.org Git - lvm2.git/commitdiff
Allow vgreduce to handle mirror log failures.
authorAlasdair Kergon <agk@redhat.com>
Thu, 11 May 2006 19:01:11 +0000 (19:01 +0000)
committerAlasdair Kergon <agk@redhat.com>
Thu, 11 May 2006 19:01:11 +0000 (19:01 +0000)
WHATS_NEW
lib/metadata/metadata.h
lib/metadata/mirror.c
tools/vgreduce.c

index d88faed9308ab57fbccbafa577b4942c2de88497..4e63dafa12eae1948629ba60d7ff556fa7254d8e 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.06 -
 =================================
+  Allow vgreduce to handle mirror log failures.
   Add --corelog to lvcreate and lvconvert.
   Create a log header for replacement in-sync mirror log.
   Use set_lv() and dev_set() to wipe sections of devices.
index 1673fd833c18680322507f9d02198e307ed5ccfb..ade86c70c6bcaab855bfbd62f183b5e403a9608b 100644 (file)
@@ -580,6 +580,8 @@ int add_mirror_layers(struct alloc_handle *ah,
 
 int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
                         struct list *removable_pvs, int remove_log);
+int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
+                             struct list *removable_pvs, int remove_log);
 /*
  * Given mirror image or mirror log segment, find corresponding mirror segment 
  */
index 84809d89744bc1794451166073809b16fc7d35e0..04bb9fa9acb7e8b9104bda67089dc6f5af24fc99 100644 (file)
@@ -230,6 +230,37 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
        return 1;
 }
 
+int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
+                             struct list *removable_pvs, int remove_log)
+{
+       int r;
+       int insync = 0;
+       int mirror_dev_failed = (mirrored_seg->area_count != num_mirrors);
+       float sync_percent = 0;
+
+       /* was the mirror in-sync before problems? */
+       if (!lv_mirror_percent(mirrored_seg->lv->vg->cmd,
+                              mirrored_seg->lv, 0, &sync_percent, NULL))
+               log_error("Unable to determine mirror sync status.");
+       else if (sync_percent >= 100.0)
+               insync = 1;
+
+       /*
+        * While we are only removing devices, we can have sync set.
+        * Setting this is only useful if we are moving to core log
+        * otherwise the disk log will contain the sync information
+        */
+       init_mirror_in_sync(insync);
+
+       r = remove_mirror_images(mirrored_seg, num_mirrors,
+                                removable_pvs, remove_log);
+       if (!r)
+               /* Unable to remove bad devices */
+               return 0;
+
+       return 1;
+}
+
 static int _create_layers_for_mirror(struct alloc_handle *ah,
                                     uint32_t first_area,
                                     uint32_t num_mirrors,
index c0f70aaf56093737f383e6db3c03784efecf8738..c637aaccd17b20f1dc976863627ed9123462ee07 100644 (file)
@@ -158,7 +158,7 @@ static int _make_vg_consistent(struct cmd_context *cmd, struct volume_group *vg)
        struct lv_segment *seg, *mirrored_seg;
        struct lv_segment_area area;
        unsigned s;
-       uint32_t mimages;
+       uint32_t mimages, remove_log;
        int list_unsafe, only_mirror_images_found;
        LIST_INIT(lvs_changed);
        only_mirror_images_found = 1;
@@ -259,7 +259,10 @@ static int _make_vg_consistent(struct cmd_context *cmd, struct volume_group *vg)
                        mirrored_seg = first_seg(lvl->lv);
                        if (!seg_is_mirrored(mirrored_seg))
                                continue;
+
                        mimages = mirrored_seg->area_count;
+                       remove_log = 0;
+
                        for (s = 0; s < mirrored_seg->area_count; s++) {
                                list_iterate_items_safe(lvl2, lvlt, &lvs_changed) {
                                        if (seg_type(mirrored_seg, s) != AREA_LV ||
@@ -272,8 +275,24 @@ static int _make_vg_consistent(struct cmd_context *cmd, struct volume_group *vg)
                                        mimages--;      /* FIXME Assumes uniqueness */
                                }
                        }
-                       if (mimages != mirrored_seg->area_count) {
-                               if (!remove_mirror_images(mirrored_seg, mimages, NULL, 0)) {
+
+                       if (mirrored_seg->log_lv) {
+                               list_iterate_items(seg, &mirrored_seg->log_lv->segments) {
+                                       /* FIXME: The second test shouldn't be required */
+                                       if ((seg->segtype ==
+                                            get_segtype_from_string(vg->cmd, "error")) ||
+                                           (!strcmp(seg->segtype->name, "error"))) {
+                                               log_print("The log device for %s/%s has failed.",
+                                                         vg->name, mirrored_seg->lv->name);
+                                               remove_log = 1;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if ((mimages != mirrored_seg->area_count) || (remove_log)){
+                               if (!reconfigure_mirror_images(mirrored_seg, mimages,
+                                                              NULL, remove_log)) {
                                        stack;
                                        return 0;
                                }
@@ -295,14 +314,20 @@ static int _make_vg_consistent(struct cmd_context *cmd, struct volume_group *vg)
 
                /* Deactivate error LVs */
                if (!test_mode()) {
-                       list_iterate_items(lvl, &lvs_changed) {
+                       list_iterate_items_safe(lvl, lvlt, &lvs_changed) {
                                log_verbose("Deactivating (if active) logical volume %s",
                                            lvl->lv->name);
 
                                if (!deactivate_lv(cmd, lvl->lv)) {
                                        log_error("Failed to deactivate LV %s",
                                                  lvl->lv->name);
-                                       return 0;
+                                       /*
+                                        * We failed to deactivate.
+                                        * Probably because this was a mirror log.
+                                        * Don't try to lv_remove it.
+                                        * Continue work on others.
+                                        */
+                                       list_del(&lvl->list);
                                }
                        }
                }
This page took 0.044882 seconds and 5 git commands to generate.