-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Description
Component
systemd
Is your feature request related to a problem? Please describe
On NixOS, we need to do some setup before executing systemd (e.g. create the /etc tree from the Nix store). On a system that doesn't use systemd in the initrd, we have a bash script as an init binary that accomplishes this. When we use systemd in the initrd, however, this doesn't work without losing access to the state from the systemd in the initrd (e.g for systemd-analyze).
This means that we currently have to do all the setting up in the initrd and build completely separate images for nspawn that have their own init binary.
Describe the solution you'd like
I'd like to switch-root from the initrd to our own init binary to do some minimal setup and then exec systemd from there. All that while preserving the systemd state from the initrd (e.g. for systemd-analyze).
Basically:
initrd-systemd --[switch-root]--> custom init binary --[exec]--> final systemd
Use cases:
- start a "normal" image (that would normally be started with an initrd) as a container with nspawn
- soft-reboot
If systemd would pass the cmdline flags to any switch-root binary, we could pass them along as is to the final systemd.
The following patch achieves what I want. This obviously needs cleanup and more consideration to be merged. Just serves to get my point across.
Subject: [PATCH] main: pass cmdline args to any init when switching root
This enables switch-root from the initrd to an init that isn't systemd
while still passing along the state. This way, we can start our own init
(i.e. nixos-init) to setup the things we need to do before systemd
starts in stage 2 while getting all the benefits of passing state from
initrd to stage 2.
---
src/core/main.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c
index 4bd2d8df75..59b8996e51 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -2027,7 +2027,7 @@ static int do_reexecute(
args_size = argc + 5;
args = newa(const char*, args_size);
- if (!switch_root_init) {
+ if (1) {
char sfd[STRLEN("--deserialize=") + DECIMAL_STR_MAX(int)];
/* First try to spawn ourselves with the right path, and with full serialization. We do this
@@ -2061,7 +2061,11 @@ static int do_reexecute(
*/
valgrind_summary_hack();
- args[0] = SYSTEMD_BINARY_PATH;
+ if (switch_root_init) {
+ args[0] = switch_root_init;
+ } else {
+ args[0] = SYSTEMD_BINARY_PATH;
+ }
(void) execv(args[0], (char* const*) args);
if (objective == MANAGER_REEXECUTE) {
@@ -2234,7 +2238,7 @@ static int invoke_main_loop(
manager_set_switching_root(m, true);
- if (!m->switch_root_init) {
+ if (1) {
r = prepare_reexecute(m, &arg_serialization, ret_fds, true);
if (r < 0) {
*ret_error_message = "Failed to prepare for reexecution";Describe alternatives you've considered
Patching systemd downstream in Nixpkgs
The systemd version you checked that didn't have the feature you are asking for
257