chiark / gitweb /
systemctl: for switch-root check, if we switch to a systemd init
[elogind.git] / src / systemctl / systemctl.c
index f3952653e153698352bae410bc6cb9f6a565eef4..17ad7f0462c3e0ec4c0a05154f07b7d4155a4143 100644 (file)
@@ -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,