summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdk-stage1/Makefile2
-rw-r--r--mdk-stage1/cdrom.c2
-rw-r--r--mdk-stage1/config-stage1.h10
-rw-r--r--mdk-stage1/init.c8
-rw-r--r--mdk-stage1/stage1.c110
-rw-r--r--mdk-stage1/tools.c9
-rw-r--r--mdk-stage1/tools.h2
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
{