1
0
mirror of https://github.com/systemd/systemd synced 2026-04-03 13:44:55 +02:00

Compare commits

...

6 Commits

Author SHA1 Message Date
Frantisek Sumsal
c3d432a3d2 test: wait for a process ID instead of job ID
Since depending on job control turned out to be flaky [0], let's just
explicitly wait for a process ID instead.

Follow-up for 3849b0701a7713c147400f205e7ddb3e3f93ad26.
Resolves: #39543

[0] https://github.com/systemd/systemd/issues/39543#issuecomment-3529418583
2025-11-18 15:18:00 +00:00
Daan De Meyer
09ee7040c8 mkosi: Add sanitizer libraries to the CentOS/Fedora tools tree 2025-11-18 15:07:49 +01:00
Armin Brauns
d31af45552 NEWS: fix typo 2025-11-18 13:00:24 +00:00
Zbigniew Jędrzejewski-Szmek
e8a7722eec tree-wide: fix log messages using %m without an errno 2025-11-18 12:27:59 +01:00
Zbigniew Jędrzejewski-Szmek
4a3d57a47a network: gracefully disable resolve hook when socket is disabled
systemd-networkd cannot create the directory /run/systemd/resolve.hook/. Even
if the directory exists, it is not owned by systemd-network user/group, so
systemd-networkd cannot create socket file in the directory. Hence, if the
systemd-networkd-resolve-hook.socket unit is disabled, networkd fails to open
the varlink socket, and fail to start:

  systemd-networkd[1304645]: Failed to bind to systemd-resolved hook Varlink socket: Permission denied
  systemd-networkd[1304645]: Could not set up manager: Permission denied
  systemd[1]: systemd-networkd.service: Main process exited, code=exited, status=1/FAILURE
  systemd[1]: systemd-networkd.service: Failed with result 'exit-code'.
  systemd[1]: Failed to start systemd-networkd.service - Network Management.

If the socket unit is disabled, that should mean the system administrator wants
to disable the feature. Let's not try to setup the varlink socket in that case.

Now the resolve hook feature can be toggled by enabling/disabling the socket
unit, let's drop the $SYSTEMD_NETWORK_RESOLVE_HOOK environment variable.

Follow-up for a7fa29b1b52210e33f4e43efc1a2f06b7c7233c0.
Co-authored-by: Yu Watanabe <watanabe.yu+github@gmail.com>
2025-11-18 12:26:07 +01:00
Daan De Meyer
7e5a07c24a Various documentation updates 2025-11-18 10:09:19 +00:00
16 changed files with 63 additions and 42 deletions

View File

@ -14,6 +14,20 @@ Always include the following files in the context:
Include any other files from the [documentation](../docs) in the context as needed based on whether you think it might be helpful to solve your current task or help to review the current PR. Include any other files from the [documentation](../docs) in the context as needed based on whether you think it might be helpful to solve your current task or help to review the current PR.
## Build + Test instructions
**CRITICAL: Read and follow these instructions exactly.**
- **NEVER** compile individual files or targets. **ALWAYS** run `mkosi -f box meson compile -C build` to build the entire project. Meson handles incremental compilation automatically.
- **NEVER** run `meson compile` followed by `meson test` as separate steps. **ALWAYS** run `mkosi -f box meson test -C build -v <TEST-NAME>` directly. Meson will automatically rebuild any required targets before running tests.
- **NEVER** invent your own build commands or try to optimize the build process.
- **NEVER** use `head`, `tail`, or pipe (`|`) the output of build or test commands. Always let the full output display. This is critical for diagnosing build and test failures.
- When asked to build and test code changes:
- **CORRECT**: Run `mkosi -f box -- meson test -C build -v <TEST-NAME>` (this builds and runs tests in one command)
- **WRONG**: Run `mkosi -f box -- meson compile -C build` followed by `mkosi -f box -- meson test -C build -v <TEST-NAME>`
- **WRONG**: Run `mkosi -f box -- meson compile -C build src/core/systemd` or similar individual target compilation
- **WRONG**: Run `mkosi -f box -- meson test -C build -v <TEST-NAME> 2>&1 | tail -100` or similar piped commands
## Pull Request review instructions ## Pull Request review instructions
- Focus on making sure the coding style is followed as documented in `docs/CODING_STYLE.md` - Focus on making sure the coding style is followed as documented in `docs/CODING_STYLE.md`

