From: Nick Rosbrook Date: Wed, 7 Aug 2024 22:18:06 +0000 (-0400) Subject: core/unit: do not use unit path cache in unit_need_daemon_reload() X-Git-Tag: v257-rc1~718 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82c482d573c9d2f3ab36f7be8d32772f90f2c335;p=thirdparty%2Fsystemd.git core/unit: do not use unit path cache in unit_need_daemon_reload() When unit_need_daemon_reload() calls unit_find_dropin_paths() to check for new drop-in configs, the manager's unit path cache is used to limit which directories are considered. If a new drop-in directory is created, it may not be in the unit path cache, and hence unit_need_daemon_reload() may return false, despite a new drop-in being present. However, if a unit path cache is not given to unit_file_find_dropin_paths() at all, then it behaves as if the target path was found in the unit path cache. So, to fix this, adapt unit_find_dropin_paths() to take a boolean argument indicating whether or not to pass along the unit path cache. Set this to false in unit_need_daemon_reload(). Fixes #31752 --- diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c index fd45744261d..dc9c44e6d64 100644 --- a/src/core/load-dropin.c +++ b/src/core/load-dropin.c @@ -102,7 +102,7 @@ int unit_load_dropin(Unit *u) { return r; /* Load .conf dropins */ - r = unit_find_dropin_paths(u, &l); + r = unit_find_dropin_paths(u, /* use_unit_path_cache = */ true, &l); if (r <= 0) return 0; diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h index f0b87d3e9fb..141bc7dd0f2 100644 --- a/src/core/load-dropin.h +++ b/src/core/load-dropin.h @@ -6,12 +6,12 @@ /* Read service data supplementary drop-in directories */ -static inline int unit_find_dropin_paths(Unit *u, char ***paths) { +static inline int unit_find_dropin_paths(Unit *u, bool use_unit_path_cache, char ***paths) { assert(u); return unit_file_find_dropin_paths(NULL, u->manager->lookup_paths.search_path, - u->manager->unit_path_cache, + use_unit_path_cache ? u->manager->unit_path_cache : NULL, ".d", ".conf", u->id, u->aliases, paths); diff --git a/src/core/unit.c b/src/core/unit.c index 257b0929afe..2bdbcdf3667 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3809,7 +3809,7 @@ bool unit_need_daemon_reload(Unit *u) { if (u->load_state == UNIT_LOADED) { _cleanup_strv_free_ char **dropins = NULL; - (void) unit_find_dropin_paths(u, &dropins); + (void) unit_find_dropin_paths(u, /* use_unit_path_cache = */ false, &dropins); if (!strv_equal(u->dropin_paths, dropins)) return true; diff --git a/test/units/TEST-07-PID1.issue-31752.sh b/test/units/TEST-07-PID1.issue-31752.sh new file mode 100755 index 00000000000..89ec07e46bf --- /dev/null +++ b/test/units/TEST-07-PID1.issue-31752.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +set -eux +set -o pipefail + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +# Make sure NeedDaemonReload= considers newly created drop-ins. +# Issue: https://github.com/systemd/systemd/issues/31752 + +UNIT=test-issue-31752.service + +cleanup() { + rm -rf /run/systemd/system/"$UNIT" /run/systemd/system/"$UNIT".d + systemctl daemon-reload +} + +trap cleanup EXIT + +cat > /run/systemd/system/"$UNIT" < /run/systemd/system/"$UNIT".d/desc.conf <