2020-11-11 02:41:04 +03:00
#!/usr/bin/env bash
# Copyright (C) 2018 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, MA 02110-1301 USA
SKIP_WITH_LVMPOLLD = 1
. lib/inittest
which mkfs.xfs || skip
which xfs_growfs || skip
2021-03-20 11:54:30 +03:00
aux have_integrity 1 5 0 || skip
# Avoid 4K ramdisk devices on older kernels
aux kernel_at_least 5 10 || export LVM_TEST_PREFER_BRD = 0
2020-11-11 02:41:04 +03:00
mnt = "mnt"
mkdir -p $mnt
aux prepare_devs 3 40
# Use awk instead of anoyingly long log out from printf
#printf "%0.sA" {1..16384} >> fileA
awk 'BEGIN { while (z++ < 16384) printf "A" }' > fileA
awk 'BEGIN { while (z++ < 16384) printf "B" }' > fileB
awk 'BEGIN { while (z++ < 16384) printf "C" }' > fileC
_prepare_vg( ) {
# zero devs so we are sure to find the correct file data
# on the underlying devs when corrupting it
dd if = /dev/zero of = " $dev1 " bs = 1M oflag = direct || true
dd if = /dev/zero of = " $dev2 " bs = 1M oflag = direct || true
dd if = /dev/zero of = " $dev3 " bs = 1M oflag = direct || true
vgcreate $SHARED $vg " $dev1 " " $dev2 " " $dev3 "
pvs
}
_test1( ) {
mkfs.xfs -f -s size = 4096 " $DM_DEV_DIR / $vg / $lv1 "
mount " $DM_DEV_DIR / $vg / $lv1 " $mnt
# we don't want fileA to be located too early in the fs,
# otherwise activating the LV will trigger the corruption
# to be found and corrected, leaving nothing for syncaction
# to find and correct.
dd if = /dev/urandom of = $mnt /rand16M bs = 1M count = 16
cp fileA $mnt
cp fileB $mnt
cp fileC $mnt
umount $mnt
lvchange -an $vg /$lv1
xxd " $dev1 " > dev1.txt
# corrupt fileB
sed -e 's/4242 4242 4242 4242 4242 4242 4242 4242/4242 4242 4242 4242 4242 4242 4242 4243/' dev1.txt > dev1.bad
rm -f dev1.txt
xxd -r dev1.bad > " $dev1 "
rm -f dev1.bad
lvchange -ay $vg /$lv1
lvs -o integritymismatches $vg /${ lv1 } _rimage_0 | tee mismatch
grep 0 mismatch
lvchange --syncaction check $vg /$lv1
_wait_recalc $vg /$lv1
lvs -o integritymismatches $vg /${ lv1 } _rimage_0 | tee mismatch
not grep 0 mismatch
mount " $DM_DEV_DIR / $vg / $lv1 " $mnt
cmp -b $mnt /fileA fileA
cmp -b $mnt /fileB fileB
cmp -b $mnt /fileC fileC
umount $mnt
}
_test2( ) {
mkfs.xfs -f -s size = 4096 " $DM_DEV_DIR / $vg / $lv1 "
mount " $DM_DEV_DIR / $vg / $lv1 " $mnt
# we don't want fileA to be located too early in the fs,
# otherwise activating the LV will trigger the corruption
# to be found and corrected, leaving nothing for syncaction
# to find and correct.
dd if = /dev/urandom of = $mnt /rand16M bs = 1M count = 16
cp fileA $mnt
cp fileB $mnt
cp fileC $mnt
umount $mnt
lvchange -an $vg /$lv1
# corrupt fileB and fileC on dev1
xxd " $dev1 " > dev1.txt
sed -e 's/4242 4242 4242 4242 4242 4242 4242 4242/4242 4242 4242 4242 4242 4242 4242 4243/' dev1.txt > dev1.bad
sed -e 's/4343 4343 4343 4343 4343 4343 4343 4343/4444 4444 4444 4444 4444 4444 4444 4444/' dev1.txt > dev1.bad
rm -f dev1.txt
xxd -r dev1.bad > " $dev1 "
rm -f dev1.bad
# corrupt fileA on dev2
xxd " $dev2 " > dev2.txt
sed -e 's/4141 4141 4141 4141 4141 4141 4141 4141/4141 4141 4141 4141 4141 4141 4145 4141/' dev2.txt > dev2.bad
rm -f dev2.txt
xxd -r dev2.bad > " $dev2 "
rm -f dev2.bad
lvchange -ay $vg /$lv1
lvs -o integritymismatches $vg /${ lv1 } _rimage_0 | tee mismatch
grep 0 mismatch
lvs -o integritymismatches $vg /${ lv1 } _rimage_1 | tee mismatch
grep 0 mismatch
lvchange --syncaction check $vg /$lv1
_wait_recalc $vg /$lv1
lvs -o integritymismatches $vg /${ lv1 } _rimage_0 | tee mismatch
not grep 0 mismatch
lvs -o integritymismatches $vg /${ lv1 } _rimage_1 | tee mismatch
not grep 0 mismatch
mount " $DM_DEV_DIR / $vg / $lv1 " $mnt
cmp -b $mnt /fileA fileA
cmp -b $mnt /fileB fileB
cmp -b $mnt /fileC fileC
umount $mnt
}
_sync_percent( ) {
local checklv = $1
get lv_field " $checklv " sync_percent | cut -d. -f1
}
_wait_recalc( ) {
local checklv = $1
for i in $( seq 1 10) ; do
sync = $( _sync_percent " $checklv " )
echo " sync_percent is $sync "
if test " $sync " = "100" ; then
return
fi
sleep 1
done
# TODO: There is some strange bug, first leg of RAID with integrity
# enabled never gets in sync. I saw this in BB, but not when executing
# the commands manually
if test -z " $sync " ; then
echo " TEST\ WARNING: Resync of dm-integrity device ' $checklv ' failed "
dmsetup status " $DM_DEV_DIR /mapper/ ${ checklv / \/ /- } "
exit
fi
echo "timeout waiting for recalc"
return 1
}
_prepare_vg
lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -l 6 $vg " $dev1 " " $dev2 "
_wait_recalc $vg /${ lv1 } _rimage_0
_wait_recalc $vg /${ lv1 } _rimage_1
_wait_recalc $vg /$lv1
_test1
2020-11-12 00:13:46 +03:00
lvs -o integritymismatches $vg /$lv1 | tee mismatch
not grep 0 mismatch
2020-11-11 02:41:04 +03:00
lvchange -an $vg /$lv1
lvconvert --raidintegrity n $vg /$lv1
lvremove $vg /$lv1
vgremove -ff $vg
_prepare_vg
lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -l 6 $vg " $dev1 " " $dev2 "
_wait_recalc $vg /${ lv1 } _rimage_0
_wait_recalc $vg /${ lv1 } _rimage_1
_wait_recalc $vg /$lv1
_test2
2020-11-12 00:13:46 +03:00
lvs -o integritymismatches $vg /$lv1 | tee mismatch
not grep 0 mismatch
2020-11-11 02:41:04 +03:00
lvchange -an $vg /$lv1
lvconvert --raidintegrity n $vg /$lv1
lvremove $vg /$lv1
vgremove -ff $vg
_prepare_vg
lvcreate --type raid5 --raidintegrity y -n $lv1 -l 6 $vg " $dev1 " " $dev2 " " $dev3 "
_wait_recalc $vg /${ lv1 } _rimage_0
_wait_recalc $vg /${ lv1 } _rimage_1
_wait_recalc $vg /${ lv1 } _rimage_2
_wait_recalc $vg /$lv1
_test1
2020-11-12 00:13:46 +03:00
lvs -o integritymismatches $vg /$lv1 | tee mismatch
not grep 0 mismatch
2020-11-11 02:41:04 +03:00
lvchange -an $vg /$lv1
lvconvert --raidintegrity n $vg /$lv1
lvremove $vg /$lv1
vgremove -ff $vg