2
NEWS
View File

@ -100,7 +100,7 @@ CHANGES WITH 259 in spe:
points to its own PID can now also verify the pidfd inode ID, which points to its own PID can now also verify the pidfd inode ID, which
does not recycle IDs. does not recycle IDs.
* The log message made when a service exists will now show the * The log message made when a service exits will now show the
wallclock time the service took in addition to the previously shown wallclock time the service took in addition to the previously shown
CPU time. CPU time.

View File

@ -583,8 +583,8 @@ SPDX-License-Identifier: LGPL-2.1-or-later
code. (With one exception: it is OK to log with DEBUG level from any code, code. (With one exception: it is OK to log with DEBUG level from any code,
with the exception of maybe inner loops). with the exception of maybe inner loops).
- In public API calls, you **must** validate all your input arguments for - In libsystemd public API calls, you **must** validate all your input arguments
programming error with `assert_return()` and return a sensible return for programming error with `assert_return()` and return a sensible return
code. In all other calls, it is recommended to check for programming errors code. In all other calls, it is recommended to check for programming errors
with a more brutal `assert()`. We are more forgiving to public users than for with a more brutal `assert()`. We are more forgiving to public users than for
ourselves! Note that `assert()` and `assert_return()` really only should be ourselves! Note that `assert()` and `assert_return()` really only should be
@ -982,5 +982,8 @@ SPDX-License-Identifier: LGPL-2.1-or-later
macro exists for your specific use case, please add a new assertion macro in a macro exists for your specific use case, please add a new assertion macro in a
separate commit. separate commit.
- Use `ASSERT_OK_ERRNO()` and similar macros instead of `ASSERT_OK()` when
calling glibc APIs that return the error in `errno`.
- When modifying existing tests, please convert the test to use the new assertion - When modifying existing tests, please convert the test to use the new assertion
macros from `tests.h` if it is not already using those. macros from `tests.h` if it is not already using those.

View File

@ -39,11 +39,11 @@ chance that your distribution's packaged version of mkosi will be too old.
Then, you can build, run and test systemd executables as follows: Then, you can build, run and test systemd executables as follows:
```sh ```sh
$ mkosi -f genkey # Generate signing keys once. $ mkosi -f genkey # Generate signing keys once.
$ mkosi -f box -- meson setup -Dbpf-framework=disabled build # bpftool detection inside mkosi box is broken on Ubuntu Noble and older $ mkosi -f box -- meson setup -Dbpf-framework=disabled build # bpftool detection inside mkosi box is broken on Ubuntu Noble and older
$ mkosi -f box -- meson compile -C build $ mkosi -f box -- meson compile -C build
$ mkosi -f box -- build/systemctl --version $ mkosi -f box -- build/systemctl --version
$ mkosi -f box -- meson test -C build # Run the unit tests $ mkosi -f box -- meson test -C build --print-errorlogs # Run the unit tests
``` ```
To build and boot an OS image with the latest systemd installed: To build and boot an OS image with the latest systemd installed:

View File

@ -13,3 +13,6 @@ Packages=
clang-tools-extra clang-tools-extra
python3-mypy python3-mypy
rpm-build rpm-build
libasan
libubsan
compiler-rt

View File

