From e79950d93af06b735b86548120dc60b2c5be6ee0 Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Thu, 13 May 2004 08:34:50 +0000 Subject: instead of keeping stage1 (mostly as temporary space but with a fixed size, and for the background init), exit the stage1 giving hand to stage2 in a tmpfs (same as what was done for Mandrakemove) --- mdk-stage1/stage1.c | 208 +++++++++++++++++++++++++++------------------------- 1 file changed, 108 insertions(+), 100 deletions(-) (limited to 'mdk-stage1/stage1.c') diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index 24ad55fbb..8306772b0 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -68,8 +68,6 @@ _syscall2(int,pivot_root,const char *,new_root,const char *,put_old) /************************************************************ * globals */ -char * method_name; -char * stage2_kickstart = NULL; void fatal_error(char *msg) @@ -93,6 +91,17 @@ void stg1_error_message(char *msg, ...) va_end(args); } +void stg1_fatal_message(char *msg, ...) +{ + va_list args; + va_start(args, msg); + log_message("unsetting automatic"); + unset_param(MODE_AUTOMATIC); + verror_message(msg, args); + va_end(args); + exit(1); +} + void stg1_info_message(char *msg, ...) { va_list args; @@ -139,7 +148,7 @@ static void spawn_shell(void) if (ioctl(0, TIOCSCTTY, NULL)) log_perror("could not set new controlling tty"); - execve(shell_name[0], shell_name, grab_env()); + execv(shell_name[0], shell_name); log_message("execve of %s failed: %s", shell_name[0], strerror(errno)); exit(-1); } @@ -268,20 +277,21 @@ static void expert_third_party_modules(void) #ifdef ENABLE_PCMCIA -static void handle_pcmcia(char ** pcmcia_adapter) +static void handle_pcmcia(void) { + char * pcmcia_adapter; if (kernel_version() == 2) { stg1_error_message("We now use kernel pcmcia support and this won't work with a 2.2 kernel."); return; } - *pcmcia_adapter = pcmcia_probe(); - if (!*pcmcia_adapter) { + pcmcia_adapter = pcmcia_probe(); + if (!pcmcia_adapter) { log_message("no pcmcia adapter found"); return; } my_insmod("pcmcia_core", ANY_DRIVER_TYPE, NULL, 0); - my_insmod(*pcmcia_adapter, ANY_DRIVER_TYPE, NULL, 0); + my_insmod(pcmcia_adapter, ANY_DRIVER_TYPE, NULL, 0); my_insmod("ds", ANY_DRIVER_TYPE, NULL, 0); /* call to cardmgr takes time, let's use the wait message */ @@ -291,6 +301,8 @@ static void handle_pcmcia(char ** pcmcia_adapter) if (IS_EXPERT) expert_third_party_modules(); + + add_to_env("PCMCIA", pcmcia_adapter); } #endif @@ -363,21 +375,47 @@ static void method_select_and_prepare(void) return method_select_and_prepare(); } -#ifdef MANDRAKE_MOVE -int mandrake_move_pre(void) +enum return_type create_initial_fs(char* symlinks, char* devices) { - log_message("move: creating %s directory and mounting as tmpfs", SLASH_LOCATION); + FILE *f; + char buf[5000]; - if (scall(mkdir(SLASH_LOCATION, 0755), "mkdir")) + if (scall(!(f = fopen(symlinks, "rb")), "fopen")) return RETURN_ERROR; + while (fgets(buf, sizeof(buf), f)) { + char oldpath[500], newpath[500], newpathfinal[500]; + buf[strlen(buf)-1] = '\0'; // trim \n + if (sscanf(buf, "%s %s", oldpath, newpath) != 2) { + sprintf(oldpath, "%s%s", STAGE2_LOCATION_REL, buf); + sprintf(newpathfinal, "%s%s", SLASH_LOCATION, buf); + } else { + sprintf(newpathfinal, "%s%s", SLASH_LOCATION, newpath); + } + log_message("creating symlink %s -> %s", oldpath, newpathfinal); + if (scall(symlink(oldpath, newpathfinal), "symlink")) + return RETURN_ERROR; + } + fclose(f); - if (scall(mount("none", SLASH_LOCATION, "tmpfs", MS_MGC_VAL, NULL), "mount tmpfs")) + // need to create the few devices needed to start up stage2 in a decent manner, we can't symlink or they will keep CD busy + if (scall(mkdir(SLASH_LOCATION "/dev", 0755), "mkdir")) return RETURN_ERROR; - + if (scall(!(f = fopen(devices, "rb")), "fopen")) + return RETURN_ERROR; + while (fgets(buf, sizeof(buf), f)) { + char name[500], path[500], type; + int major, minor; + sscanf(buf, "%s %c %d %d", name, &type, &major, &minor); + sprintf(path, "%s%s", SLASH_LOCATION, name); + log_message("creating device %s %c %d %d", path, type, major, minor); + if (scall(mknod(path, (type == 'c' ? S_IFCHR : S_IFBLK) | 0600, makedev(major, minor)), "mknod")) + return RETURN_ERROR; + } + fclose(f); return RETURN_OK; } - +#ifdef MANDRAKE_MOVE static enum return_type handle_clp(char* clp, char* live, char* location_live, char* location_mount, int* is_symlink, char* clp_tmpfs) { static int count = 0; @@ -416,10 +454,6 @@ static enum return_type handle_clp(char* clp, char* live, char* location_live, c int mandrake_move_post(void) { - FILE *f; - char buf[5000]; - int fd; - char rootdev[] = "0x0100"; int boot__real_is_symlink_to_raw = 0; int always__real_is_symlink_to_raw = 0; int totem__real_is_symlink_to_raw = 0; @@ -445,19 +479,6 @@ int mandrake_move_post(void) &main__real_is_symlink_to_raw, NULL) != RETURN_OK) return RETURN_ERROR; - if (scall(!(f = fopen(IMAGE_LOCATION_REAL "/move/symlinks", "rb")), "fopen[" IMAGE_LOCATION_REAL "/move/symlinks]")) - return RETURN_ERROR; - while (fgets(buf, sizeof(buf), f)) { - char oldpath[500], newpath[500]; - buf[strlen(buf)-1] = '\0'; // trim \n - sprintf(oldpath, "%s%s", LIVE_LOCATION_REL, buf); - sprintf(newpath, "%s%s", SLASH_LOCATION, buf); - log_message("move: creating symlink %s -> %s", oldpath, newpath); - if (scall(symlink(oldpath, newpath), "symlink")) - return RETURN_ERROR; - } - fclose(f); - // in case we didn't mount any clp, because gzloop.o is not available later in /lib/modules my_insmod("gzloop", ANY_DRIVER_TYPE, NULL, 0); @@ -467,25 +488,11 @@ int mandrake_move_post(void) return RETURN_ERROR; } else // need a fallback in case we don't use image_totem.clp nor live_tree_totem, but we're in -u mode - if (scall(symlink(LIVE_LOCATION_REL "/usr", SLASH_LOCATION "/usr"), "symlink")) + if (scall(symlink(STAGE2_LOCATION_REL "/usr", SLASH_LOCATION "/usr"), "symlink")) return RETURN_ERROR; - // need to create the few devices needed to start up stage2 in a decent manner, we can't symlink or they will keep CD busy - // we need only the ones before mounting /dev as devfs - if (scall(mkdir(SLASH_LOCATION "/dev", 0755), "mkdir")) + if (create_initial_fs(IMAGE_LOCATION_REAL "/move/symlinks", IMAGE_LOCATION_REAL "/move/devices") != RETURN_OK) return RETURN_ERROR; - if (scall(!(f = fopen(IMAGE_LOCATION_REAL "/move/devices", "rb")), "fopen")) - return RETURN_ERROR; - while (fgets(buf, sizeof(buf), f)) { - char name[500], path[500], type; - int major, minor; - sscanf(buf, "%s %c %d %d", name, &type, &major, &minor); - sprintf(path, "%s%s", SLASH_LOCATION, name); - log_message("move: creating device %s %c %d %d", path, type, major, minor); - if (scall(mknod(path, type == 'c' ? S_IFCHR : S_IFBLK, makedev(major, minor)), "mknod")) - return RETURN_ERROR; - } - fclose(f); if (boot__real_is_symlink_to_raw) { if (scall(unlink(BOOT_LOCATION), "unlink")) @@ -514,14 +521,19 @@ int mandrake_move_post(void) if (scall(symlink(RAW_LOCATION_REL "/live_tree", IMAGE_LOCATION_REAL), "symlink")) return RETURN_ERROR; } + return RETURN_OK; +} +#endif - mkdir(SLASH_LOCATION "/etc", 0755); - copy_file("/etc/resolv.conf", SLASH_LOCATION "/etc/resolv.conf", NULL); +int do_pivot_root(void) +{ + int fd; + char rootdev[] = "0x0100"; if (IS_DEBUGSTAGE1) while (1); - log_message("move: pivot_rooting"); + log_message("pivot_rooting"); // trick so that kernel won't try to mount the root device when initrd exits if (scall((fd = open("/proc/sys/kernel/real-root-dev", O_WRONLY)) < 0, "open")) return RETURN_ERROR; @@ -539,26 +551,62 @@ int mandrake_move_post(void) return RETURN_OK; } + +void finish_preparing(void) +{ + if (!IS_RESCUE) { +#ifdef MANDRAKE_MOVE + if (mandrake_move_post() != RETURN_OK) + stg1_fatal_message("Fatal error when launching MandrakeMove."); +#else + mkdir(SLASH_LOCATION "/etc", 0755); + mkdir(SLASH_LOCATION "/var", 0755); + /* STAGE2_LOCATION is wrong for live installs before pivot_root */ + if ((!IS_RAMDISK && create_initial_fs(IMAGE_LOCATION LIVE_LOCATION "/usr/share/symlinks", + IMAGE_LOCATION LIVE_LOCATION "/usr/share/devices") != RETURN_OK) + || (IS_RAMDISK && create_initial_fs(STAGE2_LOCATION "/usr/share/symlinks", + STAGE2_LOCATION "/usr/share/devices") != RETURN_OK)) + stg1_fatal_message("Fatal error finishing initialization."); #endif + + copy_file("/etc/resolv.conf", SLASH_LOCATION "/etc/resolv.conf", NULL); + mkdir(SLASH_LOCATION "/modules", 0755); + copy_file("/modules/modules.dep", SLASH_LOCATION "/modules/modules.dep", NULL); + + umount("/tmp/tmpfs"); + do_pivot_root(); + + if (file_size("/sbin/init") == -1) + stg1_fatal_message("Fatal error giving hand to second stage."); + } + if (shell_pid != 0) { + int fd; + kill(shell_pid, 9); + fd = open("/dev/tty2", O_RDWR); + write(fd, "Killed\n", 7); + close(fd); + } +} + int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)), char **env) { - char ** argptr; - char * stage2_args[30]; -#ifdef ENABLE_PCMCIA - char * pcmcia_adapter = NULL; -#endif if (getpid() > 50) set_param(MODE_TESTING); + else { + mkdir(SLASH_LOCATION, 0755); + if (scall(mount("none", SLASH_LOCATION, "tmpfs", MS_MGC_VAL, NULL), "mount tmpfs")) + fatal_error("Fatal error initializing."); + mkdir(SLASH_LOCATION "/tmp", 0755); + } spawn_interactive(); open_log(); log_message("welcome to the " DISTRIB_NAME " install (mdk-stage1, version " VERSION " built " __DATE__ " " __TIME__")"); process_cmdline(); - handle_env(env); #ifdef SPAWN_SHELL spawn_shell(); #endif @@ -579,7 +627,7 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)) #ifdef ENABLE_PCMCIA if (!IS_NOAUTO) - handle_pcmcia(&pcmcia_adapter); + handle_pcmcia(); #endif // load usb interface as soon as possible, helps usb mouse detection in stage2 */ @@ -600,8 +648,6 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)) if (total_memory() < MEM_LIMIT_MOVE) stg1_error_message(DISTRIB_NAME " typically needs more than %d Mbytes of memory (detected %d Mbytes). You may proceed, but the machine may crash or lock up for no apparent reason. Continue at your own risk. Alternatively, you may reboot your system now.", MEM_LIMIT_MOVE, total_memory()); - if (mandrake_move_pre() != RETURN_OK) - stg1_error_message("Fatal error when preparing Mandrakemove."); #endif #ifndef DISABLE_DISK @@ -619,51 +665,13 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)) if (interactive_pid != 0) kill(interactive_pid, 9); -#ifdef MANDRAKE_MOVE - if (mandrake_move_post() != RETURN_OK) - stg1_error_message("Fatal error when launching Mandrakemove."); -#endif - - if (shell_pid != 0) { - int fd; - kill(shell_pid, 9); - fd = open("/dev/tty2", O_RDWR); - write(fd, "Killed\n", 7); - close(fd); - } + finish_preparing(); - umount("/tmp/tmpfs"); finish_frontend(); close_log(); -#ifndef MANDRAKE_MOVE - if (IS_RESCUE) -#endif - return 66; if (IS_TESTING) return 0; - - argptr = stage2_args; - *argptr++ = "/usr/bin/runinstall2"; - *argptr++ = "--method"; - *argptr++ = method_name; -#ifdef ENABLE_PCMCIA - if (pcmcia_adapter) { - *argptr++ = "--pcmcia"; - *argptr++ = pcmcia_adapter; - } -#endif - if (stage2_kickstart) { - *argptr++ = "--kickstart"; - *argptr++ = stage2_kickstart; - } - *argptr++ = NULL; - - execve(stage2_args[0], stage2_args, grab_env()); - - printf("error in exec of stage2 :-(\n"); - printf("trying to execute '/usr/bin/runinstall2' from the installation volume,\nthe following fatal error occurred\n"); - fatal_error(strerror(errno)); - - return 0; /* shut up compiler (we can't get here anyway!) */ + else + return 66; } -- cgit v1.2.1