summaryrefslogtreecommitdiff
path: root/src/machine/machined-dbus.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-04-28 21:17:35 +0200
committerLennart Poettering <lennart@poettering.net>2015-04-28 21:34:23 +0200
commit9b420b3cfb8b93daf50e4cdbc92b05f2209ef893 (patch)
tree0077cd838eeb972c8c33071a85c17e49c02d2eb2 /src/machine/machined-dbus.c
parentfe506d569d82467f31862c2ed82ef35f88854149 (diff)
machined: make sure to track machine unit states properly
If a unit is stopped for a moment, we need to invalidate our knowledge of it, otherwise we might be confused by automatic restarts This makes reboots for nspawn containers run as service work correctly. https://bugs.freedesktop.org/show_bug.cgi?id=87428
Diffstat (limited to 'src/machine/machined-dbus.c')
-rw-r--r--src/machine/machined-dbus.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 066a8da918..76109700a3 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -24,6 +24,7 @@
#include <unistd.h>
#include "sd-id128.h"
+#include "strv.h"
#include "path-util.h"
#include "unit-name.h"
#include "bus-util.h"
@@ -923,9 +924,9 @@ int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_b
int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *unit = NULL;
+ const char *path, *interface;
Manager *m = userdata;
Machine *machine;
- const char *path;
int r;
assert(bus);
@@ -939,13 +940,46 @@ int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdat
r = unit_name_from_dbus_path(path, &unit);
if (r == -EINVAL) /* not for a unit */
return 0;
- if (r < 0)
- return r;
+ if (r < 0){
+ log_oom();
+ return 0;
+ }
machine = hashmap_get(m->machine_units, unit);
- if (machine)
- machine_add_to_gc_queue(machine);
+ if (!machine)
+ return 0;
+
+ r = sd_bus_message_read(message, "s", &interface);
+ if (r < 0) {
+ bus_log_parse_error(r);
+ return 0;
+ }
+
+ if (streq(interface, "org.freedesktop.systemd1.Unit")) {
+ struct properties {
+ char *active_state;
+ char *sub_state;
+ } properties = {};
+ const struct bus_properties_map map[] = {
+ { "ActiveState", "s", NULL, offsetof(struct properties, active_state) },
+ { "SubState", "s", NULL, offsetof(struct properties, sub_state) },
+ {}
+ };
+
+ r = bus_message_map_properties_changed(message, map, &properties);
+ if (r < 0)
+ bus_log_parse_error(r);
+ else if (streq_ptr(properties.active_state, "inactive") ||
+ streq_ptr(properties.active_state, "failed") ||
+ streq_ptr(properties.sub_state, "auto-restart"))
+ machine_release_unit(machine);
+
+ free(properties.active_state);
+ free(properties.sub_state);
+ }
+
+ machine_add_to_gc_queue(machine);
return 0;
}
@@ -962,12 +996,15 @@ int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
r = sd_bus_message_read(message, "so", &unit, &path);
if (r < 0) {
bus_log_parse_error(r);
- return r;
+ return 0;
}
machine = hashmap_get(m->machine_units, unit);
- if (machine)
- machine_add_to_gc_queue(machine);
+ if (!machine)
+ return 0;
+
+ machine_release_unit(machine);
+ machine_add_to_gc_queue(machine);
return 0;
}
@@ -1190,7 +1227,7 @@ int manager_unit_is_active(Manager *manager, const char *unit) {
if (r < 0)
return -EINVAL;
- return !streq(state, "inactive") && !streq(state, "failed");
+ return !STR_IN_SET(state, "inactive", "failed");
}
int manager_job_is_active(Manager *manager, const char *path) {