@ -2189,7 +2189,7 @@ void home_process_notify(Home *h, char **l, int fd) {
return (void) log_debug_errno(r, "Failed to parse SYSTEMD_LUKS_LOCK_FD value: %m"); return (void) log_debug_errno(r, "Failed to parse SYSTEMD_LUKS_LOCK_FD value: %m");
if (r > 0) { if (r > 0) {
if (taken_fd < 0) if (taken_fd < 0)
return (void) log_debug("Got notify message with SYSTEMD_LUKS_LOCK_FD=1 but no fd passed, ignoring: %m"); return (void) log_debug("Got notify message with SYSTEMD_LUKS_LOCK_FD=1 but no fd passed, ignoring.");
close_and_replace(h->luks_lock_fd, taken_fd); close_and_replace(h->luks_lock_fd, taken_fd);
@ -2199,7 +2199,7 @@ void home_process_notify(Home *h, char **l, int fd) {
home_maybe_close_luks_lock_fd(h, _HOME_STATE_INVALID); home_maybe_close_luks_lock_fd(h, _HOME_STATE_INVALID);
} else { } else {
if (taken_fd >= 0) if (taken_fd >= 0)
return (void) log_debug("Got notify message with SYSTEMD_LUKS_LOCK_FD=0 but fd passed, ignoring: %m"); return (void) log_debug("Got notify message with SYSTEMD_LUKS_LOCK_FD=0 but fd passed, ignoring.");
h->luks_lock_fd = safe_close(h->luks_lock_fd); h->luks_lock_fd = safe_close(h->luks_lock_fd);
} }

View File

@ -155,7 +155,7 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata) {
case SD_IPV4LL_EVENT_BIND: case SD_IPV4LL_EVENT_BIND:
r = ipv4ll_address_claimed(ll, link); r = ipv4ll_address_claimed(ll, link);
if (r < 0) { if (r < 0) {
log_link_error(link, "Failed to configure ipv4ll address: %m"); log_link_error_errno(link, r, "Failed to configure ipv4ll address: %m");
link_enter_failed(link); link_enter_failed(link);
return; return;
} }

View File

@ -1123,7 +1123,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
log_warning_errno(r, "rtnl: could not get NHA_ID attribute, ignoring: %m"); log_warning_errno(r, "rtnl: could not get NHA_ID attribute, ignoring: %m");
return 0; return 0;
} else if (id == 0) { } else if (id == 0) {
log_warning("rtnl: received nexthop message with invalid nexthop ID, ignoring: %m"); log_warning("rtnl: received nexthop message with invalid nexthop ID, ignoring.");
return 0; return 0;
} }

View File

