Compare commits

...

3 Commits

Author SHA1 Message Date
Luca Boccassi cfec6ec663
Merge 2b3ebe1e6a into c946b13575 2024-11-23 02:40:54 +08:00
Luca Boccassi 2b3ebe1e6a detect-virt: check the inode number of the pid namespace
The indoe number of root pid namespace is hardcoded in the kernel to
0xEFFFFFFC since 3.8, so check the inode number of our pid namespace
if all else fails. If it's not 0xEFFFFFFC then we are in a pid
namespace, hence a container environment.

Fixes https://github.com/systemd/systemd/issues/35249
2024-11-21 20:37:47 +00:00
Luca Boccassi c6cb6aee4d test: split VM-only subtests from TEST-74-AUX-UTILS to new VM-only test
TEST-74-AUX-UTILS was switched for the mkosi-based jobs, but not for the shell
based jobs, so there's the new runner doing one thing, and the legacy runner
doing something different.

Move the VM-only subtests to TEST-87-AUX-UTILS-VM that is configured to only
run in VMs under both runners. This way we keep the existing tests as-is, and
we can add new VM-only tests without worrying.

Follow-up for f4faac2073
2024-11-21 20:37:47 +00:00
14 changed files with 296 additions and 167 deletions

View File

@ -24,6 +24,10 @@
#include "uid-range.h" #include "uid-range.h"
#include "virt.h" #include "virt.h"
/* Root namespace inode number, as per include/linux/proc_ns.h in the kernel source tree, since v3.8:
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=98f842e675f96ffac96e6c50315790912b2812be */
#define PROC_PID_INIT_INO UINT64_C(0xEFFFFFFC)
enum { enum {
SMBIOS_VM_BIT_SET, SMBIOS_VM_BIT_SET,
SMBIOS_VM_BIT_UNSET, SMBIOS_VM_BIT_UNSET,
@ -645,6 +649,20 @@ static int running_in_cgroupns(void) {
} }
} }
static int running_in_pidns(void) {
_cleanup_close_ int pidns_fd = -EBADF;
struct stat st;
pidns_fd = namespace_open_by_type(NAMESPACE_PID);
if (pidns_fd < 0)
return log_debug_errno(pidns_fd, "Failed to open PID namespace, ignoring: %m");
if (fstat(pidns_fd, &st) < 0)
return log_debug_errno(errno, "Failed to fstat pid namespace fd, ignoring: %m");
return (uint64_t) st.st_ino != PROC_PID_INIT_INO;
}
static Virtualization detect_container_files(void) { static Virtualization detect_container_files(void) {
static const struct { static const struct {
const char *file_path; const char *file_path;
@ -790,12 +808,21 @@ check_files:
r = running_in_cgroupns(); r = running_in_cgroupns();
if (r > 0) { if (r > 0) {
log_debug("Running in a cgroup namespace, assuming unknown container manager.");
v = VIRTUALIZATION_CONTAINER_OTHER; v = VIRTUALIZATION_CONTAINER_OTHER;
goto finish; goto finish;
} }
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to detect cgroup namespace: %m"); log_debug_errno(r, "Failed to detect cgroup namespace: %m");
/* Finally, the root pid namespace has an hardcoded inode number of 0xEFFFFFFC since kernel 3.8, so
* if all else fails we can check the inode number of our pid namespace and compare it. */
if (running_in_pidns() > 0) {
log_debug("Running in a pid namespace, assuming unknown container manager.");
v = VIRTUALIZATION_CONTAINER_OTHER;
goto finish;
}
/* If none of that worked, give up, assume no container manager. */ /* If none of that worked, give up, assume no container manager. */
v = VIRTUALIZATION_NONE; v = VIRTUALIZATION_NONE;
goto finish; goto finish;

View File

@ -1,10 +1,10 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
# Container-specific auxiliary tests. VM-based ones go in TEST-87-AUX-UTILS-VM.
integration_tests += [ integration_tests += [
integration_test_template + { integration_test_template + {
'name' : fs.name(meson.current_source_dir()), 'name' : fs.name(meson.current_source_dir()),
'storage': 'persistent', 'storage': 'persistent',
'vm' : true,
}, },
] ]

View File

@ -0,0 +1 @@
../TEST-01-BASIC/Makefile

View File

@ -0,0 +1,10 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# VM-specific auxiliary tests. Container-based ones go in TEST-74-AUX-UTILS.
integration_tests += [
integration_test_template + {
'name' : fs.name(meson.current_source_dir()),
'storage': 'persistent',
'vm' : true,
},
]

View File

@ -0,0 +1,44 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
TEST_DESCRIPTION="Tests for auxiliary utilities (VM)"
TEST_NO_NSPAWN=1
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
# Make sure vsock is available in the VM
CID=$((RANDOM + 3))
QEMU_OPTIONS+=" -device vhost-vsock-pci,guest-cid=$CID"
test_append_files() {
local workspace="${1:?}"
if ! get_bool "${TEST_PREFER_NSPAWN:-}" && ! get_bool "${TEST_NO_QEMU:-}"; then
# Check if we can correctly boot with an invalid machine ID only if we run
# the QEMU test, as nspawn refuses the invalid machine ID with -EUCLEAN
printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >"$workspace/etc/machine-id"
fi
if host_has_btrfs && host_has_mdadm; then
install_btrfs
install_mdadm
generate_module_dependencies
fi
inst_binary socat
inst_binary ssh
inst_binary sshd
inst_binary ssh-keygen
image_install -o /usr/lib/ssh/sshd-session /usr/libexec/openssh/sshd-session
inst_binary usermod
instmods vmw_vsock_virtio_transport
instmods vsock_loopback
instmods vmw_vsock_vmci_transport
inst_binary gcc
generate_module_dependencies
inst_binary openssl
}
do_test "$@"

View File

@ -379,6 +379,7 @@ foreach dirname : [
'TEST-84-STORAGETM', 'TEST-84-STORAGETM',
'TEST-85-NETWORK', 'TEST-85-NETWORK',
'TEST-86-MULTI-PROFILE-UKI', 'TEST-86-MULTI-PROFILE-UKI',
'TEST-87-AUX-UTILS-VM',
] ]
subdir(dirname) subdir(dirname)
endforeach endforeach

View File

@ -39,149 +39,3 @@ systemd-mount --type=overlay --options="lowerdir=/etc,upperdir=$WORK_DIR/upper,w
touch "$WORK_DIR/overlay/foo" touch "$WORK_DIR/overlay/foo"
test -e "$WORK_DIR/upper/foo" test -e "$WORK_DIR/upper/foo"
systemd-umount "$WORK_DIR/overlay" 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
# Set up a simple block device for further tests
dd if=/dev/zero of="$WORK_DIR/simple.img" bs=1M count=16
mkfs.ext4 -L sd-mount-test "$WORK_DIR/simple.img"
LOOP="$(losetup --show --find "$WORK_DIR/simple.img")"
udevadm wait --timeout 60 --settle "$LOOP"
# 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"
mount "$LOOP" "$WORK_DIR/mnt"
touch "$WORK_DIR/mnt/foo.bar"
umount "$LOOP"
(! mountpoint "$WORK_DIR/mnt")
# 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"
# 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"
# 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"
# 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
systemd-mount --options=ro,x-foo-bar "$LOOP" "$WORK_DIR/mnt"
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
systemd-mount -A --automount-property="Description=Bar Baz" "$LOOP" "$WORK_DIR/mnt"
systemctl show -P Description "$(systemd-escape --path "$WORK_DIR/mnt").automount" | grep -q "Bar Baz"
test -e "$WORK_DIR/mnt/foo.bar"
# 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")
# 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
# The automount unit should disappear once the underlying blockdev is gone
timeout 10s bash -c "while systemctl status '$(systemd-escape --path "$WORK_DIR/mnt".automount)'; do sleep .2; done"
# Mount a disk image
systemd-mount --discover "$WORK_DIR/simple.img"
# We can access files in the image even if the loopback block device is not initialized by udevd.
test -e /run/media/system/simple.img/foo.bar
# systemd-mount --list and systemd-umount require the loopback block device is initialized by udevd.
udevadm settle --timeout 30
assert_in "/dev/loop.* ext4 +sd-mount-test" "$(systemd-mount --list --full)"
LOOP_AUTO=$(systemd-mount --list --full --no-legend | awk '$7 == "sd-mount-test" { print $1 }')
LOOP_AUTO_DEVPATH=$(udevadm info --query property --property DEVPATH --value "$LOOP_AUTO")
systemd-umount "$WORK_DIR/simple.img"
# 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"
# --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
mkfs.vfat -n owner-vfat "$WORK_DIR/owner-vfat.img"
LOOP="$(losetup --show --find "$WORK_DIR/owner-vfat.img")"
# 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"
# 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.
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
# Mount it and check the UID/GID
[[ "$(stat -c "%U:%G" "$WORK_DIR/mnt")" == "root:root" ]]
systemd-mount --owner=testuser "$LOOP" "$WORK_DIR/mnt"
systemctl status "$WORK_DIR/mnt"
[[ "$(stat -c "%U:%G" "$WORK_DIR/mnt")" == "testuser:testuser" ]]
touch "$WORK_DIR/mnt/hello"
[[ "$(stat -c "%U:%G" "$WORK_DIR/mnt/hello")" == "testuser:testuser" ]]
systemd-umount LABEL=owner-vfat

View File

@ -3,11 +3,6 @@
set -eux set -eux
set -o pipefail set -o pipefail
if systemd-detect-virt --quiet --container; then
echo "running on container, skipping."
exit 0
fi
if ! command -v bootctl >/dev/null; then if ! command -v bootctl >/dev/null; then
echo "bootctl not found, skipping." echo "bootctl not found, skipping."
exit 0 exit 0
@ -24,6 +19,8 @@ fi
# shellcheck source=test/units/test-control.sh # shellcheck source=test/units/test-control.sh
. "$(dirname "$0")"/test-control.sh . "$(dirname "$0")"/test-control.sh
(! systemd-detect-virt -cq)
basic_tests() { basic_tests() {
bootctl "$@" --help bootctl "$@" --help
bootctl "$@" --version bootctl "$@" --version

View File

@ -19,12 +19,9 @@ at_exit() {
rm -fv -- "$CORE_TEST_BIN" "$CORE_TEST_UNPRIV_BIN" "$MAKE_DUMP_SCRIPT" "$MAKE_STACKTRACE_DUMP" rm -fv -- "$CORE_TEST_BIN" "$CORE_TEST_UNPRIV_BIN" "$MAKE_DUMP_SCRIPT" "$MAKE_STACKTRACE_DUMP"
} }
trap at_exit EXIT (! systemd-detect-virt -cq)
if systemd-detect-virt -cq; then trap at_exit EXIT
echo "Running in a container, skipping the systemd-coredump test..."
exit 0
fi
# To make all coredump entries stored in system.journal. # To make all coredump entries stored in system.journal.
journalctl --rotate journalctl --rotate
@ -81,7 +78,7 @@ timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $CORE_TEST_BIN |
if cgroupfs_supports_user_xattrs; then if cgroupfs_supports_user_xattrs; then
# Make sure we can forward crashes back to containers # Make sure we can forward crashes back to containers
CONTAINER="TEST-74-AUX-UTILS-container" CONTAINER="TEST-87-AUX-UTILS-VM-container"
mkdir -p "/var/lib/machines/$CONTAINER" mkdir -p "/var/lib/machines/$CONTAINER"
mkdir -p "/run/systemd/system/systemd-nspawn@$CONTAINER.service.d" mkdir -p "/run/systemd/system/systemd-nspawn@$CONTAINER.service.d"

View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eux
set -o pipefail
(! systemd-detect-virt -cq)
SYSTEMD_IN_CHROOT=1 systemd-detect-virt --chroot
(! SYSTEMD_IN_CHROOT=0 systemd-detect-virt --chroot)
unshare --mount-proc --fork --user --pid systemd-detect-virt --container

View File

@ -10,12 +10,9 @@ at_exit() {
rm -rfv "${CONFIG_FILE:?}" rm -rfv "${CONFIG_FILE:?}"
} }
trap at_exit EXIT (! systemd-detect-virt -cq)
if systemd-detect-virt -cq; then trap at_exit EXIT
echo "Running in a container, skipping the systemd-modules-load test..."
exit 0
fi
ORIG_MODULES_LOAD_CONFIG="$(systemd-analyze cat-config modules-load.d)" ORIG_MODULES_LOAD_CONFIG="$(systemd-analyze cat-config modules-load.d)"

View File

@ -0,0 +1,182 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eux
set -o pipefail
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
at_exit() {
set +e
[[ -n "${LOOP:-}" ]] && losetup -d "$LOOP"
[[ -n "${WORK_DIR:-}" ]] && rm -fr "$WORK_DIR"
}
(! systemd-detect-virt -cq)
trap at_exit EXIT
WORK_DIR="$(mktemp -d)"
mkdir -p "$WORK_DIR/mnt"
systemd-mount --list
systemd-mount --list --full
systemd-mount --list --no-legend
systemd-mount --list --no-pager
systemd-mount --list --quiet
systemd-mount --list --json=pretty
# 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"
# Set up a simple block device for further tests
dd if=/dev/zero of="$WORK_DIR/simple.img" bs=1M count=16
mkfs.ext4 -L sd-mount-test "$WORK_DIR/simple.img"
LOOP="$(losetup --show --find "$WORK_DIR/simple.img")"
udevadm wait --timeout 60 --settle "$LOOP"
# 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"
mount "$LOOP" "$WORK_DIR/mnt"
touch "$WORK_DIR/mnt/foo.bar"
umount "$LOOP"
(! mountpoint "$WORK_DIR/mnt")
# 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"
# 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"
# 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"
# 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
systemd-mount --options=ro,x-foo-bar "$LOOP" "$WORK_DIR/mnt"
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
systemd-mount -A --automount-property="Description=Bar Baz" "$LOOP" "$WORK_DIR/mnt"
systemctl show -P Description "$(systemd-escape --path "$WORK_DIR/mnt").automount" | grep -q "Bar Baz"
test -e "$WORK_DIR/mnt/foo.bar"
# 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")
# 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
# The automount unit should disappear once the underlying blockdev is gone
timeout 10s bash -c "while systemctl status '$(systemd-escape --path "$WORK_DIR/mnt".automount)'; do sleep .2; done"
# Mount a disk image
systemd-mount --discover "$WORK_DIR/simple.img"
# We can access files in the image even if the loopback block device is not initialized by udevd.
test -e /run/media/system/simple.img/foo.bar
# systemd-mount --list and systemd-umount require the loopback block device is initialized by udevd.
udevadm settle --timeout 30
assert_in "/dev/loop.* ext4 +sd-mount-test" "$(systemd-mount --list --full)"
LOOP_AUTO=$(systemd-mount --list --full --no-legend | awk '$7 == "sd-mount-test" { print $1 }')
LOOP_AUTO_DEVPATH=$(udevadm info --query property --property DEVPATH --value "$LOOP_AUTO")
systemd-umount "$WORK_DIR/simple.img"
# 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"
# --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
mkfs.vfat -n owner-vfat "$WORK_DIR/owner-vfat.img"
LOOP="$(losetup --show --find "$WORK_DIR/owner-vfat.img")"
# 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"
# 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.
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
# Mount it and check the UID/GID
[[ "$(stat -c "%U:%G" "$WORK_DIR/mnt")" == "root:root" ]]
systemd-mount --owner=testuser "$LOOP" "$WORK_DIR/mnt"
systemctl status "$WORK_DIR/mnt"
[[ "$(stat -c "%U:%G" "$WORK_DIR/mnt")" == "testuser:testuser" ]]
touch "$WORK_DIR/mnt/hello"
[[ "$(stat -c "%U:%G" "$WORK_DIR/mnt/hello")" == "testuser:testuser" ]]
systemd-umount LABEL=owner-vfat

View File

@ -5,10 +5,7 @@ set -o pipefail
systemctl log-level info systemctl log-level info
if systemd-detect-virt -cq; then (! systemd-detect-virt -cq)
echo "Running in a container, skipping the systemd-pstore test..."
exit 0
fi
DUMMY_DMESG_0="$(mktemp)" DUMMY_DMESG_0="$(mktemp)"
cat >"$DUMMY_DMESG_0" <<\EOF cat >"$DUMMY_DMESG_0" <<\EOF

View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eux
set -o pipefail
# shellcheck source=test/units/test-control.sh
. "$(dirname "$0")"/test-control.sh
run_subtests
touch /testok