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