]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: support coreutils built with --enable-single-binary=symlinks
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 27 Sep 2025 04:29:07 +0000 (13:29 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 7 Dec 2025 00:09:03 +0000 (09:09 +0900)
Alpine/postmarketOS build coreutils with --enable-single-binary=symlinks.
In that case, all commands provided by coreutils are symlink to
/usr/bin/coreutils, and it calls prctl(PR_SET_NAME, argv[0]), hence the comm
will be the path to the symlink.

This also makes not kill sleep command with SIGKILL in TEST-17-UDEV, that is
totally unnecessary.

src/test/test-execute.c
test/integration-tests/TEST-17-UDEV/meson.build
test/integration-tests/TEST-59-RELOADING-RESTART/meson.build
test/units/TEST-07-PID1.private-pids.sh
test/units/TEST-17-UDEV.device_is_processing.sh
test/units/TEST-82-SOFTREBOOT.sh
test/units/TEST-87-AUX-UTILS-VM.coredump.sh

index 4c334749425a141b5ba9807b3c48606d9874ebea..16476bc0d5d8d65926652af4af90e7c5a40faae0 100644 (file)
@@ -368,6 +368,12 @@ static void test_exec_workingdirectory(Manager *m) {
 }
 
 static void test_exec_execsearchpath(Manager *m) {
+        int r;
+
+        ASSERT_OK(r = is_symlink("/bin/ls"));
+        if (r > 0)
+                return (void) log_tests_skipped("/bin/ls is a symlink, maybe coreutils is built with --enable-single-binary=symlinks");
+
         ASSERT_OK(mkdir_p("/tmp/test-exec_execsearchpath", 0755));
 
         ASSERT_OK(copy_file("/bin/ls", "/tmp/test-exec_execsearchpath/ls_temp", 0,  0777, COPY_REPLACE));
index 1d72c56e8c691dc0628e2b93cfb0b3495e1bf92c..58f809ba2937dd7b2d52c0bb5ecd89b4907e08a2 100644 (file)
@@ -4,6 +4,6 @@ integration_tests += [
         integration_test_template + {
                 'name' : fs.name(meson.current_source_dir()),
                 'vm' : true,
-                'coredump-exclude-regex' : '/(sleep|udevadm)$',
+                'coredump-exclude-regex' : '/(coreutils|sleep|udevadm)$',
         },
 ]
index 3d12024cef34a6c11b6f8c9162b22e39ab0eb062..f5fae753e2d025790537b60d4154599084555da7 100644 (file)
@@ -3,6 +3,6 @@
 integration_tests += [
         integration_test_template + {
                 'name' : fs.name(meson.current_source_dir()),
-                'coredump-exclude-regex' : '/(sleep|bash|systemd-notify)$',
+                'coredump-exclude-regex' : '/(coreutils|sleep|bash|systemd-notify)$',
         },
 ]
index 091535e3da0fc1a4545cce9cd961d11804c24e50..ae7e4538b395a75031c145e4d33c936b1639ee9f 100755 (executable)
@@ -50,7 +50,11 @@ testcase_basic() {
     systemd-run -p PrivatePIDs=yes --remain-after-exit --unit TEST-07-PID1-private-pid sleep infinity
     # Wait for ExecMainPID to be correctly populated as there might be a race between spawning service
     # and actual exec child process
-    timeout 10s bash -xec 'until [[ "$(cat /proc/$(systemctl show TEST-07-PID1-private-pid.service -p ExecMainPID --value)/comm)" == sleep ]]; do sleep .5; done'
+    # Note, Alpine/postmarketOS build coreutils with --enable-single-binary=symlinks. In that case, coreutils
+    # calls prctl(PR_SET_NAME, argv[0]), hence the comm will be the path to the symlink. If the sleep file is
+    # a dedicated binary (like most other distributions do), the comm will be the filename, i.e. "sleep". So,
+    # here we need to cut the directory part.
+    timeout 10s bash -xec 'until [[ "$(cat /proc/$(systemctl show TEST-07-PID1-private-pid.service -p ExecMainPID --value)/comm | sed -e "s|.*/||")" == sleep ]]; do sleep .5; done'
     pid=$(systemctl show TEST-07-PID1-private-pid.service -p ExecMainPID --value)
     kill -9 "$pid"
     timeout 10s bash -xec 'while [[ "$(systemctl show -P SubState TEST-07-PID1-private-pid.service)" != "failed" ]]; do sleep .5; done'
index 7bdb5fc7053bddaeb17728579148a8b16201a433..34fa126d823b97cabf2aad986ab5d5b21d9e6b1e 100755 (executable)
@@ -15,9 +15,7 @@ at_exit() {
     systemctl stop testsleep.service
     rm -f /run/udev/udev.conf.d/timeout.conf
     rm -f /run/udev/rules.d/99-testsuite.rules
-    # Forcibly kills sleep command invoked by the udev rule before restarting,
-    # otherwise systemctl restart below will takes longer.
-    killall -KILL sleep
+    killall --regexp '(|/usr/bin/)sleep'
     udevadm control --reload
     ip link del "$IFNAME"
 }
@@ -62,7 +60,7 @@ done
 grep -q -F 'ID_PROCESSING=1' "/run/udev/data/n${IFINDEX}"
 
 # Forcibly kill sleep command invoked by the udev rule to finish processing the add event.
-killall sleep
+killall --regexp '(|/usr/bin/)sleep'
 udevadm settle --timeout=30
 
 # Check if ID_PROCESSING flag is unset, and the device units are active.
index 274e54a1178007753dc3c1a6d8420f3316ec0bc3..378ac2a2a296d0bf8baf9d045a44e52d3d212d87 100755 (executable)
@@ -90,12 +90,16 @@ if [ -f /run/TEST-82-SOFTREBOOT.touch3 ]; then
 
     # Check that the surviving services are still around
     test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-survive.service)" = "active"
-    test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-survive-argv.service)" = "active"
+    if [[ ! -L $(command -v sleep) ]]; then
+        test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-survive-argv.service)" = "active"
+    fi
     test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-nosurvive-sigterm.service)" != "active"
     test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-nosurvive.service)" != "active"
 
     [[ ! -e /run/credentials/TEST-82-SOFTREBOOT-nosurvive.service ]]
