|
|
9fc0f6 |
From cad8ec5980d63253586d9f884649c45eed0667a1 Mon Sep 17 00:00:00 2001
|
|
|
9fc0f6 |
From: Harald Hoyer <harald@redhat.com>
|
|
|
9fc0f6 |
Date: Thu, 6 Mar 2014 16:35:02 +0100
|
|
|
9fc0f6 |
Subject: [PATCH] systemctl: for switch-root check, if we switch to a systemd
|
|
|
9fc0f6 |
init
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
If "systemctl switch-root" is called with a specific "INIT" or
|
|
|
9fc0f6 |
/proc/cmdline contains "init=", then systemd would not serialize
|
|
|
9fc0f6 |
itsself.
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
Let systemctl check, if the new init is in the standard systemd
|
|
|
9fc0f6 |
installation path and if so, clear the INIT parameter,
|
|
|
9fc0f6 |
to let systemd serialize itsself.
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
Conflicts:
|
|
|
9fc0f6 |
src/systemctl/systemctl.c
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
(cherry picked from commit f39d4a08e746e703d562076a0f622eb91dbdcd3e)
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
Related: #1111199
|
|
|
9fc0f6 |
---
|
|
|
9fc0f6 |
src/shared/util.h | 13 +++++++++++++
|
|
|
9fc0f6 |
src/systemctl/systemctl.c | 35 ++++++++++++++++++++++++++---------
|
|
|
9fc0f6 |
2 files changed, 39 insertions(+), 9 deletions(-)
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
diff --git a/src/shared/util.h b/src/shared/util.h
|
|
|
9fc0f6 |
index 631a385..d11fa07 100644
|
|
|
9fc0f6 |
--- a/src/shared/util.h
|
|
|
9fc0f6 |
+++ b/src/shared/util.h
|
|
|
9fc0f6 |
@@ -726,6 +726,19 @@ int unlink_noerrno(const char *path);
|
|
|
9fc0f6 |
_c_; \
|
|
|
9fc0f6 |
})
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
+#define strappenda3(a, b, c) \
|
|
|
9fc0f6 |
+ ({ \
|
|
|
9fc0f6 |
+ const char *_a_ = (a), *_b_ = (b), *_c_ = (c); \
|
|
|
9fc0f6 |
+ char *_d_; \
|
|
|
9fc0f6 |
+ size_t _x_, _y_, _z_; \
|
|
|
9fc0f6 |
+ _x_ = strlen(_a_); \
|
|
|
9fc0f6 |
+ _y_ = strlen(_b_); \
|
|
|
9fc0f6 |
+ _z_ = strlen(_c_); \
|
|
|
9fc0f6 |
+ _d_ = alloca(_x_ + _y_ + _z_ + 1); \
|
|
|
9fc0f6 |
+ strcpy(stpcpy(stpcpy(_d_, _a_), _b_), _c_); \
|
|
|
9fc0f6 |
+ _d_; \
|
|
|
9fc0f6 |
+ })
|
|
|
9fc0f6 |
+
|
|
|
9fc0f6 |
#define procfs_file_alloca(pid, field) \
|
|
|
9fc0f6 |
({ \
|
|
|
9fc0f6 |
pid_t _pid_ = (pid); \
|
|
|
9fc0f6 |
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
|
|
9fc0f6 |
index c738daf..1ca4fd3 100644
|
|
|
9fc0f6 |
--- a/src/systemctl/systemctl.c
|
|
|
9fc0f6 |
+++ b/src/systemctl/systemctl.c
|
|
|
9fc0f6 |
@@ -4143,9 +4143,10 @@ static int show_enviroment(DBusConnection *bus, char **args) {
|
|
|
9fc0f6 |
}
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
static int switch_root(DBusConnection *bus, char **args) {
|
|
|
9fc0f6 |
+ _cleanup_free_ char *cmdline_init = NULL;
|
|
|
9fc0f6 |
+ const char *root, *init;
|
|
|
9fc0f6 |
unsigned l;
|
|
|
9fc0f6 |
- const char *root;
|
|
|
9fc0f6 |
- _cleanup_free_ char *init = NULL;
|
|
|
9fc0f6 |
+ int r;
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
l = strv_length(args);
|
|
|
9fc0f6 |
if (l < 2 || l > 3) {
|
|
|
9fc0f6 |
@@ -4156,19 +4157,35 @@ static int switch_root(DBusConnection *bus, char **args) {
|
|
|
9fc0f6 |
root = args[1];
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
if (l >= 3)
|
|
|
9fc0f6 |
- init = strdup(args[2]);
|
|
|
9fc0f6 |
+ init = args[2];
|
|
|
9fc0f6 |
else {
|
|
|
9fc0f6 |
- parse_env_file("/proc/cmdline", WHITESPACE,
|
|
|
9fc0f6 |
- "init", &init,
|
|
|
9fc0f6 |
- NULL);
|
|
|
9fc0f6 |
+ r = parse_env_file("/proc/cmdline", WHITESPACE,
|
|
|
9fc0f6 |
+ "init", &cmdline_init,
|
|
|
9fc0f6 |
+ NULL);
|
|
|
9fc0f6 |
+ if (r < 0)
|
|
|
9fc0f6 |
+ log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
- if (!init)
|
|
|
9fc0f6 |
- init = strdup("");
|
|
|
9fc0f6 |
+ init = cmdline_init;
|
|
|
9fc0f6 |
}
|
|
|
9fc0f6 |
if (!init)
|
|
|
9fc0f6 |
return log_oom();
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
- log_debug("switching root - root: %s; init: %s", root, init);
|
|
|
9fc0f6 |
+ if (isempty(init))
|
|
|
9fc0f6 |
+ init = NULL;
|
|
|
9fc0f6 |
+
|
|
|
9fc0f6 |
+ if (init) {
|
|
|
9fc0f6 |
+ const char *root_systemd_path = NULL, *root_init_path = NULL;
|
|
|
9fc0f6 |
+
|
|
|
9fc0f6 |
+ root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
|
|
|
9fc0f6 |
+ root_init_path = strappenda3(root, "/", init);
|
|
|
9fc0f6 |
+
|
|
|
9fc0f6 |
+ /* If the passed init is actually the same as the
|
|
|
9fc0f6 |
+ * systemd binary, then let's suppress it. */
|
|
|
9fc0f6 |
+ if (files_same(root_init_path, root_systemd_path) > 0)
|
|
|
9fc0f6 |
+ init = NULL;
|
|
|
9fc0f6 |
+ }
|
|
|
9fc0f6 |
+
|
|
|
9fc0f6 |
+ log_debug("Switching root - root: %s; init: %s", root, strna(init));
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
return bus_method_call_with_reply(
|
|
|
9fc0f6 |
bus,
|