1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-12 13:18:14 +03:00

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.
This commit is contained in:
Harald Hoyer 2014-03-06 16:35:02 +01:00 committed by Lennart Poettering
parent 9d9951a460
commit f39d4a08e7
2 changed files with 37 additions and 11 deletions

View File

@ -813,6 +813,19 @@ int unlink_noerrno(const char *path);
_c_; \
})
#define strappenda3(a, b, c) \
({ \
const char *_a_ = (a), *_b_ = (b), *_c_ = (c); \
char *_d_; \
size_t _x_, _y_, _z_; \
_x_ = strlen(_a_); \
_y_ = strlen(_b_); \
_z_ = strlen(_c_); \
_d_ = alloca(_x_ + _y_ + _z_ + 1); \
strcpy(stpcpy(stpcpy(_d_, _a_), _b_), _c_); \
_d_; \
})
#define procfs_file_alloca(pid, field) \
({ \
pid_t _pid_ = (pid); \

View 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;
log_debug("switching root - root: %s; init: %s", root, init);
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, strna(init));
r = sd_bus_call_method(
bus,