Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] Add rdinit parameter to pick early userspace init

Since early userspace was added, there's no way to override which init to
run from it. Some people tack on an extra cpio archive with a link from
/init depending on what they want to run, but that's sometimes impractical.

Changing the "init=" to also override the early userspace isn't feasible,
since it is still used to indicate what init to run from disk when early
userspace has completed doing whatever it's doing (i.e. load filesystem
modules and drivers).

Instead, introduce "rdinit=" and make it override the default "/init" if
specified.

Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Olof Johansson and committed by
Linus Torvalds
ffdfc409 2b579bee

+32 -4
+5
Documentation/kernel-parameters.txt
··· 1174 1174 New name for the ramdisk parameter. 1175 1175 See Documentation/ramdisk.txt. 1176 1176 1177 + rdinit= [KNL] 1178 + Format: <full_path> 1179 + Run specified binary instead of /init from the ramdisk, 1180 + used for early userspace startup. See initrd. 1181 + 1177 1182 reboot= [BUGS=IA-32,BUGS=ARM,BUGS=IA-64] Rebooting mode 1178 1183 Format: <reboot_mode>[,<reboot_mode2>[,...]] 1179 1184 See arch/*/kernel/reboot.c.
+27 -4
init/main.c
··· 123 123 char saved_command_line[COMMAND_LINE_SIZE]; 124 124 125 125 static char *execute_command; 126 + static char *ramdisk_execute_command; 126 127 127 128 /* Setup configured maximum number of CPUs to activate */ 128 129 static unsigned int max_cpus = NR_CPUS; ··· 297 296 return 1; 298 297 } 299 298 __setup("init=", init_setup); 299 + 300 + static int __init rdinit_setup(char *str) 301 + { 302 + unsigned int i; 303 + 304 + ramdisk_execute_command = str; 305 + /* See "auto" comment in init_setup */ 306 + for (i = 1; i < MAX_INIT_ARGS; i++) 307 + argv_init[i] = NULL; 308 + return 1; 309 + } 310 + __setup("rdinit=", rdinit_setup); 300 311 301 312 extern void setup_arch(char **); 302 313 ··· 694 681 * check if there is an early userspace init. If yes, let it do all 695 682 * the work 696 683 */ 697 - if (sys_access((const char __user *) "/init", 0) == 0) 698 - execute_command = "/init"; 699 - else 684 + 685 + if (!ramdisk_execute_command) 686 + ramdisk_execute_command = "/init"; 687 + 688 + if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) { 689 + ramdisk_execute_command = NULL; 700 690 prepare_namespace(); 691 + } 701 692 702 693 /* 703 694 * Ok, we have completed the initial bootup, and ··· 718 701 719 702 (void) sys_dup(0); 720 703 (void) sys_dup(0); 721 - 704 + 705 + if (ramdisk_execute_command) { 706 + run_init_process(ramdisk_execute_command); 707 + printk(KERN_WARNING "Failed to execute %s\n", 708 + ramdisk_execute_command); 709 + } 710 + 722 711 /* 723 712 * We try each of these until one succeeds. 724 713 *