summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/stage1.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/stage1.c')
-rw-r--r--mdk-stage1/stage1.c436
1 files changed, 102 insertions, 334 deletions
diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c
index e484f0f41..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();
+ /* setup a dynamic resource database for non statically mapped PCMCIA sockets */
+ pcmcia_socket_startup(-1);
- if (IS_EXPERT)
- expert_third_party_modules();
-
- 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,273 +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("");
- 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. "
@@ -642,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
}