timedated: wait for jobs before SetNTP response

Backport a fix to address the dbus SetNTP response timing issue.
Fix is already available since systemd v256-rc1.

(From OE-Core rev: 4db0483cfd14e31c3e7cc87d538d73275fd51bbf)

Signed-off-by: Michal Seben <michal.seben@siemens.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
Michal Seben
2025-07-15 14:50:13 +02:00
committed by Steve Sakoman
parent f2a6317735
commit 15a4d0cfb1
2 changed files with 98 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
From 3a51e31be9f626cf772733cb289ed64739fab0e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20Koutn=C3=BD?= <mkoutny@suse.com>
Date: Tue, 20 Feb 2024 19:26:16 +0100
Subject: [PATCH] timedated: Respond on org.freedesktop.timedate1.SetNTP only
when really finished
The method returns prematurely (before jobs it triggers terminate). This
is externally visible because other methods may fail if jobs did not
finish.
Postpone the DBus method response until we collect all signals for
finished jobs.
systemd-timedated keeps track of in-flight DBus requests and answers
them all in unspecified order when jobs finish. The capacity of requests
in systemd-timedated is limited.
Fixes: #17739
Upstream-Status: Backport [https://github.com/systemd/systemd/commit/3a51e31be9f626cf772733cb289ed64739fab0e4]
Signed-off-by: Michal Seben <michal.seben@siemens.com>
---
src/timedate/timedated.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
Index: git/src/timedate/timedated.c
===================================================================
--- git.orig/src/timedate/timedated.c
+++ git/src/timedate/timedated.c
@@ -45,6 +45,7 @@
#define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
#define UNIT_LIST_DIRS (const char* const*) CONF_PATHS_STRV("systemd/ntp-units.d")
+#define SET_NTP_IN_FLIGHT_MAX 16
typedef struct UnitStatusInfo {
char *name;
@@ -61,6 +62,7 @@ typedef struct Context {
bool local_rtc;
Hashmap *polkit_registry;
sd_bus_message *cache;
+ Set *set_ntp_calls;
sd_bus_slot *slot_job_removed;
@@ -121,6 +123,7 @@ static void context_clear(Context *c) {
free(c->zone);
bus_verify_polkit_async_registry_free(c->polkit_registry);
sd_bus_message_unref(c->cache);
+ set_free(c->set_ntp_calls);
sd_bus_slot_unref(c->slot_job_removed);
@@ -461,11 +464,19 @@ static int match_job_removed(sd_bus_mess
n += !!u->path;
if (n == 0) {
+ sd_bus_message *cm;
+
c->slot_job_removed = sd_bus_slot_unref(c->slot_job_removed);
(void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m),
"/org/freedesktop/timedate1", "org.freedesktop.timedate1", "NTP",
NULL);
+ while ((cm = set_steal_first(c->set_ntp_calls))) {
+ r = sd_bus_reply_method_return(cm, NULL);
+ if (r < 0)
+ log_debug_errno(r, "Failed to reply to SetNTP method call, ignoring: %m");
+ sd_bus_message_unref(cm);
+ }
}
return 0;
@@ -944,6 +955,9 @@ static int method_set_ntp(sd_bus_message
LIST_FOREACH(units, u, c->units)
u->path = mfree(u->path);
+ if (set_size(c->set_ntp_calls) >= SET_NTP_IN_FLIGHT_MAX)
+ return sd_bus_error_set_errnof(error, EAGAIN, "Too many calls in flight.");
+
if (!c->slot_job_removed) {
r = bus_match_signal_async(
bus,
@@ -998,11 +1012,12 @@ static int method_set_ntp(sd_bus_message
c->slot_job_removed = TAKE_PTR(slot);
if (selected)
- log_info("Set NTP to enabled (%s).", selected->name);
+ log_info("Set NTP to be enabled (%s).", selected->name);
else
- log_info("Set NTP to disabled.");
+ log_info("Set NTP to be disabled.");
- return sd_bus_reply_method_return(m, NULL);
+ /* Asynchrounous reply to m in match_job_removed() */
+ return set_ensure_consume(&c->set_ntp_calls, &bus_message_hash_ops, sd_bus_message_ref(m));
}
static int method_list_timezones(sd_bus_message *m, void *userdata, sd_bus_error *error) {

View File

@@ -27,6 +27,7 @@ SRC_URI += " \
file://99-default.preset \
file://systemd-pager.sh \
file://0002-binfmt-Don-t-install-dependency-links-at-install-tim.patch \
file://0003-timedated-Respond-on-org.freedesktop.timedate1.SetNT.patch \
file://0008-implment-systemd-sysv-install-for-OE.patch \
"