From 8938db3f91253099f6491171e85784abafddfd61 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sat, 3 Aug 2024 01:11:20 +0200 Subject: [PATCH] Simplify sysmerge --booting as a real daemon. --- init/init.8 | 4 ++-- init/init.c | 43 ++++--------------------------------- share/init/sysmerge | 3 +++ share/man/man5/init.5 | 6 ++++++ sysinstall/sysmerge.8 | 2 +- sysinstall/sysmerge.c | 3 ++- update-initrd/update-initrd | 2 +- 7 files changed, 19 insertions(+), 44 deletions(-) create mode 100644 share/init/sysmerge diff --git a/init/init.8 b/init/init.8 index 972552e0..7c4d9a72 100644 --- a/init/init.8 +++ b/init/init.8 @@ -121,7 +121,7 @@ corresponding partition devices in If the target is .Sy chain or -.Sy chain-merge , +.Sy chain-sysmerge , then the real operating system is chain initialized. .Pp The root filesystem is mounted per @@ -149,7 +149,7 @@ program (or .Ar chain-init if specified) of the target root filesystem is run inside a chroot. If the target is -.Sy chain-merge , +.Sy chain-sysmerge , then the .Fl \-static-prefix=/sysmerge .Fl \-target=merge diff --git a/init/init.c b/init/init.c index 34b46637..0ca28f01 100644 --- a/init/init.c +++ b/init/init.c @@ -3632,7 +3632,7 @@ int main(int argc, char* argv[]) // If the default daemon's top level dependency is a chain boot target, then // chain boot the actual root filesystem. if ( !strcmp(first_requirement, "chain") || - !strcmp(first_requirement, "chain-merge") ) + !strcmp(first_requirement, "chain-sysmerge") ) { int next_argc = argc - optind; char** next_argv = argv + optind; @@ -3689,14 +3689,14 @@ int main(int argc, char* argv[]) const char* program = next_argv[0]; char verbose_opt[] = {'-', "sqv"[verbosity], '\0'}; // Chain boot the operating system upgrade if needed. - if ( !strcmp(first_requirement, "chain-merge") ) + if ( !strcmp(first_requirement, "chain-sysmerge") ) { program = "/sysmerge/sbin/init"; // TODO: Concat next_argv onto this argv_next, so the arguments // can be passed to the final init. next_argv = (char*[]) { (char*) program, "--static-prefix=/sysmerge", - "--target=merge", verbose_opt, NULL }; + "--target=sysmerge", verbose_opt, NULL }; } else if ( next_argc < 1 ) { @@ -3731,7 +3731,7 @@ int main(int argc, char* argv[]) // TODO: After releasing Sortix 1.1, remove this compatibility since a // sysmerge from 1.0 will not have a /var/log directory. - if ( !strcmp(first_requirement, "merge") && + if ( !strcmp(first_requirement, "sysmerge") && access(log_path, F_OK) < 0 ) mkdir(log_path, 0755); @@ -3747,41 +3747,6 @@ int main(int argc, char* argv[]) set_kblayout(); set_videomode(); - // Run the operating system upgrade if requested. - if ( !strcmp(first_requirement, "merge") ) - { - pid_t child_pid = fork(); - if ( child_pid < 0 ) - fatal("fork: %m"); - if ( !child_pid ) - { - uninstall_signal_handler(); - const char* argv[] = { "sysmerge", "--booting", NULL }; - execvp(argv[0], (char* const*) argv); - fatal("Failed to load system upgrade: %s: %m", argv[0]); - } - forward_signal_pid = child_pid; - sigprocmask(SIG_UNBLOCK, &handled_signals, NULL); - int status; - while ( waitpid(child_pid, &status, 0) < 0 ) - { - if ( errno != EINTR ) - fatal("waitpid: %m"); - } - sigprocmask(SIG_BLOCK, &handled_signals, NULL); - forward_signal_pid = -1; // Racy with waitpid. - if ( WIFEXITED(status) && WEXITSTATUS(status) != 0 ) - fatal("Automatic upgrade failed: Exit status %i", - WEXITSTATUS(status)); - else if ( WIFSIGNALED(status) ) - fatal("Automatic upgrade failed: %s", strsignal(WTERMSIG(status))); - else if ( !WIFEXITED(status) ) - fatal("Automatic upgrade failed: Unexpected unusual termination"); - // Soft reinit into the freshly upgraded operating system. - // TODO: Use next_argv here. - reinit(); - } - // TODO: Use the arguments to specify additional things the default daemon // should depend on, as well as a denylist of things not to start // even if in default's dependencies. The easiest thing is probably to diff --git a/share/init/sysmerge b/share/init/sysmerge new file mode 100644 index 00000000..a06b2900 --- /dev/null +++ b/share/init/sysmerge @@ -0,0 +1,3 @@ +echo true +exit-code-meaning poweroff-reboot +exec sysmerge --booting diff --git a/share/man/man5/init.5 b/share/man/man5/init.5 index 02b62465..46892e76 100644 --- a/share/man/man5/init.5 +++ b/share/man/man5/init.5 @@ -149,6 +149,12 @@ inside the graphical user interface environment. This operating system mode is insecure because it boots straight to root access without a password. +.It Sy sysmerge +Perform an already scheduled operating system upgrade by invoking +.Xr sysmerge 8 +.Fl \-booting +and then reinit into the freshly upgraded system. +It does not depend on any daemons to minimize the upgrade environment. .It Sy sysupgrade Starts the operating system upgrader. This foreground daemon starts the diff --git a/sysinstall/sysmerge.8 b/sysinstall/sysmerge.8 index 260c2c6f..f7342f2e 100644 --- a/sysinstall/sysmerge.8 +++ b/sysinstall/sysmerge.8 @@ -135,7 +135,7 @@ has a new that runs .Sy /sysmerge/sbin/sysmerge --booting on boot through the -.Sy chain-merge +.Sy chain-sysmerge .Xr init 8 boot target, which performs the operating system upgrade. The bootloader configuration is regenerated with a menu option to perform diff --git a/sysinstall/sysmerge.c b/sysinstall/sysmerge.c index c96ab851..f6efce84 100644 --- a/sysinstall/sysmerge.c +++ b/sysinstall/sysmerge.c @@ -580,5 +580,6 @@ int main(int argc, char* argv[]) else printf("Successfully upgraded %s.\n", target); - return 0; + // Reinitialize the operating system if upgrading on boot. + return booting ? 3 : 0; } diff --git a/update-initrd/update-initrd b/update-initrd/update-initrd index 3e81842e..cb583b1a 100755 --- a/update-initrd/update-initrd +++ b/update-initrd/update-initrd @@ -85,7 +85,7 @@ cp "$sysroot/etc/fstab" "$tmp/etc/fstab" mkdir "$tmp/etc/init" if $sysmerge; then cat > "$tmp/etc/init/default" << EOF -require chain-merge exit-code +require chain-sysmerge exit-code EOF else cat > "$tmp/etc/init/default" << EOF