core: propagate reload from RELOADING=1 notification (#6550)

This commit is contained in:
Jouke Witteveen 2017-08-07 11:27:24 +02:00 committed by Lennart Poettering
parent ca992ecf07
commit 15d167f8a3
6 changed files with 72 additions and 19 deletions

View File

@ -139,7 +139,8 @@
present it to the user. Note that a service that sends this
notification must also send a <literal>READY=1</literal>
notification when it completed reloading its
configuration.</para></listitem>
configuration. Reloads are propagated in the same way as they
are when initiated by the user.</para></listitem>
</varlistentry>
<varlistentry>

View File

@ -1494,6 +1494,40 @@ int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name,
return r;
}
int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error *e) {
int r;
Transaction *tr;
assert(m);
assert(unit);
assert(mode < _JOB_MODE_MAX);
assert(mode != JOB_ISOLATE); /* Isolate is only valid for start */
tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
if (!tr)
return -ENOMEM;
/* We need an anchor job */
r = transaction_add_job_and_dependencies(tr, JOB_NOP, unit, NULL, false, false, true, true, e);
if (r < 0)
goto tr_abort;
/* Failure in adding individual dependencies is ignored, so this always succeeds. */
transaction_add_propagate_reload_jobs(tr, unit, tr->anchor_job, mode == JOB_IGNORE_DEPENDENCIES, e);
r = transaction_activate(tr, m, mode, e);
if (r < 0)
goto tr_abort;
transaction_free(tr);
return 0;
tr_abort:
transaction_abort(tr);
transaction_free(tr);
return r;
}
Job *manager_get_job(Manager *m, uint32_t id) {
assert(m);

View File

@ -344,6 +344,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, sd_bus_error *e, Job **_ret);
int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, sd_bus_error *e, Job **_ret);
int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Job **ret);
int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, 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);

View File

@ -1945,10 +1945,18 @@ fail:
}
static void service_enter_reload_by_notify(Service *s) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
assert(s);
service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_start_usec));
service_set_state(s, SERVICE_RELOAD);
/* service_enter_reload_by_notify is never called during a reload, thus no loops are possible. */
r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_FAIL, &error);
if (r < 0)
log_unit_warning(UNIT(s), "Failed to schedule propagation of reload: %s", bus_error_message(&error, -r));
}
static void service_enter_reload(Service *s) {

View File

@ -858,6 +858,30 @@ static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependen
}
}
void transaction_add_propagate_reload_jobs(Transaction *tr, Unit *unit, Job *by, bool ignore_order, sd_bus_error *e) {
Iterator i;
Unit *dep;
JobType nt;
int r;
assert(tr);
assert(unit);
SET_FOREACH(dep, unit->dependencies[UNIT_PROPAGATES_RELOAD_TO], i) {
nt = job_type_collapse(JOB_TRY_RELOAD, dep);
if (nt == JOB_NOP)
continue;
r = transaction_add_job_and_dependencies(tr, nt, dep, by, false, false, false, ignore_order, e);
if (r < 0) {
log_unit_warning(dep,
"Cannot add dependency reload job, ignoring: %s",
bus_error_message(e, r));
sd_bus_error_free(e);
}
}
}
int transaction_add_job_and_dependencies(
Transaction *tr,
JobType type,
@ -1043,24 +1067,8 @@ int transaction_add_job_and_dependencies(
}
}
if (type == JOB_RELOAD) {
SET_FOREACH(dep, ret->unit->dependencies[UNIT_PROPAGATES_RELOAD_TO], i) {
JobType nt;
nt = job_type_collapse(JOB_TRY_RELOAD, dep);
if (nt == JOB_NOP)
continue;
r = transaction_add_job_and_dependencies(tr, nt, dep, ret, false, false, false, ignore_order, e);
if (r < 0) {
log_unit_warning(dep,
"Cannot add dependency reload job, ignoring: %s",
bus_error_message(e, r));
sd_bus_error_free(e);
}
}
}
if (type == JOB_RELOAD)
transaction_add_propagate_reload_jobs(tr, ret->unit, ret, ignore_order, e);
/* JOB_VERIFY_STARTED require no dependency handling */
}

View File

@ -36,6 +36,7 @@ struct Transaction {
Transaction *transaction_new(bool irreversible);
void transaction_free(Transaction *tr);
void transaction_add_propagate_reload_jobs(Transaction *tr, Unit *unit, Job *by, bool ignore_order, sd_bus_error *e);
int transaction_add_job_and_dependencies(
Transaction *tr,
JobType type,