mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
thin: vgsplit support for thins
Support vgsplit for VGs with thin pools and thin volumes. In case the thin data and thin metadata volumes are moved to a new VG, move there also all related thin volumes and check that external origins are also present in this new VG.
This commit is contained in:
parent
ebf0898d69
commit
fe22089edf
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.99 -
|
Version 2.02.99 -
|
||||||
===================================
|
===================================
|
||||||
|
Add support for thin volumes in vgsplit.
|
||||||
Also filter partitions on mpath components if multipath_component_detection=1.
|
Also filter partitions on mpath components if multipath_component_detection=1.
|
||||||
Add lvresize support for online thin pool metadata volume resize.
|
Add lvresize support for online thin pool metadata volume resize.
|
||||||
Add helper functions find_pool_lv() and pool_can_resize_metadata().
|
Add helper functions find_pool_lv() and pool_can_resize_metadata().
|
||||||
|
39
test/shell/vgsplit-thin.sh
Normal file
39
test/shell/vgsplit-thin.sh
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Copyright (C) 2013 Red Hat, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
# of the GNU General Public License v.2.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
# Test vgsplit command options for validity
|
||||||
|
|
||||||
|
. lib/test
|
||||||
|
|
||||||
|
aux have_thin 1 0 0 || skip
|
||||||
|
|
||||||
|
aux prepare_devs 5
|
||||||
|
|
||||||
|
vgcreate $vg1 $(cat DEVICES)
|
||||||
|
lvcreate -T -L8M $vg1/pool1 -V10M -n $lv1 "$dev1" "$dev2"
|
||||||
|
lvcreate -T -L8M $vg1/pool2 -V10M -n $lv2 "$dev3" "$dev4"
|
||||||
|
|
||||||
|
# Test with external origin if available
|
||||||
|
lvcreate -l1 -an -pr --zero n -n eorigin $vg1 "$dev5"
|
||||||
|
aux have_thin 1 5 0 && lvcreate -an -s $vg1/eorigin -n $lv3 --thinpool $vg1/pool1
|
||||||
|
|
||||||
|
# Cannot move active thin
|
||||||
|
not vgsplit $vg1 $vg2 "$dev1" "$dev2" "$dev5"
|
||||||
|
|
||||||
|
vgchange -an $vg1
|
||||||
|
not vgsplit $vg1 $vg2 "$dev1"
|
||||||
|
not vgsplit $vg1 $vg2 "$dev2" "$dev3"
|
||||||
|
vgsplit $vg1 $vg2 "$dev1" "$dev2" "$dev5"
|
||||||
|
lvs -a -o+devices $vg1 $vg2
|
||||||
|
|
||||||
|
vgmerge $vg1 $vg2
|
||||||
|
|
||||||
|
vgremove -ff $vg1
|
@ -62,6 +62,10 @@ static int _move_lvs(struct volume_group *vg_from, struct volume_group *vg_to)
|
|||||||
if ((lv->status & MIRRORED))
|
if ((lv->status & MIRRORED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (lv_is_thin_pool(lv) ||
|
||||||
|
lv_is_thin_volume(lv))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Ensure all the PVs used by this LV remain in the same */
|
/* Ensure all the PVs used by this LV remain in the same */
|
||||||
/* VG as each other */
|
/* VG as each other */
|
||||||
vg_with = NULL;
|
vg_with = NULL;
|
||||||
@ -211,6 +215,53 @@ static int _move_mirrors(struct volume_group *vg_from,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _move_thins(struct volume_group *vg_from,
|
||||||
|
struct volume_group *vg_to)
|
||||||
|
{
|
||||||
|
struct dm_list *lvh, *lvht;
|
||||||
|
struct logical_volume *lv, *data_lv;
|
||||||
|
struct lv_segment *seg;
|
||||||
|
|
||||||
|
dm_list_iterate_safe(lvh, lvht, &vg_from->lvs) {
|
||||||
|
lv = dm_list_item(lvh, struct lv_list)->lv;
|
||||||
|
|
||||||
|
if (lv_is_thin_volume(lv)) {
|
||||||
|
seg = first_seg(lv);
|
||||||
|
data_lv = seg_lv(first_seg(seg->pool_lv), 0);
|
||||||
|
if ((_lv_is_in_vg(vg_to, data_lv) ||
|
||||||
|
_lv_is_in_vg(vg_to, seg->external_lv))) {
|
||||||
|
if (_lv_is_in_vg(vg_from, seg->external_lv) ||
|
||||||
|
_lv_is_in_vg(vg_from, data_lv)) {
|
||||||
|
log_error("Can't split external origin %s "
|
||||||
|
"and pool %s between two Volume Groups.",
|
||||||
|
seg->external_lv->name,
|
||||||
|
seg->pool_lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!_move_one_lv(vg_from, vg_to, lvh))
|
||||||
|
return_0;
|
||||||
|
}
|
||||||
|
} else if (lv_is_thin_pool(lv)) {
|
||||||
|
seg = first_seg(lv);
|
||||||
|
data_lv = seg_lv(seg, 0);
|
||||||
|
if (_lv_is_in_vg(vg_to, data_lv) ||
|
||||||
|
_lv_is_in_vg(vg_to, seg->metadata_lv)) {
|
||||||
|
if (_lv_is_in_vg(vg_from, seg->metadata_lv) ||
|
||||||
|
_lv_is_in_vg(vg_from, data_lv)) {
|
||||||
|
log_error("Can't split pool data and metadata %s "
|
||||||
|
"between two Volume Groups.",
|
||||||
|
lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!_move_one_lv(vg_from, vg_to, lvh))
|
||||||
|
return_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create or open the destination of the vgsplit operation.
|
* Create or open the destination of the vgsplit operation.
|
||||||
* Returns
|
* Returns
|
||||||
@ -430,6 +481,10 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
if (!(_move_snapshots(vg_from, vg_to)))
|
if (!(_move_snapshots(vg_from, vg_to)))
|
||||||
goto_bad;
|
goto_bad;
|
||||||
|
|
||||||
|
/* Move required pools across */
|
||||||
|
if (!(_move_thins(vg_from, vg_to)))
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
/* Split metadata areas and check if both vgs have at least one area */
|
/* Split metadata areas and check if both vgs have at least one area */
|
||||||
if (!(vg_split_mdas(cmd, vg_from, vg_to)) && vg_from->pv_count) {
|
if (!(vg_split_mdas(cmd, vg_from, vg_to)) && vg_from->pv_count) {
|
||||||
log_error("Cannot split: Nowhere to store metadata for new Volume Group");
|
log_error("Cannot split: Nowhere to store metadata for new Volume Group");
|
||||||
|
Loading…
Reference in New Issue
Block a user