summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrantisek Sumsal <frantisek@sumsal.cz>2021-09-17 19:28:38 +0200
committerFrantisek Sumsal <frantisek@sumsal.cz>2021-09-19 13:46:49 +0200
commitb1471e559e8dc4ea78c896ed365f5b043c2d6ce0 (patch)
tree64e6e0831e95bbb48b7a576dd8bbfb729b6a6bfc
parent677acd210126c27c05ddb754d1f1c99e9518f0fb (diff)
downloadsystemd-b1471e559e8dc4ea78c896ed365f5b043c2d6ce0.tar.gz
test: btrfs-related udev tests
-rwxr-xr-xtest/TEST-64-UDEV-STORAGE/test.sh50
-rwxr-xr-xtest/units/testsuite-64.sh120
2 files changed, 164 insertions, 6 deletions
diff --git a/test/TEST-64-UDEV-STORAGE/test.sh b/test/TEST-64-UDEV-STORAGE/test.sh
index 4c4b39dd3f..c4119cf9ec 100755
--- a/test/TEST-64-UDEV-STORAGE/test.sh
+++ b/test/TEST-64-UDEV-STORAGE/test.sh
@@ -5,9 +5,7 @@
# * iSCSI
# * LVM over iSCSI (?)
# * SW raid (mdadm)
-# * LUKS -> MD (mdadm) -> LVM
-# * BTRFS
-# * MD BTRFS
+# * MD (mdadm) -> DM-CRYPT -> LVM
set -e
TEST_DESCRIPTION="systemd-udev storage tests"
@@ -37,7 +35,7 @@ _host_has_feature() {(
command -v lvm
;;
btrfs)
- modprobe -nv btrfs && command -v mkfs.btrfs
+ modprobe -nv btrfs && command -v mkfs.btrfs && command -v btrfs
;;
*)
echo >&2 "ERROR: Unknown feature '$1'"
@@ -51,15 +49,19 @@ test_append_files() {(
local feature
# An associative array of requested (but optional) features and their
# respective "handlers" from test/test-functions
+ #
+ # Note: we install cryptsetup unconditionally, hence it's not explicitly
+ # checked for here
local -A features=(
- [multipath]=install_multipath
+ [btrfs]=install_btrfs
[lvm]=install_lvm
+ [multipath]=install_multipath
)
instmods "=block" "=md" "=nvme" "=scsi"
install_dmevent
generate_module_dependencies
- image_install lsblk wc
+ image_install lsblk wc wipefs
# Install the optional features if the host has the respective tooling
for feature in "${!features[@]}"; do
@@ -74,6 +76,13 @@ test_append_files() {(
done
)}
+_image_cleanup() {
+ mount_initdir
+ # Clean up certain "problematic" files which may be left over by failing tests
+ : >"${initdir:?}/etc/fstab"
+ : >"${initdir:?}/etc/crypttab"
+}
+
test_run_one() {
local test_id="${1:?}"
@@ -100,6 +109,7 @@ test_run() {
# Execute each currently defined function starting with "testcase_"
for testcase in "${TESTCASES[@]}"; do
+ _image_cleanup
echo "------ $testcase: BEGIN ------"
{ "$testcase" "$test_id"; ec=$?; } || :
case $ec in
@@ -311,6 +321,34 @@ testcase_lvm_basic() {
rm -f "${TESTDIR:?}"/lvmbasic*.img
}
+testcase_btrfs_basic() {
+ if ! _host_has_feature "btrfs"; then
+ echo "Missing btrfs tools/modules, skipping the test..."
+ return 77
+ fi
+
+ local qemu_opts=("-device ahci,id=ahci0")
+ local diskpath i size
+
+ for i in {0..3}; do
+ diskpath="${TESTDIR:?}/btrfsbasic${i}.img"
+ # Make the first disk larger for multi-partition tests
+ [[ $i -eq 0 ]] && size=350 || size=128
+
+ dd if=/dev/zero of="$diskpath" bs=1M count="$size"
+ qemu_opts+=(
+ "-device ide-hd,bus=ahci0.$i,drive=drive$i,model=foobar,serial=deadbeefbtrfs$i"
+ "-drive format=raw,cache=unsafe,file=$diskpath,if=none,id=drive$i"
+ )
+ done
+
+ KERNEL_APPEND="systemd.setenv=TEST_FUNCTION_NAME=${FUNCNAME[0]} ${USER_KERNEL_APPEND:-}"
+ QEMU_OPTIONS="${qemu_opts[*]} ${USER_QEMU_OPTIONS:-}"
+ test_run_one "${1:?}"
+
+ rm -f "${TESTDIR:?}"/btrfsbasic*.img
+}
+
# Allow overriding which tests should be run from the "outside", useful for manual
# testing (make -C test/... TESTCASES="testcase1 testcase2")
if [[ -v "TESTCASES" && -n "$TESTCASES" ]]; then
diff --git a/test/units/testsuite-64.sh b/test/units/testsuite-64.sh
index 693cd87ade..4380fa0fcf 100755
--- a/test/units/testsuite-64.sh
+++ b/test/units/testsuite-64.sh
@@ -277,6 +277,126 @@ testcase_lvm_basic() {
done
}
+testcase_btrfs_basic() {
+ local dev_stub i label mpoint uuid
+ local devices=(
+ /dev/disk/by-id/ata-foobar_deadbeefbtrfs{0..3}
+ )
+
+ ls -l "${devices[@]}"
+
+ echo "Single device: default settings"
+ uuid="deadbeef-dead-dead-beef-000000000000"
+ label="btrfs_root"
+ mkfs.btrfs -L "$label" -U "$uuid" "${devices[0]}"
+ udevadm settle
+ btrfs filesystem show
+ test -e "/dev/disk/by-uuid/$uuid"
+ test -e "/dev/disk/by-label/$label"
+ helper_check_device_symlinks
+
+ echo "Multiple devices: using partitions, data: single, metadata: raid1"
+ uuid="deadbeef-dead-dead-beef-000000000001"
+ label="btrfs_mpart"
+ sfdisk --wipe=always "${devices[0]}" <<EOF
+label: gpt
+
+name="diskpart1", size=85M
+name="diskpart2", size=85M
+name="diskpart3", size=85M
+name="diskpart4", size=85M
+EOF
+ udevadm settle
+ mkfs.btrfs -d single -m raid1 -L "$label" -U "$uuid" /dev/disk/by-partlabel/diskpart{1..4}
+ udevadm settle
+ btrfs filesystem show
+ test -e "/dev/disk/by-uuid/$uuid"
+ test -e "/dev/disk/by-label/$label"
+ helper_check_device_symlinks
+ wipefs -a -f "${devices[0]}"
+
+ echo "Multiple devices: using disks, data: raid10, metadata: raid10, mixed mode"
+ uuid="deadbeef-dead-dead-beef-000000000002"
+ label="btrfs_mdisk"
+ mkfs.btrfs -M -d raid10 -m raid10 -L "$label" -U "$uuid" "${devices[@]}"
+ udevadm settle
+ btrfs filesystem show
+ test -e "/dev/disk/by-uuid/$uuid"
+ test -e "/dev/disk/by-label/$label"
+ helper_check_device_symlinks
+
+ echo "Multiple devices: using LUKS encrypted disks, data: raid1, metadata: raid1, mixed mode"
+ uuid="deadbeef-dead-dead-beef-000000000003"
+ label="btrfs_mencdisk"
+ mpoint="/btrfs_enc$RANDOM"
+ mkdir "$mpoint"
+ # Create a key-file
+ dd if=/dev/urandom of=/etc/btrfs_keyfile bs=64 count=1 iflag=fullblock
+ chmod 0600 /etc/btrfs_keyfile
+ # Encrypt each device and add it to /etc/crypttab, so it can be mounted
+ # automagically later
+ : >/etc/crypttab
+ for ((i = 0; i < ${#devices[@]}; i++)); do
+ # Intentionally use weaker cipher-related settings, since we don't care
+ # about security here as it's a throwaway LUKS partition
+ cryptsetup luksFormat -q \
+ --use-urandom --pbkdf pbkdf2 --pbkdf-force-iterations 1000 \
+ --uuid "deadbeef-dead-dead-beef-11111111111$i" --label "encdisk$i" "${devices[$i]}" /etc/btrfs_keyfile
+ udevadm settle
+ test -e "/dev/disk/by-uuid/deadbeef-dead-dead-beef-11111111111$i"
+ test -e "/dev/disk/by-label/encdisk$i"
+ # Add the device into /etc/crypttab, reload systemd, and then activate
+ # the device so we can create a filesystem on it later
+ echo "encbtrfs$i UUID=deadbeef-dead-dead-beef-11111111111$i /etc/btrfs_keyfile luks,noearly" >>/etc/crypttab
+ systemctl daemon-reload
+ systemctl start "systemd-cryptsetup@encbtrfs$i"
+ done
+ helper_check_device_symlinks
+ # Check if we have all necessary DM devices
+ ls -l /dev/mapper/encbtrfs{0..3}
+ # Create a multi-device btrfs filesystem on the LUKS devices
+ mkfs.btrfs -M -d raid1 -m raid1 -L "$label" -U "$uuid" /dev/mapper/encbtrfs{0..3}
+ udevadm settle
+ btrfs filesystem show
+ test -e "/dev/disk/by-uuid/$uuid"
+ test -e "/dev/disk/by-label/$label"
+ helper_check_device_symlinks
+ # Mount it and write some data to it we can compare later
+ mount -t btrfs /dev/mapper/encbtrfs0 "$mpoint"
+ echo "hello there" >"$mpoint/test"
+ # "Deconstruct" the btrfs device and check if we're in a sane state (symlink-wise)
+ umount "$mpoint"
+ systemctl stop systemd-cryptsetup@encbtrfs{0..3}
+ test ! -e "/dev/disk/by-uuid/$uuid"
+ helper_check_device_symlinks
+ # Add the mount point to /etc/fstab and check if the device can be put together
+ # automagically. The source device is the DM name of the first LUKS device
+ # (from /etc/crypttab). We have to specify all LUKS devices manually, as
+ # registering the necessary devices is usually initrd's job (via btrfs device scan)
+ dev_stub="/dev/mapper/encbtrfs"
+ echo "/dev/mapper/encbtrfs0 $mpoint btrfs device=${dev_stub}0,device=${dev_stub}1,device=${dev_stub}2,device=${dev_stub}3 0 2" >>/etc/fstab
+ # Tell systemd about the new mount
+ systemctl daemon-reload
+ # Restart cryptsetup.target to trigger autounlock of partitions in /etc/crypttab
+ systemctl restart cryptsetup.target
+ # Start the corresponding mount unit and check if the btrfs device was reconstructed
+ # correctly
+ systemctl start "${mpoint##*/}.mount"
+ btrfs filesystem show
+ test -e "/dev/disk/by-uuid/$uuid"
+ test -e "/dev/disk/by-label/$label"
+ helper_check_device_symlinks
+ grep "hello there" "$mpoint/test"
+ # Cleanup
+ systemctl stop "${mpoint##*/}.mount"
+ systemctl stop systemd-cryptsetup@encbtrfs{0..3}
+ sed -i "/${mpoint##*/}/d" /etc/fstab
+ : >/etc/crypttab
+ rm -fr "$mpoint"
+ systemctl daemon-reload
+ udevadm settle
+}
+
: >/failed
udevadm settle