From 9475054a352029a19bde69076b1f6b63aa2280c7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 2 Oct 2012 15:29:10 -0400 Subject: [PATCH] --- yaml --- r: 333917 b: refs/heads/master c: ba4df2808a86f8b103c4db0b8807649383e9bd13 h: refs/heads/master i: 333915: 5ad1352aef287118fd45576d5ee2a44da5d805c7 v: v3 --- [refs] | 2 +- trunk/init/do_mounts_initrd.c | 41 ++++++++++++++--------------------- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/[refs] b/[refs] index ef8031b7bd8c..8e954e09dda0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cb450766bcafc7bd7d40e9a5a0050745e8c68b3e +refs/heads/master: ba4df2808a86f8b103c4db0b8807649383e9bd13 diff --git a/trunk/init/do_mounts_initrd.c b/trunk/init/do_mounts_initrd.c index 135959a276be..5e4ded51788e 100644 --- a/trunk/init/do_mounts_initrd.c +++ b/trunk/init/do_mounts_initrd.c @@ -16,13 +16,13 @@ #include #include #include +#include #include "do_mounts.h" unsigned long initrd_start, initrd_end; int initrd_below_start_ok; unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ -static int __initdata old_fd, root_fd; static int __initdata mount_initrd = 1; static int __init no_initrd(char *str) @@ -33,33 +33,29 @@ static int __init no_initrd(char *str) __setup("noinitrd", no_initrd); -static int __init do_linuxrc(void *_shell) +static int init_linuxrc(struct subprocess_info *info, struct cred *new) { - static const char *argv[] = { "linuxrc", NULL, }; - extern const char *envp_init[]; - const char *shell = _shell; - - sys_close(old_fd);sys_close(root_fd); + sys_unshare(CLONE_FS | CLONE_FILES); + /* move initrd over / and chdir/chroot in initrd root */ + sys_chdir("/root"); + sys_mount(".", "/", NULL, MS_MOVE, NULL); + sys_chroot("."); sys_setsid(); - return kernel_execve(shell, argv, envp_init); + return 0; } static void __init handle_initrd(void) { + static char *argv[] = { "linuxrc", NULL, }; + extern char *envp_init[]; int error; - int pid; real_root_dev = new_encode_dev(ROOT_DEV); create_dev("/dev/root.old", Root_RAM0); /* mount initrd on rootfs' /root */ mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); sys_mkdir("/old", 0700); - root_fd = sys_open("/", 0, 0); - old_fd = sys_open("/old", 0, 0); - /* move initrd over / and chdir/chroot in initrd root */ - sys_chdir("/root"); - sys_mount(".", "/", NULL, MS_MOVE, NULL); - sys_chroot("."); + sys_chdir("/old"); /* * In case that a resume from disk is carried out by linuxrc or one of @@ -67,27 +63,22 @@ static void __init handle_initrd(void) */ current->flags |= PF_FREEZER_SKIP; - pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); - if (pid > 0) - while (pid != sys_wait4(-1, NULL, 0, NULL)) - yield(); + call_usermodehelper_fns("/linuxrc", argv, envp_init, UMH_WAIT_PROC, + init_linuxrc, NULL, NULL); current->flags &= ~PF_FREEZER_SKIP; /* move initrd to rootfs' /old */ - sys_fchdir(old_fd); - sys_mount("/", ".", NULL, MS_MOVE, NULL); + sys_mount("..", ".", NULL, MS_MOVE, NULL); /* switch root and cwd back to / of rootfs */ - sys_fchdir(root_fd); - sys_chroot("."); - sys_close(old_fd); - sys_close(root_fd); + sys_chroot(".."); if (new_decode_dev(real_root_dev) == Root_RAM0) { sys_chdir("/old"); return; } + sys_chdir("/"); ROOT_DEV = new_decode_dev(real_root_dev); mount_root();