@ -5,12 +5,14 @@
#include "sd-varlink.h" #include "sd-varlink.h"
#include "alloc-util.h" #include "alloc-util.h"
#include "argv-util.h"
#include "dns-answer.h" #include "dns-answer.h"
#include "dns-domain.h" #include "dns-domain.h"
#include "dns-packet.h" #include "dns-packet.h"
#include "dns-question.h" #include "dns-question.h"
#include "dns-rr.h" #include "dns-rr.h"
#include "env-util.h" #include "env-util.h"
#include "errno-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "networkd-link.h" #include "networkd-link.h"
#include "networkd-manager.h" #include "networkd-manager.h"
@ -214,17 +216,14 @@ int manager_varlink_init_resolve_hook(Manager *m, int fd) {
if (m->varlink_resolve_hook_server) if (m->varlink_resolve_hook_server)
return 0; return 0;
r = getenv_bool("SYSTEMD_NETWORK_RESOLVE_HOOK"); if (fd < 0 && invoked_by_systemd()) {
if (r < 0 && r != -ENXIO) log_debug("systemd-networkd-resolve-hook.socket seems to be disabled, not installing varlink server.");
log_warning_errno(r, "Failed to parse $SYSTEMD_NETWORK_RESOLVE_HOOK, ignoring: %m");
if (r == 0) {
log_notice("Resolve hook disabled via $SYSTEMD_NETWORK_RESOLVE_HOOK.");
return 0; return 0;
} }
r = varlink_server_new(&s, SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA, m); r = varlink_server_new(&s, SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA, m);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to allocate varlink server object: %m"); return log_error_errno(r, "Failed to allocate varlink server: %m");
(void) sd_varlink_server_set_description(s, "varlink-resolve-hook"); (void) sd_varlink_server_set_description(s, "varlink-resolve-hook");
@ -243,12 +242,17 @@ int manager_varlink_init_resolve_hook(Manager *m, int fd) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind on resolve hook disconnection events: %m"); return log_error_errno(r, "Failed to bind on resolve hook disconnection events: %m");
if (fd < 0) if (fd < 0) {
r = sd_varlink_server_listen_address(s, "/run/systemd/resolve.hook/io.systemd.Network", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755); r = sd_varlink_server_listen_address(s, "/run/systemd/resolve.hook/io.systemd.Network",
else 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
if (ERRNO_IS_NEG_PRIVILEGE(r)) {
log_info_errno(r, "Failed to bind to systemd-resolved hook varlink socket, ignoring: %m");
return 0;
}
} else
r = sd_varlink_server_listen_fd(s, fd); r = sd_varlink_server_listen_fd(s, fd);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind to systemd-resolved hook Varlink socket: %m"); return log_error_errno(r, "Failed to bind to systemd-resolved hook varlink socket: %m");
TAKE_FD(fd_close); TAKE_FD(fd_close);

View File

@ -119,7 +119,7 @@ int manager_genl_process_nl80211_config(sd_netlink *genl, sd_netlink_message *me
} }
if (!streq(ifname, link->ifname)) { if (!streq(ifname, link->ifname)) {
log_link_debug(link, "nl80211: received %s(%u) message with invalid interface name '%s', ignoring: %m", log_link_debug(link, "nl80211: received %s(%u) message with invalid interface name '%s', ignoring.",
strna(nl80211_cmd_to_string(cmd)), cmd, ifname); strna(nl80211_cmd_to_string(cmd)), cmd, ifname);
return 0; return 0;
} }
@ -139,7 +139,7 @@ int manager_genl_process_nl80211_config(sd_netlink *genl, sd_netlink_message *me
} }
if (r >= 0) { if (r >= 0) {
if (len == 0) { if (len == 0) {
log_link_debug(link, "nl80211: received SSID has zero length, ignoring it: %m"); log_link_debug(link, "nl80211: received SSID has zero length, ignoring it.");
ssid = mfree(ssid); ssid = mfree(ssid);
} else if (strlen_ptr(ssid) != len) { } else if (strlen_ptr(ssid) != len) {
log_link_debug(link, "nl80211: received SSID contains NUL characters, ignoring it."); log_link_debug(link, "nl80211: received SSID contains NUL characters, ignoring it.");

View File

@ -409,8 +409,7 @@ int manager_genl_process_nl80211_wiphy(sd_netlink *genl, sd_netlink_message *mes
(void) wiphy_get_by_index(manager, index, &w); (void) wiphy_get_by_index(manager, index, &w);
switch (cmd) { switch (cmd) {
case NL80211_CMD_NEW_WIPHY: { case NL80211_CMD_NEW_WIPHY:
if (!w) { if (!w) {
r = wiphy_new(manager, message, &w); r = wiphy_new(manager, message, &w);
if (r < 0) { if (r < 0) {
@ -432,11 +431,10 @@ int manager_genl_process_nl80211_wiphy(sd_netlink *genl, sd_netlink_message *mes
log_wiphy_warning_errno(w, r, "Failed to update wiphy, ignoring: %m"); log_wiphy_warning_errno(w, r, "Failed to update wiphy, ignoring: %m");
break; break;
}
case NL80211_CMD_DEL_WIPHY:
case NL80211_CMD_DEL_WIPHY:
if (!w) { if (!w) {
log_debug("The kernel removes wiphy we do not know, ignoring: %m"); log_debug("The kernel removed wiphy we do not know, ignoring.");
return 0; return 0;
} }
@ -445,7 +443,7 @@ int manager_genl_process_nl80211_wiphy(sd_netlink *genl, sd_netlink_message *mes
break; break;
default: default:
log_wiphy_debug(w, "nl80211: received %s(%u) message.", log_wiphy_debug(w, "nl80211: received %s(%u) message, ignoring.",
strna(nl80211_cmd_to_string(cmd)), cmd); strna(nl80211_cmd_to_string(cmd)), cmd);
} }

View File

@ -844,7 +844,7 @@ int image_find(RuntimeScope scope,
continue; continue;
} }
if (!result.path) { if (!result.path) {
log_debug("Found versioned directory '%s', without matching entry, skipping: %m", vp); log_debug("Found versioned directory '%s', without matching entry, skipping.", vp);
continue; continue;
} }
@ -1052,7 +1052,7 @@ int image_discover(
continue; continue;
} }
if (!result.path) { if (!result.path) {
log_debug("Found versioned directory '%s', without matching entry, skipping: %m", vp); log_debug("Found versioned directory '%s', without matching entry, skipping.", vp);
continue; continue;
} }

View File

@ -77,7 +77,7 @@ static int on_child_notify(sd_event_source *s, int fd, uint32_t revents, void *u
return 0; return 0;
} }
if (error <= 0) { if (error <= 0) {
log_debug("Received non-positive ERRNO= notification message, ignoring: %m"); log_debug("Received non-positive ERRNO= notification message, ignoring: %d", error);
return 0; return 0;
} }

View File

@ -917,7 +917,7 @@ static int link_apply_sr_iov_config(Link *link) {
return 0; return 0;
} }
if (n == 0) { if (n == 0) {
log_link_warning(link, "No SR-IOV virtual function exists, ignoring all [SR-IOV] sections: %m"); log_link_warning(link, "No SR-IOV virtual functions exist, ignoring all [SR-IOV] sections.");
return 0; return 0;
} }

View File

@ -97,9 +97,6 @@ def setUpModule():
if os.path.isdir('/run/systemd/resolve'): if os.path.isdir('/run/systemd/resolve'):
os.chmod('/run/systemd/resolve', 0o755) os.chmod('/run/systemd/resolve', 0o755)
shutil.chown('/run/systemd/resolve', 'systemd-resolve', 'systemd-resolve') shutil.chown('/run/systemd/resolve', 'systemd-resolve', 'systemd-resolve')
if os.path.isdir('/run/systemd/resolve.hook'):
os.chmod('/run/systemd/resolve.hook', 0o755)
shutil.chown('/run/systemd/resolve.hook', 'systemd-network', 'systemd-network')
if os.path.isdir('/run/systemd/netif'): if os.path.isdir('/run/systemd/netif'):
os.chmod('/run/systemd/netif', 0o755) os.chmod('/run/systemd/netif', 0o755)
shutil.chown('/run/systemd/netif', 'systemd-network', 'systemd-network') shutil.chown('/run/systemd/netif', 'systemd-network', 'systemd-network')
@ -976,9 +973,6 @@ EOF
# Hence, 'networkctl persistent-storage yes' cannot be used. # Hence, 'networkctl persistent-storage yes' cannot be used.
export SYSTEMD_NETWORK_PERSISTENT_STORAGE_READY=1 export SYSTEMD_NETWORK_PERSISTENT_STORAGE_READY=1
# Don't try to register resolved hook for our testcase
export SYSTEMD_NETWORK_RESOLVE_HOOK=0
# Generate debugging logs. # Generate debugging logs.
export SYSTEMD_LOG_LEVEL=debug export SYSTEMD_LOG_LEVEL=debug

View File

@ -71,16 +71,18 @@ assert_eq "$(systemctl show "$UNIT_NAME.socket" -P SubState)" "listening"
(! systemctl -q is-active "$UNIT_NAME.service") (! systemctl -q is-active "$UNIT_NAME.service")
socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" & socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" &
PID=$!
wait_for_start wait_for_start
wait %% wait $PID
touch "/tmp/$UNIT_NAME/flag" touch "/tmp/$UNIT_NAME/flag"
systemctl start "$UNIT_NAME-conflict2.service" systemctl start "$UNIT_NAME-conflict2.service"
wait_for_stop wait_for_stop
socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" & socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" &
PID=$!
wait_for_start wait_for_start
wait %% wait $PID
(! systemctl -q is-active "$UNIT_NAME-conflict2.service") (! systemctl -q is-active "$UNIT_NAME-conflict2.service")
# DeferTrigger=yes # DeferTrigger=yes
@ -97,9 +99,10 @@ assert_eq "$(systemctl show "$UNIT_NAME-conflict1.service" -P SubState)" "start"
# Wait in "deferred" state # Wait in "deferred" state
socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" & socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" &
PID=$!
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")
wait %% wait $PID
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
@ -120,9 +123,10 @@ systemctl start "$UNIT_NAME-conflict2.service"
wait_for_stop wait_for_stop
socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" & socat -u - UNIX-CONNECT:"/tmp/$UNIT_NAME/test" &
PID=$!
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")
wait %% wait $PID
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"
@ -136,9 +140,10 @@ wait_for_stop
assert_eq "$(systemctl show "$UNIT_NAME-conflict1.service" -P SubState)" "start" 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" &
PID=$!
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")
wait %% wait $PID
echo "DeferTriggerMaxSec=20s" >>/run/systemd/system/"$UNIT_NAME.socket" echo "DeferTriggerMaxSec=20s" >>/run/systemd/system/"$UNIT_NAME.socket"
systemctl daemon-reload systemctl daemon-reload