1
0
mirror of https://github.com/systemd/systemd synced 2025-11-06 02:14:45 +01:00

Compare commits

...

10 Commits

Author SHA1 Message Date
jouyouyun
fea7f5d68b nss-resolve: fix the ip addr family validity check method
`i` only counts the number of matches with the current family,
while `n_addresses` counts the number of matches with the family INET or INET6.
If the address contains both INET and INET6, `assert(i == n_addresses)` will fail.
2025-11-06 07:45:40 +09:00
Chris Down
8ab6925c5e systemctl: Support --timestamp for otherwise named properties
`systemctl show`'s `--timestamp` flag is supposed to reformat all
timestamp-based properties. However, the logic for detecting these
properties was incomplete and only checked if the name ended in
Timestamp.

Expand the check to explicitly include some non-"timestamp" named
properties that really are timestamps.

Fixes: https://github.com/systemd/systemd/issues/39282
2025-11-06 07:45:06 +09:00
Nils K
bea3b300bc
man: fix username prefix mentioned in manual for capsule users (#39573) 2025-11-06 07:33:56 +09:00
Luca Boccassi
fe753735e3
test: wait until the nspawn process is completely dead (#39576)
Before calling io.systemd.MachineImage.List.

The systemd-nspawn process takes a lock in the run() function in
nspawn.c and holds it for the entire runtime of that function. If we
call `machinectl terminate` the machine gets unregistered _before_ we
release the lock, so the original `machinectl status` check would return
early, allowing for a race where we call io.systemd.MachineImage.List
over Varlink when systemd-nspawn still holds the lock because the
process is still running.:

```
[   41.691826] TEST-13-NSPAWN.sh[1102]: + machinectl terminate long-running
[   41.695009] systemd-nspawn[2171]: Trying to halt container by sending TERM to container PID 1. Send SIGTERM again to trigger immediate termination.
[   41.698235] systemd-machined[1192]: Machine long-running terminated.
[   41.709520] TEST-13-NSPAWN.sh[1102]: + systemctl kill --signal=KILL systemd-nspawn@long-running.service
[   41.709169] systemd-nspawn[2171]: Failed to unregister machine: No machine 'long-running' known
[   41.720869] TEST-13-NSPAWN.sh[2346]: + varlinkctl --more call /run/systemd/machine/io.systemd.MachineImage io.systemd.MachineImage.List '{}'
[   41.723359] TEST-13-NSPAWN.sh[2347]: + grep long-running
...
[   41.735453] TEST-13-NSPAWN.sh[2352]: + varlinkctl call /run/systemd/machine/io.systemd.MachineImage io.systemd.MachineImage.List '{"name":"long-running", "acquireMetadata": "yes"}'
[   41.736222] TEST-13-NSPAWN.sh[2353]: + grep OSRelease
[   41.739500] TEST-13-NSPAWN.sh[2352]: Method call io.systemd.MachineImage.List() failed: Device or resource busy
[   41.740641] systemd[1]: Received SIGCHLD.
[   41.740670] systemd[1]: Child 2171 (systemd-nspawn) died (code=killed, status=9/KILL)
[   41.740725] systemd[1]: systemd-nspawn@long-running.service: Child 2171 belongs to systemd-nspawn@long-running.service.
[   41.740748] systemd[1]: systemd-nspawn@long-running.service: Main process exited, code=killed, status=9/KILL
[   41.740755] systemd[1]: systemd-nspawn@long-running.service: Will spawn child (service_enter_stop_post): systemd-nspawn
[   41.740872] systemd[1]: systemd-nspawn@long-running.service: About to execute: systemd-nspawn --cleanup --machine=long-running
...
```

Let's mitigate this by waiting until the corresponding
systemd-nspawn@.service instance enters the 'inactive' state where the
lock should be properly released.

Resolves: https://github.com/systemd/systemd/issues/39547
2025-11-05 19:39:10 +00:00
Luca Boccassi
95d4490a08
test-network: fix issues when running with sanitizers (#39572) 2025-11-05 17:40:29 +00:00
Frantisek Sumsal
3849b0701a test: wait for the backgrounded socat job
It should exit on its own anyway and this will work even if the job has
already finished* (unlike kill).

[*] assuming job control is off, as it's the case when running the
    test suite

Resolves: #39543
2025-11-05 17:38:39 +00:00
Frantisek Sumsal
ed4903660c test: wait until the nspawn process is completely dead
Before calling io.systemd.MachineImage.List.

The systemd-nspawn process takes a lock in the run() function in
nspawn.c and holds it for the entire runtime of that function. If we
call `machinectl terminate` the machine gets unregistered _before_ we
release the lock, so the original `machinectl status` check would return
early, allowing for a race where we call io.systemd.MachineImage.List
over Varlink when systemd-nspawn still holds the lock because the
process is still running.:

[   41.691826] TEST-13-NSPAWN.sh[1102]: + machinectl terminate long-running
[   41.695009] systemd-nspawn[2171]: Trying to halt container by sending TERM to container PID 1. Send SIGTERM again to trigger immediate termination.
[   41.698235] systemd-machined[1192]: Machine long-running terminated.
[   41.709520] TEST-13-NSPAWN.sh[1102]: + systemctl kill --signal=KILL systemd-nspawn@long-running.service
[   41.709169] systemd-nspawn[2171]: Failed to unregister machine: No machine 'long-running' known
[   41.720869] TEST-13-NSPAWN.sh[2346]: + varlinkctl --more call /run/systemd/machine/io.systemd.MachineImage io.systemd.MachineImage.List '{}'
[   41.723359] TEST-13-NSPAWN.sh[2347]: + grep long-running
...
[   41.735453] TEST-13-NSPAWN.sh[2352]: + varlinkctl call /run/systemd/machine/io.systemd.MachineImage io.systemd.MachineImage.List '{"name":"long-running", "acquireMetadata": "yes"}'
[   41.736222] TEST-13-NSPAWN.sh[2353]: + grep OSRelease
[   41.739500] TEST-13-NSPAWN.sh[2352]: Method call io.systemd.MachineImage.List() failed: Device or resource busy
[   41.740641] systemd[1]: Received SIGCHLD.
[   41.740670] systemd[1]: Child 2171 (systemd-nspawn) died (code=killed, status=9/KILL)
[   41.740725] systemd[1]: systemd-nspawn@long-running.service: Child 2171 belongs to systemd-nspawn@long-running.service.
[   41.740748] systemd[1]: systemd-nspawn@long-running.service: Main process exited, code=killed, status=9/KILL
[   41.740755] systemd[1]: systemd-nspawn@long-running.service: Will spawn child (service_enter_stop_post): systemd-nspawn
[   41.740872] systemd[1]: systemd-nspawn@long-running.service: About to execute: systemd-nspawn --cleanup --machine=long-running
...

Let's mitigate this by waiting until the corresponding
systemd-nspawn@.service instance enters the 'inactive' state where the
lock should be properly released.

Resolves: #39547
2025-11-05 18:13:58 +01:00
Frantisek Sumsal
79a93bb7f5 test: terminate the test containers cleanly on SIGTERM
So they exit with 0 instead of 143 when we call `machinectl terminate`
on them.
2025-11-05 18:12:39 +01:00
Yu Watanabe
454ce42305 test-network: disable several more sandbox features when running with sanitizers
These settings also imply seccomp.
Hopefully fixes #39567.
2025-11-06 00:50:11 +09:00
Yu Watanabe
da665b708a test-network: read default values from environment variables
Nowadays, the test script is run as a service, and no argument about
sanitizers are passed. Let's read them from the environment variables.
2025-11-06 00:22:17 +09:00
9 changed files with 99 additions and 22 deletions

View File

@ -83,7 +83,7 @@
<para>Capsule names may be chosen freely by the user, however, they must be suitable as UNIX filenames <para>Capsule names may be chosen freely by the user, however, they must be suitable as UNIX filenames
(i.e. 255 characters max, and contain no <literal>/</literal>), and when prefixed with (i.e. 255 characters max, and contain no <literal>/</literal>), and when prefixed with
<literal>p-</literal> be suitable as a user name matching strict POSIX rules, see <ulink <literal>c-</literal> be suitable as a user name matching strict POSIX rules, see <ulink
url="https://systemd.io/USER_NAMES">User/Group Name Syntax</ulink> for details.</para> url="https://systemd.io/USER_NAMES">User/Group Name Syntax</ulink> for details.</para>
<xi:include href="version-info.xml" xpointer="v256"/> <xi:include href="version-info.xml" xpointer="v256"/>

View File

@ -418,7 +418,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
if (r < 0) if (r < 0)
goto fail; goto fail;
if (!IN_SET(q.family, AF_INET, AF_INET6)) if (q.family != af)
continue; continue;
if (q.address_size != FAMILY_ADDRESS_SIZE(q.family)) { if (q.address_size != FAMILY_ADDRESS_SIZE(q.family)) {

View File

@ -16,6 +16,14 @@
#include "strv.h" #include "strv.h"
#include "time-util.h" #include "time-util.h"
bool bus_property_is_timestamp(const char *name) {
assert(name);
/* Trust me, this naming convention is ironclad. Except for these three. Okay four. Well... */
return endswith(name, "Timestamp") ||
STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec", "TimeUSec", "RTCTimeUSec");
}
int bus_print_property_value(const char *name, const char *expected_value, BusPrintPropertyFlags flags, const char *value) { int bus_print_property_value(const char *name, const char *expected_value, BusPrintPropertyFlags flags, const char *value) {
assert(name); assert(name);
@ -104,12 +112,7 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
if (r < 0) if (r < 0)
return r; return r;
/* Yes, heuristics! But we can change this check if (bus_property_is_timestamp(name))
* should it turn out to not be sufficient */
if (endswith(name, "Timestamp") ||
STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec", "TimeUSec", "RTCTimeUSec"))
bus_print_property_value(name, expected_value, flags, FORMAT_TIMESTAMP(u)); bus_print_property_value(name, expected_value, flags, FORMAT_TIMESTAMP(u));
/* Managed OOM pressure default implies "unset" and use the default set in oomd.conf. Without /* Managed OOM pressure default implies "unset" and use the default set in oomd.conf. Without

View File

@ -10,6 +10,8 @@ typedef enum BusPrintPropertyFlags {
typedef int (*bus_message_print_t) (const char *name, const char *expected_value, sd_bus_message *m, BusPrintPropertyFlags flags); typedef int (*bus_message_print_t) (const char *name, const char *expected_value, sd_bus_message *m, BusPrintPropertyFlags flags);
bool bus_property_is_timestamp(const char *name);
int bus_print_property_value(const char *name, const char *expected_value, BusPrintPropertyFlags flags, const char *value); int bus_print_property_value(const char *name, const char *expected_value, BusPrintPropertyFlags flags, const char *value);
int bus_print_property_valuef(const char *name, const char *expected_value, BusPrintPropertyFlags flags, const char *fmt, ...) _printf_(4,5); int bus_print_property_valuef(const char *name, const char *expected_value, BusPrintPropertyFlags flags, const char *fmt, ...) _printf_(4,5);
int bus_message_print_all_properties(sd_bus_message *m, bus_message_print_t func, char **filter, BusPrintPropertyFlags flags, Set **found_properties); int bus_message_print_all_properties(sd_bus_message *m, bus_message_print_t func, char **filter, BusPrintPropertyFlags flags, Set **found_properties);

View File

@ -1215,7 +1215,7 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
break; break;
case SD_BUS_TYPE_UINT64: case SD_BUS_TYPE_UINT64:
if (endswith(name, "Timestamp")) { if (bus_property_is_timestamp(name)) {
uint64_t timestamp; uint64_t timestamp;
r = sd_bus_message_read_basic(m, bus_type, &timestamp); r = sd_bus_message_read_basic(m, bus_type, &timestamp);

View File

@ -81,10 +81,10 @@ valgrind_cmd = ''
enable_debug = True enable_debug = True
env = {} env = {}
wait_online_env = {} wait_online_env = {}
asan_options = None asan_options = os.getenv('ASAN_OPTIONS')
lsan_options = None lsan_options = os.getenv('LSAN_OPTIONS')
ubsan_options = None ubsan_options = os.getenv('UBSAN_OPTIONS')
with_coverage = False with_coverage = os.getenv('COVERAGE_BUILD_DIR') != None
show_journal = True # When true, show journal on stopping networkd. show_journal = True # When true, show journal on stopping networkd.
active_units = [] active_units = []
@ -487,7 +487,19 @@ def create_service_dropin(service, command, additional_settings=None):
if ubsan_options: if ubsan_options:
drop_in += [f'Environment=UBSAN_OPTIONS="{ubsan_options}"'] drop_in += [f'Environment=UBSAN_OPTIONS="{ubsan_options}"']
if asan_options or lsan_options or ubsan_options: if asan_options or lsan_options or ubsan_options:
drop_in += ['SystemCallFilter='] # Disable system call filter when running with sanitizers, as they seem to call filtered syscall at
# the very end of the execution and stuck the process. See issue #39567.
drop_in += [
'LockPersonality=no',
'ProtectClock=no',
'ProtectKernelLogs=no',
'RestrictAddressFamilies=',
'RestrictNamespaces=no',
'RestrictRealtime=no',
'RestrictSUIDSGID=no',
'SystemCallArchitectures=',
'SystemCallFilter=',
]
if use_valgrind or asan_options or lsan_options or ubsan_options: if use_valgrind or asan_options or lsan_options or ubsan_options:
drop_in += ['MemoryDenyWriteExecute=no'] drop_in += ['MemoryDenyWriteExecute=no']
if use_valgrind: if use_valgrind:

View File

@ -72,7 +72,7 @@ assert_eq "$(systemctl show "$UNIT_NAME.socket" -P SubState)" "listening"
socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" & socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" &
wait_for_start wait_for_start
kill %% wait %%
touch "/tmp/$UNIT_NAME/flag" touch "/tmp/$UNIT_NAME/flag"
systemctl start "$UNIT_NAME-conflict2.service" systemctl start "$UNIT_NAME-conflict2.service"
@ -80,7 +80,7 @@ wait_for_stop
socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" & socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" &
wait_for_start wait_for_start
kill %% wait %%
(! systemctl -q is-active "$UNIT_NAME-conflict2.service") (! systemctl -q is-active "$UNIT_NAME-conflict2.service")
# DeferTrigger=yes # DeferTrigger=yes
@ -99,7 +99,7 @@ assert_eq "$(systemctl show "$UNIT_NAME-conflict1.service" -P SubState)" "start"
socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" & socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" &
timeout 30 bash -c "until [[ \$(systemctl show '$UNIT_NAME.socket' -P SubState) == 'deferred' ]]; do sleep .5; done" timeout 30 bash -c "until [[ \$(systemctl show '$UNIT_NAME.socket' -P SubState) == 'deferred' ]]; do sleep .5; done"
(! systemctl -q is-active "$UNIT_NAME.service") (! systemctl -q is-active "$UNIT_NAME.service")
kill %% wait %%
assert_eq "$(systemctl show "$UNIT_NAME-conflict1.service" -P SubState)" "start" assert_eq "$(systemctl show "$UNIT_NAME-conflict1.service" -P SubState)" "start"
systemctl daemon-reload systemctl daemon-reload
@ -122,7 +122,7 @@ wait_for_stop
socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" & socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" &
timeout 30 bash -c "until [[ \$(systemctl show '$UNIT_NAME.socket' -P SubState) == 'deferred' ]]; do sleep .5; done" timeout 30 bash -c "until [[ \$(systemctl show '$UNIT_NAME.socket' -P SubState) == 'deferred' ]]; do sleep .5; done"
(! systemctl -q is-active "$UNIT_NAME.service") (! systemctl -q is-active "$UNIT_NAME.service")
kill %% wait %%
rm "/tmp/$UNIT_NAME/flag" rm "/tmp/$UNIT_NAME/flag"
timeout 30 bash -c "while systemctl -q is-active '$UNIT_NAME-conflict2.service'; do sleep .2; done" timeout 30 bash -c "while systemctl -q is-active '$UNIT_NAME-conflict2.service'; do sleep .2; done"
@ -138,7 +138,7 @@ assert_eq "$(systemctl show "$UNIT_NAME-conflict1.service" -P SubState)" "start"
socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" & socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" &
timeout 30 bash -c "until [[ \$(systemctl show '$UNIT_NAME.socket' -P SubState) == 'deferred' ]]; do sleep .5; done" timeout 30 bash -c "until [[ \$(systemctl show '$UNIT_NAME.socket' -P SubState) == 'deferred' ]]; do sleep .5; done"
(! systemctl -q is-active "$UNIT_NAME.service") (! systemctl -q is-active "$UNIT_NAME.service")
kill %% wait %%
echo "DeferTriggerMaxSec=20s" >>/run/systemd/system/"$UNIT_NAME.socket" echo "DeferTriggerMaxSec=20s" >>/run/systemd/system/"$UNIT_NAME.socket"
systemctl daemon-reload systemctl daemon-reload

View File

@ -48,6 +48,7 @@ trap 'touch /terminate; kill 0' RTMIN+3
trap 'touch /poweroff' RTMIN+4 trap 'touch /poweroff' RTMIN+4
trap 'touch /reboot' INT trap 'touch /reboot' INT
trap 'touch /trap' TRAP trap 'touch /trap' TRAP
trap 'exit 0' TERM
trap 'kill $PID' EXIT trap 'kill $PID' EXIT
# We need to wait for the sleep process asynchronously in order to allow # We need to wait for the sleep process asynchronously in order to allow
@ -325,6 +326,7 @@ ip address add 192.0.2.1/24 dev hoge
PID=0 PID=0
trap 'kill 0' RTMIN+3 trap 'kill 0' RTMIN+3
trap 'exit 0' TERM
trap 'kill $PID' EXIT trap 'kill $PID' EXIT
# We need to wait for the sleep process asynchronously in order to allow # We need to wait for the sleep process asynchronously in order to allow
@ -439,9 +441,14 @@ varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.OpenR
# Terminating machine, otherwise acquiring image metadata by io.systemd.MachineImage.List may fail in the below. # Terminating machine, otherwise acquiring image metadata by io.systemd.MachineImage.List may fail in the below.
machinectl terminate long-running machinectl terminate long-running
# wait for the container being stopped, otherwise acquiring image metadata by io.systemd.MachineImage.List may fail in the below. # Wait for the container to stop, otherwise acquiring image metadata by io.systemd.MachineImage.List below
timeout 30 bash -c "while machinectl status long-running &>/dev/null; do sleep .5; done" # may fail.
systemctl kill --signal=KILL systemd-nspawn@long-running.service || : #
# We need to wait until the systemd-nspawn process is completely stopped, as the lock is held for almost the
# entire life of the process (see the run() function in nspawn.c). This means that the machine gets
# unregistered _before_ this lock is lifted which makes `machinectl status` return non-zero EC earlier than
# we need.
timeout 30 bash -xec 'until [[ "$(systemctl show -P ActiveState systemd-nspawn@long-running.service)" == inactive ]]; do sleep .5; done'
# test io.systemd.MachineImage.List # test io.systemd.MachineImage.List
varlinkctl --more call /run/systemd/machine/io.systemd.MachineImage io.systemd.MachineImage.List '{}' | grep 'long-running' varlinkctl --more call /run/systemd/machine/io.systemd.MachineImage io.systemd.MachineImage.List '{}' | grep 'long-running'

View File

@ -287,6 +287,59 @@ for value in pretty us µs utc us+utc µs+utc; do
systemctl show -P KernelTimestamp --timestamp="$value" systemctl show -P KernelTimestamp --timestamp="$value"
done done
# --timestamp with timer properties (issue #39282)
TIMER1="timestamp-test1-$RANDOM.timer"
SERVICE1="${TIMER1%.timer}.service"
cat >"/run/systemd/system/$SERVICE1" <<EOF
[Service]
Type=oneshot
ExecStart=true
EOF
cat >"/run/systemd/system/$TIMER1" <<EOF
[Timer]
OnCalendar=*-*-* 00:00:00
EOF
systemctl daemon-reload
systemctl start "$TIMER1"
output=$(systemctl show -P NextElapseUSecRealtime --timestamp=unix "$TIMER1")
if [[ ! "$output" =~ ^@[0-9]+$ ]]; then
echo "NextElapseUSecRealtime: expected @<number> with --timestamp=unix, got: $output" >&2
exit 1
fi
systemctl stop "$TIMER1"
rm -f "/run/systemd/system/$TIMER1" "/run/systemd/system/$SERVICE1"
TIMER2="timestamp-test2-$RANDOM.timer"
SERVICE2="${TIMER2%.timer}.service"
cat >"/run/systemd/system/$SERVICE2" <<EOF
[Service]
Type=oneshot
ExecStart=true
EOF
cat >"/run/systemd/system/$TIMER2" <<EOF
[Timer]
OnActiveSec=100ms
EOF
systemctl daemon-reload
systemctl start "$TIMER2"
sleep 0.5
output=$(systemctl show -P LastTriggerUSec --timestamp=unix "$TIMER2")
if [[ ! "$output" =~ ^@[0-9]+$ ]]; then
echo "LastTriggerUSec: expected @<number> with --timestamp=unix, got: $output" >&2
exit 1
fi
systemctl stop "$TIMER2"
rm -f "/run/systemd/system/$TIMER2" "/run/systemd/system/$SERVICE2"
systemctl daemon-reload
# set-default/get-default # set-default/get-default
test_get_set_default() { test_get_set_default() {
target="$(systemctl get-default "$@")" target="$(systemctl get-default "$@")"