summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2016-05-11 10:03:13 +0000
committertrasz <trasz@FreeBSD.org>2016-05-11 10:03:13 +0000
commit6517c9db491c33980f1ce202e5363102be7bf7d0 (patch)
tree86495d51fc0bd0c9291aa028925bde949f980b3d /sbin
parent2a88184c42d305ccddddfab4c4ea206aef3b5e37 (diff)
downloadFreeBSD-src-6517c9db491c33980f1ce202e5363102be7bf7d0.zip
FreeBSD-src-6517c9db491c33980f1ce202e5363102be7bf7d0.tar.gz
When rerooting, take the init(8) path from argv[0] instead of fetching
it via kern.proc.pathname sysctl(2). In some cases - booting from NFS or rerooting after replacing the init binary with a new one - the sysctl would fail. In other cases - after upgrading, which moves the old init to /sbin/init.bak - it would return /sbin/init.bak, which is the actual path of the running init, instead of /sbin/init. Reported by: Melissa Jenkins <melissa-freebsd at littlebluecar.co.uk>, jilles@ MFC after: 1 month Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sbin')
-rw-r--r--sbin/init/init.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/sbin/init/init.c b/sbin/init/init.c
index 7355a53..5abdcd3 100644
--- a/sbin/init/init.c
+++ b/sbin/init/init.c
@@ -138,6 +138,7 @@ static int Reboot = FALSE;
static int howto = RB_AUTOBOOT;
static int devfs;
+static char *init_path_argv0;
static void transition(state_t);
static state_t requested_transition;
@@ -246,6 +247,11 @@ invalid:
#endif
errx(1, "already running");
}
+
+ init_path_argv0 = strdup(argv[0]);
+ if (init_path_argv0 == NULL)
+ err(1, "strdup");
+
/*
* Note that this does NOT open a file...
* Does 'init' deserve its own facility number?
@@ -755,25 +761,12 @@ static state_func_t
reroot(void)
{
void *buf;
- char init_path[PATH_MAX];
- size_t bufsize, init_path_len;
- int error, name[4];
+ size_t bufsize;
+ int error;
buf = NULL;
bufsize = 0;
- name[0] = CTL_KERN;
- name[1] = KERN_PROC;
- name[2] = KERN_PROC_PATHNAME;
- name[3] = -1;
- init_path_len = sizeof(init_path);
- error = sysctl(name, 4, init_path, &init_path_len, NULL, 0);
- if (error != 0) {
- emergency("failed to get kern.proc.pathname: %s",
- strerror(errno));
- goto out;
- }
-
revoke_ttys();
runshutdown();
@@ -792,7 +785,7 @@ reroot(void)
* Copy the init binary into tmpfs, so that we can unmount
* the old rootfs without committing suicide.
*/
- error = read_file(init_path, &buf, &bufsize);
+ error = read_file(init_path_argv0, &buf, &bufsize);
if (error != 0)
goto out;
error = mount_tmpfs(_PATH_REROOT);
OpenPOWER on IntegriCloud