Refactor init(8) chain-merge target and add merge target.

The chain-merge target now invokes the /sysmerge init(8) with the merge
target, which now mounts the mountpoints. This change allows having a /boot
partition for the purpose of sysupgrade(8).
This commit is contained in:
Jonas 'Sortie' Termansen 2016-08-21 23:03:33 +02:00
parent 0e4f9a7ab8
commit 1791a19539
3 changed files with 77 additions and 36 deletions

View File

@ -40,22 +40,32 @@ option if specified or
otherwise. Supported targets are:
.Pp
.Bl -tag -width "single-user" -compact -offset indent
.It chain
.It Sy chain
mount real root filesystem and run its
.Nm
.It chain-merge
complete a
.Nm .
.It Sy chain-merge
like
.Sy chain
but run
.Pa /sysmerge/sbin/init
with the
.Sy merge
target.
.It Sy merge
finish a
.Xr sysmerge 8
upgrade during a chain boot
.It multi-user
upgrade and then execute the real
.Nm
with its default target.
.It Sy multi-user
boot to
.Xr login 8
.It single-user
boot to root shell without password (not secure)
.It sysinstall
boot to operating system installer (not secure)
.It sysupgrade
boot to operating system upgrader (not secure)
.Xr login 8 .
.It Sy single-user
boot to root shell without password (not secure).
.It Sy sysinstall
boot to operating system installer (not secure).
.It Sy sysupgrade
boot to operating system upgrader (not secure).
.El
.Pp
It is a full system compromise if unauthenticated users are able to boot the
@ -72,7 +82,9 @@ will scan every block device for valid partition tables and create the
corresponding partition devices in
.Pa /dev .
.Ss Chain Initialization
The chain target mounts the root filesystem as in
The
.Sy chain
target mounts the root filesystem as in
.Pa /etc/fstab
(see
.Xr fstab 5) and runs the next
@ -115,6 +127,20 @@ set graphics resolution (see
.Nm
mounts all the filesystems according to
.Xr fstab 5 .
.Ss Merge
The
.Sy merge
target completes a delayed system upgrade by invoking the
.Xr sysmerge 8
at
.Pa /sysmerge/sbin/sysmerge
with the
.Ar --booting
option. If the upgrade succeeds, the temporary
.Nm
deinitializes the system and invokes the real (now upgraded)
.Nm
which will restart system initialization in the normal fashion.
.Ss Session
Finally
.Nm

View File

@ -756,6 +756,33 @@ static int init(const char* target)
prepare_block_devices();
load_fstab();
mountpoints_mount(false);
if ( !strcmp(target, "merge") )
{
pid_t child_pid = fork();
if ( child_pid < 0 )
fatal("fork: %m");
if ( !child_pid )
{
const char* argv[] = { "sysmerge", "--booting", NULL };
execv("/sysmerge/sbin/sysmerge", (char* const*) argv);
fatal("Failed to run automatic update: %s: %m", argv[0]);
}
int status;
if ( waitpid(child_pid, &status, 0) < 0 )
fatal("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");
niht();
unsetenv("INIT_PID");
const char* argv[] = { "init", NULL };
execv("/sbin/init", (char* const*) argv);
fatal("Failed to load chain init: %s: %m", argv[0]);
}
sigset_t oldset, sigttou;
sigemptyset(&sigttou);
sigaddset(&sigttou, SIGTTOU);
@ -891,15 +918,15 @@ static int init_chain(const char* target)
fatal("chroot: %s: %m", chain_location);
if ( chdir("/") < 0 )
fatal("chdir: %s: %m", chain_location);
unsetenv("INIT_PID");
if ( !strcmp(target, "chain-merge") )
{
const char* argv[] = { "sysmerge", "--booting", NULL };
execv("/sysmerge/sbin/sysmerge", (char* const*) argv);
fatal("Failed to run automatic update: %s: %m", argv[0]);
const char* argv[] = { "init", "--target=merge", NULL };
execv("/sysmerge/sbin/init", (char* const*) argv);
fatal("Failed to load automatic update chain init: %s: %m", argv[0]);
}
else
{
unsetenv("INIT_PID");
const char* argv[] = { "init", NULL };
execv("/sbin/init", (char* const*) argv);
fatal("Failed to load chain init: %s: %m", argv[0]);
@ -908,23 +935,10 @@ static int init_chain(const char* target)
int status;
if ( waitpid(child_pid, &status, 0) < 0 )
fatal("waitpid");
const char* back = ": Trying to bring it back up again";
// Only run an automatic update once.
if ( !strcmp(target, "chain-merge") )
{
if ( WIFEXITED(status) && WEXITSTATUS(status) == 0 )
{
target = "chain";
continue;
}
if ( WIFEXITED(status) )
fatal("Automatic upgrade failed: Exit status %i",
WEXITSTATUS(status));
else if ( WIFSIGNALED(status) )
fatal("Automatic upgrade failed: %s",
strsignal(WTERMSIG(status)));
else
fatal("Automatic upgrade failed: Unexpected unusual termination");
}
target = "chain";
const char* back = ": Trying to bring it back up again";
if ( WIFEXITED(status) )
{
result = WEXITSTATUS(status);
@ -1019,7 +1033,8 @@ int main(int argc, char* argv[])
if ( !strcmp(target, "single-user") ||
!strcmp(target, "multi-user") ||
!strcmp(target, "sysinstall") ||
!strcmp(target, "sysupgrade") )
!strcmp(target, "sysupgrade") ||
!strcmp(target, "merge") )
return init(target);
if ( !strcmp(target, "chain") ||

View File

@ -54,7 +54,7 @@ It's boot time, complete the system upgrade that was delayed. This is meant to
be used by
.Xr init 8
through the
.Sy chain-merge
.Sy merge
boot target. This installs the
.Pa /sysmerge
directory onto the root filesystem and removes the