1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-08-13 21:49:29 +03:00

vgsplit: Make vgsplit work on mirrors with leg and log on same PV

Given a named mirror LV, vgsplit will look for the PVs that compose it
and move them to a new VG.  It does this by first looking at the log
and then the legs.  If the log is on the same device as one of the mirror
images, a problem occurs.  This is because the PV is moved to the new VG
as the log is processed and thus cannot be found in the current VG when
the image is processed.  The solution is to check and see if the PV we are
looking for has already been moved to the new VG.  If so, it is not an
error.
This commit is contained in:
Jonathan Brassow
2014-04-25 14:53:34 -05:00
parent 0ee9d59b48
commit 9ac858fe6b
2 changed files with 72 additions and 6 deletions

View File

@ -360,14 +360,23 @@ out:
return r;
}
int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
const char *pv_name)
int _move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
const char *pv_name, int enforce_pv_from_source)
{
struct physical_volume *pv;
struct pv_list *pvl;
/* FIXME: handle tags */
if (!(pvl = find_pv_in_vg(vg_from, pv_name))) {
if (!enforce_pv_from_source &&
(pvl = find_pv_in_vg(vg_to, pv_name)))
/*
* PV has already been moved. This can happen if an
* LV is being moved that has multiple sub-LVs on the
* same PV.
*/
return 1;
log_error("Physical volume %s not in volume group %s",
pv_name, vg_from->name);
return 0;
@ -391,6 +400,12 @@ int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
return 1;
}
int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
const char *pv_name)
{
return _move_pv(vg_from, vg_to, pv_name, 1);
}
int move_pvs_used_by_lv(struct volume_group *vg_from,
struct volume_group *vg_to,
const char *lv_name)
@ -418,8 +433,8 @@ int move_pvs_used_by_lv(struct volume_group *vg_from,
return_0;
for (s = 0; s < lvseg->area_count; s++) {
if (seg_type(lvseg, s) == AREA_PV) {
if (!move_pv(vg_from, vg_to,
pv_dev_name(seg_pv(lvseg, s))))
if (!_move_pv(vg_from, vg_to,
pv_dev_name(seg_pv(lvseg, s)), 0))
return_0;
} else if (seg_type(lvseg, s) == AREA_LV) {
lv = seg_lv(lvseg, s);

View File

@ -79,6 +79,10 @@ COMM "vgsplit correctly splits mirror LV into $i VG ($j args)"
lvcreate -an -Zn -l 64 --type mirror -m1 -n $lv1 $vg1 "$dev1" "$dev2" "$dev3"
if [ $j = PV ]; then
# FIXME: Not an exhaustive check of possible bad combinations
not vgsplit $vg1 $vg2 "$dev1" "$dev2"
not vgsplit $vg1 $vg2 "$dev1" "$dev3"
not vgsplit $vg1 $vg2 "$dev2" "$dev3"
vgsplit $vg1 $vg2 "$dev1" "$dev2" "$dev3"
else
vgsplit -n $lv1 $vg1 $vg2
@ -90,7 +94,27 @@ COMM "vgsplit correctly splits mirror LV into $i VG ($j args)"
fi
lvremove -f $vg2/$lv1
vgremove -f $vg2
# FIXME: ensure split /doesn't/ work when not all devs of mirror specified
# RHBZ 875903
COMM "vgsplit correctly splits mirror (log+leg on same dev) into $i VG ($j args)"
create_vg_ $vg1 "$dev1" "$dev2" "$dev3"
test $i = existing && create_vg_ $vg2 "$dev4"
lvcreate -an -Zn -l 64 --type mirror -m1 -n $lv1 $vg1 "$dev1" "$dev2"
if [ $j = PV ]; then
not vgsplit $vg1 $vg2 "$dev1"
not vgsplit $vg1 $vg2 "$dev2"
vgsplit $vg1 $vg2 "$dev1" "$dev2"
else
vgsplit -n $lv1 $vg1 $vg2
fi
if [ $i = existing ]; then
check pvlv_counts $vg2 3 1 0
else
check pvlv_counts $vg2 2 1 0
fi
lvremove -f $vg2/$lv1
vgremove -f $vg1 $vg2
COMM "vgsplit correctly splits mirror LV with mirrored log into $i VG ($j args)"
create_vg_ -c n $vg1 "$dev1" "$dev2" "$dev3" "$dev4"
@ -100,6 +124,11 @@ COMM "vgsplit correctly splits mirror LV with mirrored log into $i VG ($j args)"
"$dev1" "$dev2" "$dev3" "$dev4"
if [ $j = PV ]; then
# FIXME: Not an exhaustive check of possible bad combinations
not vgsplit $vg1 $vg2 "$dev1" "$dev2"
not vgsplit $vg1 $vg2 "$dev3" "$dev4"
not vgsplit $vg1 $vg2 "$dev1" "$dev3"
not vgsplit $vg1 $vg2 "$dev2" "$dev4"
vgsplit $vg1 $vg2 "$dev1" "$dev2" "$dev3" "$dev4"
else
vgsplit -n $lv1 $vg1 $vg2
@ -111,7 +140,29 @@ COMM "vgsplit correctly splits mirror LV with mirrored log into $i VG ($j args)"
fi
lvremove -f $vg2/$lv1
vgremove -f $vg2
# FIXME: ensure split /doesn't/ work when not all devs of mirror specified
# RHBZ 875903
COMM "vgsplit correctly splits mirror LV with mirrored log on same devs into $i VG ($j args)"
create_vg_ -c n $vg1 "$dev1" "$dev2" "$dev3" "$dev4"
test $i = existing && create_vg_ -c n $vg2 "$dev5"
lvcreate -an -Zn -l 64 --mirrorlog mirrored --type mirror -m1 -n $lv1 $vg1 \
"$dev1" "$dev2"
if [ $j = PV ]; then
not vgsplit $vg1 $vg2 "$dev1"
not vgsplit $vg1 $vg2 "$dev2"
vgsplit $vg1 $vg2 "$dev1" "$dev2"
else
vgsplit -n $lv1 $vg1 $vg2
fi
if [ $i = existing ]; then
check pvlv_counts $vg2 3 1 0
else
check pvlv_counts $vg2 2 1 0
fi
lvremove -f $vg2/$lv1
vgremove -f $vg1 $vg2
COMM "vgsplit correctly splits origin and snapshot LV into $i VG ($j args)"
create_vg_ $vg1 "$dev1" "$dev2"