diff options
author | trasz <trasz@FreeBSD.org> | 2016-05-11 10:03:13 +0000 |
---|---|---|
committer | trasz <trasz@FreeBSD.org> | 2016-05-11 10:03:13 +0000 |
commit | 6517c9db491c33980f1ce202e5363102be7bf7d0 (patch) | |
tree | 86495d51fc0bd0c9291aa028925bde949f980b3d /sbin | |
parent | 2a88184c42d305ccddddfab4c4ea206aef3b5e37 (diff) | |
download | FreeBSD-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.c | 25 |
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); |