diff options
Diffstat (limited to 'mdk-stage1/stage1.c')
| -rw-r--r-- | mdk-stage1/stage1.c | 438 |
1 files changed, 102 insertions, 336 deletions
diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index 59b9c52aa..94bb1e0df 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -1,7 +1,7 @@ /* - * Guillaume Cottenceau (was gc@mandrakesoft.com) + * Guillaume Cottenceau (gc) * - * Copyright 2000-2004 MandrakeSoft + * Copyright 2000-2004 Mandriva * * * This software may be freely redistributed under the terms of the GNU @@ -34,7 +34,7 @@ #include <stdarg.h> #include <signal.h> #include <linux/unistd.h> -_syscall2(int,pivot_root,const char *,new_root,const char *,put_old) +#include <libldetect.h> #include "stage1.h" @@ -43,13 +43,13 @@ _syscall2(int,pivot_root,const char *,new_root,const char *,put_old) #include "frontend.h" #include "modules.h" #include "tools.h" +#include "utils.h" #include "automatic.h" #include "mount.h" -#include "lomount.h" -#include "insmod.h" +#include "thirdparty.h" #ifdef ENABLE_PCMCIA -#include "pcmcia_/pcmcia.h" +#include "pcmcia/pcmcia.h" #endif #ifndef DISABLE_CDROM @@ -85,8 +85,7 @@ void stg1_error_message(char *msg, ...) { va_list args; va_start(args, msg); - log_message("unsetting automatic"); - unset_param(MODE_AUTOMATIC); + unset_automatic(); verror_message(msg, args); va_end(args); } @@ -95,8 +94,7 @@ void stg1_fatal_message(char *msg, ...) { va_list args; va_start(args, msg); - log_message("unsetting automatic"); - unset_param(MODE_AUTOMATIC); + unset_automatic(); verror_message(msg, args); va_end(args); exit(1); @@ -123,7 +121,7 @@ static pid_t shell_pid = 0; static void spawn_shell(void) { int fd; - char * shell_name[] = { "/tmp/sh", NULL }; + char * shell_name[] = { "/bin/sh", NULL }; log_message("spawning a shell"); @@ -158,14 +156,13 @@ static void spawn_shell(void) } #endif - +#ifdef SPAWN_INTERACTIVE char * interactive_fifo = "/tmp/stage1-fifo"; static pid_t interactive_pid = 0; /* spawns my small interactive on console #6 */ static void spawn_interactive(void) { -#ifdef SPAWN_INTERACTIVE int fd; char * dev = "/dev/tty6"; @@ -196,7 +193,7 @@ static void spawn_interactive(void) perror("could not set new controlling tty"); fif_out = open(interactive_fifo, O_WRONLY); - printf("Please enter your command (availables: [+,-] [rescue,expert]).\n"); + printf("Please enter your command (availables: [+,-] [rescue]).\n"); while (1) { char s[50]; @@ -214,98 +211,48 @@ static void spawn_interactive(void) close(fd); } -#endif -} - - -/************************************************************ - */ - -static void expert_third_party_modules(void) -{ - enum return_type results; - char * floppy_mount_location = "/tmp/floppy"; - char ** modules; - char final_name[500]; - char * choice; - int rc; - char * questions[] = { "Options", NULL }; - static char ** answers = NULL; - - results = ask_yes_no("If you want to insert third-party kernel modules, insert " - "a Linux (ext2fs) formatted floppy containing the modules and confirm. Otherwise, select \"no\".");; - if (results != RETURN_OK) - return; - - if (my_mount(floppy_device(), floppy_mount_location, "ext2", 0) == -1) { - stg1_error_message("I can't find a Linux ext2 floppy in first floppy drive."); - return expert_third_party_modules(); - } - - modules = list_directory(floppy_mount_location); - - if (!modules || !*modules) { - stg1_error_message("No modules found on floppy disk."); - umount(floppy_mount_location); - return expert_third_party_modules(); - } - - results = ask_from_list("Which driver would you like to insmod?", modules, &choice); - if (results != RETURN_OK) { - umount(floppy_mount_location); - return; - } - - sprintf(final_name, "%s/%s", floppy_mount_location, choice); - - results = ask_from_entries("Please enter the options:", questions, &answers, 24, NULL); - if (results != RETURN_OK) { - umount(floppy_mount_location); - return expert_third_party_modules(); - } - - rc = insmod_local_file(final_name, answers[0]); - umount(floppy_mount_location); - - if (rc) { - log_message("\tfailed"); - stg1_error_message("Insmod failed."); - } - - return expert_third_party_modules(); } +#endif #ifdef ENABLE_PCMCIA 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) { 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("ds", ANY_DRIVER_TYPE, NULL, 0); + my_modprobe("pcmcia_core", ANY_DRIVER_TYPE, NULL); + my_modprobe(pcmcia_adapter, ANY_DRIVER_TYPE, NULL); + /* ds is an alias for pcmcia in recent 2.6 kernels + but we don't have modules.alias in install, so try to load both */ + my_modprobe("ds", ANY_DRIVER_TYPE, NULL); + my_modprobe("pcmcia", ANY_DRIVER_TYPE, NULL); - /* call to cardmgr takes time, let's use the wait message */ - wait_message("Enabling PCMCIA extension cards..."); - log_message("cardmgr rc: %d", cardmgr_call()); - remove_wait_message(); - - if (IS_EXPERT) - expert_third_party_modules(); + /* setup a dynamic resource database for non statically mapped PCMCIA sockets */ + pcmcia_socket_startup(-1); - add_to_env("PCMCIA", pcmcia_adapter); + add_to_env("PCMCIA", pcmcia_adapter); } #endif +#ifndef ENABLE_NETWORK_STANDALONE +static void handle_hid(void) +{ + struct hid_entries entry_list; + unsigned int i; + + entry_list = hid_probe(); + for (i = 0; i < entry_list.nb; i++) { + if (entry_list.entries[i].module != NULL) + my_modprobe(entry_list.entries[i].module, ANY_DRIVER_TYPE, NULL); + } + my_modprobe("hid_generic", ANY_DRIVER_TYPE, NULL); +} + /************************************************************ */ @@ -327,24 +274,32 @@ static void method_select_and_prepare(void) char * network_nfs_install = "NFS server"; char * network_nfs_install_auto = "nfs"; char * network_ftp_install = "FTP server"; char * network_ftp_install_auto = "ftp"; char * network_http_install = "HTTP server"; char * network_http_install_auto = "http"; +#ifndef DISABLE_KA + char * network_ka_install = "KA server"; char * network_ka_install_auto = "ka"; +#endif #endif + char * thirdparty_install = "Load third party modules"; char * thirdparty_install_auto = "thirdparty"; i = 0; #ifndef DISABLE_NETWORK means[i] = network_nfs_install; means_auto[i++] = network_nfs_install_auto; means[i] = network_ftp_install; means_auto[i++] = network_ftp_install_auto; means[i] = network_http_install; means_auto[i++] = network_http_install_auto; +#ifndef DISABLE_KA + means[i] = network_ka_install; means_auto[i++] = network_ka_install_auto; +#endif #endif #ifndef DISABLE_CDROM means[i] = cdrom_install; means_auto[i++] = cdrom_install_auto; - allow_additional_modules_floppy = 0; #endif #ifndef DISABLE_DISK means[i] = disk_install; means_auto[i++] = disk_install_auto; - allow_additional_modules_floppy = 0; #endif + means[i] = thirdparty_install; means_auto[i++] = thirdparty_install_auto; means[i] = NULL; + unlink(IMAGE_LOCATION); + results = ask_from_list_auto("Please choose the installation method.", means, &choice, "method", means_auto); if (results != RETURN_OK) @@ -363,275 +318,93 @@ static void method_select_and_prepare(void) #ifndef DISABLE_NETWORK if (!strcmp(choice, network_nfs_install)) results = nfs_prepare(); - + if (!strcmp(choice, network_ftp_install)) results = ftp_prepare(); if (!strcmp(choice, network_http_install)) results = http_prepare(); + +#ifndef DISABLE_KA + if (!strcmp(choice, network_ka_install)) + results = ka_prepare(); +#endif #endif - if (results != RETURN_OK) + if (!strcmp(choice, thirdparty_install)) { + thirdparty_load_modules(); return method_select_and_prepare(); -} - -enum return_type create_initial_fs(char* symlinks, char* devices) -{ - FILE *f; - char buf[5000]; - - 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); - - // 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; - if (access(clp, R_OK)) { - log_message("no %s found (or disabled), trying to fallback on plain tree", clp); - if (!access(live, R_OK)) { - if (scall(symlink(location_live, location_mount), "symlink")) - return RETURN_ERROR; - *is_symlink = 1; - return RETURN_OK; - } else { - log_message("move: can't find %s nor %s, proceeding hoping files will be there", clp, live); - return RETURN_OK; - } - } - - if (clp_tmpfs) { - int ret; - char buf[5000]; - sprintf(buf, "Loading (part %d)...", ++count); - init_progression(buf, file_size(clp)); - ret = copy_file(clp, clp_tmpfs, update_progression); - end_progression(); - if (ret != RETURN_OK) - return ret; - clp = clp_tmpfs; - } - - if (lomount(clp, location_mount, NULL, 1)) { - stg1_error_message("Could not mount compressed loopback :(."); - return RETURN_ERROR; - } - - return RETURN_OK; -} - -int mandrake_move_post(void) -{ - int boot__real_is_symlink_to_raw = 0; - int always__real_is_symlink_to_raw = 0; - int totem__real_is_symlink_to_raw = 0; - int main__real_is_symlink_to_raw = 0; - - if (handle_clp(IMAGE_LOCATION "/live_tree_boot.clp", IMAGE_LOCATION "/live_tree_boot/usr/bin/runstage2.pl", - IMAGE_LOCATION "/live_tree_boot", BOOT_LOCATION, - &boot__real_is_symlink_to_raw, SLASH_LOCATION "/live_tree_boot.clp") != RETURN_OK) - return RETURN_ERROR; - - if (handle_clp(IMAGE_LOCATION "/live_tree_always.clp", IMAGE_LOCATION "/live_tree_always/bin/bash", - IMAGE_LOCATION "/live_tree_always", ALWAYS_LOCATION, - &always__real_is_symlink_to_raw, SLASH_LOCATION "/live_tree_always.clp") != RETURN_OK) - return RETURN_ERROR; - - if (handle_clp(IMAGE_LOCATION "/live_tree_totem.clp", IMAGE_LOCATION "/live_tree_totem/usr/bin/totem", - IMAGE_LOCATION "/live_tree_totem", TOTEM_LOCATION, - &totem__real_is_symlink_to_raw, SLASH_LOCATION "/live_tree_totem.clp") != RETURN_OK) - return RETURN_ERROR; - - if (handle_clp(IMAGE_LOCATION "/live_tree.clp", IMAGE_LOCATION "/live_tree/etc/fstab", - IMAGE_LOCATION "/live_tree", IMAGE_LOCATION_REAL, - &main__real_is_symlink_to_raw, NULL) != RETURN_OK) - return RETURN_ERROR; - - // 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); - - // hardcoded :( - if (!access(TOTEM_LOCATION, R_OK)) { - if (scall(symlink("/image_totem/usr", SLASH_LOCATION "/usr"), "symlink")) - 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(STAGE2_LOCATION_REL "/usr", SLASH_LOCATION "/usr"), "symlink")) - return RETURN_ERROR; - - if (create_initial_fs(IMAGE_LOCATION_REAL "/move/symlinks", IMAGE_LOCATION_REAL "/move/devices") != RETURN_OK) - return RETURN_ERROR; - - if (boot__real_is_symlink_to_raw) { - if (scall(unlink(BOOT_LOCATION), "unlink")) - return RETURN_ERROR; - if (scall(symlink(RAW_LOCATION_REL "/live_tree_boot", BOOT_LOCATION), "symlink")) - return RETURN_ERROR; } - if (always__real_is_symlink_to_raw) { - if (scall(unlink(ALWAYS_LOCATION), "unlink")) - return RETURN_ERROR; - if (scall(symlink(RAW_LOCATION_REL "/live_tree_always", ALWAYS_LOCATION), "symlink")) - return RETURN_ERROR; - } - - if (totem__real_is_symlink_to_raw) { - if (scall(unlink(TOTEM_LOCATION), "unlink")) - return RETURN_ERROR; - if (scall(symlink(RAW_LOCATION_REL "/live_tree_totem", TOTEM_LOCATION), "symlink")) - return RETURN_ERROR; - } + if (results != RETURN_OK) + return method_select_and_prepare(); - if (main__real_is_symlink_to_raw) { - if (scall(unlink(IMAGE_LOCATION_REAL), "unlink")) - return RETURN_ERROR; - if (scall(symlink(RAW_LOCATION_REL "/live_tree", IMAGE_LOCATION_REAL), "symlink")) - return RETURN_ERROR; - } - return RETURN_OK; + /* try to find third party modules on the install media */ + thirdparty_load_media_modules(); } #endif -int do_pivot_root(void) -{ - int fd; - char rootdev[] = "0x0100"; - - if (IS_DEBUGSTAGE1) - while (1); - - 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; - if (scall(write(fd, rootdev, strlen(rootdev)) != (signed)strlen(rootdev), "write")) { - close(fd); - return RETURN_ERROR; - } - close(fd); - - if (scall(mkdir(SLASH_LOCATION "/stage1", 0755), "mkdir")) - return RETURN_ERROR; - - if (scall(pivot_root(SLASH_LOCATION, SLASH_LOCATION "/stage1"), "pivot_root")) - return RETURN_ERROR; - - 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."); - } - - +#ifdef SPAWN_SHELL if (shell_pid != 0) { - int fd; + int fd; + const char *clear = "\033[H\033[J"; kill(shell_pid, 9); + log_message("killed shell"); fd = open("/dev/tty2", O_RDWR); - write(fd, "Killed\n", 7); - close(fd); + write(fd, clear, strlen(clear)); + close(fd); } +#endif } int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)), char **env) { - if (getenv("DEBUGSTAGE1")) - set_param(MODE_TESTING); +#ifdef ENABLE_NETWORK_STANDALONE + open_log(); + init_frontend(""); - if (!IS_TESTING) { - 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); - } + unlink("/etc/resolv.conf"); /* otherwise it is read-only */ + set_param(MODE_AUTOMATIC); + grab_automatic_params("network:dhcp"); + intf_select_and_up(); + finish_frontend(); + return 0; +#else + if (getenv("DEBUGSTAGE1")) { + set_param(MODE_DEBUGSTAGE1); + set_param(MODE_TESTING); + } + +#ifdef SPAWN_INTERACTIVE spawn_interactive(); +#endif open_log(); - log_message("welcome to the " DISTRIB_NAME " install (mdk-stage1, version " VERSION " built " __DATE__ " " __TIME__")"); + log_message("welcome to the " DISTRIB_NAME " install (mdk-stage1, version " DISTRIB_VERSION " built " __DATE__ " " __TIME__")"); process_cmdline(); #ifdef SPAWN_SHELL spawn_shell(); #endif init_modules_insmoding(); - init_frontend("Welcome to " DISTRIB_NAME -#ifdef MANDRAKE_MOVE - ", " -#else - " (" VERSION ") " -#endif - __DATE__ " " __TIME__); + init_frontend("Welcome to " DISTRIB_DESCR ", " __DATE__ " " __TIME__); - if (IS_EXPERT) - expert_third_party_modules(); + probe_that_type(VIRTIO_DEVICES, BUS_ANY); - if (IS_UPDATEMODULES) - update_modules(); + /* load usb interface as soon as possible, helps usb mouse detection in stage2 */ + probe_that_type(USB_CONTROLLERS, BUS_USB); + + if (IS_THIRDPARTY) + thirdparty_load_modules(); #ifdef ENABLE_PCMCIA if (!IS_NOAUTO) handle_pcmcia(); #endif - // load usb interface as soon as possible, helps usb mouse detection in stage2 */ - probe_that_type(USB_CONTROLLERS, BUS_USB); + handle_hid(); if (IS_CHANGEDISK) stg1_info_message("You are starting the installation with an alternate booting method. " @@ -644,34 +417,27 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)) "your own risk. Alternatively, you may reboot your system now."); } -#ifdef MANDRAKE_MOVE - if (total_memory() < MEM_LIMIT_MOVE) - stg1_info_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()); -#endif + method_select_and_prepare(); -#ifndef DISABLE_DISK - if (IS_RECOVERY && streq(get_auto_value("method"), "cdrom")) { - if (!process_recovery()) - method_select_and_prepare(); - } else -#endif - method_select_and_prepare(); + thirdparty_destroy(); - if (!IS_RAMDISK) - if (symlink(IMAGE_LOCATION_REAL LIVE_LOCATION, STAGE2_LOCATION) != 0) - log_perror("symlink from " IMAGE_LOCATION_REAL LIVE_LOCATION " to " STAGE2_LOCATION " failed"); + if (access(STAGE2_LOCATION, R_OK) != 0) + if (symlink(IMAGE_LOCATION_REL "/" LIVE_LOCATION_REL, STAGE2_LOCATION) != 0) + log_perror("symlink from " IMAGE_LOCATION_REL "/" LIVE_LOCATION_REL " to " STAGE2_LOCATION " failed"); +#ifdef SPAWN_INTERACTIVE if (interactive_pid != 0) kill(interactive_pid, 9); +#endif finish_preparing(); finish_frontend(); close_log(); - if (IS_TESTING) - return 0; - else - return 66; + if (IS_RESCUE) + return 66; /* ask init to exec new init */ + + return 0; +#endif } |
