]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: properly reset all ExecStatus structures when entering a new unit cycle
authorLennart Poettering <lennart@poettering.net>
Tue, 17 Jul 2018 17:36:46 +0000 (19:36 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 23 Jul 2018 11:36:47 +0000 (13:36 +0200)
Whenever a unit is started fresh we should flush out any runtime data
from the previous cycle. We are pretty good at that already, but what so
far we missed was the ExecStart=/ExecStop=/… command exit status data.
Let's fix that, and properly flush out that stuff too.

Consider this service:

    [Service]
    ExecStart=/bin/sleep infinity
    ExecStop=/bin/false

When this service is started, then stopped and then started again
"systemctl status" would show the ExecStop= results of the previous run
along with the ExecStart= results of the current one, which is very
confusing. With this patch this is corrected: the data is kept right
until the moment the new service cycle starts, and then flushed out.
Hence "systemctl status" in that case will only show the ExecStart=
data, but no ExecStop= data, like it should be.

This should fix part of the confusion of #9588

src/core/execute.c
src/core/execute.h
src/core/mount.c
src/core/service.c
src/core/socket.c
src/core/swap.c

index 80736abbfd5695148fd206ed2be1565b9000ff91..ccfe3e097d325575ade6bd425e998537ba874167 100644 (file)
@@ -3685,6 +3685,24 @@ void exec_command_free_array(ExecCommand **c, size_t n) {
                 c[i] = exec_command_free_list(c[i]);
 }
 
+void exec_command_reset_status_array(ExecCommand *c, size_t n) {
+        size_t i;
+
+        for (i = 0; i < n; i++)
+                exec_status_reset(&c[i].exec_status);
+}
+
+void exec_command_reset_status_list_array(ExecCommand **c, size_t n) {
+        size_t i;
+
+        for (i = 0; i < n; i++) {
+                ExecCommand *z;
+
+                LIST_FOREACH(command, z, c[i])
+                        exec_status_reset(&z->exec_status);
+        }
+}
+
 typedef struct InvalidEnvInfo {
         const Unit *unit;
         const char *path;
@@ -4364,6 +4382,12 @@ void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int
         }
 }
 
+void exec_status_reset(ExecStatus *s) {
+        assert(s);
+
+        *s = (ExecStatus) {};
+}
+
 void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix) {
         char buf[FORMAT_TIMESTAMP_MAX];
 
index bc832eebf04e46f2567fc37f18a493c6d5b17ce0..678ee5b1893aabbc2642239c776fcbb44f63b52e 100644 (file)
@@ -340,10 +340,10 @@ int exec_spawn(Unit *unit,
                pid_t *ret);
 
 void exec_command_done_array(ExecCommand *c, size_t n);
-
 ExecCommand* exec_command_free_list(ExecCommand *c);
 void exec_command_free_array(ExecCommand **c, size_t n);
-
+void exec_command_reset_status_array(ExecCommand *c, size_t n);
+void exec_command_reset_status_list_array(ExecCommand **c, size_t n);
 void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix);
 void exec_command_append_list(ExecCommand **l, ExecCommand *e);
 int exec_command_set(ExecCommand *c, const char *path, ...);
@@ -367,6 +367,7 @@ void exec_context_free_log_extra_fields(ExecContext *c);
 void exec_status_start(ExecStatus *s, pid_t pid);
 void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int code, int status);
 void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix);
+void exec_status_reset(ExecStatus *s);
 
 int exec_runtime_acquire(Manager *m, const ExecContext *c, const char *name, bool create, ExecRuntime **ret);
 ExecRuntime *exec_runtime_unref(ExecRuntime *r, bool destroy);
index 21437dad086d424c2dead596078c6318539ad07a..75e1b6ac53017059003085f49a5cf25a4dd9599b 100644 (file)
@@ -1074,6 +1074,7 @@ static int mount_start(Unit *u) {
 
         m->result = MOUNT_SUCCESS;
         m->reload_result = MOUNT_SUCCESS;
+        exec_command_reset_status_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
 
         u->reset_accounting = true;
 
index 872bb7752656544faf729bf12657584bb49436fd..7476ee533395071c979681013716fcaeb68c9043 100644 (file)
@@ -1673,7 +1673,6 @@ static void service_enter_stop_post(Service *s, ServiceResult f) {
                 s->result = f;
 
         service_unwatch_control_pid(s);
-
         (void) unit_enqueue_rewatch_pids(UNIT(s));
 
         s->control_command = s->exec_command[SERVICE_EXEC_STOP_POST];
@@ -2252,8 +2251,6 @@ static int service_start(Unit *u) {
         s->main_pid_alien = false;
         s->forbid_restart = false;
 
-        u->reset_accounting = true;
-
         s->status_text = mfree(s->status_text);
         s->status_errno = 0;
 
@@ -2262,12 +2259,17 @@ static int service_start(Unit *u) {
         s->watchdog_override_enable = false;
         s->watchdog_override_usec = 0;
 
+        exec_command_reset_status_list_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
+        exec_status_reset(&s->main_exec_status);
+
         /* This is not an automatic restart? Flush the restart counter then */
         if (s->flush_n_restarts) {
                 s->n_restarts = 0;
                 s->flush_n_restarts = false;
         }
 
+        u->reset_accounting = true;
+
         service_enter_start_pre(s);
         return 1;
 }
index 1bd32cf2504c0d00422c10dc24b6c323dbe7f6ef..a6127654b5229f479771c526872e2016c1c0badf 100644 (file)
@@ -2457,6 +2457,7 @@ static int socket_start(Unit *u) {
                 return r;
 
         s->result = SOCKET_SUCCESS;
+        exec_command_reset_status_list_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
 
         u->reset_accounting = true;
 
index b78b1aa266ee30d36d5ddf420fff8f4af286d8b1..f8d6a4dd22f5fb555f9352f3e28ced9383d07c1a 100644 (file)
@@ -853,6 +853,7 @@ static int swap_start(Unit *u) {
                 return r;
 
         s->result = SWAP_SUCCESS;
+        exec_command_reset_status_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
 
         u->reset_accounting = true;