Skip to content
This repository has been archived by the owner on Aug 6, 2020. It is now read-only.

Commit

Permalink
timedate: defer the property changed signal until job of starting/sto…
Browse files Browse the repository at this point in the history
…pping 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 systemd#9672.

(cherry picked from commit 3af0a96)
  • Loading branch information
yuwata authored and keszybz committed Oct 29, 2018
1 parent afa97b6 commit 193fa92
Showing 1 changed file with 65 additions and 13 deletions.
78 changes: 65 additions & 13 deletions src/timedate/timedated.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,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;

Expand Down Expand Up @@ -73,6 +76,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);
Expand Down Expand Up @@ -344,17 +350,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,
Expand All @@ -363,13 +407,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;
}

Expand Down Expand Up @@ -421,8 +474,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;
}

Expand Down Expand Up @@ -812,7 +866,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;
}
Expand All @@ -826,17 +880,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;
}

Expand All @@ -845,8 +899,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);
}

Expand Down

0 comments on commit 193fa92

Please sign in to comment.