]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test-64-udev-storage: check device units
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 31 Aug 2022 18:48:02 +0000 (03:48 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Sep 2022 20:58:40 +0000 (05:58 +0900)
test/units/testsuite-64.sh

index 9a2540ad0cd92795ce4fafd44f30f3e663a82885..dccb531242f8edb0b691946ee6baf83367e14d09 100755 (executable)
@@ -83,6 +83,93 @@ helper_check_udev_watch() {(
     done < <(find /run/udev/watch -type l)
 )}
 
+check_device_unit() {(
+    set +x
+
+    local log_level link links path syspath unit
+
+    log_level="${1?}"
+    path="${2?}"
+    unit=$(systemd-escape --path --suffix=device "$path")
+
+    syspath=$(systemctl show --value --property SysFSPath "$unit" 2>/dev/null)
+    if [[ -z "$syspath" ]]; then
+        [[ "$log_level" == 1 ]] && echo >&2 "ERROR: $unit not found."
+        return 1
+    fi
+
+    if [[ ! -L "$path" ]]; then
+        if [[ ! -d "$syspath" ]]; then
+            [[ "$log_level" == 1 ]] && echo >&2 "ERROR: $unit exists for $syspath but it does not exist."
+            return 1
+        fi
+        return 0
+    fi
+
+    if [[ ! -b "$path" && ! -c "$path" ]]; then
+        [[ "$log_level" == 1 ]] && echo >&2 "ERROR: invalid file type $path"
+        return 1
+    fi
+
+    read -r -a links < <(udevadm info -q symlink "$syspath" 2>/dev/null)
+    for link in "${links[@]}"; do
+        if [[ "/dev/$link" == "$path" ]]; then # DEVLINKS= given by -q symlink are relative to /dev
+            return 0
+        fi
+    done
+
+    read -r -a links < <(udevadm info "$syspath" | sed -ne '/SYSTEMD_ALIAS=/ { s/^E: SYSTEMD_ALIAS=//; p }' 2>/dev/null)
+    for link in "${links[@]}"; do
+        if [[ "$link" == "$path" ]]; then # SYSTEMD_ALIAS= are absolute
+            return 0
+        fi
+    done
+
+    [[ "$log_level" == 1 ]] && echo >&2 "ERROR: $unit exists for $syspath but it does not have the corresponding DEVLINKS or SYSTEMD_ALIAS."
+    return 1
+)}
+
+check_device_units() {(
+    set +x
+
+    local log_level path paths
+
+    log_level="${1?}"
+    shift
+    paths=("$@")
+
+    for path in "${paths[@]}"; do
+        if ! check_device_unit "$log_level" "$path"; then
+           return 1
+        fi
+    done
+
+    while read -r unit _; do
+        path=$(systemd-escape --path --unescape "$unit")
+        if ! check_device_unit "$log_level" "$path"; then
+           return 1
+        fi
+    done < <(systemctl list-units --all --type=device --no-legend dev-* | awk '{ print $1 }' | sed -e 's/\.device$//')
+
+    return 0
+)}
+
+helper_check_device_units() {(
+    set +x
+
+    local i
+
+    for ((i = 0; i < 20; i++)); do
+        (( i == 0 )) || sleep .5
+
+        if check_device_units 0 "$@"; then
+            return 0
+        fi
+    done
+
+    check_device_units 1 "$@"
+)}
+
 testcase_megasas2_basic() {
     lsblk -S
     [[ "$(lsblk --scsi --noheadings | wc -l)" -ge 128 ]]
@@ -160,6 +247,7 @@ EOF
         "/dev/disk/by-uuid/deadbeef-dead-dead-beef-111111111111"
     )
     udevadm wait --settle --timeout=30 "${part_links[@]}"
+    helper_check_device_units "${part_links[@]}"
 
     # Choose a random symlink to the failover data partition each time, for
     # a better coverage
@@ -191,6 +279,7 @@ EOF
 
         # Make sure all symlinks are still valid
         udevadm wait --settle --timeout=30 "${part_links[@]}"
+        helper_check_device_units "${part_links[@]}"
     done
 
     multipath -l "$path"
@@ -287,6 +376,7 @@ EOF
         fi
     done
 
+    helper_check_device_units
     rm -f "$rule" "$partscript"
 
     udevadm control --reload
@@ -317,16 +407,19 @@ testcase_lvm_basic() {
     mkfs.ext4 -L mylvpart1 "/dev/$vgroup/mypart1"
     udevadm wait --settle --timeout="$timeout" "/dev/disk/by-label/mylvpart1"
     helper_check_device_symlinks "/dev/disk" "/dev/$vgroup"
+    helper_check_device_units
 
     # Disable the VG and check symlinks...
     lvm vgchange -an "$vgroup"
     udevadm wait --settle --timeout="$timeout" --removed "/dev/$vgroup" "/dev/disk/by-label/mylvpart1"
     helper_check_device_symlinks "/dev/disk"
+    helper_check_device_units
 
     # reenable the VG and check the symlinks again if all LVs are properly activated
     lvm vgchange -ay "$vgroup"
     udevadm wait --settle --timeout="$timeout" "/dev/$vgroup/mypart1" "/dev/$vgroup/mypart2" "/dev/disk/by-label/mylvpart1"
     helper_check_device_symlinks "/dev/disk" "/dev/$vgroup"
+    helper_check_device_units
 
     # Same as above, but now with more "stress"
     [[ -n "${ASAN_OPTIONS:-}" ]] && iterations=10 || iterations=50
@@ -337,6 +430,7 @@ testcase_lvm_basic() {
         if ((i % 5 == 0)); then
             udevadm wait --settle --timeout="$timeout" "/dev/$vgroup/mypart1" "/dev/$vgroup/mypart2" "/dev/disk/by-label/mylvpart1"
             helper_check_device_symlinks "/dev/disk" "/dev/$vgroup"
+            helper_check_device_units
         fi
     done
 
@@ -345,6 +439,7 @@ testcase_lvm_basic() {
     udevadm wait --settle --timeout="$timeout" --removed "/dev/$vgroup/mypart1"
     udevadm wait --timeout=0 "/dev/$vgroup/mypart2"
     helper_check_device_symlinks "/dev/disk" "/dev/$vgroup"
+    helper_check_device_units
 
     # Create & remove LVs in a loop, i.e. with more "stress"
     [[ -n "${ASAN_OPTIONS:-}" ]] && iterations=8 || iterations=16
@@ -364,6 +459,7 @@ testcase_lvm_basic() {
                 udevadm wait --settle --timeout="$timeout" --removed "/dev/$vgroup/looppart$part"
             done
             helper_check_device_symlinks "/dev/disk" "/dev/$vgroup"
+            helper_check_device_units
         fi
     done
 }
@@ -383,6 +479,7 @@ testcase_btrfs_basic() {
     udevadm wait --settle --timeout=30 "${devices[0]}" "/dev/disk/by-uuid/$uuid" "/dev/disk/by-label/$label"
     btrfs filesystem show
     helper_check_device_symlinks
+    helper_check_device_units
 
     echo "Multiple devices: using partitions, data: single, metadata: raid1"
     uuid="deadbeef-dead-dead-beef-000000000001"
@@ -400,6 +497,7 @@ EOF
     udevadm wait --settle --timeout=30 "/dev/disk/by-uuid/$uuid" "/dev/disk/by-label/$label"
     btrfs filesystem show
     helper_check_device_symlinks
+    helper_check_device_units
     wipefs -a -f "${devices[0]}"
     udevadm wait --settle --timeout=30 --removed /dev/disk/by-partlabel/diskpart{1..4}
 
@@ -415,6 +513,7 @@ EOF
     udevadm wait --settle --timeout=30 "/dev/disk/by-uuid/$uuid" "/dev/disk/by-label/$label"
     btrfs filesystem show
     helper_check_device_symlinks
+    helper_check_device_units
 
     echo "Multiple devices: using LUKS encrypted disks, data: raid1, metadata: raid1, mixed mode"
     uuid="deadbeef-dead-dead-beef-000000000003"
@@ -441,6 +540,7 @@ EOF
         systemctl start "systemd-cryptsetup@encbtrfs$i"
     done
     helper_check_device_symlinks
+    helper_check_device_units
     # 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
@@ -453,6 +553,7 @@ EOF
     udevadm wait --settle --timeout=30 "/dev/disk/by-uuid/$uuid" "/dev/disk/by-label/$label"
     btrfs filesystem show
     helper_check_device_symlinks
+    helper_check_device_units
     # Mount it and write some data to it we can compare later
     mount -t btrfs /dev/mapper/encbtrfs0 "$mpoint"
     echo "hello there" >"$mpoint/test"
@@ -461,6 +562,7 @@ EOF
     systemctl stop systemd-cryptsetup@encbtrfs{0..3}
     udevadm wait --settle --timeout=30 --removed "/dev/disk/by-uuid/$uuid"
     helper_check_device_symlinks
+    helper_check_device_units
     # 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
@@ -477,6 +579,7 @@ EOF
     udevadm wait --settle --timeout=30 "/dev/disk/by-uuid/$uuid" "/dev/disk/by-label/$label"
     btrfs filesystem show
     helper_check_device_symlinks
+    helper_check_device_units
     grep "hello there" "$mpoint/test"
     # Cleanup
     systemctl stop "${mpoint##*/}.mount"
@@ -525,6 +628,7 @@ testcase_iscsi_lvm() {
     iscsiadm --mode node --targetname "$target_name" --portal "$target_ip:$target_port" --login
     udevadm wait --settle --timeout=30 "${expected_symlinks[@]}"
     helper_check_device_symlinks
+    helper_check_device_units
     # Cleanup
     iscsiadm --mode node --targetname "$target_name" --portal "$target_ip:$target_port" --logout
     tgtadm --lld iscsi --op delete --mode target --tid=1
@@ -560,6 +664,7 @@ testcase_iscsi_lvm() {
     iscsiadm --mode node --targetname "$target_name" --portal "$target_ip:$target_port" --login
     udevadm wait --settle --timeout=30 "${expected_symlinks[@]}"
     helper_check_device_symlinks
+    helper_check_device_units
     # Add all iSCSI devices into a LVM volume group, create two logical volumes,
     # and check if necessary symlinks exist (and are valid)
     lvm pvcreate -y "${expected_symlinks[@]}"
@@ -574,6 +679,7 @@ testcase_iscsi_lvm() {
     mkfs.ext4 -L mylvpart1 "/dev/$vgroup/mypart1"
     udevadm wait --settle --timeout=30 "/dev/disk/by-label/mylvpart1"
     helper_check_device_symlinks "/dev/disk" "/dev/$vgroup"
+    helper_check_device_units
     # Disconnect the iSCSI devices and check all the symlinks
     iscsiadm --mode node --targetname "$target_name" --portal "$target_ip:$target_port" --logout
     # "Reset" the DM state, since we yanked the backing storage from under the LVM,
@@ -582,11 +688,13 @@ testcase_iscsi_lvm() {
     # The LVM and iSCSI related symlinks should be gone
     udevadm wait --settle --timeout=30 --removed "/dev/$vgroup" "/dev/disk/by-label/mylvpart1" "${expected_symlinks[@]}"
     helper_check_device_symlinks "/dev/disk"
+    helper_check_device_units
     # Reconnect the iSCSI devices and check if everything get detected correctly
     iscsiadm --mode discoverydb --type sendtargets --portal "$target_ip" --discover
     iscsiadm --mode node --targetname "$target_name" --portal "$target_ip:$target_port" --login
     udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" "/dev/$vgroup/mypart1" "/dev/$vgroup/mypart2" "/dev/disk/by-label/mylvpart1"
     helper_check_device_symlinks "/dev/disk" "/dev/$vgroup"
+    helper_check_device_units
     # Cleanup
     iscsiadm --mode node --targetname "$target_name" --portal "$target_ip:$target_port" --logout
     tgtadm --lld iscsi --op delete --mode target --tid=2
@@ -687,6 +795,7 @@ testcase_mdadm_basic() {
         udevadm wait --settle --timeout=30 "${expected_symlinks[@]}"
     done
     helper_check_device_symlinks
+    helper_check_device_units
     # Cleanup
     mdadm -v --stop "$raid_dev"
     udevadm wait --settle --timeout=30 --removed "${expected_symlinks[@]}"
@@ -715,9 +824,11 @@ testcase_mdadm_basic() {
         udevadm wait --settle --timeout=30 "${expected_symlinks[@]}"
     done
     helper_check_device_symlinks
+    helper_check_device_units
     # Cleanup
     mdadm -v --stop "$raid_dev"
     udevadm wait --settle --timeout=30 --removed "${expected_symlinks[@]}"
+    helper_check_device_units
 
     echo "Mirror + parity raid (RAID 10) + multiple partitions"
     raid_name="mdmirpar"
@@ -763,10 +874,12 @@ EOF
         udevadm wait --settle --timeout=30 "${expected_symlinks[@]}"
     done
     helper_check_device_symlinks
+    helper_check_device_units
     # Cleanup
     mdadm -v --stop "$raid_dev"
     # Check if all expected symlinks were removed after the cleanup
     udevadm wait --settle --timeout=30 --removed "${expected_symlinks[@]}"
+    helper_check_device_units
 }
 
 testcase_mdadm_lvm() {
@@ -811,15 +924,18 @@ testcase_mdadm_lvm() {
     mdadm -v --stop "$raid_dev"
     udevadm wait --settle --timeout=30 --removed "${expected_symlinks[@]}"
     helper_check_device_symlinks
+    helper_check_device_units
     # Reassemble it and check if all required symlinks exist
     mdadm --assemble "$raid_dev" --name "$raid_name" -v
     udevadm wait --settle --timeout=30 "${expected_symlinks[@]}"
     helper_check_device_symlinks
+    helper_check_device_units
     # Cleanup
     lvm vgchange -an "$vgroup"
     mdadm -v --stop "$raid_dev"
     # Check if all expected symlinks were removed after the cleanup
     udevadm wait --settle --timeout=30 --removed "${expected_symlinks[@]}"
+    helper_check_device_units
 }
 
 : >/failed