systemd-252-61

Resolves: RHEL-103801,RHEL-118215,RHEL-14112
This commit is contained in:
Jan Macku 2025-11-21 15:59:41 +01:00
parent a673ceed38
commit 3b9729cdd7
7 changed files with 580 additions and 1 deletions

View File

@ -0,0 +1,131 @@
From 69c124810e3b4bc4b7aa441cfed65d3d7594d443 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Mon, 13 Oct 2025 17:36:55 +0200
Subject: [PATCH] timer: rebase the next elapse timestamp only if timer didn't
already run
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The test added in f4c3c107d9be4e922a080fc292ed3889c4e0f4a5 uncovered a
corner case while recalculating the next elapse timestamp of a timer unit
that uses RandomizedDelaySec= during deserialization.
If the scheduled time (without RandomizedDelaySec=) already elapsed,
systemd "rebases" the next elapse timestamp to the time when systemd
first started, to make the RandomizedDelaySec= feature work even at
boot. However, since it was done unconditionally, it always overrode the
next elapse timestamp, which could then cause the final next elapse
timestamp to fall out of the expected window.
With a couple of additional debug logs one of the test fail looks like
this:
[ 132.129815] TEST-53-TIMER.sh[384]: + : 'Next elapse timestamp after daemon-reload, try #328'
[ 132.129815] TEST-53-TIMER.sh[384]: + systemctl daemon-reload
[ 132.136352] systemd[1]: Reload requested from client PID 16399 ('systemctl') (unit TEST-53-TIMER.service)...
[ 132.136636] systemd[1]: Reloading...
[ 132.446160] systemd[1]: Rebasing next elapse timestamp
[ 132.446168] systemd[1]: v->next_elapse: Tue 2025-10-14 00:10:00 CEST
[ 132.446170] systemd[1]: rebased: Tue 2025-10-14 00:10:56 CEST
[ 132.446172] systemd[1]: v->next_elapse after rebase: Tue 2025-10-14 00:10:56 CEST
[ 132.447361] systemd[1]: Reloading finished in 310 ms.
[ 132.484041] TEST-53-TIMER.sh[384]: + check_elapse_timestamp
[ 132.484041] TEST-53-TIMER.sh[384]: + systemctl status timer-RandomizedDelaySec-16377.timer
[ 132.533657] TEST-53-TIMER.sh[16440]: ● timer-RandomizedDelaySec-16377.timer
[ 132.533657] TEST-53-TIMER.sh[16440]: Loaded: loaded (/run/systemd/system/timer-RandomizedDelaySec-16377.timer; static)
[ 132.533657] TEST-53-TIMER.sh[16440]: Active: active (waiting) since Mon 2025-10-13 23:00:00 CEST; 1h 13min ago
[ 132.533657] TEST-53-TIMER.sh[16440]: Invocation: 5555d4f060114a5493ff228013830d17
[ 132.533657] TEST-53-TIMER.sh[16440]: Trigger: Tue 2025-10-14 22:10:04 CEST; 21h left
[ 132.533657] TEST-53-TIMER.sh[16440]: Triggers: ● timer-RandomizedDelaySec-16377.service
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:07 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Changed dead -> waiting
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:07 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Adding 15h 35min 1.230173s random time.
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:07 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Realtime timer elapses at Tue 2025-10-14 15:45:58 CEST.
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:07 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Changed dead -> waiting
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:08 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Adding 16h 29min 44.084409s random time.
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:08 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Realtime timer elapses at Tue 2025-10-14 16:40:41 CEST.
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:08 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Changed dead -> waiting
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:08 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Adding 21h 59min 7.955828s random time.
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:08 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Realtime timer elapses at Tue 2025-10-14 22:10:04 CEST.
[ 132.533657] TEST-53-TIMER.sh[16440]: Oct 14 00:13:08 H systemd[1]: timer-RandomizedDelaySec-16377.timer: Changed dead -> waiting
[ 132.535386] TEST-53-TIMER.sh[384]: + systemctl show -p InactiveExitTimestamp timer-RandomizedDelaySec-16377.timer
[ 132.537727] TEST-53-TIMER.sh[16442]: InactiveExitTimestamp=Mon 2025-10-13 23:00:00 CEST
[ 132.540317] TEST-53-TIMER.sh[16444]: ++ systemctl show -P NextElapseUSecRealtime timer-RandomizedDelaySec-16377.timer
[ 132.547745] TEST-53-TIMER.sh[384]: + NEXT_ELAPSE_REALTIME='Tue 2025-10-14 22:10:04 CEST'
[ 132.548020] TEST-53-TIMER.sh[16445]: ++ date '--date=Tue 2025-10-14 22:10:04 CEST' +%s
[ 132.550218] TEST-53-TIMER.sh[384]: + NEXT_ELAPSE_REALTIME_S=1760472604
[ 132.550218] TEST-53-TIMER.sh[384]: + : 'Next elapse timestamp should be Tue 2025-10-14 00:10:00 CEST <= Tue 2025-10-14 22:10:04 CEST <= Tue 2025-10-14 22:10:00 CEST'
[ 132.550218] TEST-53-TIMER.sh[384]: + assert_ge 1760472604 1760393400
[ 132.550555] TEST-53-TIMER.sh[16446]: + set +ex
[ 132.550702] TEST-53-TIMER.sh[384]: + assert_le 1760472604 1760472600
[ 132.550832] TEST-53-TIMER.sh[16447]: + set +ex
[ 132.551091] TEST-53-TIMER.sh[16447]: FAIL: '1760472604' > '1760472600'
Here the original next elapse timestamp was Tue 2025-10-14 00:10:00 CEST
as expected, but it was overridden by the rebased timestamp:
Tue 2025-10-14 00:10:56 CEST. And when a new randomized delay was added
to it (21h 59min 7.955828s) the final next elapse timestamp fell out of
the expected window, i.e. Tue 2025-10-14 00:10:00 (scheduled time) <
Tue 2025-10-14 22:10:04 CEST (rebased elapse timestamp + randomized
delay) < Tue 2025-10-14 22:10:00 CEST (scheduled time + maximum from
RandomizedDelaySec=, i.e. 22h).
By limiting the timestamp rebase only the case where the unit hasn't
already run should prevent this from happening during daemon-reload.
(cherry picked from commit bdb8e584f4509de0daebbe2357d23156160c3a90)
Related: RHEL-118215
---
src/core/timer.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/src/core/timer.c b/src/core/timer.c
index 2eadca4f1a..4b0266bc68 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -392,7 +392,8 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
continue;
if (v->base == TIMER_CALENDAR) {
- usec_t b, rebased;
+ bool rebase_after_boot_time = false;
+ usec_t b;
/* If we know the last time this was
* triggered, schedule the job based relative
@@ -403,21 +404,25 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
b = t->last_trigger.realtime;
else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp))
b = UNIT(t)->inactive_exit_timestamp.realtime;
- else
+ else {
b = ts.realtime;
+ rebase_after_boot_time = true;
+ }
r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
if (r < 0)
continue;
- /* To make the delay due to RandomizedDelaySec= work even at boot, if the scheduled
- * time has already passed, set the time when systemd first started as the scheduled
- * time. Note that we base this on the monotonic timestamp of the boot, not the
- * realtime one, since the wallclock might have been off during boot. */
- rebased = map_clock_usec(UNIT(t)->manager->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic,
- CLOCK_MONOTONIC, CLOCK_REALTIME);
- if (v->next_elapse < rebased)
- v->next_elapse = rebased;
+ if (rebase_after_boot_time) {
+ /* To make the delay due to RandomizedDelaySec= work even at boot, if the scheduled
+ * time has already passed, set the time when systemd first started as the scheduled
+ * time. Note that we base this on the monotonic timestamp of the boot, not the
+ * realtime one, since the wallclock might have been off during boot. */
+ usec_t rebased = map_clock_usec(UNIT(t)->manager->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic,
+ CLOCK_MONOTONIC, CLOCK_REALTIME);
+ if (v->next_elapse < rebased)
+ v->next_elapse = rebased;
+ }
if (!found_realtime)
t->next_elapse_realtime = v->next_elapse;

View File

@ -0,0 +1,85 @@
From e16ede11dab405749b776aa6d58a9c7461a0dda5 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 28 Jan 2025 08:50:14 +0900
Subject: [PATCH] strv: introduce string_strv_hashmap_remove()
(cherry picked from commit c540875cd3b024f64980966376637ecc284d643c)
Related: RHEL-14112
---
src/basic/strv.c | 17 +++++++++++++++++
src/basic/strv.h | 5 +++++
src/test/test-hashmap-plain.c | 16 ++++++++++++++++
3 files changed, 38 insertions(+)
diff --git a/src/basic/strv.c b/src/basic/strv.c
index 66b70befd6..1f5d6f058f 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -920,6 +920,23 @@ int fputstrv(FILE *f, char * const *l, const char *separator, bool *space) {
return 0;
}
+void string_strv_hashmap_remove(Hashmap *h, const char *key, const char *value) {
+ assert(key);
+
+ if (value) {
+ char **l = hashmap_get(h, key);
+ if (!l)
+ return;
+
+ strv_remove(l, value);
+ if (!strv_isempty(l))
+ return;
+ }
+
+ _unused_ _cleanup_free_ char *key_free = NULL;
+ strv_free(hashmap_remove2(h, key, (void**) &key_free));
+}
+
static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const char *value) {
char **l;
int r;
diff --git a/src/basic/strv.h b/src/basic/strv.h
index 6c9fa47943..9eb685fb86 100644
--- a/src/basic/strv.h
+++ b/src/basic/strv.h
@@ -261,6 +261,11 @@ int fputstrv(FILE *f, char * const *l, const char *separator, bool *space);
free_and_replace_full(a, b, strv_free)
extern const struct hash_ops string_strv_hash_ops;
+
+void string_strv_hashmap_remove(Hashmap *h, const char *key, const char *value);
+static inline void string_strv_ordered_hashmap_remove(OrderedHashmap *h, const char *key, const char *value) {
+ string_strv_hashmap_remove(PLAIN_HASHMAP(h), key, value);
+}
int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS);
int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS);
#define string_strv_hashmap_put(h, k, v) _string_strv_hashmap_put(h, k, v HASHMAP_DEBUG_SRC_ARGS)
diff --git a/src/test/test-hashmap-plain.c b/src/test/test-hashmap-plain.c
index 36a775012b..3bc96fc944 100644
--- a/src/test/test-hashmap-plain.c
+++ b/src/test/test-hashmap-plain.c
@@ -996,6 +996,22 @@ TEST(string_strv_hashmap) {
s = hashmap_get(m, "xxx");
assert_se(strv_equal(s, STRV_MAKE("bar", "BAR")));
+
+ string_strv_hashmap_remove(m, "foo", "bar");
+ ASSERT_NOT_NULL(s = hashmap_get(m, "foo"));
+ ASSERT_TRUE(strv_equal(s, STRV_MAKE("BAR")));
+
+ string_strv_hashmap_remove(m, "foo", "BAR");
+ ASSERT_NULL(hashmap_get(m, "foo"));
+
+ string_strv_hashmap_remove(m, "xxx", "BAR");
+ ASSERT_NOT_NULL(s = hashmap_get(m, "xxx"));
+ ASSERT_TRUE(strv_equal(s, STRV_MAKE("bar")));
+
+ string_strv_hashmap_remove(m, "xxx", "bar");
+ ASSERT_NULL(hashmap_get(m, "xxx"));
+
+ ASSERT_TRUE(hashmap_isempty(m));
}
/* Signal to test-hashmap.c that tests from this compilation unit were run. */

