diff options
author | H. Peter Anvin <hpa@zytor.com> | 2006-01-29 21:10:12 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2006-01-29 21:10:12 -0800 |
commit | 64187a8b51fe5e9380e3528c6d08a7651fead139 (patch) | |
tree | 7a01d61239df1e9083cb89da75523020a7c47e91 | |
parent | 460f7bfcdf8810b75bdacb042fa5b4d1cc5ba3a7 (diff) | |
download | klibc-64187a8b51fe5e9380e3528c6d08a7651fead139.tar.gz |
Call run-init from kinitklibc-1.2.1
-rw-r--r-- | usr/kinit/Kbuild | 2 | ||||
-rw-r--r-- | usr/kinit/kinit.c | 75 |
2 files changed, 43 insertions, 34 deletions
diff --git a/usr/kinit/Kbuild b/usr/kinit/Kbuild index 0735da63fb01a..fbf9f4bb553c6 100644 --- a/usr/kinit/Kbuild +++ b/usr/kinit/Kbuild @@ -4,7 +4,7 @@ static-y := kinit kinit-y := kinit.o do_mounts.o nfsroot.o getintfile.o initrd.o -kinit-y += open.o readfile.o +kinit-y += open.o readfile.o ../../utils/runinitlib.o kinit-y += ipconfig/ kinit-y += nfsmount/ diff --git a/usr/kinit/kinit.c b/usr/kinit/kinit.c index 738d40f874d2b..b4e1f2d568961 100644 --- a/usr/kinit/kinit.c +++ b/usr/kinit/kinit.c @@ -10,11 +10,18 @@ #include "kinit.h" #include "ipconfig.h" +#include "../../utils/run-init.h" const char *progname = "kinit"; int mnt_procfs; int mnt_sysfs; +void __attribute__((noreturn)) die(const char *msg) +{ + fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(errno)); + exit(1); +} + void dump_args(int argc, char *argv[]) { (void) argc; @@ -189,7 +196,27 @@ static void check_path(const char *path) } } +static const char *find_init(const char *root) +{ + const char *init_paths[] = { + "/sbin/init", "/bin/init", "/etc/init", "/bin/sh", NULL + }; + const char **p; + + if ( chdir(root) ) { + perror("chdir"); + exit(1); + } + for ( p = init_paths ; *p ; p++ ) { + if ( !access(*p+1, X_OK) ) + break; + } + chdir("/"); + return *p; +} + /* This is the argc and argv we pass to init */ +const char *init_path; int init_argc; char **init_argv; @@ -198,17 +225,11 @@ extern ssize_t readfile(const char *, char **); int main(int argc, char *argv[]) { char **cmdv; - char *kinit = NULL; char buf[1024]; char *cmdline; int ret = 0; int cmdc; int fd; - - ret = readfile("/proc/cmdline", &cmdline); - printf("Got: len = %d data = \"%s\"\n", ret, cmdline); - - exit(0); /* Default parameters for anything init-like we execute */ init_argc = argc; @@ -230,6 +251,8 @@ int main(int argc, char *argv[]) goto bail; } + ret = readfile("/proc/cmdline", &cmdline); + if ((mnt_sysfs = mount_sys_fs("/sys/bus", "/sys", "sysfs")) == -1) { ret = 1; goto bail; @@ -256,42 +279,28 @@ int main(int argc, char *argv[]) /* do_mounts cd's to /root so below tests /root/old_root */ check_path("old_root"); -#ifndef INI_DEBUG - if (pivot_root(".", "old_root") == -1) { - perror("pivot_root"); - ret = 2; - goto bail; - } - /* the below chdir() is recommended after a pivot_root() */ - chdir("/"); - if (mnt_procfs == 1) umount2("/proc", 0); if (mnt_sysfs == 1) umount2("/sys", 0); - if ((kinit = get_arg(cmdc, cmdv, "kinit="))) { - char *s = strrchr(kinit, '/'); - if (s) { - s++; - } - init_argv[0] = s; - execv(kinit, init_argv); + init_path = find_init("/root"); + + if ( !init_path ) { + fprintf(stderr, "%s: init not found!\n", progname); + ret = 2; + goto done; } - init_argv[0] = "init"; - execv("/sbin/init", init_argv); - execv("/etc/init", init_argv); - execv("/bin/init", init_argv); - init_argv[0] = "sh"; - execv("/bin/sh", init_argv); - - fprintf(stderr, "%s: I give up - there's nothing to run.\n", progname); + + init_argv[0] = strrchr(init_path, '/')+1; + + run_init("/root", "/dev/console", init_path, init_argv); + + /* run_init shouldn't fail; it rather calls die(). */ + fprintf(stderr, "%s: failed to run init for unknown reason...\n", progname); ret = 2; goto done; -#else - printf("%s: imagine pivot_root and exec\n", progname); -#endif bail: if (mnt_procfs == 1) |