mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-11 20:58:50 +03:00
dm-integrity stores checksums of the data written to an LV, and returns an error if data read from the LV does not match the previously saved checksum. When used on raid images, dm-raid will correct the error by reading the block from another image, and the device user sees no error. Create a linear LV with an integrity layer above it: lvcreate --type integrity --integrity String [options] Create a raid LV with an integrity layer over each raid image (for raid levels 1,4,5,6): lvcreate --type raidN --integrity y [options] Add an integrity layer to an existing linear LV, or to each image of an existing raid LV: lvconvert --integrity y LV Remove the integrity layer from a linear LV, or from the images of a raid LV: lvconvert --integrity n LV Integrity metadata: The --integrity String specifies if the dm-integrity metadata (checksums) should be interleaved with data blocks, or written to a separate external LV. --integrity external (default) Use integrity with metadata on a separate LV. Allows removing integrity from the LV later. --integrity y Same as integrity external. --integrity n Remove integrity (external metadata only.) --integrity internal Use integrity with metadata interleaved with data on the same LV. Only allowed with new linear LVs. Internal integrity cannot be removed from an LV. Around 1% of the LV size is used for integrity metadata. Command variations: lvcreate --type integrity -n Name -L Size VG [Uses integrity external, the default.] lvcreate --integrity y|external -n Name -L Size VG [Uses type integrity, which is implied.] lvcreate --integrity internal -n Name -L Size VG [Uses type integrity, which is implied.] lvcreate --type raidN --integrity y -m Num -n Name -L Size VG [Uses type integrity for each raid image.] lvconvert --type integrity LV [Converts linear LV to type integrity.] lvconvert --integrity y|external LV [Converts linear LV to type integrity, or each image to type integrity in a raid LV.] Options: --integritymetadata LV|PV Use a specified LV for external metadata, or allocate a integrity metadata LV(s) from the named PV. With raid, only a PV can be specified (because multiple metadata LVs are required.) When this option is not used, the command allocates integrity metadata LVs using any PVs in the VG. --integritysettings String set dm-integrity parameters, e.g. to use a journal instead of bitmap, --integritysettings "mode=J". Example: $ lvcreate --integrity external -n lvex -L1G vg $ lvs -a vg LV VG Attr LSize Origin lvex vg gwi-a----- 1.00g [lvex_iorig] [lvex_imeta] vg ewi-ao---- 12.00m [lvex_iorig] vg -wi-ao---- 1.00g $ lvcreate --integrity internal -n lvin -L1G vg $ lvs -a vg LV VG Attr LSize Origin lvin vg gwi-a----- 1.00g [lvin_iorig] [lvin_iorig] vg -wi-ao---- 1.00g $ lvcreate --type raid1 --integrity y -m 1 -n lver -L1G vg $ lvs -a vg LV VG Attr LSize Origin lver vg rwi-a-r--- 1.00g [lver_rimage_0] vg gwi-aor--- 1.00g [lver_rimage_0_iorig] [lver_rimage_0_imeta] vg ewi-ao---- 12.00m [lver_rimage_0_iorig] vg -wi-ao---- 1.00g [lver_rimage_1] vg gwi-aor--- 1.00g [lver_rimage_1_iorig] [lver_rimage_1_imeta] vg ewi-ao---- 12.00m [lver_rimage_1_iorig] vg -wi-ao---- 1.00g [lver_rmeta_0] vg ewi-aor--- 4.00m [lver_rmeta_1] vg ewi-aor--- 4.00m
193 lines
4.6 KiB
Bash
193 lines
4.6 KiB
Bash
#!/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
|
|
|
|
# Test writecache usage
|
|
|
|
SKIP_WITH_LVMPOLLD=1
|
|
|
|
. lib/inittest
|
|
|
|
# aux have_integrity 1 0 0 || skip
|
|
which mkfs.xfs || skip
|
|
|
|
mnt="mnt"
|
|
mkdir -p $mnt
|
|
aux prepare_devs 5 64
|
|
|
|
for i in `seq 1 16384`; do echo -n "A" >> fileA; done
|
|
for i in `seq 1 16384`; do echo -n "B" >> fileB; done
|
|
for i in `seq 1 16384`; do echo -n "C" >> fileC; done
|
|
|
|
_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" || true
|
|
dd if=/dev/zero of="$dev2" || true
|
|
dd if=/dev/zero of="$dev3" || true
|
|
dd if=/dev/zero of="$dev4" || true
|
|
dd if=/dev/zero of="$dev5" || true
|
|
vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
|
|
}
|
|
|
|
_test_fs_with_error() {
|
|
mkfs.xfs -f "$DM_DEV_DIR/$vg/$lv1"
|
|
|
|
mount "$DM_DEV_DIR/$vg/$lv1" $mnt
|
|
|
|
# add original data
|
|
cp fileA $mnt
|
|
cp fileB $mnt
|
|
cp fileC $mnt
|
|
|
|
umount $mnt
|
|
lvchange -an $vg/$lv1
|
|
|
|
# corrupt the original data on the underying dev
|
|
# flip one bit in fileB, changing a 0x42 to 0x43
|
|
# the bit is changed in the last 4096 byte block
|
|
# of the file, so when reading back the file we
|
|
# will get the first three 4096 byte blocks, for
|
|
# a total of 12288 bytes before getting an error
|
|
# on the last 4096 byte block.
|
|
xxd "$dev1" > dev1.txt
|
|
tac dev1.txt > dev1.rev
|
|
sed -e '0,/4242 4242 4242 4242 4242 4242 4242 4242/ s/4242 4242 4242 4242 4242 4242 4242 4242/4242 4242 4242 4242 4242 4242 4242 4243/' dev1.rev > dev1.rev.bad
|
|
tac dev1.rev.bad > dev1.bad
|
|
xxd -r dev1.bad > "$dev1"
|
|
rm dev1.txt dev1.rev dev1.rev.bad dev1.bad
|
|
|
|
lvchange -ay $vg/$lv1
|
|
mount "$DM_DEV_DIR/$vg/$lv1" $mnt
|
|
|
|
# read complete fileA which was not corrupted
|
|
dd if=$mnt/fileA of=tmp bs=1k
|
|
ls -l tmp
|
|
stat -c %s tmp
|
|
diff fileA tmp
|
|
rm tmp
|
|
|
|
# read partial fileB which was corrupted
|
|
not dd if=$mnt/fileB of=tmp bs=1k
|
|
ls -l tmp
|
|
stat -c %s tmp | grep 12288
|
|
not diff fileB tmp
|
|
rm tmp
|
|
|
|
umount $mnt
|
|
}
|
|
|
|
_test_fs_with_raid() {
|
|
mkfs.xfs -f "$DM_DEV_DIR/$vg/$lv1"
|
|
|
|
mount "$DM_DEV_DIR/$vg/$lv1" $mnt
|
|
|
|
# add original data
|
|
cp fileA $mnt
|
|
cp fileB $mnt
|
|
cp fileC $mnt
|
|
|
|
umount $mnt
|
|
lvchange -an $vg/$lv1
|
|
|
|
xxd "$dev1" > dev1.txt
|
|
tac dev1.txt > dev1.rev
|
|
sed -e '0,/4242 4242 4242 4242 4242 4242 4242 4242/ s/4242 4242 4242 4242 4242 4242 4242 4242/4242 4242 4242 4242 4242 4242 4242 4243/' dev1.rev > dev1.rev.bad
|
|
tac dev1.rev.bad > dev1.bad
|
|
xxd -r dev1.bad > "$dev1"
|
|
rm dev1.txt dev1.rev dev1.rev.bad dev1.bad
|
|
|
|
lvchange -ay $vg/$lv1
|
|
mount "$DM_DEV_DIR/$vg/$lv1" $mnt
|
|
|
|
# read complete fileA which was not corrupted
|
|
dd if=$mnt/fileA of=tmp bs=1k
|
|
ls -l tmp
|
|
stat -c %s tmp | grep 16384
|
|
diff fileA tmp
|
|
rm tmp
|
|
|
|
# read complete fileB, corruption is corrected by raid
|
|
dd if=$mnt/fileB of=tmp bs=1k
|
|
ls -l tmp
|
|
stat -c %s tmp | grep 16384
|
|
diff fileB tmp
|
|
rm tmp
|
|
|
|
umount $mnt
|
|
}
|
|
|
|
_prepare_vg
|
|
lvcreate --integrity y -n $lv1 -l 8 $vg "$dev1"
|
|
_test_fs_with_error
|
|
lvchange -an $vg/$lv1
|
|
lvconvert --integrity n $vg/$lv1
|
|
lvremove $vg/$lv1
|
|
vgremove -ff $vg
|
|
|
|
_prepare_vg
|
|
lvcreate -y --integrity internal -n $lv1 -l 8 $vg "$dev1"
|
|
_test_fs_with_error
|
|
lvchange -an $vg/$lv1
|
|
not lvconvert --integrity n $vg/$lv1
|
|
lvremove $vg/$lv1
|
|
vgremove -ff $vg
|
|
|
|
_prepare_vg
|
|
lvcreate -an -n meta -L4M $vg "$dev2"
|
|
lvcreate --integrity y --integritymetadata meta -n $lv1 -l 8 $vg "$dev1"
|
|
_test_fs_with_error
|
|
lvchange -an $vg/$lv1
|
|
lvconvert --integrity n $vg/$lv1
|
|
lvremove $vg/$lv1
|
|
vgremove -ff $vg
|
|
|
|
_prepare_vg
|
|
lvcreate --type raid1 -m1 --integrity y -n $lv1 -l 8 $vg
|
|
_test_fs_with_raid
|
|
lvchange -an $vg/$lv1
|
|
lvconvert --integrity n $vg/$lv1
|
|
lvremove $vg/$lv1
|
|
vgremove -ff $vg
|
|
|
|
_prepare_vg
|
|
lvcreate --type raid1 -m2 --integrity y -n $lv1 -l 8 $vg
|
|
_test_fs_with_raid
|
|
lvchange -an $vg/$lv1
|
|
lvconvert --integrity n $vg/$lv1
|
|
lvremove $vg/$lv1
|
|
vgremove -ff $vg
|
|
|
|
_prepare_vg
|
|
lvcreate --type raid4 --integrity y -n $lv1 -l 8 $vg
|
|
_test_fs_with_raid
|
|
lvchange -an $vg/$lv1
|
|
lvconvert --integrity n $vg/$lv1
|
|
lvremove $vg/$lv1
|
|
vgremove -ff $vg
|
|
|
|
_prepare_vg
|
|
lvcreate --type raid5 --integrity y -n $lv1 -l 8 $vg
|
|
_test_fs_with_raid
|
|
lvchange -an $vg/$lv1
|
|
lvconvert --integrity n $vg/$lv1
|
|
lvremove $vg/$lv1
|
|
vgremove -ff $vg
|
|
|
|
_prepare_vg
|
|
lvcreate --type raid6 --integrity y -n $lv1 -l 8 $vg
|
|
_test_fs_with_raid
|
|
lvchange -an $vg/$lv1
|
|
lvconvert --integrity n $vg/$lv1
|
|
lvremove $vg/$lv1
|
|
vgremove -ff $vg
|
|
|