64a629f
From f19e9a19f5e59869673609fde8deba80e48f42bc Mon Sep 17 00:00:00 2001
64a629f
From: Lennart Poettering <lennart@poettering.net>
64a629f
Date: Thu, 6 Aug 2015 16:50:54 +0300
64a629f
Subject: [PATCH 5/5] machined: rework state tracking logic for machines
64a629f
64a629f
This splits up the stopping logic for machines into two steps: first on
64a629f
machine_stop() we begin with the shutdown of a machine by queuing the
64a629f
stop method call for it. Then, in machine_finalize() we actually remove
64a629f
the rest of its runtime context. This mimics closely how sessions are
64a629f
handled in logind.
64a629f
64a629f
This also reworks the GC logic to strictly check the current state of
64a629f
the machine unit, rather than shortcutting a few cases, like for example
64a629f
assuming that UnitRemoved really means a machine is gone (which it isn't
64a629f
since Reloading might trigger it, see #376).
64a629f
64a629f
Fixes #376.
64a629f
64a629f
(cherry picked from commit 49f3fffd94591bdf2bd6c2233a9300daeab79566)
64a629f
64a629f
Resolves: #1297225
64a629f
---
64a629f
 src/machine/machine.c       | 32 +++++++++++++++++++++-----------
64a629f
 src/machine/machine.h       |  2 ++
64a629f
 src/machine/machined-dbus.c | 39 ++++-----------------------------------
64a629f
 src/machine/machined.c      | 10 +++++++++-
64a629f
 4 files changed, 36 insertions(+), 47 deletions(-)
64a629f
64a629f
diff --git a/src/machine/machine.c b/src/machine/machine.c
64a629f
index 05fc4f8..7c449ff 100644
64a629f
--- a/src/machine/machine.c
64a629f
+++ b/src/machine/machine.c
64a629f
@@ -421,7 +421,19 @@ static int machine_stop_scope(Machine *m) {
64a629f
 }
64a629f
 
64a629f
 int machine_stop(Machine *m) {
64a629f
-        int r = 0, k;
64a629f
+        int r;
64a629f
+        assert(m);
64a629f
+
64a629f
+        r = machine_stop_scope(m);
64a629f
+
64a629f
+        m->stopping = true;
64a629f
+
64a629f
+        machine_save(m);
64a629f
+
64a629f
+        return r;
64a629f
+}
64a629f
+
64a629f
+int machine_finalize(Machine *m) {
64a629f
         assert(m);
64a629f
 
64a629f
         if (m->started)
64a629f
@@ -432,20 +444,15 @@ int machine_stop(Machine *m) {
64a629f
                            LOG_MESSAGE("Machine %s terminated.", m->name),
64a629f
                            NULL);
64a629f
 
64a629f
-        /* Kill cgroup */
64a629f
-        k = machine_stop_scope(m);
64a629f
-        if (k < 0)
64a629f
-                r = k;
64a629f
-
64a629f
         machine_unlink(m);
64a629f
         machine_add_to_gc_queue(m);
64a629f
 
64a629f
-        if (m->started)
64a629f
+        if (m->started) {
64a629f
                 machine_send_signal(m, false);
64a629f
+                m->started = false;
64a629f
+        }
64a629f
 
64a629f
-        m->started = false;
64a629f
-
64a629f
-        return r;
64a629f
+        return 0;
64a629f
 }
64a629f
 
64a629f
 bool machine_check_gc(Machine *m, bool drop_not_started) {
64a629f
@@ -476,8 +483,11 @@ void machine_add_to_gc_queue(Machine *m) {
64a629f
 MachineState machine_get_state(Machine *s) {
64a629f
         assert(s);
64a629f
 
64a629f
+        if (s->stopping)
64a629f
+                return MACHINE_CLOSING;
64a629f
+
64a629f
         if (s->scope_job)
64a629f
-                return s->started ? MACHINE_OPENING : MACHINE_CLOSING;
64a629f
+                return MACHINE_OPENING;
64a629f
 
64a629f
         return MACHINE_RUNNING;
64a629f
 }
64a629f
diff --git a/src/machine/machine.h b/src/machine/machine.h
64a629f
index bbe5217..74a311c 100644
64a629f
--- a/src/machine/machine.h
64a629f
+++ b/src/machine/machine.h
64a629f
@@ -83,6 +83,7 @@ struct Machine {
64a629f
 
64a629f
         bool in_gc_queue:1;
64a629f
         bool started:1;
64a629f
+        bool stopping:1;
64a629f
 
64a629f
         sd_bus_message *create_message;
64a629f
 
64a629f
@@ -101,6 +102,7 @@ bool machine_check_gc(Machine *m, bool drop_not_started);
64a629f
 void machine_add_to_gc_queue(Machine *m);
64a629f
 int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error);
64a629f
 int machine_stop(Machine *m);
64a629f
+int machine_finalize(Machine *m);
64a629f
 int machine_save(Machine *m);
64a629f
 int machine_load(Machine *m);
64a629f
 int machine_kill(Machine *m, KillWho who, int signo);
64a629f
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
64a629f
index 0e971a6..755c218 100644
64a629f
--- a/src/machine/machined-dbus.c
64a629f
+++ b/src/machine/machined-dbus.c
64a629f
@@ -908,8 +908,9 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
64a629f
 
64a629f
                                 machine_send_create_reply(machine, &e);
64a629f
                         }
64a629f
-                } else
64a629f
-                        machine_save(machine);
64a629f
+                }
64a629f
+
64a629f
+                machine_save(machine);
64a629f
         }
