diff options
author | Harald Hoyer <harald@redhat.com> | 2014-03-06 16:35:02 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-03-11 04:45:33 +0100 |
commit | f39d4a08e746e703d562076a0f622eb91dbdcd3e (patch) | |
tree | cb624857a80da40d0ff4e5ccb34b231d3bd4ecb3 /src/systemctl/systemctl.c | |
parent | 9d9951a460a90ef0e1e0384742cefdcf85193f8c (diff) |
systemctl: for switch-root check, if we switch to a systemd init
If "systemctl switch-root" is called with a specific "INIT" or
/proc/cmdline contains "init=", then systemd would not serialize
itsself.
Let systemctl check, if the new init is in the standard systemd
installation path and if so, clear the INIT parameter,
to let systemd serialize itsself.
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r-- | src/systemctl/systemctl.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index f3952653e1..17ad7f0462 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4282,8 +4282,8 @@ static int show_environment(sd_bus *bus, char **args) { static int switch_root(sd_bus *bus, char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_free_ char *init = NULL; - const char *root; + _cleanup_free_ char *cmdline_init = NULL; + const char *root, *init; unsigned l; int r; @@ -4296,20 +4296,33 @@ static int switch_root(sd_bus *bus, char **args) { root = args[1]; if (l >= 3) - init = strdup(args[2]); + init = args[2]; else { - parse_env_file("/proc/cmdline", WHITESPACE, - "init", &init, - NULL); + r = parse_env_file("/proc/cmdline", WHITESPACE, + "init", &cmdline_init, + NULL); + if (r < 0) + log_debug("Failed to parse /proc/cmdline: %s", strerror(-r)); - if (!init) - init = strdup(""); + init = cmdline_init; } - if (!init) - return log_oom(); + if (isempty(init)) + init = NULL; + + if (init) { + const char *root_systemd_path = NULL, *root_init_path = NULL; + + root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH); + root_init_path = strappenda3(root, "/", init); + + /* If the passed init is actually the same as the + * systemd binary, then let's suppress it. */ + if (files_same(root_init_path, root_systemd_path) > 0) + init = NULL; + } - log_debug("switching root - root: %s; init: %s", root, init); + log_debug("Switching root - root: %s; init: %s", root, strna(init)); r = sd_bus_call_method( bus, |