View File

@ -0,0 +1,230 @@
From fe5bad818a26875914f3b0c59fa3d4f5e6b3a41d Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 28 Jan 2025 09:55:12 +0900
Subject: [PATCH] unit-file: introduce unit_file_remove_from_name_map()
(cherry picked from commit d8b34aaef24599917d4e7fa04c78fffac3afe7cf)
Related: RHEL-14112
[msekleta: I've backported strv_equal_ignore_order() in the same commit
in order to get this to compile.]
---
src/basic/strv.c | 20 ++++++++++
src/basic/strv.h | 1 +
src/basic/unit-file.c | 35 +++++++++++++++++
src/basic/unit-file.h | 8 ++++
src/test/test-unit-file.c | 81 +++++++++++++++++++++++++++++++++++++++
5 files changed, 145 insertions(+)
diff --git a/src/basic/strv.c b/src/basic/strv.c
index 1f5d6f058f..47cc6931c1 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -775,6 +775,26 @@ int strv_compare(char * const *a, char * const *b) {
return 0;
}
+bool strv_equal_ignore_order(char **a, char **b) {
+
+ /* Just like strv_equal(), but doesn't care about the order of elements or about redundant entries
+ * (i.e. it's even ok if the number of entries in the array differ, as long as the difference just
+ * consists of repititions) */
+
+ if (a == b)
+ return true;
+
+ STRV_FOREACH(i, a)
+ if (!strv_contains(b, *i))
+ return false;
+
+ STRV_FOREACH(i, b)
+ if (!strv_contains(a, *i))
+ return false;
+
+ return true;
+}
+
void strv_print(char * const *l) {
STRV_FOREACH(s, l)
puts(*s);
diff --git a/src/basic/strv.h b/src/basic/strv.h
index 9eb685fb86..1de3c98e5c 100644
--- a/src/basic/strv.h
+++ b/src/basic/strv.h
@@ -160,6 +160,7 @@ bool strv_overlap(char * const *a, char * const *b) _pure_;
_STRV_FOREACH_PAIR(x, y, l, UNIQ_T(i, UNIQ))
char** strv_sort(char **l);
+bool strv_equal_ignore_order(char **a, char **b);
void strv_print(char * const *l);
#define strv_from_stdarg_alloca(first) \
diff --git a/src/basic/unit-file.c b/src/basic/unit-file.c
index c81c69db30..d7d7fd70f6 100644
--- a/src/basic/unit-file.c
+++ b/src/basic/unit-file.c
@@ -627,6 +627,41 @@ int unit_file_build_name_map(
return 1;
}
+int unit_file_remove_from_name_map(
+ const LookupPaths *lp,
+ uint64_t *cache_timestamp_hash,
+ Hashmap **unit_ids_map,
+ Hashmap **unit_names_map,
+ Set **path_cache,
+ const char *path) {
+
+ int r;
+
+ assert(path);
+
+ /* This assumes the specified path is already removed, and drops the relevant entries from the maps. */
+
+ /* If one of the lookup paths we are monitoring is already changed, let's rebuild the map. Then, the
+ * new map should not contain entries relevant to the specified path. */
+ r = unit_file_build_name_map(lp, cache_timestamp_hash, unit_ids_map, unit_names_map, path_cache);
+ if (r != 0)
+ return r;
+
+ /* If not, drop the relevant entries. */
+
+ _cleanup_free_ char *name = NULL;
+ r = path_extract_filename(path, &name);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to extract file name from '%s': %m", path);
+
+ _unused_ _cleanup_free_ char *key = NULL;
+ free(hashmap_remove2(*unit_ids_map, name, (void**) &key));
+ string_strv_hashmap_remove(*unit_names_map, name, name);
+ free(set_remove(*path_cache, path));
+
+ return 0;
+}
+
static int add_name(
const char *unit_name,
Set **names,
diff --git a/src/basic/unit-file.h b/src/basic/unit-file.h
index 1c43861f00..78f65dbc8e 100644
--- a/src/basic/unit-file.h
+++ b/src/basic/unit-file.h
@@ -52,6 +52,14 @@ int unit_file_build_name_map(
Hashmap **unit_names_map,
Set **path_cache);
+int unit_file_remove_from_name_map(
+ const LookupPaths *lp,
+ uint64_t *cache_timestamp_hash,
+ Hashmap **unit_ids_map,
+ Hashmap **unit_names_map,
+ Set **path_cache,
+ const char *path);
+
int unit_file_find_fragment(
Hashmap *unit_ids_map,
Hashmap *unit_name_map,
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
index dffa2822e6..389113c336 100644
--- a/src/test/test-unit-file.c
+++ b/src/test/test-unit-file.c
@@ -1,10 +1,15 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include "fileio.h"
#include "path-lookup.h"
+#include "path-util.h"
+#include "random-util.h"
+#include "rm-rf.h"
#include "set.h"
#include "special.h"
#include "strv.h"
#include "tests.h"
+#include "tmpfile-util.h"
#include "unit-file.h"
TEST(unit_validate_alias_symlink_and_warn) {
@@ -85,6 +90,82 @@ TEST(unit_file_build_name_map) {
}
}
+static bool test_unit_file_remove_from_name_map_trail(const LookupPaths *lp, size_t trial) {
+ int r;
+
+ log_debug("/* %s(trial=%zu) */", __func__, trial);
+
+ _cleanup_hashmap_free_ Hashmap *unit_ids = NULL, *unit_names = NULL;
+ _cleanup_set_free_ Set *path_cache = NULL;
+ assert_se(unit_file_build_name_map(lp, NULL, &unit_ids, &unit_names, &path_cache) > 0);
+
+ _cleanup_free_ char *name = NULL;
+ for (size_t i = 0; i < 100; i++) {
+ ASSERT_OK(asprintf(&name, "test-unit-file-%"PRIx64".service", random_u64()));
+ if (!hashmap_contains(unit_ids, name))
+ break;
+ name = mfree(name);
+ }
+ ASSERT_NOT_NULL(name);
+
+ _cleanup_free_ char *path = path_join(lp->transient, name);
+ ASSERT_NOT_NULL(path);
+ ASSERT_OK(write_string_file(path, "[Unit]\n", WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MKDIR_0755));
+
+ uint64_t cache_timestamp_hash = 0;
+ assert_se(unit_file_build_name_map(lp, &cache_timestamp_hash, &unit_ids, &unit_names, &path_cache) > 0);
+
+ ASSERT_STREQ(hashmap_get(unit_ids, name), path);
+ ASSERT_TRUE(strv_equal(hashmap_get(unit_names, name), STRV_MAKE(name)));
+ ASSERT_TRUE(set_contains(path_cache, path));
+
+ assert_se(unlink(path) >= 0);
+
+ ASSERT_OK(r = unit_file_remove_from_name_map(lp, &cache_timestamp_hash, &unit_ids, &unit_names, &path_cache, path));
+ if (r > 0)
+ return false; /* someone touches unit files. Retrying. */
+
+ ASSERT_FALSE(hashmap_contains(unit_ids, name));
+ ASSERT_FALSE(hashmap_contains(unit_names, path));
+ ASSERT_FALSE(set_contains(path_cache, path));
+
+ _cleanup_hashmap_free_ Hashmap *unit_ids_2 = NULL, *unit_names_2 = NULL;
+ _cleanup_set_free_ Set *path_cache_2 = NULL;
+ assert_se(unit_file_build_name_map(lp, NULL, &unit_ids_2, &unit_names_2, &path_cache_2) > 0);
+
+ if (hashmap_size(unit_ids) != hashmap_size(unit_ids_2) ||
+ hashmap_size(unit_names) != hashmap_size(unit_names_2) ||
+ !set_equal(path_cache, path_cache_2))
+ return false;
+
+ const char *k, *v;
+ HASHMAP_FOREACH_KEY(v, k, unit_ids)
+ if (!streq_ptr(hashmap_get(unit_ids_2, k), v))
+ return false;
+
+ char **l;
+ HASHMAP_FOREACH_KEY(l, k, unit_names)
+ if (!strv_equal_ignore_order(hashmap_get(unit_names_2, k), l))
+ return false;
+
+ return true;
+}
+
+
+TEST(unit_file_remove_from_name_map) {
+ _cleanup_(rm_rf_physical_and_freep) char *d = NULL;
+
+ _cleanup_(lookup_paths_free) LookupPaths lp = {};
+ ASSERT_OK(lookup_paths_init(&lp, LOOKUP_SCOPE_SYSTEM, LOOKUP_PATHS_TEMPORARY_GENERATED, NULL));
+ ASSERT_NOT_NULL(d = strdup(lp.temporary_dir));
+
+ for (size_t i = 0; i < 10; i++)
+ if (test_unit_file_remove_from_name_map_trail(&lp, i))
+ return;
+
+ assert_not_reached();
+}
+
TEST(runlevel_to_target) {
in_initrd_force(false);
assert_se(streq_ptr(runlevel_to_target(NULL), NULL));

View File

@ -0,0 +1,52 @@
From 4726233b421628eae405b3b3fb08222cf0befae4 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 28 Jan 2025 10:09:32 +0900
Subject: [PATCH] core/unit: remove path to transient unit file from unit name
maps on stop
Fixes #35190.
(cherry picked from commit fce94c5c563b8f6ede2b8f7f283d2d2faff4e062)
Resolves: RHEL-14112
---
src/core/unit.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index 9e349402ff..afe3fdab04 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -598,13 +598,11 @@ static void unit_clear_dependencies(Unit *u) {
static void unit_remove_transient(Unit *u) {
assert(u);
+ assert(u->manager);
if (!u->transient)
return;
- if (u->fragment_path)
- (void) unlink(u->fragment_path);
-
STRV_FOREACH(i, u->dropin_paths) {
_cleanup_free_ char *p = NULL, *pp = NULL;
@@ -621,6 +619,17 @@ static void unit_remove_transient(Unit *u) {
(void) unlink(*i);
(void) rmdir(p);
}
+
+ if (u->fragment_path) {
+ (void) unlink(u->fragment_path);
+ (void) unit_file_remove_from_name_map(
+ &u->manager->lookup_paths,
+ &u->manager->unit_cache_timestamp_hash,
+ &u->manager->unit_id_map,
+ &u->manager->unit_name_map,
+ &u->manager->unit_path_cache,
+ u->fragment_path);
+ }
}
static void unit_free_requires_mounts_for(Unit *u) {

View File

@ -0,0 +1,33 @@
From 1aa6c0d3bcac98d3442d07412f4296d5b9b18dc0 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 27 Jan 2025 22:24:16 +0900
Subject: [PATCH] TEST-07-PID1: add reprudcer for issue #35190
(cherry picked from commit 448e99251aa47a5986425a1783da44d1200fe733)
Related: RHEL-14112
---
test/units/testsuite-07.transient.sh | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100755 test/units/testsuite-07.transient.sh
diff --git a/test/units/testsuite-07.transient.sh b/test/units/testsuite-07.transient.sh
new file mode 100755
index 0000000000..ae71a38143
--- /dev/null
+++ b/test/units/testsuite-07.transient.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -ex
+set -o pipefail
+
+journalctl --sync
+TS="$(date '+%H:%M:%S')"
+
+systemd-run -u hogehoge.service sleep infinity
+systemctl daemon-reload
+systemctl stop hogehoge.service
+
+journalctl --sync
+[[ -z "$(journalctl -b -q --since "$TS" -u hogehoge.service -p notice)" ]]

View File

@ -0,0 +1,34 @@
From 2fe492a2f0fefa0f782cb04a248fc9dcd5667bf0 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 24 Oct 2025 12:55:20 +0200
Subject: [PATCH] coredump: handle ENOBUFS and EMSGSIZE the same way
Depending on the runtime configuration, e.g. sysctls
net.core.wmem_default= and net.core.rmem_default and on the actual
message size, sendmsg() can fail also with ENOBUFS. E.g. alloc_skb()
failure caused by net.core.[rw]mem_default=64MiB and huge fdinfo list
from process that has 90k opened FDs.
We should handle this case in the same way as EMSGSIZE and drop part of
the message.
(cherry picked from commit 28e62e684b631f928f1d857b04f45f0d34441675)
Resolves: RHEL-103801
---
src/coredump/coredump.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index e0aac3c8d0..28dabf017b 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -1273,7 +1273,7 @@ static int send_iovec(const struct iovec_wrapper *iovw, int input_fd, int mntns_
if (sendmsg(fd, &mh, MSG_NOSIGNAL) >= 0)
break;
- if (errno == EMSGSIZE && mh.msg_iov[0].iov_len > 0) {
+ if (IN_SET(errno, EMSGSIZE, ENOBUFS) && mh.msg_iov[0].iov_len > 0) {
/* This field didn't fit? That's a pity. Given that this is
* just metadata, let's truncate the field at half, and try
* again. We append three dots, in order to show that this is

View File

@ -21,7 +21,7 @@
Name: systemd
Url: https://systemd.io
Version: 252
Release: 60%{?dist}
Release: 61%{?dist}
# For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+
Summary: System and Service Manager
@ -1366,6 +1366,12 @@ Patch1280: 1280-coredump-use-d-in-kernel-core-pattern.patch
Patch1281: 1281-pidref-add-structure-that-can-reference-a-pid-via-bo.patch
Patch1282: 1282-fd-util-introduce-parse_fd.patch
Patch1283: 1283-coredump-add-support-for-new-F-PIDFD-specifier.patch
Patch1284: 1284-timer-rebase-the-next-elapse-timestamp-only-if-timer.patch
Patch1285: 1285-strv-introduce-string_strv_hashmap_remove.patch
Patch1286: 1286-unit-file-introduce-unit_file_remove_from_name_map.patch
Patch1287: 1287-core-unit-remove-path-to-transient-unit-file-from-un.patch
Patch1288: 1288-TEST-07-PID1-add-reprudcer-for-issue-35190.patch
Patch1289: 1289-coredump-handle-ENOBUFS-and-EMSGSIZE-the-same-way.patch
# Downstream-only patches (90009999)
@ -2243,6 +2249,14 @@ systemd-hwdb update &>/dev/null || :
%{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/*
%changelog
* Fri Nov 21 2025 systemd maintenance team <systemd-maint@redhat.com> - 252-61
- timer: rebase the next elapse timestamp only if timer didn't already run (RHEL-118215)
- strv: introduce string_strv_hashmap_remove() (RHEL-14112)
- unit-file: introduce unit_file_remove_from_name_map() (RHEL-14112)
- core/unit: remove path to transient unit file from unit name maps on stop (RHEL-14112)
- TEST-07-PID1: add reprudcer for issue #35190 (RHEL-14112)
- coredump: handle ENOBUFS and EMSGSIZE the same way (RHEL-103801)
* Wed Nov 05 2025 systemd maintenance team <systemd-maint@redhat.com> - 252-60
- man: fix a missing word (RHEL-115182)
- cryptsetup: Add optional support for linking volume key in keyring. (RHEL-97175)