diff options
-rw-r--r-- | mdk-stage1/Makefile | 2 | ||||
-rw-r--r-- | mdk-stage1/cdrom.c | 2 | ||||
-rw-r--r-- | mdk-stage1/config-stage1.h | 10 | ||||
-rw-r--r-- | mdk-stage1/init.c | 8 | ||||
-rw-r--r-- | mdk-stage1/stage1.c | 110 | ||||
-rw-r--r-- | mdk-stage1/tools.c | 9 | ||||
-rw-r--r-- | mdk-stage1/tools.h | 2 |
7 files changed, 113 insertions, 30 deletions
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile index 60fcf0830..727c1e2dc 100644 --- a/mdk-stage1/Makefile +++ b/mdk-stage1/Makefile @@ -47,7 +47,7 @@ top_dir = . include $(top_dir)/Makefile.common -DEFS = -DVERSION=\"$(VERSION)\" -DSPAWN_SHELL +DEFS = -DVERSION=\"$(VERSION)\" -DSPAWN_SHELL -DMANDRAKE_MOVE COMPILE = $(CC) $(DEFS) $(CFLAGS) diff --git a/mdk-stage1/cdrom.c b/mdk-stage1/cdrom.c index ba0341b30..6004ddf98 100644 --- a/mdk-stage1/cdrom.c +++ b/mdk-stage1/cdrom.c @@ -66,8 +66,10 @@ static enum return_type do_with_device(char * dev_name, char * dev_model) log_message("found a " DISTRIB_NAME " CDROM, good news!"); +#ifndef MANDRAKE_MOVE if (IS_SPECIAL_STAGE2 || ramdisk_possible()) load_ramdisk(); /* we don't care about return code, we'll do it live if we failed */ +#endif if (IS_RESCUE) umount(IMAGE_LOCATION); diff --git a/mdk-stage1/config-stage1.h b/mdk-stage1/config-stage1.h index 823694df2..75dfb838d 100644 --- a/mdk-stage1/config-stage1.h +++ b/mdk-stage1/config-stage1.h @@ -30,9 +30,17 @@ #define LIVE_LOCATION "/Mandrake/mdkinst/" #define RAMDISK_LOCATION "/Mandrake/base/" -#define IMAGE_LOCATION "/tmp/image" #define STAGE2_LOCATION "/tmp/stage2" +#ifdef MANDRAKE_MOVE +#define IMAGE_LOCATION "/sysroot/image" +#define SLASH_LOCATION "/sysroot" +#define LIVE_LOCATION_REL "/image/Mandrake/mdkinst" +#else +#define IMAGE_LOCATION "/tmp/image" +#endif + + /* user-definable (in Makefile): DISABLE_NETWORK, DISABLE_DISK, DISABLE_CDROM, DISABLE_PCMCIA */ diff --git a/mdk-stage1/init.c b/mdk-stage1/init.c index 1c7bb9e97..943d755d4 100644 --- a/mdk-stage1/init.c +++ b/mdk-stage1/init.c @@ -333,7 +333,7 @@ void unmount_filesystems(void) } } -int exit_value_rescue = 66; +int exit_value_proceed = 66; int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused))) { @@ -428,15 +428,15 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)) end_stage2 = 1; } - if (!WIFEXITED(wait_status) || (WEXITSTATUS(wait_status) != 0 && WEXITSTATUS(wait_status) != exit_value_rescue)) { + if (!WIFEXITED(wait_status) || (WEXITSTATUS(wait_status) != 0 && WEXITSTATUS(wait_status) != exit_value_proceed)) { printf("install exited abnormally :-( "); if (WIFSIGNALED(wait_status)) printf("-- received signal %d", WTERMSIG(wait_status)); printf("\n"); abnormal_termination = 1; - } else if (WIFEXITED(wait_status) && WEXITSTATUS(wait_status) == exit_value_rescue) { + } else if (WIFEXITED(wait_status) && WEXITSTATUS(wait_status) == exit_value_proceed) { kill(klog_pid, 9); - printf("exiting init -- giving hand to rescue\n"); + printf("exiting init -- proceeding\n"); return 0; } else printf("install succeeded\n"); diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index bc3b457e3..c411140a6 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -35,6 +35,8 @@ #include <ctype.h> #include <stdarg.h> #include <signal.h> +#include <linux/unistd.h> +_syscall2(int,pivot_root,const char *,new_root,const char *,put_old) #include "stage1.h" @@ -105,11 +107,13 @@ 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 }; @@ -126,7 +130,7 @@ static void spawn_shell(void) return; } - if (!fork()) { + if (!(shell_pid = fork())) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); @@ -143,8 +147,8 @@ static void spawn_shell(void) close(fd); } -#endif } +#endif char * interactive_fifo = "/tmp/stage1-fifo"; @@ -306,7 +310,7 @@ static void handle_pcmcia(char ** pcmcia_adapter) /************************************************************ */ -static enum return_type method_select_and_prepare(void) +static void method_select_and_prepare(void) { enum return_type results; char * choice; @@ -344,8 +348,6 @@ static enum return_type method_select_and_prepare(void) if (results != RETURN_OK) return method_select_and_prepare(); - results = RETURN_ERROR; - #ifndef DISABLE_CDROM if (!strcmp(choice, cdrom_install)) results = cdrom_prepare(); @@ -369,14 +371,65 @@ static enum return_type method_select_and_prepare(void) if (results != RETURN_OK) return method_select_and_prepare(); +} + +#ifdef MANDRAKE_MOVE +int mandrake_move_pre(void) +{ + log_message("move: creating %s directory and mounting as tmpfs", SLASH_LOCATION); + + if (scall(mkdir(SLASH_LOCATION, 0755), "mkdir")) + return RETURN_ERROR; + + if (scall(mount("none", SLASH_LOCATION, "tmpfs", MS_MGC_VAL, NULL), "mount tmpfs")) + return RETURN_ERROR; + + return RETURN_OK; +} - return RETURN_OK; +int mandrake_move_post(void) +{ + FILE *f; + char buf[5000]; + int fd; + char rootdev[] = "0x0100"; + + if (scall(!(f = fopen(IMAGE_LOCATION LIVE_LOCATION "symlinks", "rb")), "fopen")) + 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); + + log_message("move: 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; } +#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 @@ -392,7 +445,9 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)) 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 init_modules_insmoding(); init_frontend("Welcome to " DISTRIB_NAME " (" VERSION ") " __DATE__ " " __TIME__); @@ -418,30 +473,37 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)) "your own risk. Alternatively, you may reboot your system now."); } -#ifndef DISABLE_DISK - if (IS_RECOVERY && streq(get_auto_value("method"), "cdrom") && process_recovery()) - ret = RETURN_OK; - else +#ifdef MANDRAKE_MOVE + if (mandrake_move_pre() != RETURN_OK) + stg1_error_message("Fatal error when preparing Mandrake Move."); #endif - ret = method_select_and_prepare(); - - finish_frontend(); - close_log(); - if (ret != RETURN_OK) - fatal_error("could not select an installation method"); +#ifndef DISABLE_DISK + if (IS_RECOVERY && streq(get_auto_value("method"), "cdrom") && !process_recovery()) +#endif + method_select_and_prepare(); - 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 (!IS_RAMDISK) + if (symlink(IMAGE_LOCATION LIVE_LOCATION, STAGE2_LOCATION) != 0) + log_perror("symlink from " IMAGE_LOCATION LIVE_LOCATION " to " STAGE2_LOCATION " failed"); if (interactive_pid != 0) kill(interactive_pid, 9); +#ifdef MANDRAKE_MOVE + if (mandrake_move_post() != RETURN_OK) + stg1_error_message("Fatal error when launching Mandrake Move."); +#endif + + if (shell_pid != 0) + kill(shell_pid, 9); + + finish_frontend(); + close_log(); + +#ifndef MANDRAKE_MOVE if (IS_RESCUE) +#endif return 66; if (IS_TESTING) return 0; diff --git a/mdk-stage1/tools.c b/mdk-stage1/tools.c index 5faad8d88..89c87fbd1 100644 --- a/mdk-stage1/tools.c +++ b/mdk-stage1/tools.c @@ -435,3 +435,12 @@ int string_array_length(char ** a) } return i; } + +int scall_(int retval, char * msg, char * file, int line) +{ + char tmp[5000]; + sprintf(tmp, "%s(%s:%d) failed", msg, file, line); + if (retval) + log_perror(tmp); + return retval; +} diff --git a/mdk-stage1/tools.h b/mdk-stage1/tools.h index e168ebe9f..c6c9aea14 100644 --- a/mdk-stage1/tools.h +++ b/mdk-stage1/tools.h @@ -40,6 +40,8 @@ void handle_env(char ** env); char ** grab_env(void); char ** list_directory(char * direct); int string_array_length(char ** a); +int scall_(int retval, char * msg, char * file, int line); +#define scall(retval, msg) scall_(retval, msg, __FILE__, __LINE__) struct param_elem { |