1*4c9f6488SKonstantin Belousov /*-
2*4c9f6488SKonstantin Belousov * SPDX-License-Identifier: BSD-3-Clause
3*4c9f6488SKonstantin Belousov *
4*4c9f6488SKonstantin Belousov * Copyright (c) 1991, 1993
5*4c9f6488SKonstantin Belousov * The Regents of the University of California. All rights reserved.
6*4c9f6488SKonstantin Belousov *
7*4c9f6488SKonstantin Belousov * This code is derived from software contributed to Berkeley by
8*4c9f6488SKonstantin Belousov * Donn Seeley at Berkeley Software Design, Inc.
9*4c9f6488SKonstantin Belousov *
10*4c9f6488SKonstantin Belousov * Redistribution and use in source and binary forms, with or without
11*4c9f6488SKonstantin Belousov * modification, are permitted provided that the following conditions
12*4c9f6488SKonstantin Belousov * are met:
13*4c9f6488SKonstantin Belousov * 1. Redistributions of source code must retain the above copyright
14*4c9f6488SKonstantin Belousov * notice, this list of conditions and the following disclaimer.
15*4c9f6488SKonstantin Belousov * 2. Redistributions in binary form must reproduce the above copyright
16*4c9f6488SKonstantin Belousov * notice, this list of conditions and the following disclaimer in the
17*4c9f6488SKonstantin Belousov * documentation and/or other materials provided with the distribution.
18*4c9f6488SKonstantin Belousov * 3. Neither the name of the University nor the names of its contributors
19*4c9f6488SKonstantin Belousov * may be used to endorse or promote products derived from this software
20*4c9f6488SKonstantin Belousov * without specific prior written permission.
21*4c9f6488SKonstantin Belousov *
22*4c9f6488SKonstantin Belousov * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23*4c9f6488SKonstantin Belousov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24*4c9f6488SKonstantin Belousov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*4c9f6488SKonstantin Belousov * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26*4c9f6488SKonstantin Belousov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27*4c9f6488SKonstantin Belousov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28*4c9f6488SKonstantin Belousov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29*4c9f6488SKonstantin Belousov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30*4c9f6488SKonstantin Belousov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31*4c9f6488SKonstantin Belousov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32*4c9f6488SKonstantin Belousov * SUCH DAMAGE.
33*4c9f6488SKonstantin Belousov */
34*4c9f6488SKonstantin Belousov
35*4c9f6488SKonstantin Belousov #include <sys/param.h>
36*4c9f6488SKonstantin Belousov #include <sys/mount.h>
37*4c9f6488SKonstantin Belousov #include <sys/reboot.h>
38*4c9f6488SKonstantin Belousov #include <sys/sysctl.h>
39*4c9f6488SKonstantin Belousov
40*4c9f6488SKonstantin Belousov #include <err.h>
41*4c9f6488SKonstantin Belousov #include <kenv.h>
42*4c9f6488SKonstantin Belousov #include <paths.h>
43*4c9f6488SKonstantin Belousov #include <stdarg.h>
44*4c9f6488SKonstantin Belousov #include <stdlib.h>
45*4c9f6488SKonstantin Belousov #include <string.h>
46*4c9f6488SKonstantin Belousov #include <syslog.h>
47*4c9f6488SKonstantin Belousov #include <unistd.h>
48*4c9f6488SKonstantin Belousov
49*4c9f6488SKonstantin Belousov static void emergency(const char *, ...) __printflike(1, 2);
50*4c9f6488SKonstantin Belousov
51*4c9f6488SKonstantin Belousov static void
emergency(const char * message,...)52*4c9f6488SKonstantin Belousov emergency(const char *message, ...)
53*4c9f6488SKonstantin Belousov {
54*4c9f6488SKonstantin Belousov va_list ap;
55*4c9f6488SKonstantin Belousov va_start(ap, message);
56*4c9f6488SKonstantin Belousov
57*4c9f6488SKonstantin Belousov vsyslog(LOG_EMERG, message, ap);
58*4c9f6488SKonstantin Belousov va_end(ap);
59*4c9f6488SKonstantin Belousov }
60*4c9f6488SKonstantin Belousov
61*4c9f6488SKonstantin Belousov int
main(void)62*4c9f6488SKonstantin Belousov main(void)
63*4c9f6488SKonstantin Belousov {
64*4c9f6488SKonstantin Belousov char init_path[PATH_MAX], *path, *path_component;
65*4c9f6488SKonstantin Belousov size_t init_path_len;
66*4c9f6488SKonstantin Belousov int nbytes, error;
67*4c9f6488SKonstantin Belousov
68*4c9f6488SKonstantin Belousov openlog("init", LOG_CONS, LOG_AUTH);
69*4c9f6488SKonstantin Belousov
70*4c9f6488SKonstantin Belousov /*
71*4c9f6488SKonstantin Belousov * Ask the kernel to mount the new rootfs.
72*4c9f6488SKonstantin Belousov */
73*4c9f6488SKonstantin Belousov error = reboot(RB_REROOT);
74*4c9f6488SKonstantin Belousov if (error != 0) {
75*4c9f6488SKonstantin Belousov emergency("RB_REBOOT failed: %m");
76*4c9f6488SKonstantin Belousov _exit(1);
77*4c9f6488SKonstantin Belousov }
78*4c9f6488SKonstantin Belousov
79*4c9f6488SKonstantin Belousov /*
80*4c9f6488SKonstantin Belousov * Figure out where the destination init(8) binary is. Note that
81*4c9f6488SKonstantin Belousov * the path could be different than what we've started with. Use
82*4c9f6488SKonstantin Belousov * the value from kenv, if set, or the one from sysctl otherwise.
83*4c9f6488SKonstantin Belousov * The latter defaults to a hardcoded value, but can be overridden
84*4c9f6488SKonstantin Belousov * by a build time option.
85*4c9f6488SKonstantin Belousov */
86*4c9f6488SKonstantin Belousov nbytes = kenv(KENV_GET, "init_path", init_path, sizeof(init_path));
87*4c9f6488SKonstantin Belousov if (nbytes <= 0) {
88*4c9f6488SKonstantin Belousov init_path_len = sizeof(init_path);
89*4c9f6488SKonstantin Belousov error = sysctlbyname("kern.init_path",
90*4c9f6488SKonstantin Belousov init_path, &init_path_len, NULL, 0);
91*4c9f6488SKonstantin Belousov if (error != 0) {
92*4c9f6488SKonstantin Belousov emergency("failed to retrieve kern.init_path: %m");
93*4c9f6488SKonstantin Belousov _exit(1);
94*4c9f6488SKonstantin Belousov }
95*4c9f6488SKonstantin Belousov }
96*4c9f6488SKonstantin Belousov
97*4c9f6488SKonstantin Belousov /*
98*4c9f6488SKonstantin Belousov * Repeat the init search logic from sys/kern/init_path.c
99*4c9f6488SKonstantin Belousov */
100*4c9f6488SKonstantin Belousov path_component = init_path;
101*4c9f6488SKonstantin Belousov while ((path = strsep(&path_component, ":")) != NULL) {
102*4c9f6488SKonstantin Belousov /*
103*4c9f6488SKonstantin Belousov * Execute init(8) from the new rootfs.
104*4c9f6488SKonstantin Belousov */
105*4c9f6488SKonstantin Belousov execl(path, path, NULL);
106*4c9f6488SKonstantin Belousov }
107*4c9f6488SKonstantin Belousov emergency("cannot exec init from %s: %m", init_path);
108*4c9f6488SKonstantin Belousov _exit(1);
109*4c9f6488SKonstantin Belousov }
110