Add init_exec kenv(1) variable, to make init(8) execute a file

after opening the console, replacing init as PID 1.

From the user point of view, it makes it possible to run eg the
shell as PID 1, using 'set init_exec=/bin/sh' at the loader(8)
prompt.

Reviewed by:	kib
MFC after:	2 weeks
Relnotes:	yes
Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D16625
This commit is contained in:
Edward Tomasz Napierala 2018-08-14 11:01:52 +00:00
parent 398810619c
commit 335fe94f90
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=337740
3 changed files with 37 additions and 2 deletions

View File

@ -31,7 +31,7 @@
.\" @(#)init.8 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
.Dd August 7, 2018
.Dd August 14, 2018
.Dt INIT 8
.Os
.Sh NAME
@ -316,6 +316,14 @@ See
.Xr reboot 8
.Fl r
for details.
.It Va init_exec
If set to a valid file name in the root file system,
instructs
.Nm
to directly execute that file as the very first action,
replacing
.Nm
as PID 1.
.It Va init_script
If set to a valid file name in the root file system,
instructs
@ -341,6 +349,8 @@ Defines the shell binary to be used for executing the various shell scripts.
The default is
.Dq Li /bin/sh .
It is used for running the
.Va init_exec
or
.Va init_script
if set, as well as for the
.Pa /etc/rc

View File

@ -149,6 +149,7 @@ static state_t current_state = death_single;
static void execute_script(char *argv[]);
static void open_console(void);
static const char *get_shell(void);
static void replace_init(char *path);
static void write_stderr(const char *message);
typedef struct init_session {
@ -330,6 +331,11 @@ main(int argc, char *argv[])
close(1);
close(2);
if (kenv(KENV_GET, "init_exec", kenv_value, sizeof(kenv_value)) > 0) {
replace_init(kenv_value);
_exit(0); /* reboot */
}
if (kenv(KENV_GET, "init_script", kenv_value, sizeof(kenv_value)) > 0) {
state_func_t next_transition;
@ -1087,6 +1093,22 @@ execute_script(char *argv[])
stall("can't exec %s for %s: %m", shell, script);
}
/*
* Execute binary, replacing init(8) as PID 1.
*/
static void
replace_init(char *path)
{
char *argv[3];
char sh[] = "sh";
argv[0] = sh;
argv[1] = path;
argv[2] = NULL;
execute_script(argv);
}
/*
* Run a shell script.
* Returns 0 on success, otherwise the next transition to enter:

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd August 13, 2018
.Dd August 14, 2018
.Dt LOADER 8
.Os
.Sh NAME
@ -492,6 +492,9 @@ of boot to be captured.
.It Va init_chroot
See
.Xr init 8 .
.It Va init_exec
See
.Xr init 8 .
.It Va init_path
Sets the list of binaries which the kernel will try to run as the initial
process.