diff options
Diffstat (limited to 'meta-phosphor/recipes-core/systemd/systemd/0001-timedate-defer-the-property-changed-signal-until-job.patch')
-rw-r--r-- | meta-phosphor/recipes-core/systemd/systemd/0001-timedate-defer-the-property-changed-signal-until-job.patch | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/meta-phosphor/recipes-core/systemd/systemd/0001-timedate-defer-the-property-changed-signal-until-job.patch b/meta-phosphor/recipes-core/systemd/systemd/0001-timedate-defer-the-property-changed-signal-until-job.patch new file mode 100644 index 000000000..a43c36b33 --- /dev/null +++ b/meta-phosphor/recipes-core/systemd/systemd/0001-timedate-defer-the-property-changed-signal-until-job.patch @@ -0,0 +1,179 @@ +From 3af0a96c0fcc623bd16649fc3640396a657cf9ef Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sun, 22 Jul 2018 23:10:02 +0900 +Subject: [PATCH] timedate: defer the property changed signal until job of + starting/stopping NTP service is finished + +Before this, the property changed signal is emitted immediately after +StartUnit/StopUnit method is called. So, the running state of the NTP +client service may not updated. +This makes the timing of emitting property changed signal is deferred +until job of starting/stopping NTP client service is completed. + +Fixes #9672. +--- + src/timedate/timedated.c | 78 ++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 65 insertions(+), 13 deletions(-) + +diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c +index 6c95764..012cbe0 100644 +--- a/src/timedate/timedated.c ++++ b/src/timedate/timedated.c +@@ -46,6 +46,9 @@ typedef struct Context { + Hashmap *polkit_registry; + sd_bus_message *cache; + ++ sd_bus_slot *slot_job_removed; ++ char *path_ntp_unit; ++ + LIST_HEAD(UnitStatusInfo, units); + } Context; + +@@ -74,6 +77,9 @@ static void context_free(Context *c) { + bus_verify_polkit_async_registry_free(c->polkit_registry); + sd_bus_message_unref(c->cache); + ++ sd_bus_slot_unref(c->slot_job_removed); ++ free(c->path_ntp_unit); ++ + while ((p = c->units)) { + LIST_REMOVE(units, c->units, p); + unit_status_info_free(p); +@@ -345,17 +351,55 @@ static int context_update_ntp_status(Context *c, sd_bus *bus, sd_bus_message *m) + return 0; + } + +-static int unit_start_or_stop(UnitStatusInfo *u, sd_bus *bus, sd_bus_error *error, bool start) { ++static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) { ++ const char *path; ++ Context *c = userdata; ++ int r; ++ ++ assert(c); ++ assert(m); ++ ++ r = sd_bus_message_read(m, "uoss", NULL, &path, NULL, NULL); ++ if (r < 0) { ++ bus_log_parse_error(r); ++ return 0; ++ } ++ ++ if (!streq_ptr(path, c->path_ntp_unit)) ++ return 0; ++ ++ (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "NTP", NULL); ++ ++ c->slot_job_removed = sd_bus_slot_unref(c->slot_job_removed); ++ c->path_ntp_unit = mfree(c->path_ntp_unit); ++ ++ return 0; ++} ++ ++static int unit_start_or_stop(Context *c, UnitStatusInfo *u, sd_bus *bus, sd_bus_error *error, bool start) { ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; ++ _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *slot = NULL; ++ const char *path; + int r; + ++ assert(c); + assert(u); + assert(bus); + assert(error); + +- /* Call context_update_ntp_status() to update UnitStatusInfo before calling this. */ ++ /* This method may be called frequently. Forget the previous job if it has not completed yet. */ ++ c->slot_job_removed = sd_bus_slot_unref(c->slot_job_removed); + +- if (streq(u->active_state, "active") == start) +- return 0; ++ r = sd_bus_match_signal_async( ++ bus, ++ &slot, ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ "JobRemoved", ++ match_job_removed, NULL, c); ++ if (r < 0) ++ return r; + + r = sd_bus_call_method( + bus, +@@ -364,13 +408,22 @@ static int unit_start_or_stop(UnitStatusInfo *u, sd_bus *bus, sd_bus_error *erro + "org.freedesktop.systemd1.Manager", + start ? "StartUnit" : "StopUnit", + error, +- NULL, ++ &reply, + "ss", + u->name, + "replace"); + if (r < 0) + return r; + ++ r = sd_bus_message_read(reply, "o", &path); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ ++ r = free_and_strdup(&c->path_ntp_unit, path); ++ if (r < 0) ++ return log_oom(); ++ ++ c->slot_job_removed = TAKE_PTR(slot); + return 0; + } + +@@ -422,8 +475,9 @@ static int unit_enable_or_disable(UnitStatusInfo *u, sd_bus *bus, sd_bus_error * + error, + NULL, + NULL); +- if (r < 0) +- return r; ++ if (r < 0) ++ return r; ++ + return 0; + } + +@@ -813,7 +867,7 @@ static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error + if (q < 0) + r = q; + +- q = unit_start_or_stop(u, bus, error, enable); ++ q = unit_start_or_stop(c, u, bus, error, enable); + if (q < 0) + r = q; + } +@@ -827,17 +881,17 @@ static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error + if (r < 0) + continue; + +- r = unit_start_or_stop(u, bus, error, enable); ++ r = unit_start_or_stop(c, u, bus, error, enable); + break; + } + +- else if (context_ntp_service_is_active(c) <= 0) ++ else + LIST_FOREACH(units, u, c->units) { + if (!streq(u->load_state, "loaded") || + !streq(u->unit_file_state, "enabled")) + continue; + +- r = unit_start_or_stop(u, bus, error, enable); ++ r = unit_start_or_stop(c, u, bus, error, enable); + break; + } + +@@ -846,8 +900,6 @@ static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error + + log_info("Set NTP to %sd", enable_disable(enable)); + +- (void) sd_bus_emit_properties_changed(bus, "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "NTP", NULL); +- + return sd_bus_reply_method_return(m, NULL); + } + +-- +2.7.4 + |