diff options
Diffstat (limited to 'test')
-rwxr-xr-x | test/TEST-01-BASIC/test.sh | 34 | ||||
l--------- | test/TEST-08-INITRD/Makefile | 1 | ||||
-rwxr-xr-x | test/TEST-08-INITRD/test.sh | 101 | ||||
-rwxr-xr-x | test/units/testsuite-01.sh | 5 | ||||
-rw-r--r-- | test/units/testsuite-08.service | 9 | ||||
-rwxr-xr-x | test/units/testsuite-08.sh | 22 |
6 files changed, 138 insertions, 34 deletions
diff --git a/test/TEST-01-BASIC/test.sh b/test/TEST-01-BASIC/test.sh index c729e95f1d..93185cf896 100755 --- a/test/TEST-01-BASIC/test.sh +++ b/test/TEST-01-BASIC/test.sh @@ -17,37 +17,13 @@ KERNEL_APPEND="foo -- -z bar --- baz $KERNEL_APPEND" . "${TEST_BASE_DIR:?}/test-functions" test_append_files() { - # install tests manually so the test is functional even when -Dinstall-tests=false - local dst="${1:?}/usr/lib/systemd/tests/testdata/units/" + local workspace="${1:?}" + local dst + + # Install tests manually so the test is functional even when -Dinstall-tests=false + dst="$workspace/usr/lib/systemd/tests/testdata/units/" mkdir -p "$dst" cp -v "$TEST_UNITS_DIR"/{testsuite-01,end}.service "$TEST_UNITS_DIR/testsuite.target" "$dst" } -# Setup a one shot service in initrd that creates a dummy bind mount under /run -# to check if the mount persists though the initrd transition. The "check" part -# is in the respective testsuite-01.sh script. -# -# See: https://github.com/systemd/systemd/issues/28452 -run_qemu_hook() { - local extra="$WORKDIR/initrd.extra" - - mkdir -m 755 "$extra" - mkdir -m 755 "$extra/etc" "$extra/etc/systemd" "$extra/etc/systemd/system" "$extra/etc/systemd/system/initrd.target.wants" - - cat >"$extra/etc/systemd/system/initrd-run-mount.service" <<EOF -[Unit] -Description=Create a mount in /run that should survive the transition from initrd - -[Service] -Type=oneshot -RemainAfterExit=yes -ExecStart=sh -xec "mkdir /run/initrd-mount-source /run/initrd-mount-target; mount -v --bind /run/initrd-mount-source /run/initrd-mount-target" -EOF - ln -svrf "$extra/etc/systemd/system/initrd-run-mount.service" "$extra/etc/systemd/system/initrd.target.wants/initrd-run-mount.service" - - (cd "$extra" && find . | cpio -o -H newc -R root:root > "$extra.cpio") - - INITRD_EXTRA="$extra.cpio" -} - do_test "$@" diff --git a/test/TEST-08-INITRD/Makefile b/test/TEST-08-INITRD/Makefile new file mode 120000 index 0000000000..e9f93b1104 --- /dev/null +++ b/test/TEST-08-INITRD/Makefile @@ -0,0 +1 @@ +../TEST-01-BASIC/Makefile
\ No newline at end of file diff --git a/test/TEST-08-INITRD/test.sh b/test/TEST-08-INITRD/test.sh new file mode 100755 index 0000000000..29fd1f7899 --- /dev/null +++ b/test/TEST-08-INITRD/test.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -e + +TEST_DESCRIPTION="Test various scenarios involving transition from/to initrd" +TEST_NO_NSPAWN=1 + +# shellcheck source=test/test-functions +. "${TEST_BASE_DIR:?}/test-functions" + +test_append_files() { + local workspace="${1:?}" + local sd_initrd file dir + + # Create a shutdown initrd + # + # This should provide coverage for shutdown initrd related issues, see: + # - https://github.com/systemd/systemd/issues/28645 + # - https://github.com/systemd/systemd/pull/28648 + # - https://github.com/systemd/systemd/pull/28793 + # + # This is a bit messier than I originally anticipated, as installing our own libraries + # is handled implicitly by install_systemd() which I don't want to use here, since + # I need only the systemd-shutdown binary + sd_initrd="$workspace/shutdown-initrd" + mkdir -p "$sd_initrd/etc" "$sd_initrd/usr" + initdir="$sd_initrd" image_install bash /usr/lib/os-release + ln -srf "$sd_initrd/usr/lib/os-release" "$sd_initrd/etc/initrd-release" + initdir="$sd_initrd" inst_binary "$workspace/usr/lib/systemd/systemd-shutdown" "/usr/lib/systemd/systemd-shutdown" + initdir="$sd_initrd" inst_libs "$sd_initrd/usr/lib/systemd/systemd-shutdown" + # We need to deal with libsystemd stuff explicitly, as we don't call install_systemd() here + while read -r file; do + initdir="$sd_initrd" inst_library "$file" "${file##"$workspace"}" + initdir="$sd_initrd" inst_libs "$file" + done < <(find "$workspace/usr/" -name "libsystemd*.so*") + # Call systemd-shutdown indirectly, so we can show a message that we can check for + # later to make sure the shutdown initrd was actually executed + cat >"$sd_initrd/shutdown" <<\EOF +#!/usr/bin/bash -eu +echo "Hello from shutdown initrd" +exec /usr/lib/systemd/systemd-shutdown "$@" +EOF + chmod +x "$sd_initrd/shutdown" +} + +check_result_qemu_hook() { + local console_log="${TESTDIR:?}/console.log" + + if [[ ! -e "$console_log" ]]; then + dfatal "Missing console log - this shouldn't happen" + return 1 + fi + + # The console log should not contain messages like: + # [ 6.245000] systemd-shutdown[1]: Failed to move /run/initramfs to /: Invalid argument + # [ 6.245955] systemd-shutdown[1]: Failed to switch root to "/run/initramfs": Invalid argument + if grep -qE "systemd-shutdown.+: Failed to move /run/initramfs" "$console_log" || + grep -qE "systemd-shutdown.+: Failed to switch root" "$console_log"; then + derror "sd-shutdown failed to switch root in shutdown initrd" + return 1 + fi + + # Check if the shutdown initrd was executed at all + if ! grep -qE "^Hello from shutdown initrd\s*$" "$console_log"; then + derror "Missing 'hello' message from shutdown initrd" + return 1 + fi + + return 0 +} + +# Setup a one shot service in initrd that creates a dummy bind mount under /run +# to check if the mount persists though the initrd transition. The "check" part +# is in the respective testsuite-08.sh script. +# +# See: https://github.com/systemd/systemd/issues/28452 +run_qemu_hook() { + local extra="${TESTDIR:?}/initrd.extra" + + mkdir -m 755 "$extra" + mkdir -m 755 "$extra/etc" "$extra/etc/systemd" "$extra/etc/systemd/system" "$extra/etc/systemd/system/initrd.target.wants" + + cat >"$extra/etc/systemd/system/initrd-run-mount.service" <<EOF +[Unit] +Description=Create a mount in /run that should survive the transition from initrd + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=mkdir /run/initrd-mount-source /run/initrd-mount-target +ExecStart=mount -v --bind /run/initrd-mount-source /run/initrd-mount-target +ExecStart=cp -v /etc/initrd-release /run/initrd-mount-target/hello-world +EOF + ln -svrf "$extra/etc/systemd/system/initrd-run-mount.service" "$extra/etc/systemd/system/initrd.target.wants/initrd-run-mount.service" + + (cd "$extra" && find . | cpio -o -H newc -R root:root > "$extra.cpio") + + INITRD_EXTRA="$extra.cpio" +} + +do_test "$@" diff --git a/test/units/testsuite-01.sh b/test/units/testsuite-01.sh index a1193ce6fb..780f37ee12 100755 --- a/test/units/testsuite-01.sh +++ b/test/units/testsuite-01.sh @@ -19,11 +19,6 @@ if systemd-detect-virt -q --container; then test ! -e /run/systemd/container cp -afv /tmp/container /run/systemd/container else - # We should've created a mount under /run in initrd (see the other half of the test) - # that should've survived the transition from initrd to the real system - test -d /run/initrd-mount-target - mountpoint /run/initrd-mount-target - # We bring the loopback netdev up only during a full setup, so it should # not get brought back up during reexec if we disable it beforehand [[ "$(ip -o link show lo)" =~ LOOPBACK,UP ]] diff --git a/test/units/testsuite-08.service b/test/units/testsuite-08.service new file mode 100644 index 0000000000..2db35cf5b0 --- /dev/null +++ b/test/units/testsuite-08.service @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[Unit] +Description=TEST-08-INITRD +After=multi-user.target + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/units/testsuite-08.sh b/test/units/testsuite-08.sh new file mode 100755 index 0000000000..9598c8ea0c --- /dev/null +++ b/test/units/testsuite-08.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +if systemd-detect-virt -qc; then + echo >&2 "This test can't run in a container" + exit 1 +fi + +# We should've created a mount under /run in initrd (see the other half of the test) +# that should've survived the transition from initrd to the real system +test -d /run/initrd-mount-target +mountpoint /run/initrd-mount-target +[[ -e /run/initrd-mount-target/hello-world ]] + +# Copy the prepared shutdown initrd to its intended location. Check the respective +# test.sh file for details +mkdir -p /run/initramfs +cp -r /shutdown-initrd/* /run/initramfs/ + +touch /testok |