mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
vgsplit: Make RAID 4/5/6 fail cleanly when too few PV specified
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.
This commit is contained in:
parent
4dffb9fca9
commit
3c4234f825
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user