Index: sbin/init/init.8 =================================================================== --- sbin/init/init.8 +++ sbin/init/init.8 @@ -316,6 +316,14 @@ .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 @@ 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 Index: sbin/init/init.c =================================================================== --- sbin/init/init.c +++ sbin/init/init.c @@ -149,6 +149,7 @@ 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 @@ 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; @@ -1085,6 +1091,22 @@ shell = get_shell(); execv(shell, 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); } /* Index: stand/man/loader.8 =================================================================== --- stand/man/loader.8 +++ stand/man/loader.8 @@ -492,6 +492,9 @@ .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.