a9339c
From 7bc07eb6c9a31f2c26d0fe3e6d7a26a13cbb2369 Mon Sep 17 00:00:00 2001
a9339c
From: Michal Schmidt <mschmidt@redhat.com>
a9339c
Date: Thu, 16 Jul 2015 20:08:30 +0200
a9339c
Subject: [PATCH] core: fix confusing logging of instantaneous jobs
a9339c
a9339c
For instantaneous jobs (e.g. starting of targets, sockets, slices, or
a9339c
Type=simple services) the log shows the job completion
a9339c
before starting:
a9339c
a9339c
        systemd[1]: Created slice -.slice.
a9339c
        systemd[1]: Starting -.slice.
a9339c
        systemd[1]: Created slice System Slice.
a9339c
        systemd[1]: Starting System Slice.
a9339c
        systemd[1]: Listening on Journal Audit Socket.
a9339c
        systemd[1]: Starting Journal Audit Socket.
a9339c
        systemd[1]: Reached target Timers.
a9339c
        systemd[1]: Starting Timers.
a9339c
        ...
a9339c
a9339c
The reason is that the job completes before the ->start() method returns
a9339c
and only then does unit_start() print the "Starting ..." message.
a9339c
The same thing happens when stopping units.
a9339c
a9339c
Rather than fixing the order of the messages, let's just not emit the
a9339c
Starting/Stopping message at all when the job completes instantaneously.
a9339c
The job completion message is sufficient in this case.
a9339c
a9339c
(cherry picked from commit d1a34ae9c20f1c02aab17884919eccef572b1d21)
a9339c
a9339c
Resolves: #1506256
a9339c
---
de8967
 src/core/job.c  | 65 ++++++++++++++++++++++++++++++++++---------------
de8967
 src/core/unit.c | 36 +++++++++------------------
a9339c
 src/core/unit.h |  1 +
a9339c
 3 files changed, 58 insertions(+), 44 deletions(-)
a9339c
a9339c
diff --git a/src/core/job.c b/src/core/job.c
a9339c
index c9a43a4cb..612caa604 100644
a9339c
--- a/src/core/job.c
a9339c
+++ b/src/core/job.c
a9339c
@@ -504,10 +504,48 @@ static void job_change_type(Job *j, JobType newtype) {
a9339c
         j->type = newtype;
a9339c
 }
a9339c
 
