From 95850a44c2fd911c2a7f86b82b8ad577e68a31f4 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Sat, 7 Sep 2024 22:28:05 +0200 Subject: [PATCH] feat(recovery): implement failsafe boot for TFTP or anything, really. Signed-off-by: Raito Bezarius --- modules/outputs/initramfs.nix | 25 +++++++++++++++++++++++-- pkgs/preinit/preinit.c | 10 ++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/modules/outputs/initramfs.nix b/modules/outputs/initramfs.nix index 89d017f..c666c77 100644 --- a/modules/outputs/initramfs.nix +++ b/modules/outputs/initramfs.nix @@ -41,17 +41,38 @@ in system.outputs = { initramfs = - let inherit (pkgs.pkgsBuildBuild) gen_init_cpio; + let + inherit (pkgs.pkgsBuildBuild) gen_init_cpio cpio writeScript; + inherit (pkgs) busybox; + failsafe-init = writeScript "init" '' + #!/bin/sh + exec >/dev/console + echo Running in initramfs + PATH=${busybox}/bin:$PATH + export PATH + mount -t proc none /proc + mount -t sysfs none /sys + ${busybox}/bin/sh + ''; + refs = pkgs.writeReferencesToFile busybox; in runCommand "initramfs.cpio" {} '' - cat << SPECIALS | ${gen_init_cpio}/bin/gen_init_cpio /dev/stdin > $out + cat << SPECIALS | ${gen_init_cpio}/bin/gen_init_cpio /dev/stdin > out dir /proc 0755 0 0 dir /dev 0755 0 0 nod /dev/console 0600 0 0 c 5 1 dir /target 0755 0 0 dir /target/persist 0755 0 0 dir /target/nix 0755 0 0 + dir /nix 0755 0 0 + dir /nix/store 0755 0 0 + dir /bin 0755 0 0 + file /bin/sh ${busybox}/bin/sh 0755 0 0 file /init ${pkgs.preinit}/bin/preinit 0755 0 0 + file /failsafe-init ${failsafe-init} 0755 0 0 SPECIALS + + find $(cat ${refs}) | ${cpio}/bin/cpio -H newc -o -A -v -O out + mv out $out ''; systemConfiguration = pkgs.systemconfig config.filesystem.contents; diff --git a/pkgs/preinit/preinit.c b/pkgs/preinit/preinit.c index 7dd896b..4b5f3f1 100644 --- a/pkgs/preinit/preinit.c +++ b/pkgs/preinit/preinit.c @@ -98,6 +98,7 @@ int main(int argc, char *argv[], char *envp[]) AVER(mount(opts.device, "/target/persist", opts.fstype, 0, opts.mount_opts)); } else { if(mount(opts.device, "/target/persist", opts.fstype, 0, opts.mount_opts) < 0) { + ERR("failed to mount primary device, mount the alternative device\n"); AVER(mount(opts.altdevice, "/target/persist", opts.fstype, 0, opts.mount_opts)); } } @@ -118,5 +119,14 @@ int main(int argc, char *argv[], char *envp[]) AVER(execve("/persist/init", argv, envp)); } + + ERR("failed to mount the rootfs\n"); + ERR("final stand using the failsafe initialization method\n"); + ERR("the boot process is manual from now on\n"); + + argv[0] = "init"; + argv[1] = NULL; + AVER(execve("/failsafe-init", argv, envp)); + die(); }