mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
313 lines
8.2 KiB
Bash
313 lines
8.2 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# Copyright (C) 2024 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., 51 Franklin Street, Fifth Floor, Boston, MA2110-1301 USA
|
|
|
|
LVM_SKIP_LARGE_TESTS=1
|
|
SKIP_RESIZE=0
|
|
|
|
. lib/inittest
|
|
|
|
which mkfs.ext4 || skip
|
|
[ $SKIP_RESIZE -eq 0 ] && ( which resize2fs || skip )
|
|
|
|
aux kernel_at_least 6 9 0 || skip
|
|
|
|
test "$(aux total_mem)" -gt 1048576 || skip "Not enough RAM for this test"
|
|
|
|
# List of stripes to add or remove
|
|
tst_stripes=""
|
|
|
|
# Delay on first 'PV' to be able to retrieve status during reshape.
|
|
# Needs to be varied depending on layout as they come with different reshape overhead.
|
|
ms=0
|
|
|
|
# PV numbers and size
|
|
npvs=0
|
|
pvsz=0
|
|
|
|
function _get_pvs_stripes_and_delay
|
|
{
|
|
local raid_type=$1
|
|
|
|
case $LVM_SKIP_LARGE_TESTS in
|
|
0)
|
|
npvs=64
|
|
pvsz=32
|
|
|
|
case $raid_type in
|
|
raid[45]*)
|
|
ms=30
|
|
tst_stripes="5 4 11 9 15 13 19 18 22 21 25 23 28 30 31 29 33 31 34 33 37 45 41 50 55 60 63 30 15 10 8 3"
|
|
;;
|
|
raid6*)
|
|
ms=20
|
|
tst_stripes="5 4 11 9 15 13 19 18 22 21 25 23 28 30 31 29 33 31 34 33 37 45 41 50 55 60 62 30 15 10 8 3"
|
|
;;
|
|
raid10*)
|
|
ms=50
|
|
tst_stripes="5 8 9 11 13 14 15 19 20 22 23 25 27 28 29 32"
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
npvs=20
|
|
pvsz=16
|
|
|
|
case $raid_type in
|
|
raid[45]*)
|
|
ms=40
|
|
tst_stripes="5 4 8 7 11 9 15 19 18 10"
|
|
;;
|
|
raid6*)
|
|
ms=25
|
|
tst_stripes="5 4 8 7 11 9 15 18 10 5"
|
|
;;
|
|
raid10*)
|
|
ms=40
|
|
tst_stripes="5 6 7 8 9 10"
|
|
;;
|
|
esac
|
|
esac
|
|
}
|
|
|
|
function _get_size
|
|
{
|
|
local vg=$1
|
|
local lv=$2
|
|
local data_stripes=$3
|
|
local reshape_len rimagesz
|
|
|
|
# Get any reshape size in sectors
|
|
reshape_len=$(lvs --noheadings -aoname,reshapelen --unit s $vg/${lv}_rimage_0|head -1|cut -d ']' -f2)
|
|
reshape_len=$(echo ${reshape_len/S}|xargs)
|
|
|
|
# Get rimage size - reshape length
|
|
rimagesz=$(($(blockdev --getsz /dev/mapper/${vg}-${lv}_rimage_0) - $reshape_len))
|
|
|
|
# Calculate size of LV based on above sizes
|
|
echo $(($rimagesz * $data_stripes))
|
|
}
|
|
|
|
function _check_size
|
|
{
|
|
local vg=$1
|
|
local lv=$2
|
|
local data_stripes=$3
|
|
|
|
# Compare size of LV with calculated one
|
|
[ $(blockdev --getsz /dev/$vg/$lv) -eq $(_get_size $vg $lv $data_stripes) ] && echo 0 || echo 1
|
|
}
|
|
|
|
function _total_stripes
|
|
{
|
|
local raid_type=$1
|
|
local data_stripes=$2
|
|
|
|
case $raid_type in
|
|
raid[45]*) echo $(($data_stripes + 1)) ;;
|
|
raid6*) echo $(($data_stripes + 2)) ;;
|
|
raid10*) echo $(($data_stripes * 2)) ;;
|
|
esac
|
|
}
|
|
|
|
function _lvcreate
|
|
{
|
|
local raid_type=$1
|
|
local data_stripes=$2
|
|
local size=$3
|
|
local vg=$4
|
|
local lv=$5
|
|
shift 5
|
|
local opts="$*"
|
|
local stripes=$(_total_stripes $raid_type $data_stripes)
|
|
|
|
lvcreate -y -aey --type $raid_type -i $data_stripes -L $size -n $lv $vg $opts
|
|
|
|
check lv_first_seg_field $vg/$lv segtype "$raid_type"
|
|
check lv_first_seg_field $vg/$lv datastripes $data_stripes
|
|
check lv_first_seg_field $vg/$lv stripes $stripes
|
|
|
|
mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
}
|
|
|
|
function _reshape_layout
|
|
{
|
|
local raid_type=$1
|
|
local data_stripes=$2
|
|
local vg=$3
|
|
local lv=$4
|
|
local wait_for_reshape=$5
|
|
local ignore_a_chars=$6
|
|
shift 6
|
|
local opts="$*"
|
|
local stripes=$(_total_stripes $raid_type $data_stripes)
|
|
|
|
# Avoid random udev sync delays causing _check_size to be unreliable
|
|
lvconvert -y --noudevsync --ty $raid_type --stripes $data_stripes $opts $vg/$lv
|
|
check lv_first_seg_field $vg/$lv1 segtype "$raid_type"
|
|
|
|
if [ $wait_for_reshape -eq 1 ]
|
|
then
|
|
aux wait_for_sync $vg $lv $ignore_a_chars
|
|
fsck -fn "$DM_DEV_DIR/$vg/$lv"
|
|
fi
|
|
}
|
|
|
|
function _add_stripes
|
|
{
|
|
local raid_type=$1
|
|
local vg=$2
|
|
local lv=$3
|
|
local data_stripes=$4
|
|
local stripes=$(_total_stripes $raid_type $data_stripes)
|
|
local stripesize="$((16 << ($data_stripes % 5))).00k" # Stripe size variation
|
|
|
|
aux delay_dev "$dev1" $ms 0
|
|
_reshape_layout $raid_type $data_stripes $vg $lv 0 1 --stripesize $stripesize
|
|
|
|
# Size has to be inconsistent until reshape finishes
|
|
[ $(_check_size $vg $lv $data_stripes) -ne 0 ] || die "LV size should be small"
|
|
|
|
check lv_first_seg_field $vg/$lv stripesize "$stripesize"
|
|
check lv_first_seg_field $vg/$lv datastripes $data_stripes
|
|
check lv_first_seg_field $vg/$lv stripes $stripes
|
|
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
aux delay_dev "$dev1" 0 0
|
|
aux wait_for_sync $vg $lv 0
|
|
sleep 1
|
|
|
|
# Now size consistency has to be fine
|
|
[ $(_check_size $vg $lv $data_stripes) -eq 0 ] || die "LV size should be grown"
|
|
|
|
# Check, use grown capacity for the filesystem and check again
|
|
if [ $SKIP_RESIZE -eq 0 ]
|
|
then
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
resize2fs "$DM_DEV_DIR/$vg/$lv"
|
|
fi
|
|
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
|
|
udevadm settle
|
|
}
|
|
|
|
function _remove_stripes
|
|
{
|
|
local raid_type=$1
|
|
local vg=$2
|
|
local lv=$3
|
|
local data_stripes=$4
|
|
local cur_data_stripes=$(get lv_field "$vg/$lv" datastripes -a)
|
|
local stripes=$(get lv_field "$vg/$lv" stripes -a)
|
|
local stripesize="$((16 << ($data_stripes % 5))).00k" # Stripe size variation
|
|
|
|
# Check, shrink hilesystem to the resulting smaller size and check again
|
|
if [ $SKIP_RESIZE -eq 0 ]
|
|
then
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
resize2fs "$DM_DEV_DIR/$vg/$lv" $(_get_size $vg $lv $data_stripes)s
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
fi
|
|
|
|
aux delay_dev "$dev1" $ms 0
|
|
_reshape_layout $raid_type $data_stripes $vg $lv 0 1 --force --stripesize $stripesize
|
|
|
|
# Size has to be inconsistent, as to be removed legs still exist
|
|
[ $(_check_size $vg $lv $cur_data_stripes) -ne 0 ] || die "LV size should be reduced but not rimage count"
|
|
|
|
check lv_first_seg_field $vg/$lv stripesize "$stripesize"
|
|
check lv_first_seg_field $vg/$lv datastripes $data_stripes
|
|
check lv_first_seg_field $vg/$lv stripes $stripes
|
|
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
|
|
# Have to remove freed legs before another restriping conversion. Will fail while reshaping is ongoing as stripes are still in use
|
|
not _reshape_layout $raid_type $(($data_stripes + 1)) 0 1 $vg $lv --force
|
|
aux delay_dev "$dev1" 0 0
|
|
aux wait_for_sync $vg $lv 1
|
|
|
|
# Remove freed legs as they are now idle has to succeed without --force
|
|
_reshape_layout $raid_type $data_stripes $vg $lv 1 1
|
|
check lv_first_seg_field $vg/$lv datastripes $data_stripes
|
|
check lv_first_seg_field $vg/$lv stripes $(_total_stripes $raid_type $data_stripes)
|
|
|
|
sleep 1
|
|
|
|
# Now size consistency has to be fine
|
|
[ $(_check_size $vg $lv $data_stripes) -eq 0 ] || die "LV size should be completely reduced"
|
|
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
|
|
udevadm settle
|
|
}
|
|
|
|
function _test
|
|
{
|
|
local vg=$1
|
|
local lv=$2
|
|
local raid_type=$3
|
|
local data_stripes=$4
|
|
local cur_data_stripes
|
|
|
|
_get_pvs_stripes_and_delay $raid_type
|
|
|
|
aux prepare_pvs $npvs $pvsz
|
|
get_devs
|
|
|
|
vgcreate $SHARED -s 1M "$vg" "${DEVICES[@]}"
|
|
|
|
# Calculate maximum rimage size in MiB and subtract 3 extents to leave room for rounding
|
|
rimagesz=$(($(blockdev --getsz "$dev1") / 2048 - 3))
|
|
|
|
# Create (data_stripes+1)-way striped $raid_type
|
|
_lvcreate $raid_type $data_stripes $(($data_stripes * ${rimagesz}))M $vg $lv --stripesize 128k
|
|
[ $(_check_size $vg $lv $data_stripes) -eq 0 ] || die "LV size bogus"
|
|
check lv_first_seg_field $vg/$lv stripesize "128.00k"
|
|
aux wait_for_sync $vg $lv 0
|
|
|
|
# Delay its first 'PV' so that size can be evaluated before reshape finished too quick.
|
|
aux delay_dev "$dev1" $ms 0
|
|
|
|
# Reshape it to one more stripe and 256K stripe size
|
|
_reshape_layout $raid_type $(($data_stripes + 1)) $vg $lv 0 0 --stripesize 256K
|
|
[ $(_check_size $vg $lv $(($data_stripes + 1))) -ne 0 ] || die "LV size should still be small"
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
|
|
# Reset delay
|
|
aux delay_dev "$dev1" 0 0
|
|
|
|
# Wait for sync to finish to check frow extended LV size
|
|
aux wait_for_sync $vg $lv 0
|
|
|
|
[ $(_check_size $vg $lv $(($data_stripes + 1))) -eq 0 ] || die "LV size should be grown"
|
|
fsck -fy "$DM_DEV_DIR/$vg/$lv"
|
|
udevadm settle
|
|
|
|
# Loop adding stripes and check size consistency on each iteration
|
|
for data_stripes in $tst_stripes
|
|
do
|
|
cur_data_stripes=$(get lv_field "$vg/$lv" datastripes -a)
|
|
[ $cur_data_stripes -lt $data_stripes ] && _add_stripes $raid_type $vg $lv $data_stripes \
|
|
|| _remove_stripes $raid_type $vg $lv $data_stripes
|
|
done
|
|
|
|
vgremove -ff $vg
|
|
aux remove_dm_devs "${DEVICES[@]}"
|
|
}
|
|
|
|
# Test all respective RAID levels
|
|
_test $vg $lv1 raid4 2
|
|
_test $vg $lv1 raid5_ra 2
|
|
_test $vg $lv1 raid6_nc 3
|
|
_test $vg $lv1 raid10 2
|