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:
@ -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);
|
||||
|
@ -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"
|
||||
|
Reference in New Issue
Block a user