From c8bbb87d4f56457b6554a384dd077fa0334f60a1 Mon Sep 17 00:00:00 2001 From: Jouke Witteveen Date: Mon, 29 Dec 2014 23:40:57 +0100 Subject: [PATCH] Propagate reload from RELOADING=1 notification https://bugs.freedesktop.org/show_bug.cgi?id=87251 service_enter_reload_by_notify is only ever called when the state of the service is RUNNING. In particular it is not called when the state is RELOADING, thus preventing loops. --- src/core/manager.c | 35 +++++++++++++++++++++++++++++++++++ src/core/manager.h | 1 + src/core/service.c | 7 +++++++ 3 files changed, 43 insertions(+) diff --git a/src/core/manager.c b/src/core/manager.c index 9705e64..b53e67a 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1226,6 +1226,41 @@ int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode return manager_add_job(m, type, unit, mode, override, e, _ret); } +int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, bool override, sd_bus_error *e) { + int r; + Transaction *tr; + Iterator i; + Unit *dep; + + + assert(m); + assert(unit); + assert(mode < _JOB_MODE_MAX); + + tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY); + if (!tr) + return -ENOMEM; + + SET_FOREACH(dep, unit->dependencies[UNIT_PROPAGATES_RELOAD_TO], i) { + r = transaction_add_job_and_dependencies(tr, JOB_RELOAD, dep, NULL, false, override, false, false, mode == JOB_IGNORE_DEPENDENCIES, e); + if (r < 0) { + log_unit_warning(dep->id, + "Cannot add dependency reload job for unit %s, ignoring: %s", + dep->id, bus_error_message(e, r)); + + if (e) + sd_bus_error_free(e); + } + } + + r = transaction_activate(tr, m, mode, e); + if (r < 0) + transaction_abort(tr); + + transaction_free(tr); + return r; +} + Job *manager_get_job(Manager *m, uint32_t id) { assert(m); diff --git a/src/core/manager.h b/src/core/manager.h index ab75f90..bc11f87 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -316,6 +316,7 @@ int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool force, sd_bus_error *e, Job **_ret); int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool force, sd_bus_error *e, Job **_ret); +int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, bool force, sd_bus_error *e); void manager_dump_units(Manager *s, FILE *f, const char *prefix); void manager_dump_jobs(Manager *s, FILE *f, const char *prefix); diff --git a/src/core/service.c b/src/core/service.c index bfbe959..71c7bf6 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1496,11 +1496,18 @@ fail: } static void service_enter_reload_by_notify(Service *s) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + int r; + assert(s); if (s->timeout_start_usec > 0) service_arm_timer(s, s->timeout_start_usec); + r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_REPLACE, false, &error); + if(r < 0) + log_unit_warning(UNIT(s)->id, "%s failed to schedule propagation of reload: %s", UNIT(s)->id, bus_error_message(&error, -r)); + service_set_state(s, SERVICE_RELOAD); } -- 2.2.1