1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-11 20:58:50 +03:00
lvm2/test/shell/integrity.sh
David Teigland aa9019d8a2 dm-integrity support
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
2020-01-15 15:44:31 -06:00

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