a9339c
+static int job_perform_on_unit(Job **j) {
a9339c
+        /* While we execute this operation the job might go away (for
a9339c
+         * example: because it finishes immediately or is replaced by a new,
a9339c
+         * conflicting job.) To make sure we don't access a freed job later on
a9339c
+         * we store the id here, so that we can verify the job is still
a9339c
+         * valid. */
a9339c
+        Manager *m  = (*j)->manager;
a9339c
+        Unit *u     = (*j)->unit;
a9339c
+        JobType t   = (*j)->type;
a9339c
+        uint32_t id = (*j)->id;
a9339c
+        int r;
a9339c
+
a9339c
+        switch (t) {
a9339c
+                case JOB_START:
a9339c
+                        r = unit_start(u);
a9339c
+                        break;
a9339c
+
a9339c
+                case JOB_RESTART:
a9339c
+                        t = JOB_STOP;
a9339c
+                case JOB_STOP:
a9339c
+                        r = unit_stop(u);
a9339c
+                        break;
a9339c
+
a9339c
+                case JOB_RELOAD:
a9339c
+                        r = unit_reload(u);
a9339c
+                        break;
a9339c
+
a9339c
+                default:
a9339c
+                        assert_not_reached("Invalid job type");
a9339c
+        }
a9339c
+
a9339c
+        /* Log if the job still exists and the start/stop/reload function
a9339c
+         * actually did something. */
a9339c
+        *j = manager_get_job(m, id);
a9339c
+        if (*j && r > 0)
a9339c
+                unit_status_emit_starting_stopping_reloading(u, t);
a9339c
+
a9339c
+        return r;
a9339c
+}
a9339c
+
a9339c
 int job_run_and_invalidate(Job *j) {
a9339c
         int r;
a9339c
-        uint32_t id;
a9339c
-        Manager *m = j->manager;
a9339c
 
a9339c
         assert(j);
a9339c
         assert(j->installed);
a9339c
@@ -526,23 +564,9 @@ int job_run_and_invalidate(Job *j) {
a9339c
         job_set_state(j, JOB_RUNNING);
a9339c
         job_add_to_dbus_queue(j);
a9339c
 
a9339c
-        /* While we execute this operation the job might go away (for
a9339c
-         * example: because it is replaced by a new, conflicting
a9339c
-         * job.) To make sure we don't access a freed job later on we
a9339c
-         * store the id here, so that we can verify the job is still
a9339c
-         * valid. */
a9339c
-        id = j->id;
a9339c
 
a9339c
         switch (j->type) {
a9339c
 
a9339c
-                case JOB_START:
a9339c
-                        r = unit_start(j->unit);
a9339c
-
a9339c
-                        /* If this unit cannot be started, then simply wait */
a9339c
-                        if (r == -EBADR)
a9339c
-                                r = 0;
a9339c
-                        break;
a9339c
-
a9339c
                 case JOB_VERIFY_ACTIVE: {
a9339c
                         UnitActiveState t = unit_active_state(j->unit);
a9339c
                         if (UNIT_IS_ACTIVE_OR_RELOADING(t))
a9339c
@@ -554,17 +578,19 @@ int job_run_and_invalidate(Job *j) {
a9339c
                         break;
a9339c
                 }
a9339c
 
a9339c
+                case JOB_START:
a9339c
                 case JOB_STOP:
a9339c
                 case JOB_RESTART:
a9339c
-                        r = unit_stop(j->unit);
a9339c
+                        r = job_perform_on_unit(&j);
a9339c
 
a9339c
-                        /* If this unit cannot stopped, then simply wait. */
a9339c
+                        /* If the unit type does not support starting/stopping,
a9339c
+                         * then simply wait. */
a9339c
                         if (r == -EBADR)
a9339c
                                 r = 0;
a9339c
                         break;
a9339c
 
a9339c
                 case JOB_RELOAD:
a9339c
-                        r = unit_reload(j->unit);
a9339c
+                        r = job_perform_on_unit(&j);
a9339c
                         break;
a9339c
 
a9339c
                 case JOB_NOP:
a9339c
@@ -575,7 +601,6 @@ int job_run_and_invalidate(Job *j) {
a9339c
                         assert_not_reached("Unknown job type");
a9339c
         }
a9339c
 
a9339c
-        j = manager_get_job(m, id);
a9339c
         if (j) {
a9339c
                 if (r == -EALREADY)
a9339c
                         r = job_finish_and_invalidate(j, JOB_DONE, true, true);
a9339c
diff --git a/src/core/unit.c b/src/core/unit.c
a9339c
index 6d535ae12..907a4bf7f 100644
a9339c
--- a/src/core/unit.c
a9339c
+++ b/src/core/unit.c
a9339c
@@ -1417,6 +1417,15 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
a9339c
                         NULL);
a9339c
 }
a9339c
 
a9339c
+void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t) {
a9339c
+
a9339c
+        unit_status_log_starting_stopping_reloading(u, t);
a9339c
+
a9339c
+        /* Reload status messages have traditionally not been printed to console. */
a9339c
+        if (t != JOB_RELOAD)
a9339c
+                unit_status_print_starting_stopping(u, t);
a9339c
+}
a9339c
+
a9339c
 /* Errors:
a9339c
  *         -EBADR:     This unit type does not support starting.
a9339c
  *         -EALREADY:  Unit is already started.
a9339c
@@ -1427,7 +1436,6 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
a9339c
 int unit_start(Unit *u) {
a9339c
         UnitActiveState state;
a9339c
         Unit *following;
a9339c
-        int r;
a9339c
 
a9339c
         assert(u);
a9339c
 
a9339c
@@ -1481,14 +1489,7 @@ int unit_start(Unit *u) {
a9339c
 
a9339c
         unit_add_to_dbus_queue(u);
a9339c
 
a9339c
-        r = UNIT_VTABLE(u)->start(u);
a9339c
-        if (r <= 0)
a9339c
-                return r;
a9339c
-
a9339c
-        /* Log if the start function actually did something */
a9339c
-        unit_status_log_starting_stopping_reloading(u, JOB_START);
a9339c
-        unit_status_print_starting_stopping(u, JOB_START);
a9339c
-        return r;
a9339c
+        return UNIT_VTABLE(u)->start(u);
a9339c
 }
a9339c
 
a9339c
 bool unit_can_start(Unit *u) {
a9339c
@@ -1512,7 +1513,6 @@ bool unit_can_isolate(Unit *u) {
a9339c
 int unit_stop(Unit *u) {
a9339c
         UnitActiveState state;
a9339c
         Unit *following;
a9339c
-        int r;
a9339c
 
a9339c
         assert(u);
a9339c
 
a9339c
@@ -1531,13 +1531,7 @@ int unit_stop(Unit *u) {
a9339c
 
a9339c
         unit_add_to_dbus_queue(u);
a9339c
 
a9339c
-        r = UNIT_VTABLE(u)->stop(u);
a9339c
-        if (r <= 0)
a9339c
-                return r;
a9339c
-
a9339c
-        unit_status_log_starting_stopping_reloading(u, JOB_STOP);
a9339c
-        unit_status_print_starting_stopping(u, JOB_STOP);
a9339c
-        return r;
a9339c
+        return UNIT_VTABLE(u)->stop(u);
a9339c
 }
a9339c
 
a9339c
 /* Errors:
a9339c
@@ -1548,7 +1542,6 @@ int unit_stop(Unit *u) {
a9339c
 int unit_reload(Unit *u) {
a9339c
         UnitActiveState state;
a9339c
         Unit *following;
a9339c
-        int r;
a9339c
 
a9339c
         assert(u);
a9339c
 
a9339c
@@ -1575,12 +1568,7 @@ int unit_reload(Unit *u) {
a9339c
 
a9339c
         unit_add_to_dbus_queue(u);
a9339c
 
a9339c
-        r = UNIT_VTABLE(u)->reload(u);
a9339c
-        if (r <= 0)
a9339c
-                return r;
a9339c
-
a9339c
-        unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
a9339c
-        return r;
a9339c
+        return UNIT_VTABLE(u)->reload(u);
a9339c
 }
a9339c
 
a9339c
 bool unit_can_reload(Unit *u) {
a9339c
diff --git a/src/core/unit.h b/src/core/unit.h
a9339c
index 85f52df18..480e2e95f 100644
a9339c
--- a/src/core/unit.h
a9339c
+++ b/src/core/unit.h
a9339c
@@ -562,6 +562,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency d);
a9339c
 int unit_coldplug(Unit *u, Hashmap *deferred_work);
a9339c
 
a9339c
 void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_(3, 0);
a9339c
+void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t);
a9339c
 
a9339c
 bool unit_need_daemon_reload(Unit *u);
a9339c