[systemd-commits] 8 commits - TODO src/core src/libsystemd src/libsystemd-terminal src/machine src/nspawn src/shared units/systemd-nspawn at .service.in
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Apr 28 12:34:40 PDT 2015
TODO | 8 +++-
src/core/service.c | 58 ++++++++++++++++++++++++--------
src/libsystemd-terminal/idev-keyboard.c | 2 -
src/libsystemd/sd-bus/bus-util.c | 44 +++++++++++++-----------
src/libsystemd/sd-bus/bus-util.h | 16 +-------
src/machine/machine.c | 20 +++++++----
src/machine/machine.h | 2 +
src/machine/machined-dbus.c | 55 +++++++++++++++++++++++++-----
src/machine/machined.c | 3 +
src/nspawn/nspawn.c | 9 ++++
src/shared/exit-status.c | 14 +++++++
src/shared/exit-status.h | 1
units/systemd-nspawn at .service.in | 14 +++++++
13 files changed, 182 insertions(+), 64 deletions(-)
New commits:
commit 5c5b7911d34c765f9de5528e1259ea028d5518c1
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Apr 28 21:33:02 2015 +0200
update TODO
diff --git a/TODO b/TODO
index 4b2feb0..a39ee28 100644
--- a/TODO
+++ b/TODO
@@ -40,8 +40,14 @@ Before 220:
* timer units triggering services with failing conditions run busy:
http://lists.freedesktop.org/archives/systemd-devel/2015-April/030095.html
+* logind: follow PropertiesChanged state more closely, to deal with quick logouts and relogins
+
Features:
+* networkd: fix ip forwarding boolean
+
+* sd-bus.h: drop bus parameter in message handlers
+
* journalctl: -m should access container journals directly by enumerating them via machined, and also watch containers coming and going. Benefit: nspawn --ephemeral would start working nicely with the journal.
* nspawn: don't copy /etc/resolv.conf from host into container unless we are in shared-network mode
@@ -66,8 +72,6 @@ Features:
* rework C11 utf8.[ch] to use char32_t instead of uint32_t when referring
to unicode chars, to make things more expressive.
-* networkd: MTU= switch for .network units needs documentation in systemd.network(5)
-
* "machinectl migrate" or similar to copy a container from or to a
difference host, via ssh
commit 11b90e69e5620c2483b019340eff121d504db115
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Apr 28 21:32:42 2015 +0200
machined: make PropertiesChanged match more strict
diff --git a/src/machine/machined.c b/src/machine/machined.c
index 7980293..1e862ad 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -194,7 +194,8 @@ static int manager_connect_bus(Manager *m) {
"type='signal',"
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.DBus.Properties',"
- "member='PropertiesChanged'",
+ "member='PropertiesChanged',"
+ "arg0='org.freedesktop.systemd1.Unit'",
match_properties_changed,
m);
if (r < 0)
commit 9b420b3cfb8b93daf50e4cdbc92b05f2209ef893
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Apr 28 21:17:35 2015 +0200
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
diff --git a/src/machine/machine.c b/src/machine/machine.c
index dd073ad..05fc4f8 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -80,17 +80,14 @@ void machine_free(Machine *m) {
if (m->in_gc_queue)
LIST_REMOVE(gc_queue, m->manager->machine_gc_queue, m);
- if (m->unit) {
- hashmap_remove(m->manager->machine_units, m->unit);
- free(m->unit);
- }
+ machine_release_unit(m);
free(m->scope_job);
- hashmap_remove(m->manager->machines, m->name);
+ (void) hashmap_remove(m->manager->machines, m->name);
if (m->leader > 0)
- hashmap_remove_value(m->manager->machine_leaders, UINT_TO_PTR(m->leader), m);
+ (void) hashmap_remove_value(m->manager->machine_leaders, UINT_TO_PTR(m->leader), m);
sd_bus_message_unref(m->create_message);
@@ -526,6 +523,17 @@ MachineOperation *machine_operation_unref(MachineOperation *o) {
return NULL;
}
+void machine_release_unit(Machine *m) {
+ assert(m);
+
+ if (!m->unit)
+ return;
+
+ (void) hashmap_remove(m->manager->machine_units, m->unit);
+ free(m->unit);
+ m->unit = NULL;
+}
+
static const char* const machine_class_table[_MACHINE_CLASS_MAX] = {
[MACHINE_CONTAINER] = "container",
[MACHINE_VM] = "vm"
diff --git a/src/machine/machine.h b/src/machine/machine.h
index 7b27aa2..bbe5217 100644
--- a/src/machine/machine.h
+++ b/src/machine/machine.h
@@ -105,6 +105,8 @@ int machine_save(Machine *m);
int machine_load(Machine *m);
int machine_kill(Machine *m, KillWho who, int signo);
+void machine_release_unit(Machine *m);
+
MachineState machine_get_state(Machine *u);
MachineOperation *machine_operation_unref(MachineOperation *o);
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 066a8da..7610970 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) {
commit fe506d569d82467f31862c2ed82ef35f88854149
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Apr 28 20:48:54 2015 +0200
bus-util: drop redundant bus argument from bus_message_map_all_properties() and related calls
diff --git a/src/libsystemd-terminal/idev-keyboard.c b/src/libsystemd-terminal/idev-keyboard.c
index 05f5e0c..b5eb737 100644
--- a/src/libsystemd-terminal/idev-keyboard.c
+++ b/src/libsystemd-terminal/idev-keyboard.c
@@ -462,7 +462,7 @@ static int kbdctx_locale_props_changed_fn(sd_bus *bus,
if (r < 0)
goto error;
- r = bus_message_map_properties_changed(bus, signal, kbdctx_locale_map, kc);
+ r = bus_message_map_properties_changed(signal, kbdctx_locale_map, kc);
if (r < 0)
goto error;
diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c
index 258265d..31bd45c 100644
--- a/src/libsystemd/sd-bus/bus-util.c
+++ b/src/libsystemd/sd-bus/bus-util.c
@@ -1037,14 +1037,14 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_
return r;
}
-int bus_message_map_all_properties(sd_bus *bus,
- sd_bus_message *m,
- const struct bus_properties_map *map,
- void *userdata) {
+int bus_message_map_all_properties(
+ sd_bus_message *m,
+ const struct bus_properties_map *map,
+ void *userdata) {
+
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
- assert(bus);
assert(m);
assert(map);
@@ -1080,9 +1080,9 @@ int bus_message_map_all_properties(sd_bus *bus,
v = (uint8_t *)userdata + prop->offset;
if (map[i].set)
- r = prop->set(bus, member, m, &error, v);
+ r = prop->set(sd_bus_message_get_bus(m), member, m, &error, v);
else
- r = map_basic(bus, member, m, &error, v);
+ r = map_basic(sd_bus_message_get_bus(m), member, m, &error, v);
if (r < 0)
return r;
@@ -1099,22 +1099,24 @@ int bus_message_map_all_properties(sd_bus *bus,
if (r < 0)
return r;
}
+ if (r < 0)
+ return r;
return sd_bus_message_exit_container(m);
}
-int bus_message_map_properties_changed(sd_bus *bus,
- sd_bus_message *m,
- const struct bus_properties_map *map,
- void *userdata) {
+int bus_message_map_properties_changed(
+ sd_bus_message *m,
+ const struct bus_properties_map *map,
+ void *userdata) {
+
const char *member;
int r, invalidated, i;
- assert(bus);
assert(m);
assert(map);
- r = bus_message_map_all_properties(bus, m, map, userdata);
+ r = bus_message_map_all_properties(m, map, userdata);
if (r < 0)
return r;
@@ -1129,6 +1131,8 @@ int bus_message_map_properties_changed(sd_bus *bus,
++invalidated;
break;
}
+ if (r < 0)
+ return r;
r = sd_bus_message_exit_container(m);
if (r < 0)
@@ -1137,11 +1141,13 @@ int bus_message_map_properties_changed(sd_bus *bus,
return invalidated;
}
-int bus_map_all_properties(sd_bus *bus,
- const char *destination,
- const char *path,
- const struct bus_properties_map *map,
- void *userdata) {
+int bus_map_all_properties(
+ sd_bus *bus,
+ const char *destination,
+ const char *path,
+ const struct bus_properties_map *map,
+ void *userdata) {
+
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
@@ -1163,7 +1169,7 @@ int bus_map_all_properties(sd_bus *bus,
if (r < 0)
return r;
- return bus_message_map_all_properties(bus, m, map, userdata);
+ return bus_message_map_all_properties(m, map, userdata);
}
int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
diff --git a/src/libsystemd/sd-bus/bus-util.h b/src/libsystemd/sd-bus/bus-util.h
index 0f7a3b2..d3a18e2 100644
--- a/src/libsystemd/sd-bus/bus-util.h
+++ b/src/libsystemd/sd-bus/bus-util.h
@@ -45,19 +45,9 @@ struct bus_properties_map {
int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
-int bus_message_map_all_properties(sd_bus *bus,
- sd_bus_message *m,
- const struct bus_properties_map *map,
- void *userdata);
-int bus_message_map_properties_changed(sd_bus *bus,
- sd_bus_message *m,
- const struct bus_properties_map *map,
- void *userdata);
-int bus_map_all_properties(sd_bus *bus,
- const char *destination,
- const char *path,
- const struct bus_properties_map *map,
- void *userdata);
+int bus_message_map_all_properties(sd_bus_message *m, const struct bus_properties_map *map, void *userdata);
+int bus_message_map_properties_changed(sd_bus_message *m, const struct bus_properties_map *map, void *userdata);
+int bus_map_all_properties(sd_bus *bus, const char *destination, const char *path, const struct bus_properties_map *map, void *userdata);
int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name);
commit 1a2399e57d9f5943a508720aaddc87512a972378
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Apr 28 20:46:33 2015 +0200
nspawn: when run as a service, don't ask machined for terminatin of ourselves
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 29652e0..05d2c71 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2081,6 +2081,11 @@ static int terminate_machine(pid_t pid) {
if (!arg_register)
return 0;
+ /* If we are reusing the unit, then just exit, systemd will do
+ * the right thing when we exit. */
+ if (arg_keep_unit)
+ return 0;
+
r = sd_bus_default_system(&bus);
if (r < 0)
return log_error_errno(r, "Failed to open system bus: %m");
commit 773ce3d89c25aa51b0fe9085bd0eb7ba5e50508b
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Apr 28 20:46:03 2015 +0200
nspawn: make sure we install the device policy if nspawn is run as unit as on the command line
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index f43ffd9..29652e0 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2014,6 +2014,10 @@ static int register_machine(pid_t pid, int local_ifindex) {
if (r < 0)
return bus_log_create_error(r);
+ /* If you make changes here, also make sure to update
+ * systemd-nspawn at .service, to keep the device
+ * policies in sync regardless if we are run with or
+ * without the --keep-unit switch. */
r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 9,
/* Allow the container to
* access and create the API
diff --git a/units/systemd-nspawn at .service.in b/units/systemd-nspawn at .service.in
index 3e26b53..6bfa55a 100644
--- a/units/systemd-nspawn at .service.in
+++ b/units/systemd-nspawn at .service.in
@@ -19,5 +19,19 @@ RestartForceExitStatus=133
SuccessExitStatus=133
Delegate=yes
+# Enforce a strict device policy, similar to the one nspawn configures
+# when it allocates its own scope unit. Make sure to keep these
+# policies in sync if you change them!
+DevicePolicy=strict
+DeviceAllow=/dev/null rwm
+DeviceAllow=/dev/zero rwm
+DeviceAllow=/dev/full rwm
+DeviceAllow=/dev/random rwm
+DeviceAllow=/dev/urandom rwm
+DeviceAllow=/dev/tty rwm
+DeviceAllow=/dev/net/tun rwm
+DeviceAllow=/dev/pts/ptmx rw
+DeviceAllow=char-pts rw
+
[Install]
WantedBy=machines.target
commit a509f0e631b12cfec6aafe4d152532109082efc9
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Apr 28 20:45:25 2015 +0200
service: make restart logic a bit easier to understand
diff --git a/src/core/service.c b/src/core/service.c
index d004728..3a614b1 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1268,6 +1268,49 @@ static int cgroup_good(Service *s) {
return !r;
}
+static bool service_shall_restart(Service *s) {
+ assert(s);
+
+ /* Don't restart after manual stops */
+ if (s->forbid_restart)
+ return false;
+
+ /* Never restart if this is configured as special exception */
+ if (exit_status_set_test(&s->restart_prevent_status, s->main_exec_status.code, s->main_exec_status.status))
+ return false;
+
+ /* Restart if the exit code/status are configured as restart triggers */
+ if (exit_status_set_test(&s->restart_force_status, s->main_exec_status.code, s->main_exec_status.status))
+ return true;
+
+ switch (s->restart) {
+
+ case SERVICE_RESTART_NO:
+ return false;
+
+ case SERVICE_RESTART_ALWAYS:
+ return true;
+
+ case SERVICE_RESTART_ON_SUCCESS:
+ return s->result == SERVICE_SUCCESS;
+
+ case SERVICE_RESTART_ON_FAILURE:
+ return s->result != SERVICE_SUCCESS;
+
+ case SERVICE_RESTART_ON_ABNORMAL:
+ return !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE);
+
+ case SERVICE_RESTART_ON_WATCHDOG:
+ return s->result == SERVICE_FAILURE_WATCHDOG;
+
+ case SERVICE_RESTART_ON_ABORT:
+ return IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP);
+
+ default:
+ assert_not_reached("unknown restart setting");
+ }
+}
+
static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) {
int r;
assert(s);
@@ -1282,16 +1325,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
failure_action(UNIT(s)->manager, s->failure_action, s->reboot_arg);
}
- if (allow_restart &&
- !s->forbid_restart &&
- (s->restart == SERVICE_RESTART_ALWAYS ||
- (s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) ||
- (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) ||
- (s->restart == SERVICE_RESTART_ON_ABNORMAL && !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE)) ||
- (s->restart == SERVICE_RESTART_ON_WATCHDOG && s->result == SERVICE_FAILURE_WATCHDOG) ||
- (s->restart == SERVICE_RESTART_ON_ABORT && IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP)) ||
- exit_status_set_test(&s->restart_force_status, s->main_exec_status.code, s->main_exec_status.status)) &&
- !exit_status_set_test(&s->restart_prevent_status, s->main_exec_status.code, s->main_exec_status.status)) {
+ if (allow_restart && service_shall_restart(s)) {
r = service_arm_timer(s, s->restart_usec);
if (r < 0)
@@ -1896,7 +1930,7 @@ static int service_stop(Unit *u) {
assert(s);
- /* Don't create restart jobs from here. */
+ /* Don't create restart jobs from manual stops. */
s->forbid_restart = true;
/* Already on it */
commit 597466f49752a52e85ea04051d020f97e8739f72
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Apr 28 18:24:20 2015 +0200
exit-status: introduce common exit_status_set_test() call for testing exit status set membership
diff --git a/src/core/service.c b/src/core/service.c
index 9104347..d004728 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1290,10 +1290,8 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
(s->restart == SERVICE_RESTART_ON_ABNORMAL && !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE)) ||
(s->restart == SERVICE_RESTART_ON_WATCHDOG && s->result == SERVICE_FAILURE_WATCHDOG) ||
(s->restart == SERVICE_RESTART_ON_ABORT && IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP)) ||
- (s->main_exec_status.code == CLD_EXITED && set_contains(s->restart_force_status.status, INT_TO_PTR(s->main_exec_status.status))) ||
- (IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) && set_contains(s->restart_force_status.signal, INT_TO_PTR(s->main_exec_status.status)))) &&
- (s->main_exec_status.code != CLD_EXITED || !set_contains(s->restart_prevent_status.status, INT_TO_PTR(s->main_exec_status.status))) &&
- (!IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) || !set_contains(s->restart_prevent_status.signal, INT_TO_PTR(s->main_exec_status.status)))) {
+ exit_status_set_test(&s->restart_force_status, s->main_exec_status.code, s->main_exec_status.status)) &&
+ !exit_status_set_test(&s->restart_prevent_status, s->main_exec_status.code, s->main_exec_status.status)) {
r = service_arm_timer(s, s->restart_usec);
if (r < 0)
diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c
index 9e14eb8..c09efdd 100644
--- a/src/shared/exit-status.c
+++ b/src/shared/exit-status.c
@@ -225,3 +225,17 @@ bool exit_status_set_is_empty(ExitStatusSet *x) {
return set_isempty(x->status) && set_isempty(x->signal);
}
+
+bool exit_status_set_test(ExitStatusSet *x, int code, int status) {
+
+ if (exit_status_set_is_empty(x))
+ return false;
+
+ if (code == CLD_EXITED && set_contains(x->status, INT_TO_PTR(status)))
+ return true;
+
+ if (IN_SET(code, CLD_KILLED, CLD_DUMPED) && set_contains(x->signal, INT_TO_PTR(status)))
+ return true;
+
+ return false;
+}
diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h
index 1d774f2..7259cd1 100644
--- a/src/shared/exit-status.h
+++ b/src/shared/exit-status.h
@@ -100,3 +100,4 @@ bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status);
void exit_status_set_free(ExitStatusSet *x);
bool exit_status_set_is_empty(ExitStatusSet *x);
+bool exit_status_set_test(ExitStatusSet *x, int code, int status);
More information about the systemd-commits
mailing list