diff options
Diffstat (limited to 'mdk-stage1/stage1.c')
-rw-r--r-- | mdk-stage1/stage1.c | 301 |
1 files changed, 138 insertions, 163 deletions
diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index 44ed25155..94bb1e0df 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -1,9 +1,7 @@ /* - * Guillaume Cottenceau (gc@mandrakesoft.com) + * Guillaume Cottenceau (gc) * - * Copyright 2000-2001 MandrakeSoft - * - * View the homepage: http://people.mandrakesoft.com/~gc/html/stage1.html + * Copyright 2000-2004 Mandriva * * * This software may be freely redistributed under the terms of the GNU @@ -35,6 +33,8 @@ #include <ctype.h> #include <stdarg.h> #include <signal.h> +#include <linux/unistd.h> +#include <libldetect.h> #include "stage1.h" @@ -43,12 +43,13 @@ #include "frontend.h" #include "modules.h" #include "tools.h" +#include "utils.h" #include "automatic.h" #include "mount.h" -#include "insmod.h" +#include "thirdparty.h" #ifdef ENABLE_PCMCIA -#include "pcmcia_/pcmcia.h" +#include "pcmcia/pcmcia.h" #endif #ifndef DISABLE_CDROM @@ -67,8 +68,6 @@ /************************************************************ * globals */ -char * method_name; -char * stage2_kickstart = NULL; void fatal_error(char *msg) @@ -86,12 +85,21 @@ 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); } +void stg1_fatal_message(char *msg, ...) +{ + va_list args; + va_start(args, msg); + unset_automatic(); + verror_message(msg, args); + va_end(args); + exit(1); +} + void stg1_info_message(char *msg, ...) { va_list args; @@ -105,13 +113,15 @@ void stg1_info_message(char *msg, ...) } +#ifdef SPAWN_SHELL +static pid_t shell_pid = 0; + /************************************************************ * spawns a shell on console #2 */ static void spawn_shell(void) { -#ifdef SPAWN_SHELL int fd; - char * shell_name[] = { "/tmp/sh", NULL }; + char * shell_name[] = { "/bin/sh", NULL }; log_message("spawning a shell"); @@ -126,7 +136,7 @@ static void spawn_shell(void) return; } - if (!fork()) { + if (!(shell_pid = fork())) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); @@ -136,24 +146,23 @@ 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); } close(fd); } -#endif } +#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"; @@ -184,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]; @@ -202,111 +211,53 @@ static void spawn_interactive(void) close(fd); } -#endif } +#endif -/************************************************************ - */ - -static void expert_third_party_modules(void) +#ifdef ENABLE_PCMCIA +static void handle_pcmcia(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; + char * pcmcia_adapter; - 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; - - my_insmod("floppy", ANY_DRIVER_TYPE, NULL); - - if (my_mount("/dev/fd0", 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); + pcmcia_adapter = pcmcia_probe(); + if (!pcmcia_adapter) { + log_message("no pcmcia adapter found"); return; } + 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); + + /* setup a dynamic resource database for non statically mapped PCMCIA sockets */ + pcmcia_socket_startup(-1); - 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_call(final_name, answers[0]); - umount(floppy_mount_location); - - if (rc) { - log_message("\tfailed"); - stg1_error_message("Insmod failed."); - } - - return expert_third_party_modules(); + add_to_env("PCMCIA", pcmcia_adapter); } +#endif - -#ifdef ENABLE_PCMCIA -static void handle_pcmcia(char ** pcmcia_adapter) +#ifndef ENABLE_NETWORK_STANDALONE +static void handle_hid(void) { - char buf[50]; - int fd = open("/proc/version", O_RDONLY); - int size; - if (fd == -1) - fatal_error("could not open /proc/version"); - size = read(fd, buf, sizeof(buf)); - buf[size-1] = '\0'; // -1 to eat the \n - close(fd); - buf[17] = '\0'; // enough to extract `2.2' - if (ptr_begins_static_str(buf+14, "2.2")) { - stg1_error_message("We now use kernel pcmcia support and this won't work with a 2.2 kernel."); - return; - } + struct hid_entries entry_list; + unsigned int i; - *pcmcia_adapter = pcmcia_probe(); - if (!*pcmcia_adapter) { - log_message("no pcmcia adapter found"); - return; + 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_insmod("pcmcia_core", ANY_DRIVER_TYPE, NULL); - my_insmod(*pcmcia_adapter, ANY_DRIVER_TYPE, NULL); - my_insmod("ds", 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(); + my_modprobe("hid_generic", ANY_DRIVER_TYPE, NULL); } -#endif /************************************************************ */ -static enum return_type method_select_and_prepare(void) +static void method_select_and_prepare(void) { enum return_type results; char * choice; @@ -323,13 +274,20 @@ static enum return_type 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; @@ -337,15 +295,16 @@ static enum return_type method_select_and_prepare(void) #ifndef DISABLE_DISK means[i] = disk_install; means_auto[i++] = disk_install_auto; #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) return method_select_and_prepare(); - results = RETURN_ERROR; - #ifndef DISABLE_CDROM if (!strcmp(choice, cdrom_install)) results = cdrom_prepare(); @@ -359,52 +318,93 @@ static enum return_type 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 (!strcmp(choice, thirdparty_install)) { + thirdparty_load_modules(); + return method_select_and_prepare(); + } if (results != RETURN_OK) return method_select_and_prepare(); - return RETURN_OK; + /* try to find third party modules on the install media */ + thirdparty_load_media_modules(); } +#endif +void finish_preparing(void) +{ +#ifdef SPAWN_SHELL + if (shell_pid != 0) { + 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, clear, strlen(clear)); + close(fd); + } +#endif +} int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)), char **env) { - enum return_type ret; - char ** argptr; - char * stage2_args[30]; -#ifdef ENABLE_PCMCIA - char * pcmcia_adapter = NULL; -#endif +#ifdef ENABLE_NETWORK_STANDALONE + open_log(); + init_frontend(""); + + unlink("/etc/resolv.conf"); /* otherwise it is read-only */ + set_param(MODE_AUTOMATIC); + grab_automatic_params("network:dhcp"); - if (getpid() > 50) + 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(); - handle_env(env); +#ifdef SPAWN_SHELL spawn_shell(); +#endif init_modules_insmoding(); - init_frontend("Welcome to " DISTRIB_NAME " (" VERSION ") " __DATE__ " " __TIME__); + init_frontend("Welcome to " DISTRIB_DESCR ", " __DATE__ " " __TIME__); + + probe_that_type(VIRTIO_DEVICES, BUS_ANY); - if (IS_EXPERT) - expert_third_party_modules(); + /* load usb interface as soon as possible, helps usb mouse detection in stage2 */ + probe_that_type(USB_CONTROLLERS, BUS_USB); - if (IS_UPDATEMODULES) - update_modules(); + if (IS_THIRDPARTY) + thirdparty_load_modules(); #ifdef ENABLE_PCMCIA - handle_pcmcia(&pcmcia_adapter); + if (!IS_NOAUTO) + handle_pcmcia(); #endif + + handle_hid(); if (IS_CHANGEDISK) stg1_info_message("You are starting the installation with an alternate booting method. " @@ -417,52 +417,27 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)) "your own risk. Alternatively, you may reboot your system now."); } - ret = method_select_and_prepare(); + method_select_and_prepare(); - finish_frontend(); - close_log(); - - if (ret != RETURN_OK) - fatal_error("could not select an installation method"); + thirdparty_destroy(); - if (!IS_RAMDISK) { - if (symlink(IMAGE_LOCATION LIVE_LOCATION, STAGE2_LOCATION) != 0) { - printf("symlink from " IMAGE_LOCATION LIVE_LOCATION " to " STAGE2_LOCATION " failed"); - fatal_error(strerror(errno)); - } - } + 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); - - if (IS_RESCUE) - 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 (disable_modules) - *argptr++ = "--blank"; - if (stage2_kickstart) { - *argptr++ = "--kickstart"; - *argptr++ = stage2_kickstart; - } - *argptr++ = NULL; - execve(stage2_args[0], stage2_args, grab_env()); + finish_preparing(); - 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!) */ + finish_frontend(); + close_log(); + + if (IS_RESCUE) + return 66; /* ask init to exec new init */ + + return 0; +#endif } |