]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: propagate reload from RELOADING=1 notification (#6550)
authorJouke Witteveen <j.witteveen@gmail.com>
Mon, 7 Aug 2017 09:27:24 +0000 (11:27 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 7 Aug 2017 09:27:24 +0000 (11:27 +0200)
man/sd_notify.xml
src/core/manager.c
src/core/manager.h
src/core/service.c
src/core/transaction.c
src/core/transaction.h

index e8ddea2f5fba91a02dedea98ea6e1634491bc4e3..7d7b0077bec0c31611f55c1c6a786c682ef1c095 100644 (file)
         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>
index fb5e2b55132e10b6d17a4865f173a3cdd99533f4..7f9c6164c71b7a2aaa9a8034435616178f7b5699 100644 (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);
 
index 6aceed281a1736fb93c9410de482af37770727fc..5146a795f1d93e4bafb790c25ad9b7010c30b8c7 100644 (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);
index baeed70554ea8c495790899b4a56654f5721c700..39fcdcc1a76bd929beb99ce10078ad32f5abc91c 100644 (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) {
index 710a6a394899a30cc6b0bc0dc4498b8d11ab5157..1af4ed910061fdf6ef1fd56450db0b543a4cebae 100644 (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 */
         }
index 6a3f927b0f3986350054a52702f532df1d8be2d7..ddfdbf9987eb6ffd4db0fbf19bfe6387ab8cdecb 100644 (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,