2022-11-07 00:40:40 +03:00
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eux
set -o pipefail
2023-05-16 20:09:13 +03:00
# shellcheck source=test/units/util.sh
. " $( dirname " $0 " ) " /util.sh
2022-12-15 21:04:22 +03:00
2022-11-07 00:40:40 +03:00
at_exit( ) {
set +e
[ [ -n " ${ LOOP :- } " ] ] && losetup -d " $LOOP "
[ [ -n " ${ WORK_DIR :- } " ] ] && rm -fr " $WORK_DIR "
}
trap at_exit EXIT
WORK_DIR = " $( mktemp -d) "
2024-05-21 01:20:57 +03:00
mkdir -p " $WORK_DIR /mnt "
2022-11-07 00:40:40 +03:00
systemd-mount --list
systemd-mount --list --full
systemd-mount --list --no-legend
systemd-mount --list --no-pager
systemd-mount --list --quiet
2024-07-08 14:44:12 +03:00
systemd-mount --list --json= pretty
2022-11-07 00:40:40 +03:00
2024-05-21 01:20:57 +03:00
# tmpfs
mkdir -p " $WORK_DIR /mnt/foo/bar "
systemd-mount --tmpfs " $WORK_DIR /mnt/foo "
test ! -d " $WORK_DIR /mnt/foo/bar "
touch " $WORK_DIR /mnt/foo/baz "
systemd-umount " $WORK_DIR /mnt/foo "
test -d " $WORK_DIR /mnt/foo/bar "
test ! -e " $WORK_DIR /mnt/foo/baz "
# overlay
systemd-mount --type= overlay --options= " lowerdir=/etc,upperdir= $WORK_DIR /upper,workdir= $WORK_DIR /work " /etc " $WORK_DIR /overlay "
touch " $WORK_DIR /overlay/foo "
test -e " $WORK_DIR /upper/foo "
systemd-umount " $WORK_DIR /overlay "
# We're going to play around with block/loop devices, so bail out early
# if we're running in nspawn
if systemd-detect-virt --container >/dev/null; then
echo "Container detected, skipping the test"
exit 0
fi
2022-11-07 00:40:40 +03:00
# Set up a simple block device for further tests
dd if = /dev/zero of = " $WORK_DIR /simple.img " bs = 1M count = 16
2024-05-08 12:21:42 +03:00
mkfs.ext4 -L sd-mount-test " $WORK_DIR /simple.img "
2022-11-07 00:40:40 +03:00
LOOP = " $( losetup --show --find " $WORK_DIR /simple.img " ) "
2024-05-08 12:21:42 +03:00
udevadm wait --timeout 60 --settle " $LOOP "
2024-05-17 09:04:31 +03:00
# Also wait for the .device unit for the loop device is active. Otherwise, the .device unit activation
# that is triggered by the .mount unit introduced by systemd-mount below may time out.
timeout 60 bash -c " until systemctl is-active $LOOP ; do sleep 1; done "
2022-11-07 00:40:40 +03:00
mount " $LOOP " " $WORK_DIR /mnt "
touch " $WORK_DIR /mnt/foo.bar "
umount " $LOOP "
( ! mountpoint " $WORK_DIR /mnt " )
2024-05-20 22:48:42 +03:00
# Wait for the mount unit to be unloaded. Otherwise, creation of the transient unit below may fail.
MOUNT_UNIT = $( systemd-escape --path --suffix= mount " $WORK_DIR /mnt " )
timeout 60 bash -c " while [[ -n \$(systemctl list-units --all --no-legend $MOUNT_UNIT ) ]]; do sleep 1; done "
2022-11-07 00:40:40 +03:00
# Mount with both source and destination set
systemd-mount " $LOOP " " $WORK_DIR /mnt "
systemctl status " $WORK_DIR /mnt "
systemd-mount --list --full
test -e " $WORK_DIR /mnt/foo.bar "
systemd-umount " $WORK_DIR /mnt "
# Same thing, but with explicitly specified filesystem and disabled filesystem check
systemd-mount --type= ext4 --fsck= no --collect " $LOOP " " $WORK_DIR /mnt "
systemctl status " $( systemd-escape --path " $WORK_DIR /mnt " ) .mount "
test -e " $WORK_DIR /mnt/foo.bar "
systemd-mount --umount " $LOOP "
# Discover additional metadata (unit description should now contain filesystem label)
systemd-mount --no-ask-password --discover " $LOOP " " $WORK_DIR /mnt "
test -e " $WORK_DIR /mnt/foo.bar "
systemctl show -P Description " $WORK_DIR /mnt " | grep -q sd-mount-test
systemd-umount " $WORK_DIR /mnt "
2022-11-08 14:44:37 +03:00
# Set a unit description
systemd-mount --description= "Very Important Unit" " $LOOP " " $WORK_DIR /mnt "
test -e " $WORK_DIR /mnt/foo.bar "
systemctl show -P Description " $WORK_DIR /mnt " | grep -q "Very Important Unit"
systemd-umount " $WORK_DIR /mnt "
2022-11-07 00:40:40 +03:00
# Set a property
systemd-mount --property= "Description=Foo Bar" " $LOOP " " $WORK_DIR /mnt "
test -e " $WORK_DIR /mnt/foo.bar "
systemctl show -P Description " $WORK_DIR /mnt " | grep -q "Foo Bar"
systemd-umount " $WORK_DIR /mnt "
# Set mount options
2022-11-08 14:44:37 +03:00
systemd-mount --options= ro,x-foo-bar " $LOOP " " $WORK_DIR /mnt "
2022-11-07 00:40:40 +03:00
test -e " $WORK_DIR /mnt/foo.bar "
systemctl show -P Options " $WORK_DIR /mnt " | grep -Eq "(^ro|,ro)"
systemctl show -P Options " $WORK_DIR /mnt " | grep -q "x-foo-bar"
systemd-umount " $WORK_DIR /mnt "
# Mount with only source set
systemd-mount " $LOOP "
systemctl status /run/media/system/sd-mount-test
systemd-mount --list --full
test -e /run/media/system/sd-mount-test/foo.bar
systemd-umount LABEL = sd-mount-test
# Automount
systemd-mount --automount= yes " $LOOP " " $WORK_DIR /mnt "
systemd-mount --list --full
systemctl status " $( systemd-escape --path " $WORK_DIR /mnt " ) .automount "
[ [ " $( systemctl show -P ActiveState " $WORK_DIR /mnt " ) " = = inactive ] ]
test -e " $WORK_DIR /mnt/foo.bar "
systemctl status " $WORK_DIR /mnt "
systemd-umount " $WORK_DIR /mnt "
# Automount + automount-specific property
2022-11-08 14:44:37 +03:00
systemd-mount -A --automount-property= "Description=Bar Baz" " $LOOP " " $WORK_DIR /mnt "
2022-11-07 00:40:40 +03:00
systemctl show -P Description " $( systemd-escape --path " $WORK_DIR /mnt " ) .automount " | grep -q "Bar Baz"
test -e " $WORK_DIR /mnt/foo.bar "
2022-11-08 14:44:37 +03:00
# Call --umount via --machine=, first with a relative path (bad) and then with
# an absolute one (good)
( ! systemd-umount --machine= .host " $( realpath --relative-to= . " $WORK_DIR /mnt " ) " )
systemd-umount --machine= .host " $WORK_DIR /mnt "
# ext4 doesn't support uid=/gid=
( ! systemd-mount -t ext4 --owner= testuser " $LOOP " " $WORK_DIR /mnt " )
2022-11-07 00:40:40 +03:00
# Automount + --bind-device
systemd-mount --automount= yes --bind-device --timeout-idle-sec= 1 " $LOOP " " $WORK_DIR /mnt "
systemctl status " $( systemd-escape --path " $WORK_DIR /mnt " ) .automount "
# Trigger the automount
test -e " $WORK_DIR /mnt/foo.bar "
# Wait until it's idle again
sleep 1.5
# Safety net for slower/overloaded systems
timeout 10s bash -c " while systemctl is-active -q $WORK_DIR /mnt; do sleep .2; done "
systemctl status " $( systemd-escape --path " $WORK_DIR /mnt " ) .automount "
# Disassemble the underlying block device
losetup -d " $LOOP "
unset LOOP
2022-11-08 14:01:13 +03:00
# The automount unit should disappear once the underlying blockdev is gone
2023-03-28 20:00:41 +03:00
timeout 10s bash -c " while systemctl status ' $( systemd-escape --path " $WORK_DIR /mnt " .automount) '; do sleep .2; done "
2022-11-07 00:40:40 +03:00
# Mount a disk image
2022-11-08 14:44:37 +03:00
systemd-mount --discover " $WORK_DIR /simple.img "
2022-12-15 21:04:22 +03:00
# We can access files in the image even if the loopback block device is not initialized by udevd.
2022-11-07 00:40:40 +03:00
test -e /run/media/system/simple.img/foo.bar
2022-12-15 21:04:22 +03:00
# systemd-mount --list and systemd-umount require the loopback block device is initialized by udevd.
udevadm settle --timeout 30
2023-03-28 21:41:38 +03:00
assert_in "/dev/loop.* ext4 +sd-mount-test" " $( systemd-mount --list --full) "
2024-07-08 15:38:22 +03:00
LOOP_AUTO = $( systemd-mount --list --full --no-legend | awk '$7 == "sd-mount-test" { print $1 }' )
2024-05-21 13:10:49 +03:00
LOOP_AUTO_DEVPATH = $( udevadm info --query property --property DEVPATH --value " $LOOP_AUTO " )
2022-11-07 00:40:40 +03:00
systemd-umount " $WORK_DIR /simple.img "
2024-05-21 13:10:49 +03:00
# Wait for 'change' uevent for the device with DISK_MEDIA_CHANGE=1.
# After the event, the backing_file attribute should be removed.
timeout 60 bash -c " while [[ -e /sys/ $LOOP_AUTO_DEVPATH /loop/backing_file ]]; do sleep 1; done "
2022-11-07 00:40:40 +03:00
2022-11-07 17:55:08 +03:00
# --owner + vfat
#
# Create a vfat image, as ext4 doesn't support uid=/gid= fixating for all
# files/directories
dd if = /dev/zero of = " $WORK_DIR /owner-vfat.img " bs = 1M count = 16
2024-05-08 12:21:42 +03:00
mkfs.vfat -n owner-vfat " $WORK_DIR /owner-vfat.img "
2022-11-07 17:55:08 +03:00
LOOP = " $( losetup --show --find " $WORK_DIR /owner-vfat.img " ) "
2024-05-28 05:51:48 +03:00
# If the synthesized uevent triggered by inotify event has been processed earlier than the kernel finishes to
# attach the backing file, then SYSTEMD_READY=0 is set for the device. As a workaround, monitor sysattr
# and re-trigger uevent after that.
LOOP_DEVPATH = $( udevadm info --query property --property DEVPATH --value " $LOOP " )
timeout 60 bash -c " until [[ -e /sys/ $LOOP_DEVPATH /loop/backing_file ]]; do sleep 1; done "
udevadm trigger --settle " $LOOP "
2024-05-17 09:04:31 +03:00
# Also wait for the .device unit for the loop device is active. Otherwise, the .device unit activation
# that is triggered by the .mount unit introduced by systemd-mount below may time out.
2024-05-20 23:35:50 +03:00
if ! timeout 60 bash -c " until systemctl is-active $LOOP ; do sleep 1; done " ; then
# For debugging issue like
# https://github.com/systemd/systemd/issues/32680#issuecomment-2120959238
# https://github.com/systemd/systemd/issues/32680#issuecomment-2122074805
udevadm info " $LOOP "
udevadm info --attribute-walk " $LOOP "
cat /sys/" $( udevadm info --query property --property DEVPATH --value " $LOOP " ) " /loop/backing_file || :
false
fi
2022-11-07 17:55:08 +03:00
# Mount it and check the UID/GID
2022-11-07 00:40:40 +03:00
[ [ " $( stat -c "%U:%G" " $WORK_DIR /mnt " ) " = = "root:root" ] ]
2022-11-08 14:44:37 +03:00
systemd-mount --owner= testuser " $LOOP " " $WORK_DIR /mnt "
2022-11-07 00:40:40 +03:00
systemctl status " $WORK_DIR /mnt "
[ [ " $( stat -c "%U:%G" " $WORK_DIR /mnt " ) " = = "testuser:testuser" ] ]
2022-11-07 17:55:08 +03:00
touch " $WORK_DIR /mnt/hello "
[ [ " $( stat -c "%U:%G" " $WORK_DIR /mnt/hello " ) " = = "testuser:testuser" ] ]
systemd-umount LABEL = owner-vfat