]> sourceware.org Git - lvm2.git/commitdiff
vgsplit: Make RAID 4/5/6 fail cleanly when too few PV specified
authorJonathan Brassow <jbrassow@redhat.com>
Fri, 25 Apr 2014 21:24:50 +0000 (16:24 -0500)
committerJonathan Brassow <jbrassow@redhat.com>
Fri, 25 Apr 2014 21:24:50 +0000 (16:24 -0500)
While the 'raid1/10' segment types were being handled inadvertently
by '_move_mirrors()', the parity RAIDs were not being properly checked
to ensure that the user had specified all necessary PVs when moving
them.  Thus, internal errors were being triggered when only part of
a RAID LV was moved to the new VG.  I've added a new function,
'_move_raid()', which properly checks over any affected RAID LVs and
ensures that all the necessary PVs are being moved.

WHATS_NEW
test/shell/vgsplit-operation.sh
tools/vgsplit.c

index af9f6c3a873136dac3d85b056ae5aa79bc2d29be..3f879c9bd9598277b3027676d44debce702c73db 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.107 - 
 ==================================
+  Make vgsplit fail cleanly when not all PVs are specified for RAID 4/5/6.
   Make vgsplit work on mirrors with logs that share PVs with images.
   Use devices/ignore_suspended_devices=0 by default if not defined in lvm.conf.
   Use proper libmem mempool for allocation of unknown segment name.
index 5dbff69b2e32cdf7c01b86635e80453c72c511d3..3a8a51a6c39b7e343600b2f2e5d6d1084d9ca349 100644 (file)
@@ -238,9 +238,9 @@ COMM "vgsplit correctly splits RAID LV into $i VG ($j args)"
 
                lvcreate -an -Zn -l 64 --type raid5 -i 2 -n $lv1 $vg1
                if [ $j = PV ]; then
-#                not vgsplit $vg1 $vg2 "$dev1"
-#                not vgsplit $vg1 $vg2 "$dev2"
-#                not vgsplit $vg1 $vg2 "$dev1" "$dev2"
+                 not vgsplit $vg1 $vg2 "$dev1"
+                 not vgsplit $vg1 $vg2 "$dev2"
+                 not vgsplit $vg1 $vg2 "$dev1" "$dev2"
                  vgsplit $vg1 $vg2 "$dev1" "$dev2" "$dev3"
                else
                  vgsplit -n $lv1 $vg1 $vg2
index 9d260797359c37b54bfe93d4698ea3c26bf4ff6d..fb6791993c9c833ba97aed010513658885749fe3 100644 (file)
@@ -66,6 +66,9 @@ static int _move_lvs(struct volume_group *vg_from, struct volume_group *vg_to)
                if ((lv->status & SNAPSHOT))
                        continue;
 
+               if (lv_is_raid(lv))
+                       continue;
+
                if ((lv->status & MIRRORED))
                        continue;
 
@@ -184,6 +187,9 @@ static int _move_mirrors(struct volume_group *vg_from,
        dm_list_iterate_safe(lvh, lvht, &vg_from->lvs) {
                lv = dm_list_item(lvh, struct lv_list)->lv;
 
+               if (lv_is_raid(lv))
+                       continue;
+
                if (!(lv->status & MIRRORED))
                        continue;
 
@@ -226,6 +232,43 @@ static int _move_mirrors(struct volume_group *vg_from,
        return 1;
 }
 
+static int _move_raid(struct volume_group *vg_from,
+                     struct volume_group *vg_to)
+{
+       struct dm_list *lvh, *lvht;
+       struct logical_volume *lv;
+       struct lv_segment *seg;
+       unsigned s, seg_in;
+
+       dm_list_iterate_safe(lvh, lvht, &vg_from->lvs) {
+               lv = dm_list_item(lvh, struct lv_list)->lv;
+
+               if (!lv_is_raid(lv))
+                       continue;
+
+               seg = first_seg(lv);
+
+               seg_in = 0;
+               for (s = 0; s < seg->area_count; s++) {
+                       if (_lv_is_in_vg(vg_to, seg_lv(seg, s)))
+                               seg_in++;
+                       if (_lv_is_in_vg(vg_to, seg_metalv(seg, s)))
+                               seg_in++;
+               }
+
+               if (seg_in && seg_in != (seg->area_count * 2)) {
+                       log_error("Can't split RAID %s between "
+                                 "two Volume Groups", lv->name);
+                       return 0;
+               }
+
+               if (!_move_one_lv(vg_from, vg_to, lvh))
+                       return_0;
+       }
+
+       return 1;
+}
+
 static int _move_thins(struct volume_group *vg_from,
                       struct volume_group *vg_to)
 {
@@ -547,6 +590,10 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
                goto_bad;
 
        /* FIXME Separate the 'move' from the 'validation' to fix dev stacks */
+       /* Move required RAID across */
+       if (!(_move_raid(vg_from, vg_to)))
+               goto_bad;
+
        /* Move required mirrors across */
        if (!(_move_mirrors(vg_from, vg_to)))
                goto_bad;
This page took 0.0465179999999999 seconds and 5 git commands to generate.