64a629f
 
64a629f
         machine_add_to_gc_queue(machine);
64a629f
@@ -918,7 +919,7 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
64a629f
 
64a629f
 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
64a629f
         _cleanup_free_ char *unit = NULL;
64a629f
-        const char *path, *interface;
64a629f
+        const char *path;
64a629f
         Manager *m = userdata;
64a629f
         Machine *machine;
64a629f
         int r;
64a629f
@@ -942,36 +943,6 @@ int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_err
64a629f
         if (!machine)
64a629f
                 return 0;
64a629f
 
64a629f
-        r = sd_bus_message_read(message, "s", &interface);
64a629f
-        if (r < 0) {
64a629f
-                bus_log_parse_error(r);
64a629f
-                return 0;
64a629f
-        }
64a629f
-
64a629f
-        if (streq(interface, "org.freedesktop.systemd1.Unit")) {
64a629f
-                struct properties {
64a629f
-                        char *active_state;
64a629f
-                        char *sub_state;
64a629f
-                } properties = {};
64a629f
-
64a629f
-                const struct bus_properties_map map[] = {
64a629f
-                        { "ActiveState", "s", NULL, offsetof(struct properties, active_state) },
64a629f
-                        { "SubState",    "s", NULL, offsetof(struct properties, sub_state)    },
64a629f
-                        {}
64a629f
-                };
64a629f
-
64a629f
-                r = bus_message_map_properties_changed(message, map, &properties);
64a629f
-                if (r < 0)
64a629f
-                        bus_log_parse_error(r);
64a629f
-                else if (streq_ptr(properties.active_state, "inactive") ||
64a629f
-                         streq_ptr(properties.active_state, "failed") ||
64a629f
-                         streq_ptr(properties.sub_state, "auto-restart"))
64a629f
-                        machine_release_unit(machine);
64a629f
-
64a629f
-                free(properties.active_state);
64a629f
-                free(properties.sub_state);
64a629f
-        }
64a629f
-
64a629f
         machine_add_to_gc_queue(machine);
64a629f
         return 0;
64a629f
 }
64a629f
@@ -995,9 +966,7 @@ int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *er
64a629f
         if (!machine)
64a629f
                 return 0;
64a629f
 
64a629f
-        machine_release_unit(machine);
64a629f
         machine_add_to_gc_queue(machine);
64a629f
-
64a629f
         return 0;
64a629f
 }
64a629f
 
64a629f
diff --git a/src/machine/machined.c b/src/machine/machined.c
64a629f
index 9bfe2ad..1eeeaf1 100644
64a629f
--- a/src/machine/machined.c
64a629f
+++ b/src/machine/machined.c
64a629f
@@ -247,8 +247,16 @@ void manager_gc(Manager *m, bool drop_not_started) {
64a629f
                 LIST_REMOVE(gc_queue, m->machine_gc_queue, machine);
64a629f
                 machine->in_gc_queue = false;
64a629f
 
64a629f
-                if (!machine_check_gc(machine, drop_not_started)) {
64a629f
+                /* First, if we are not closing yet, initiate stopping */
64a629f
+                if (!machine_check_gc(machine, drop_not_started) &&
64a629f
+                    machine_get_state(machine) != MACHINE_CLOSING)
64a629f
                         machine_stop(machine);
64a629f
+
64a629f
+                /* Now, the stop stop probably made this referenced
64a629f
+                 * again, but if it didn't, then it's time to let it
64a629f
+                 * go entirely. */
64a629f
+                if (!machine_check_gc(machine, drop_not_started)) {
64a629f
+                        machine_finalize(machine);
64a629f
                         machine_free(machine);
64a629f
                 }
64a629f
         }
64a629f
-- 
64a629f
2.5.0
64a629f