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:
parent
0e4f9a7ab8
commit
1791a19539
54
init/init.8
54
init/init.8
|
@ -40,22 +40,32 @@ option if specified or
|
||||||
otherwise. Supported targets are:
|
otherwise. Supported targets are:
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -tag -width "single-user" -compact -offset indent
|
.Bl -tag -width "single-user" -compact -offset indent
|
||||||
.It chain
|
.It Sy chain
|
||||||
mount real root filesystem and run its
|
mount real root filesystem and run its
|
||||||
.Nm
|
.Nm .
|
||||||
.It chain-merge
|
.It Sy chain-merge
|
||||||
complete a
|
like
|
||||||
|
.Sy chain
|
||||||
|
but run
|
||||||
|
.Pa /sysmerge/sbin/init
|
||||||
|
with the
|
||||||
|
.Sy merge
|
||||||
|
target.
|
||||||
|
.It Sy merge
|
||||||
|
finish a
|
||||||
.Xr sysmerge 8
|
.Xr sysmerge 8
|
||||||
upgrade during a chain boot
|
upgrade and then execute the real
|
||||||
.It multi-user
|
.Nm
|
||||||
|
with its default target.
|
||||||
|
.It Sy multi-user
|
||||||
boot to
|
boot to
|
||||||
.Xr login 8
|
.Xr login 8 .
|
||||||
.It single-user
|
.It Sy single-user
|
||||||
boot to root shell without password (not secure)
|
boot to root shell without password (not secure).
|
||||||
.It sysinstall
|
.It Sy sysinstall
|
||||||
boot to operating system installer (not secure)
|
boot to operating system installer (not secure).
|
||||||
.It sysupgrade
|
.It Sy sysupgrade
|
||||||
boot to operating system upgrader (not secure)
|
boot to operating system upgrader (not secure).
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
It is a full system compromise if unauthenticated users are able to boot the
|
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
|
corresponding partition devices in
|
||||||
.Pa /dev .
|
.Pa /dev .
|
||||||
.Ss Chain Initialization
|
.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
|
.Pa /etc/fstab
|
||||||
(see
|
(see
|
||||||
.Xr fstab 5) and runs the next
|
.Xr fstab 5) and runs the next
|
||||||
|
@ -115,6 +127,20 @@ set graphics resolution (see
|
||||||
.Nm
|
.Nm
|
||||||
mounts all the filesystems according to
|
mounts all the filesystems according to
|
||||||
.Xr fstab 5 .
|
.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
|
.Ss Session
|
||||||
Finally
|
Finally
|
||||||
.Nm
|
.Nm
|
||||||
|
|
57
init/init.c
57
init/init.c
|
@ -756,6 +756,33 @@ static int init(const char* target)
|
||||||
prepare_block_devices();
|
prepare_block_devices();
|
||||||
load_fstab();
|
load_fstab();
|
||||||
mountpoints_mount(false);
|
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;
|
sigset_t oldset, sigttou;
|
||||||
sigemptyset(&sigttou);
|
sigemptyset(&sigttou);
|
||||||
sigaddset(&sigttou, SIGTTOU);
|
sigaddset(&sigttou, SIGTTOU);
|
||||||
|
@ -891,15 +918,15 @@ static int init_chain(const char* target)
|
||||||
fatal("chroot: %s: %m", chain_location);
|
fatal("chroot: %s: %m", chain_location);
|
||||||
if ( chdir("/") < 0 )
|
if ( chdir("/") < 0 )
|
||||||
fatal("chdir: %s: %m", chain_location);
|
fatal("chdir: %s: %m", chain_location);
|
||||||
|
unsetenv("INIT_PID");
|
||||||
if ( !strcmp(target, "chain-merge") )
|
if ( !strcmp(target, "chain-merge") )
|
||||||
{
|
{
|
||||||
const char* argv[] = { "sysmerge", "--booting", NULL };
|
const char* argv[] = { "init", "--target=merge", NULL };
|
||||||
execv("/sysmerge/sbin/sysmerge", (char* const*) argv);
|
execv("/sysmerge/sbin/init", (char* const*) argv);
|
||||||
fatal("Failed to run automatic update: %s: %m", argv[0]);
|
fatal("Failed to load automatic update chain init: %s: %m", argv[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsetenv("INIT_PID");
|
|
||||||
const char* argv[] = { "init", NULL };
|
const char* argv[] = { "init", NULL };
|
||||||
execv("/sbin/init", (char* const*) argv);
|
execv("/sbin/init", (char* const*) argv);
|
||||||
fatal("Failed to load chain init: %s: %m", argv[0]);
|
fatal("Failed to load chain init: %s: %m", argv[0]);
|
||||||
|
@ -908,23 +935,10 @@ static int init_chain(const char* target)
|
||||||
int status;
|
int status;
|
||||||
if ( waitpid(child_pid, &status, 0) < 0 )
|
if ( waitpid(child_pid, &status, 0) < 0 )
|
||||||
fatal("waitpid");
|
fatal("waitpid");
|
||||||
const char* back = ": Trying to bring it back up again";
|
// Only run an automatic update once.
|
||||||
if ( !strcmp(target, "chain-merge") )
|
if ( !strcmp(target, "chain-merge") )
|
||||||
{
|
target = "chain";
|
||||||
if ( WIFEXITED(status) && WEXITSTATUS(status) == 0 )
|
const char* back = ": Trying to bring it back up again";
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
if ( WIFEXITED(status) )
|
if ( WIFEXITED(status) )
|
||||||
{
|
{
|
||||||
result = WEXITSTATUS(status);
|
result = WEXITSTATUS(status);
|
||||||
|
@ -1019,7 +1033,8 @@ int main(int argc, char* argv[])
|
||||||
if ( !strcmp(target, "single-user") ||
|
if ( !strcmp(target, "single-user") ||
|
||||||
!strcmp(target, "multi-user") ||
|
!strcmp(target, "multi-user") ||
|
||||||
!strcmp(target, "sysinstall") ||
|
!strcmp(target, "sysinstall") ||
|
||||||
!strcmp(target, "sysupgrade") )
|
!strcmp(target, "sysupgrade") ||
|
||||||
|
!strcmp(target, "merge") )
|
||||||
return init(target);
|
return init(target);
|
||||||
|
|
||||||
if ( !strcmp(target, "chain") ||
|
if ( !strcmp(target, "chain") ||
|
||||||
|
|
|
@ -54,7 +54,7 @@ It's boot time, complete the system upgrade that was delayed. This is meant to
|
||||||
be used by
|
be used by
|
||||||
.Xr init 8
|
.Xr init 8
|
||||||
through the
|
through the
|
||||||
.Sy chain-merge
|
.Sy merge
|
||||||
boot target. This installs the
|
boot target. This installs the
|
||||||
.Pa /sysmerge
|
.Pa /sysmerge
|
||||||
directory onto the root filesystem and removes the
|
directory onto the root filesystem and removes the
|
||||||
|
|
Loading…
Reference in New Issue