]> sourceware.org Git - lvm2.git/commitdiff
Add further consistency checking to vg_validate, ensuring that all segment
authorPetr Rockai <prockai@redhat.com>
Tue, 14 Dec 2010 17:51:09 +0000 (17:51 +0000)
committerPetr Rockai <prockai@redhat.com>
Tue, 14 Dec 2010 17:51:09 +0000 (17:51 +0000)
areas point to LVs or PVs that are listed in the respective VG.

lib/metadata/metadata.c
tools/vgmerge.c
tools/vgsplit.c

index a942332adb1d7ab582b0b6b393129a086b493604..5f75a66dc3d48daabde009b6931fc0e58b0a9f65 100644 (file)
@@ -2153,6 +2153,61 @@ void lv_calculate_readahead(const struct logical_volume *lv, uint32_t *read_ahea
        }
 }
 
+/*
+ * Check that an LV and all its PV references are correctly listed in vg->lvs
+ * and vg->pvs, respectively. This only looks at a single LV, but *not* at the
+ * LVs it is using. To do the latter, you should use _lv_postorder with this
+ * function. C.f. vg_validate.
+ */
+static int _lv_validate_references_single(struct logical_volume *lv, void *data)
+{
+       struct volume_group *vg = lv->vg;
+       struct lv_segment *lvseg;
+       struct pv_list *pvl;
+       struct lv_list *lvl;
+       int s;
+       int r = 1;
+       int ok = 0;
+
+       dm_list_iterate_items(lvl, &vg->lvs) {
+               if (lvl->lv == lv) {
+                       ok = 1;
+                       break;
+               }
+       }
+
+       if (!ok) {
+               log_error(INTERNAL_ERROR
+                         "Referenced LV %s not listed in VG %s.",
+                         lv->name, vg->name);
+               r = 0;
+       }
+
+       dm_list_iterate_items(lvseg, &lv->segments) {
+               for (s = 0; s < lvseg->area_count; ++s) {
+                       if (seg_type(lvseg, s) == AREA_PV) {
+                               ok = 0;
+                               /* look up the reference in vg->pvs */
+                               dm_list_iterate_items(pvl, &vg->pvs) {
+                                       if (pvl->pv == seg_pv(lvseg, s)) {
+                                               ok = 1;
+                                               break;
+                                       }
+                               }
+
+                               if (!ok) {
+                                       log_error(INTERNAL_ERROR
+                                                 "Referenced PV %s not listed in VG %s.",
+                                                 pv_dev_name(seg_pv(lvseg, s)), vg->name);
+                                       r = 0;
+                               }
+                       }
+               }
+       }
+
+       return r;
+}
+
 int vg_validate(struct volume_group *vg)
 {
        struct pv_list *pvl, *pvl2;
@@ -2319,6 +2374,11 @@ int vg_validate(struct volume_group *vg)
                }
        }
 
+       dm_list_iterate_items(lvl, &vg->lvs) {
+               if (!_lv_postorder(lvl->lv, _lv_validate_references_single, NULL))
+                       r = 0;
+       }
+
        dm_list_iterate_items(lvl, &vg->lvs) {
                if (!(lvl->lv->status & PVMOVE))
                        continue;
index 4d55510e25abb302b79c761caf5f25c156fdc53d..391764f9a8b31d0be12fbe6e0d676c8843edc5d2 100644 (file)
@@ -114,6 +114,10 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
                }
        }
 
+       dm_list_iterate_items(lvl1, &vg_from->lvs) {
+               lvl1->lv->vg = vg_to;
+       }
+
        while (!dm_list_empty(&vg_from->lvs)) {
                struct dm_list *lvh = vg_from->lvs.n;
 
index 045c699ff57c9eb2e74ab0649a32312b06ec8cbe..bd2f0ab31e7b59d7dadebeee6c3a6b2fb741a64d 100644 (file)
@@ -34,6 +34,7 @@ static int _move_one_lv(struct volume_group *vg_from,
        struct logical_volume *lv = dm_list_item(lvh, struct lv_list)->lv;
 
        dm_list_move(&vg_to->lvs, lvh);
+       lv->vg = vg_to;
 
        if (lv_is_active(lv)) {
                log_error("Logical volume \"%s\" must be inactive", lv->name);
This page took 0.046765 seconds and 5 git commands to generate.