diff options
-rw-r--r-- | meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch | 315 | ||||
-rw-r--r-- | meta-agl/recipes-core/systemd/systemd_%.bbappend | 8 |
2 files changed, 4 insertions, 319 deletions
diff --git a/meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch b/meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch deleted file mode 100644 index 1f4a23ea7..000000000 --- a/meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch +++ /dev/null @@ -1,315 +0,0 @@ -commit e266c068b5597e18b2299f9c9d3ee6cf04198c41 -Author: Michal Sekletar <msekleta@redhat.com> -Date: Mon Jan 23 17:12:35 2017 +0100 - - service: serialize information about currently executing command - - Stored information will help us to resume execution after the - daemon-reload. - - This commit implements following scheme, - - * On serialization: - - we count rank of the currently executing command - - we store command type, its rank and command line arguments - - * On deserialization: - - configuration is parsed and loaded - - we deserialize stored data, command type, rank and arguments - - we look at the given rank in the list and if command there has same - arguments then we restore execution at that point - - otherwise we search respective command list and we look for command - that has the same arguments - - if both methods fail we do not do not resume execution at all - - To better illustrate how does above scheme works, please consider - following cases (<<< denotes position where we resume execution after reload) - - ; Original unit file - [Service] - ExecStart=/bin/true <<< - ExecStart=/bin/false - - ; Swapped commands - ; Second command is not going to be executed - [Service] - ExecStart=/bin/false - ExecStart=/bin/true <<< - - ; Commands added before - ; Same commands are problematic and execution could be restarted at wrong place - [Service] - ExecStart=/bin/foo - ExecStart=/bin/bar - ExecStart=/bin/true <<< - ExecStart=/bin/false - - ; Commands added after - ; Same commands are not an issue in this case - [Service] - ExecStart=/bin/true <<< - ExecStart=/bin/false - ExecStart=/bin/foo - ExecStart=/bin/bar - - ; New commands interleaved with old commands - ; Some new commands will be executed while others won't - ExecStart=/bin/foo - ExecStart=/bin/true <<< - ExecStart=/bin/bar - ExecStart=/bin/false - - As you can see, above scheme has some drawbacks. However, in most - cases (we assume that in most common case unit file command list is not - changed while some other command is running for the same unit) it - should cause that systemd does the right thing, which is restoring - execution exactly at the point we were before daemon-reload. - - Fixes #518 - -Signed-off-by: Scott Murray <scott.murray@konsulko.com> - -Upstream-Status: backport - -diff --git a/src/core/service.c b/src/core/service.c -index 74054887b..5e681fb71 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -45,6 +45,7 @@ - #include "service.h" - #include "signal-util.h" - #include "special.h" -+#include "stdio-util.h" - #include "string-table.h" - #include "string-util.h" - #include "strv.h" -@@ -2140,6 +2141,80 @@ _pure_ static bool service_can_reload(Unit *u) { - return !!s->exec_command[SERVICE_EXEC_RELOAD]; - } - -+static unsigned service_exec_command_index(Unit *u, ServiceExecCommand id, ExecCommand *current) { -+ Service *s = SERVICE(u); -+ unsigned idx = 0; -+ ExecCommand *first, *c; -+ -+ assert(s); -+ -+ first = s->exec_command[id]; -+ -+ /* Figure out where we are in the list by walking back to the beginning */ -+ for (c = current; c != first; c = c->command_prev) -+ idx++; -+ -+ return idx; -+} -+ -+static int service_serialize_exec_command(Unit *u, FILE *f, ExecCommand *command) { -+ Service *s = SERVICE(u); -+ ServiceExecCommand id; -+ unsigned idx; -+ const char *type; -+ char **arg; -+ _cleanup_strv_free_ char **escaped_args = NULL; -+ _cleanup_free_ char *args = NULL, *p = NULL; -+ size_t allocated = 0, length = 0; -+ -+ assert(s); -+ assert(f); -+ -+ if (!command) -+ return 0; -+ -+ if (command == s->control_command) { -+ type = "control"; -+ id = s->control_command_id; -+ } else { -+ type = "main"; -+ id = SERVICE_EXEC_START; -+ } -+ -+ idx = service_exec_command_index(u, id, command); -+ -+ STRV_FOREACH(arg, command->argv) { -+ size_t n; -+ _cleanup_free_ char *e = NULL; -+ -+ e = xescape(*arg, WHITESPACE); -+ if (!e) -+ return -ENOMEM; -+ -+ n = strlen(e); -+ if (!GREEDY_REALLOC(args, allocated, length + 1 + n + 1)) -+ return -ENOMEM; -+ -+ if (length > 0) -+ args[length++] = ' '; -+ -+ memcpy(args + length, e, n); -+ length += n; -+ } -+ -+ if (!GREEDY_REALLOC(args, allocated, length + 1)) -+ return -ENOMEM; -+ args[length++] = 0; -+ -+ p = xescape(command->path, WHITESPACE); -+ if (!p) -+ return -ENOMEM; -+ -+ fprintf(f, "%s-command=%s %u %s %s\n", type, service_exec_command_to_string(id), idx, p, args); -+ -+ return 0; -+} -+ - static int service_serialize(Unit *u, FILE *f, FDSet *fds) { - Service *s = SERVICE(u); - ServiceFDStore *fs; -@@ -2167,11 +2242,8 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) { - if (r < 0) - return r; - -- /* FIXME: There's a minor uncleanliness here: if there are -- * multiple commands attached here, we will start from the -- * first one again */ -- if (s->control_command_id >= 0) -- unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id)); -+ service_serialize_exec_command(u, f, s->control_command); -+ service_serialize_exec_command(u, f, s->main_command); - - r = unit_serialize_item_fd(u, f, fds, "stdin-fd", s->stdin_fd); - if (r < 0) -@@ -2227,6 +2299,106 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) { - return 0; - } - -+static int service_deserialize_exec_command(Unit *u, const char *key, const char *value) { -+ Service *s = SERVICE(u); -+ int r; -+ unsigned idx = 0, i; -+ bool control, found = false; -+ ServiceExecCommand id = _SERVICE_EXEC_COMMAND_INVALID; -+ ExecCommand *command = NULL; -+ _cleanup_free_ char *args = NULL, *path = NULL; -+ _cleanup_strv_free_ char **argv = NULL; -+ -+ enum ExecCommandState { -+ STATE_EXEC_COMMAND_TYPE, -+ STATE_EXEC_COMMAND_INDEX, -+ STATE_EXEC_COMMAND_PATH, -+ STATE_EXEC_COMMAND_ARGS, -+ _STATE_EXEC_COMMAND_MAX, -+ _STATE_EXEC_COMMAND_INVALID = -1, -+ } state; -+ -+ assert(s); -+ assert(key); -+ assert(value); -+ -+ control = streq(key, "control-command"); -+ -+ state = STATE_EXEC_COMMAND_TYPE; -+ -+ for (;;) { -+ _cleanup_free_ char *arg = NULL; -+ -+ r = extract_first_word(&value, &arg, NULL, EXTRACT_CUNESCAPE); -+ if (r == 0) -+ break; -+ else if (r < 0) -+ return r; -+ -+ switch (state) { -+ case STATE_EXEC_COMMAND_TYPE: -+ id = service_exec_command_from_string(arg); -+ if (id < 0) -+ return -EINVAL; -+ -+ state = STATE_EXEC_COMMAND_INDEX; -+ break; -+ case STATE_EXEC_COMMAND_INDEX: -+ r = safe_atou(arg, &idx); -+ if (r < 0) -+ return -EINVAL; -+ -+ state = STATE_EXEC_COMMAND_PATH; -+ break; -+ case STATE_EXEC_COMMAND_PATH: -+ path = arg; -+ arg = NULL; -+ state = STATE_EXEC_COMMAND_ARGS; -+ -+ if (!path_is_absolute(path)) -+ return -EINVAL; -+ break; -+ case STATE_EXEC_COMMAND_ARGS: -+ r = strv_extend(&argv, arg); -+ if (r < 0) -+ return -ENOMEM; -+ break; -+ default: -+ assert_not_reached("Unknown error at deserialization of exec command"); -+ break; -+ } -+ } -+ -+ if (state != STATE_EXEC_COMMAND_ARGS) -+ return -EINVAL; -+ -+ /* Let's check whether exec command on given offset matches data that we just deserialized */ -+ for (command = s->exec_command[id], i = 0; command; command = command->command_next, i++) { -+ if (i != idx) -+ continue; -+ -+ found = strv_equal(argv, command->argv) && streq(command->path, path); -+ break; -+ } -+ -+ if (!found) { -+ /* Command at the index we serialized is different, let's look for command that exactly -+ * matches but is on different index. If there is no such command we will not resume execution. */ -+ for (command = s->exec_command[id]; command; command = command->command_next) -+ if (strv_equal(command->argv, argv) && streq(command->path, path)) -+ break; -+ } -+ -+ if (command && control) -+ s->control_command = command; -+ else if (command) -+ s->main_command = command; -+ else -+ log_unit_warning(u, "Current command vanished from the unit file, execution of the command list won't be resumed."); -+ -+ return 0; -+} -+ - static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { - Service *s = SERVICE(u); - int r; -@@ -2309,16 +2481,6 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, - s->status_text = t; - } - -- } else if (streq(key, "control-command")) { -- ServiceExecCommand id; -- -- id = service_exec_command_from_string(value); -- if (id < 0) -- log_unit_debug(u, "Failed to parse exec-command value: %s", value); -- else { -- s->control_command_id = id; -- s->control_command = s->exec_command[id]; -- } - } else if (streq(key, "accept-socket")) { - Unit *socket; - -@@ -2437,6 +2599,10 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, - s->watchdog_override_enable = true; - s->watchdog_override_usec = watchdog_override_usec; - } -+ } else if (STR_IN_SET(key, "main-command", "control-command")) { -+ r = service_deserialize_exec_command(u, key, value); -+ if (r < 0) -+ log_unit_debug_errno(u, r, "Failed to parse serialized command \"%s\": %m", value); - } else - log_unit_debug(u, "Unknown serialization key: %s", key); - diff --git a/meta-agl/recipes-core/systemd/systemd_%.bbappend b/meta-agl/recipes-core/systemd/systemd_%.bbappend index 354464c12..f64ca8c8a 100644 --- a/meta-agl/recipes-core/systemd/systemd_%.bbappend +++ b/meta-agl/recipes-core/systemd/systemd_%.bbappend @@ -1,9 +1,9 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" -SRC_URI += "file://backport-v234-e266c06.patch \ - file://e2fsck.conf \ - ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','systemd','file://wired.network','',d)} \ - " +SRC_URI += "\ + file://e2fsck.conf \ + ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','systemd','file://wired.network','',d)} \ +" # enable networkd/resolved support PACKAGECONFIG_append_pn-systemd = " \ |