systemd-252-61
Resolves: RHEL-103801,RHEL-118215,RHEL-14112
This commit is contained in:
parent
a673ceed38
commit
3b9729cdd7
131
1284-timer-rebase-the-next-elapse-timestamp-only-if-timer.patch
Normal file
131
1284-timer-rebase-the-next-elapse-timestamp-only-if-timer.patch
Normal 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;
|
||||
85
1285-strv-introduce-string_strv_hashmap_remove.patch
Normal file
85
1285-strv-introduce-string_strv_hashmap_remove.patch
Normal 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. */
|
||||
230
1286-unit-file-introduce-unit_file_remove_from_name_map.patch
Normal file
230
1286-unit-file-introduce-unit_file_remove_from_name_map.patch
Normal 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));
|
||||
@ -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) {
|
||||
33
1288-TEST-07-PID1-add-reprudcer-for-issue-35190.patch
Normal file
33
1288-TEST-07-PID1-add-reprudcer-for-issue-35190.patch
Normal 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)" ]]
|
||||
34
1289-coredump-handle-ENOBUFS-and-EMSGSIZE-the-same-way.patch
Normal file
34
1289-coredump-handle-ENOBUFS-and-EMSGSIZE-the-same-way.patch
Normal 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
|
||||
16
systemd.spec
16
systemd.spec
@ -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 (9000–9999)
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user