mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
test: wait for userspace mount options applied (#38327)
Hopefully fixes #32712.
This commit is contained in:
@@ -133,6 +133,10 @@ that make use of `run_testcases`.
|
||||
|
||||
`TEST_SKIP_TESTCASE=testcase`: takes a space separated list of testcases to skip.
|
||||
|
||||
`TEST_SAVE_JOURNAL=0|1|fail`: When `0`, journal file will be removed on exit.
|
||||
When `1`, journal file will be saved at `$BUILD_DIR/test/journal`. When `fail`,
|
||||
journal file will be saved only when the test is failed. Defaults to `fail`.
|
||||
|
||||
`TEST_JOURNAL_USE_TMP=1`: Write test journal to `/tmp` while the test is in
|
||||
progress and only move the journal to its final location in the build directory
|
||||
(`$BUILD_DIR/test/journal`) when the test is finished.
|
||||
|
||||
8
test/integration-tests/TEST-10-MOUNT/meson.build
Normal file
8
test/integration-tests/TEST-10-MOUNT/meson.build
Normal file
@@ -0,0 +1,8 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
integration_tests += [
|
||||
integration_test_template + {
|
||||
'name' : fs.name(meson.current_source_dir()),
|
||||
'vm' : true,
|
||||
},
|
||||
]
|
||||
@@ -660,7 +660,12 @@ def main() -> None:
|
||||
journal_file = Path(shutil.move(journal_file, dst))
|
||||
|
||||
if shell or (result.returncode in (args.exit_code, 77) and not coredumps and not sanitizer):
|
||||
exit(0 if shell or result.returncode == args.exit_code else 77)
|
||||
exit_code = 0 if shell or result.returncode == args.exit_code else 77
|
||||
exit_str = 'succeeded' if exit_code == 0 else 'skipped'
|
||||
else:
|
||||
# 0 also means we failed so translate that to a non-zero exit code to mark the test as failed.
|
||||
exit_code = result.returncode or 1
|
||||
exit_str = 'failed'
|
||||
|
||||
if journal_file.exists():
|
||||
ops = []
|
||||
@@ -678,10 +683,11 @@ def main() -> None:
|
||||
|
||||
ops += [f'journalctl --file {journal_file} --no-hostname -o short-monotonic -u {args.unit} -p info']
|
||||
|
||||
print(f'Test failed, relevant logs can be viewed with: \n\n{(" && ".join(ops))}\n', file=sys.stderr)
|
||||
print(
|
||||
f'Test {exit_str}, relevant logs can be viewed with: \n\n{(" && ".join(ops))}\n', file=sys.stderr
|
||||
)
|
||||
|
||||
# 0 also means we failed so translate that to a non-zero exit code to mark the test as failed.
|
||||
exit(result.returncode or 1)
|
||||
exit(exit_code)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -43,6 +43,7 @@ foreach dirname : [
|
||||
'TEST-07-PID1',
|
||||
'TEST-08-INITRD',
|
||||
'TEST-09-REBOOT',
|
||||
'TEST-10-MOUNT',
|
||||
'TEST-13-NSPAWN',
|
||||
'TEST-15-DROPIN',
|
||||
'TEST-16-EXTEND-TIMEOUT',
|
||||
|
||||
169
test/units/TEST-10-MOUNT.sh
Executable file
169
test/units/TEST-10-MOUNT.sh
Executable file
@@ -0,0 +1,169 @@
|
||||
#!/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
|
||||
# shellcheck source=test/units/util.sh
|
||||
. "$(dirname "$0")"/util.sh
|
||||
|
||||
teardown_test_dependencies() (
|
||||
set +eux
|
||||
|
||||
if mountpoint /tmp/deptest; then
|
||||
umount /tmp/deptest
|
||||
fi
|
||||
|
||||
if [[ -n "${LOOP}" ]]; then
|
||||
losetup -d "${LOOP}" || :
|
||||
fi
|
||||
if [[ -n "${LOOP_0}" ]]; then
|
||||
losetup -d "${LOOP_0}" || :
|
||||
fi
|
||||
if [[ -n "${LOOP_1}" ]]; then
|
||||
losetup -d "${LOOP_1}" || :
|
||||
fi
|
||||
|
||||
rm -f /tmp/TEST-60-MOUNT-RATELIMIT-dependencies-0.img
|
||||
rm -f /tmp/TEST-60-MOUNT-RATELIMIT-dependencies-1.img
|
||||
|
||||
rm -f /run/systemd/system/tmp-deptest.mount
|
||||
systemctl daemon-reload
|
||||
|
||||
return 0
|
||||
)
|
||||
|
||||
setup_loop() {
|
||||
truncate -s 30m "/tmp/TEST-60-MOUNT-RATELIMIT-dependencies-${1?}.img"
|
||||
sfdisk --wipe=always "/tmp/TEST-60-MOUNT-RATELIMIT-dependencies-${1?}.img" <<EOF
|
||||
label:gpt
|
||||
|
||||
name="loop${1?}-part1"
|
||||
EOF
|
||||
LOOP=$(losetup -P --show -f "/tmp/TEST-60-MOUNT-RATELIMIT-dependencies-${1?}.img")
|
||||
udevadm wait --settle --timeout=30 "${LOOP}"
|
||||
udevadm lock --timeout=30 --device="${LOOP}" mkfs.ext4 -L "partname${1?}-1" "${LOOP}p1"
|
||||
}
|
||||
|
||||
check_dependencies() {
|
||||
local escaped_0 escaped_1 after
|
||||
|
||||
escaped_0=$(systemd-escape -p "${LOOP_0}p1")
|
||||
escaped_1=$(systemd-escape -p "${LOOP_1}p1")
|
||||
|
||||
if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
fi
|
||||
|
||||
# mount LOOP_0
|
||||
mount -t ext4 "${LOOP_0}p1" /tmp/deptest
|
||||
timeout 10 bash -c 'until systemctl -q is-active tmp-deptest.mount; do sleep .1; done'
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_in "local-fs-pre.target" "$after"
|
||||
assert_not_in "remote-fs-pre.target" "$after"
|
||||
assert_not_in "network.target" "$after"
|
||||
assert_in "${escaped_0}.device" "$after"
|
||||
assert_in "blockdev@${escaped_0}.target" "$after"
|
||||
assert_not_in "${escaped_1}.device" "$after"
|
||||
assert_not_in "blockdev@${escaped_1}.target" "$after"
|
||||
systemctl stop tmp-deptest.mount
|
||||
|
||||
if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
fi
|
||||
|
||||
# mount LOOP_1 (using fake _netdev option)
|
||||
mount -t ext4 -o _netdev "${LOOP_1}p1" /tmp/deptest
|
||||
timeout 10 bash -c 'until systemctl -q is-active tmp-deptest.mount; do sleep .1; done'
|
||||
# When a device is mounted with userspace options such as _netdev, even when the mount event source is
|
||||
# triggered, only /proc/self/mountinfo may be updated, and /run/mount/utab may not be updated yet.
|
||||
# Hence, the mount unit may be created/updated without the userspace options. In that case, the mount
|
||||
# event source will be retriggered when /run/mount/utab is updated, and the mount unit will be updated
|
||||
# again with the userspace options. Typically, the window between the two calls is very short, but when
|
||||
# the mount event source is ratelimited after the first event, processing the second event may be delayed
|
||||
# about 1 secound. Hence, here we need to wait for a while.
|
||||
timeout 10 bash -c 'until systemctl show --property=After --value tmp-deptest.mount | grep -q -F remote-fs-pre.target; do sleep .1; done'
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
assert_not_in "${escaped_0}.device" "$after"
|
||||
assert_not_in "blockdev@${escaped_0}.target" "$after"
|
||||
assert_in "${escaped_1}.device" "$after"
|
||||
assert_in "blockdev@${escaped_1}.target" "$after"
|
||||
systemctl stop tmp-deptest.mount
|
||||
|
||||
if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
fi
|
||||
|
||||
# mount tmpfs
|
||||
mount -t tmpfs tmpfs /tmp/deptest
|
||||
timeout 10 bash -c 'until systemctl -q is-active tmp-deptest.mount; do sleep .1; done'
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_in "local-fs-pre.target" "$after"
|
||||
assert_not_in "remote-fs-pre.target" "$after"
|
||||
assert_not_in "network.target" "$after"
|
||||
assert_not_in "${escaped_0}.device" "$after"
|
||||
assert_not_in "blockdev@${escaped_0}.target" "$after"
|
||||
assert_not_in "${escaped_1}.device" "$after"
|
||||
assert_not_in "blockdev@${escaped_1}.target" "$after"
|
||||
systemctl stop tmp-deptest.mount
|
||||
|
||||
if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
fi
|
||||
}
|
||||
|
||||
testcase_dependencies() {
|
||||
# test for issue #19983 and #23552.
|
||||
|
||||
if systemd-detect-virt --quiet --container; then
|
||||
echo "Skipping test_dependencies in container"
|
||||
return
|
||||
fi
|
||||
|
||||
trap teardown_test_dependencies RETURN EXIT ERR INT TERM
|
||||
|
||||
setup_loop 0
|
||||
LOOP_0="${LOOP}"
|
||||
LOOP=
|
||||
setup_loop 1
|
||||
LOOP_1="${LOOP}"
|
||||
LOOP=
|
||||
|
||||
mkdir -p /tmp/deptest
|
||||
|
||||
# without .mount file
|
||||
check_dependencies
|
||||
|
||||
# create .mount file
|
||||
mkdir -p /run/systemd/system
|
||||
cat >/run/systemd/system/tmp-deptest.mount <<EOF
|
||||
[Mount]
|
||||
Where=/tmp/deptest
|
||||
What=192.168.0.1:/tmp/mnt
|
||||
Type=nfs
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
|
||||
# with .mount file
|
||||
check_dependencies
|
||||
}
|
||||
|
||||
run_testcases
|
||||
|
||||
touch /testok
|
||||
@@ -8,154 +8,6 @@ set -o pipefail
|
||||
# shellcheck source=test/units/util.sh
|
||||
. "$(dirname "$0")"/util.sh
|
||||
|
||||
teardown_test_dependencies() (
|
||||
set +eux
|
||||
|
||||
if mountpoint /tmp/deptest; then
|
||||
umount /tmp/deptest
|
||||
fi
|
||||
|
||||
if [[ -n "${LOOP}" ]]; then
|
||||
losetup -d "${LOOP}" || :
|
||||
fi
|
||||
if [[ -n "${LOOP_0}" ]]; then
|
||||
losetup -d "${LOOP_0}" || :
|
||||
fi
|
||||
if [[ -n "${LOOP_1}" ]]; then
|
||||
losetup -d "${LOOP_1}" || :
|
||||
fi
|
||||
|
||||
rm -f /tmp/TEST-60-MOUNT-RATELIMIT-dependencies-0.img
|
||||
rm -f /tmp/TEST-60-MOUNT-RATELIMIT-dependencies-1.img
|
||||
|
||||
rm -f /run/systemd/system/tmp-deptest.mount
|
||||
systemctl daemon-reload
|
||||
|
||||
return 0
|
||||
)
|
||||
|
||||
setup_loop() {
|
||||
truncate -s 30m "/tmp/TEST-60-MOUNT-RATELIMIT-dependencies-${1?}.img"
|
||||
sfdisk --wipe=always "/tmp/TEST-60-MOUNT-RATELIMIT-dependencies-${1?}.img" <<EOF
|
||||
label:gpt
|
||||
|
||||
name="loop${1?}-part1"
|
||||
EOF
|
||||
LOOP=$(losetup -P --show -f "/tmp/TEST-60-MOUNT-RATELIMIT-dependencies-${1?}.img")
|
||||
udevadm wait --settle --timeout=30 "${LOOP}"
|
||||
udevadm lock --timeout=30 --device="${LOOP}" mkfs.ext4 -L "partname${1?}-1" "${LOOP}p1"
|
||||
}
|
||||
|
||||
check_dependencies() {
|
||||
local escaped_0 escaped_1 after
|
||||
|
||||
escaped_0=$(systemd-escape -p "${LOOP_0}p1")
|
||||
escaped_1=$(systemd-escape -p "${LOOP_1}p1")
|
||||
|
||||
if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
fi
|
||||
|
||||
# mount LOOP_0
|
||||
mount -t ext4 "${LOOP_0}p1" /tmp/deptest
|
||||
timeout 10 bash -c 'until systemctl -q is-active tmp-deptest.mount; do sleep .1; done'
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_in "local-fs-pre.target" "$after"
|
||||
assert_not_in "remote-fs-pre.target" "$after"
|
||||
assert_not_in "network.target" "$after"
|
||||
assert_in "${escaped_0}.device" "$after"
|
||||
assert_in "blockdev@${escaped_0}.target" "$after"
|
||||
assert_not_in "${escaped_1}.device" "$after"
|
||||
assert_not_in "blockdev@${escaped_1}.target" "$after"
|
||||
systemctl stop tmp-deptest.mount
|
||||
|
||||
if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
fi
|
||||
|
||||
# mount LOOP_1 (using fake _netdev option)
|
||||
mount -t ext4 -o _netdev "${LOOP_1}p1" /tmp/deptest
|
||||
timeout 10 bash -c 'until systemctl -q is-active tmp-deptest.mount; do sleep .1; done'
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
assert_not_in "${escaped_0}.device" "$after"
|
||||
assert_not_in "blockdev@${escaped_0}.target" "$after"
|
||||
assert_in "${escaped_1}.device" "$after"
|
||||
assert_in "blockdev@${escaped_1}.target" "$after"
|
||||
systemctl stop tmp-deptest.mount
|
||||
|
||||
if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
fi
|
||||
|
||||
# mount tmpfs
|
||||
mount -t tmpfs tmpfs /tmp/deptest
|
||||
timeout 10 bash -c 'until systemctl -q is-active tmp-deptest.mount; do sleep .1; done'
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_in "local-fs-pre.target" "$after"
|
||||
assert_not_in "remote-fs-pre.target" "$after"
|
||||
assert_not_in "network.target" "$after"
|
||||
assert_not_in "${escaped_0}.device" "$after"
|
||||
assert_not_in "blockdev@${escaped_0}.target" "$after"
|
||||
assert_not_in "${escaped_1}.device" "$after"
|
||||
assert_not_in "blockdev@${escaped_1}.target" "$after"
|
||||
systemctl stop tmp-deptest.mount
|
||||
|
||||
if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
|
||||
after=$(systemctl show --property=After --value tmp-deptest.mount)
|
||||
assert_not_in "local-fs-pre.target" "$after"
|
||||
assert_in "remote-fs-pre.target" "$after"
|
||||
assert_in "network.target" "$after"
|
||||
fi
|
||||
}
|
||||
|
||||
testcase_dependencies() {
|
||||
# test for issue #19983 and #23552.
|
||||
|
||||
if systemd-detect-virt --quiet --container; then
|
||||
echo "Skipping test_dependencies in container"
|
||||
return
|
||||
fi
|
||||
|
||||
trap teardown_test_dependencies RETURN
|
||||
|
||||
setup_loop 0
|
||||
LOOP_0="${LOOP}"
|
||||
LOOP=
|
||||
setup_loop 1
|
||||
LOOP_1="${LOOP}"
|
||||
LOOP=
|
||||
|
||||
mkdir -p /tmp/deptest
|
||||
|
||||
# without .mount file
|
||||
check_dependencies
|
||||
|
||||
# create .mount file
|
||||
mkdir -p /run/systemd/system
|
||||
cat >/run/systemd/system/tmp-deptest.mount <<EOF
|
||||
[Mount]
|
||||
Where=/tmp/deptest
|
||||
What=192.168.0.1:/tmp/mnt
|
||||
Type=nfs
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
|
||||
# with .mount file
|
||||
check_dependencies
|
||||
}
|
||||
|
||||
testcase_issue_20329() {
|
||||
# test that handling of mount start jobs is delayed when /proc/self/mouninfo monitor is rate limited
|
||||
|
||||
@@ -324,7 +176,7 @@ cat >/run/systemd/journald.conf.d/99-ratelimit.conf <<EOF
|
||||
[Journal]
|
||||
RateLimitBurst=0
|
||||
EOF
|
||||
systemctl restart systemd-journald.service
|
||||
systemctl reload systemd-journald.service
|
||||
|
||||
run_testcases
|
||||
|
||||
|
||||
Reference in New Issue
Block a user