-    assert_eq "$(cat /run/credentials/TEST-82-SOFTREBOOT-survive-argv.service/preserve)" "yay"
+    if [[ ! -L $(command -v sleep) ]]; then
+        assert_eq "$(cat /run/credentials/TEST-82-SOFTREBOOT-survive-argv.service/preserve)" "yay"
+    fi
 
     # There may be huge amount of pending messages in sockets. Processing them may cause journal rotation and
     # removal of old archived journal files. If a journal file is removed during journalctl reading it,
@@ -130,7 +134,9 @@ elif [ -f /run/TEST-82-SOFTREBOOT.touch2 ]; then
 
     # Check that the surviving services are still around
     test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-survive.service)" = "active"
-    test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-survive-argv.service)" = "active"
+    if [[ ! -L $(command -v sleep) ]]; then
+        test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-survive-argv.service)" = "active"
+    fi
     test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-nosurvive-sigterm.service)" != "active"
     test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-nosurvive.service)" != "active"
 
@@ -186,7 +192,9 @@ elif [ -f /run/TEST-82-SOFTREBOOT.touch ]; then
 
     # Check that the surviving services are still around
     test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-survive.service)" = "active"
-    test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-survive-argv.service)" = "active"
+    if [[ ! -L $(command -v sleep) ]]; then
+        test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-survive-argv.service)" = "active"
+    fi
     test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-nosurvive-sigterm.service)" != "active"
     test "$(systemctl show -P ActiveState TEST-82-SOFTREBOOT-nosurvive.service)" != "active"
 
@@ -272,15 +280,19 @@ EOF
     # '@', and the second will use SurviveFinalKillSignal=yes. Both should survive.
     # By writing to stdout, which is connected to the journal, we also ensure logging doesn't break across
     # soft reboots due to journald being temporarily stopped.
-    systemd-run --service-type=notify --unit=TEST-82-SOFTREBOOT-survive-argv.service \
-        --property SurviveFinalKillSignal=no \
-        --property IgnoreOnIsolate=yes \
-        --property DefaultDependencies=no \
-        --property After=basic.target \
-        --property "Conflicts=reboot.target kexec.target poweroff.target halt.target emergency.target rescue.target" \
-        --property "Before=reboot.target kexec.target poweroff.target halt.target emergency.target rescue.target" \
-        --property SetCredential=preserve:yay \
-         "$survive_argv"
+    # Note, when coreutils is built with --enable-single-binary=symlinks, unfortunately we cannot freely rename
+    # sleep command, hence we cannot test the feature.
+    if [[ ! -L $(command -v sleep) ]]; then
+        systemd-run --service-type=notify --unit=TEST-82-SOFTREBOOT-survive-argv.service \
+            --property SurviveFinalKillSignal=no \
+            --property IgnoreOnIsolate=yes \
+            --property DefaultDependencies=no \
+            --property After=basic.target \
+            --property "Conflicts=reboot.target kexec.target poweroff.target halt.target emergency.target rescue.target" \
+            --property "Before=reboot.target kexec.target poweroff.target halt.target emergency.target rescue.target" \
+            --property SetCredential=preserve:yay \
+            "$survive_argv"
+    fi
     # shellcheck disable=SC2016
     systemd-run --service-type=exec --unit=TEST-82-SOFTREBOOT-survive.service \
         --property TemporaryFileSystem="/run /tmp /var" \
index 19f0fa280e78658ede2a214f3962e729a2d9d664..1b37197bde0ac5ff9be32acc2dcd023cb60ae280 100755 (executable)
@@ -4,7 +4,12 @@ set -eux
 set -o pipefail
 
 # shellcheck source=test/units/util.sh
- . "$(dirname "$0")"/util.sh
+. "$(dirname "$0")"/util.sh
+
+if [[ -L $(command -v sleep) ]]; then
+    # coreutils is built with --enable-single-binary=symlinks, and we cannot rename it.
+    exit 0
+fi
 
 # Make sure the binary name fits into 15 characters
 CORE_TEST_BIN="/tmp/test-dump"