From 75dbadee24b0bd6b738093b66f8415a630692671 Mon Sep 17 00:00:00 2001 From: Guillaume Cottenceau Date: Mon, 11 Dec 2000 15:10:33 +0000 Subject: week-end stuff: now supports second stage as a ramdisk adds better device files handling (some in initrd, others dynamically created) better logging of detected IDE and SCSI devices --- mdk-stage1/Makefile | 5 +- mdk-stage1/cdrom.c | 13 +- mdk-stage1/disk.c | 3 +- mdk-stage1/log.c | 19 ++- mdk-stage1/log.h | 2 + mdk-stage1/modules.c | 3 +- mdk-stage1/mount.c | 81 ++++++++++- mdk-stage1/newt-frontend.c | 2 +- mdk-stage1/probing.c | 9 +- mdk-stage1/probing.h | 2 +- mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 | Bin 346027 -> 345007 bytes mdk-stage1/stage1.c | 105 ++++---------- mdk-stage1/stage1.h | 36 +++-- mdk-stage1/tools.c | 177 ++++++++++++++++++++++++ mdk-stage1/tools.h | 6 +- 15 files changed, 341 insertions(+), 122 deletions(-) (limited to 'mdk-stage1') diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile index 7e02acb78..793c707c7 100644 --- a/mdk-stage1/Makefile +++ b/mdk-stage1/Makefile @@ -27,7 +27,7 @@ ARCH := $(patsubst sparc%,sparc,$(ARCH)) #- We can leave "-g" forever since stripping will remove everything -CFLAGS = -Os -g -Wall -Werror -fomit-frame-pointer +CFLAGS = -Os -g -Wall -Werror # -fomit-frame-pointer INCLUDES = -I. DEFS = -D_GNU_SOURCE=1 -DVERSION=\"$(VERSION)\" @@ -104,6 +104,9 @@ stage1-network-diet: $(STAGE1OBJS) stage1-network.o $(NETOBJS) gcc -nostdlib -o $@ ../../../tmp/dietlibc/start.o $^ ../../../tmp/dietlibc/dietlibc.a strip -s $@ +test: stage1-network.o $(STAGE1OBJS) $(NETOBJS) + $(CC) -o st1 $^ + .c.o: $(COMPILE) -c $< diff --git a/mdk-stage1/cdrom.c b/mdk-stage1/cdrom.c index 1ac84979c..7a43e8ccc 100644 --- a/mdk-stage1/cdrom.c +++ b/mdk-stage1/cdrom.c @@ -59,10 +59,13 @@ static enum return_type try_with_device(char *dev_name) } log_message("found a Linux-Mandrake CDROM, good news!"); -/* - if (special_stage2 || total_memory() > 52 * 1024) loadMdkinstStage2(); - if (rescue) umount("/tmp/rhimage"); -*/ + + if (IS_SPECIAL_STAGE2 || ramdisk_possible()) + load_ramdisk(); /* we don't care about return code, we'll do it live if we failed */ + + if (IS_RESCUE) umount("/tmp/image"); /* TOCHECK */ + + method_name = strdup("cdrom"); return RETURN_OK; } @@ -82,7 +85,6 @@ enum return_type cdrom_prepare(void) ptr = medias; while (ptr && *ptr) { - log_message("have CDROM %s", *ptr); count++; ptr++; } @@ -96,7 +98,6 @@ enum return_type cdrom_prepare(void) } if (count == 1) { - log_message("Only one CDROM detected: %s (%s)", *medias, *medias_models); results = try_with_device(*medias); if (results == RETURN_OK) return RETURN_OK; diff --git a/mdk-stage1/disk.c b/mdk-stage1/disk.c index e64782471..58658fc3c 100644 --- a/mdk-stage1/disk.c +++ b/mdk-stage1/disk.c @@ -32,6 +32,8 @@ static enum return_type try_with_device(char *dev_name) { + /* I have to do the partition check here */ + return RETURN_OK; } @@ -48,7 +50,6 @@ enum return_type disk_prepare(void) medias = get_medias(DISK, QUERY_NAME); - /* TODO partition check */ ptr = medias; while (ptr && *ptr) { log_message("found DISK %s", *ptr); diff --git a/mdk-stage1/log.c b/mdk-stage1/log.c index 173ebe520..8faa166c0 100644 --- a/mdk-stage1/log.c +++ b/mdk-stage1/log.c @@ -65,9 +65,26 @@ void log_message(const char * s, ...) void log_perror(char *msg) { - log_message("%s %s", strerror(errno), msg); + log_message("%s: %s", msg, strerror(errno)); } +void log_progression(int divide_for_count) +{ + static int count = 0; + if (count <= 0) { + fprintf(logfile, "."); + fflush(logfile); + count = divide_for_count; + } + else + count--; +} + +void log_progression_done(void) +{ + fprintf(logfile, "done\n"); +} + void open_log(void) { diff --git a/mdk-stage1/log.h b/mdk-stage1/log.h index 65e0a2416..7e206c881 100644 --- a/mdk-stage1/log.h +++ b/mdk-stage1/log.h @@ -29,6 +29,8 @@ void log_message(const char * s, ...); void vlog_message(const char * s, va_list args); void vlog_message_nobs(const char * s, va_list args); void log_perror(char *msg); +void log_progression(int divide_for_count); +void log_progression_done(void); void open_log(void); void close_log(void); diff --git a/mdk-stage1/modules.c b/mdk-stage1/modules.c index cdf50d9eb..70bdc4a9f 100644 --- a/mdk-stage1/modules.c +++ b/mdk-stage1/modules.c @@ -198,6 +198,5 @@ int my_insmod(char * mod_name) enum return_type ask_scsi_insmod(void) { - error_message("Try to load a SCSI module"); - return RETURN_OK; + return ask_yes_no("Try to load a SCSI module"); } diff --git a/mdk-stage1/mount.c b/mdk-stage1/mount.c index 9a5dfca55..ef0c0f676 100644 --- a/mdk-stage1/mount.c +++ b/mdk-stage1/mount.c @@ -30,16 +30,88 @@ #include "mount.h" +/* WARNING: this won't work if the argument is not /dev/ based */ +static int ensure_dev_exists(char *dev) +{ + int major, minor; + int type = S_IFBLK; /* my default type is block. don't forget to change for chars */ + char * name; + struct stat buf; + + name = &dev[5]; /* we really need that dev be passed as /dev/something.. */ + + if (!stat(dev, &buf)) + return 0; /* if the file already exists, we assume it's correct */ + + if (name[0] == 's' && name[1] == 'd') { + /* SCSI disks */ + major = 8; + minor = (name[2] - 'a') << 4; + if (name[3] && name[4]) + minor += 10 + (name[4] - '0'); + else if (name[3]) + minor += (name[3] - '0'); + } else if (name[0] == 'h' && name[1] == 'd') { + /* IDE disks/cd's */ + if (name[2] == 'a') + major = 3, minor = 0; + else if (name[2] == 'b') + major = 3, minor = 64; + else if (name[2] == 'c') + major = 22, minor = 0; + else if (name[2] == 'd') + major = 22, minor = 64; + else if (name[2] == 'e') + major = 33, minor = 0; + else if (name[2] == 'f') + major = 33, minor = 64; + else if (name[2] == 'g') + major = 34, minor = 0; + else if (name[2] == 'h') + major = 34, minor = 64; + else + return -1; + + if (name[3] && name[4]) + minor += 10 + (name[4] - '0'); + else if (name[3]) + minor += (name[3] - '0'); + } else if (name[0] == 's' && name[1] == 'c' && name[2] == 'd') { + /* SCSI cd's */ + major = 11; + minor = name[3] - '0'; + } else { + log_message("I don't know how to create device %s, please post bugreport to me!", dev); + return -1; + } + + if (mknod(dev, type | 0600, makedev(major, minor))) { + log_perror(dev); + return -1; + } + + return 0; +} + + +/* mounts, creating the device if needed+possible */ int my_mount(char *dev, char *location, char *fs) { unsigned long flags; char * opts = NULL; struct stat buf; + int rc; + + rc = ensure_dev_exists(dev); + + if (rc != 0) { + log_message("could not create required device file"); + return -1; + } log_message("mounting %s on %s as type %s", dev, location, fs); if (stat(location, &buf)) { - log_message("creating dir %s", location); if (mkdir(location, 0755)) { log_message("could not create location dir"); return -1; @@ -64,5 +136,10 @@ int my_mount(char *dev, char *location, char *fs) if (!strcmp(fs, "iso9660")) flags |= MS_RDONLY; - return mount(dev, location, fs, flags, opts); + rc = mount(dev, location, fs, flags, opts); + + if (rc != 0) + log_perror(dev); + + return rc; } diff --git a/mdk-stage1/newt-frontend.c b/mdk-stage1/newt-frontend.c index 9321108d6..2114cbc70 100644 --- a/mdk-stage1/newt-frontend.c +++ b/mdk-stage1/newt-frontend.c @@ -61,7 +61,7 @@ void error_message(char *msg) void wait_message(char *msg, ...) { - int width = 36; + int width = strlen(msg) + 12; int height = 3; char * title = "Please wait..."; newtComponent t, f; diff --git a/mdk-stage1/probing.c b/mdk-stage1/probing.c index e2bd61aae..0a012ad95 100644 --- a/mdk-stage1/probing.c +++ b/mdk-stage1/probing.c @@ -47,7 +47,7 @@ static void pci_probing(enum driver_type type) if (IS_EXPERT) { error_message("You should be asked if you have some SCSI."); } else { - wait_message("Installing SCSI module..."); + wait_message("Installing SCSI module..."); sleep(1); remove_wait_message(); } } @@ -127,11 +127,11 @@ static void find_media(void) tmp[count].model = strdup(buf); } + log_message("IDE/%d: %s is a %s", tmp[count].type, tmp[count].name, tmp[count].model); tmp[count].bus = IDE; count++; } - log_message("found %d IDE media", count); /* ----------------------------------------------- */ @@ -215,7 +215,7 @@ static void find_media(void) while (*chptr == ' ') chptr--; *(chptr + 1) = '\0'; - strcat(tmp_model, ", "); + strcat(tmp_model, " "); strcat(tmp_model, start); tmp[count].model = strdup(tmp_model); @@ -242,6 +242,7 @@ static void find_media(void) if (*tmp_name) { tmp[count].name = strdup(tmp_name); + log_message("SCSI/%d: %s is a %s", tmp[count].type, tmp[count].name, tmp[count].model); tmp[count].bus = SCSI; count++; } @@ -255,8 +256,6 @@ static void find_media(void) end_scsi: } - log_message("adding SCSI totals %d media", count); - /* ----------------------------------------------- */ tmp[count].name = NULL; diff --git a/mdk-stage1/probing.h b/mdk-stage1/probing.h index ee221f01b..8fe43251e 100644 --- a/mdk-stage1/probing.h +++ b/mdk-stage1/probing.h @@ -22,7 +22,7 @@ #ifndef _PROBING_H_ #define _PROBING_H_ -enum media_type { DISK, FLOPPY, CDROM, TAPE, UNKNOWN_MEDIA }; +enum media_type { CDROM, DISK, FLOPPY, TAPE, UNKNOWN_MEDIA }; enum bus_type { IDE, SCSI }; diff --git a/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 b/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 index 52c15a238..5deeaa266 100644 Binary files a/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 and b/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 differ diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index f984b3058..04cba80e7 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -38,7 +38,7 @@ #include "probing.h" #include "frontend.h" #include "modules.h" - +#include "tools.h" #include "cdrom.h" #include "network.h" #include "disk.h" @@ -46,74 +46,16 @@ /* globals */ -struct cmdline_elem params[500]; -int stage1_mode = 0; char * method_name; void fatal_error(char *msg) { - printf("FATAL ERROR IN STAGE1: %s\n\nI can't recover from this, please reboot manually and send bugreport.\n", msg); + printf("FATAL ERROR IN STAGE1: %s\n\nI can't recover from this.\n", msg); while (1); } -void process_cmdline(void) -{ - char buf[512]; - int fd, size, i, p; - - log_message("opening /proc/cmdline... "); - - if ((fd = open("/proc/cmdline", O_RDONLY, 0)) == -1) - fatal_error("could not open /proc/cmdline"); - - size = read(fd, buf, sizeof(buf)); - buf[size-1] = 0; - close(fd); - - log_message("\t%s", buf); - - i = 0; p = 0; - while (buf[i] != 0) { - char *name, *value = NULL; - int j = i; - while (buf[i] != ' ' && buf[i] != '=' && buf[i] != 0) - i++; - if (i == j) { - i++; - continue; - } - name = (char *) malloc(i-j + 1); - memcpy(name, &buf[j], i-j); - name[i-j] = 0; - - if (buf[i] == '=') { - int k = i+1; - i++; - while (buf[i] != ' ' && buf[i] != 0) - i++; - value = (char *) malloc(i-k + 1); - memcpy(value, &buf[k], i-k); - value[i-k] = 0; - } - - params[p].name = name; - params[p].value = value; - p++; - i++; - if (!strcmp(name, "expert")) stage1_mode |= MODE_EXPERT; - if (!strcmp(name, "text")) stage1_mode |= MODE_TEXT; - if (!strcmp(name, "rescue")) stage1_mode |= MODE_RESCUE; - if (!strcmp(name, "pcmcia")) stage1_mode |= MODE_PCMCIA; - if (!strcmp(name, "cdrom")) stage1_mode |= MODE_CDROM; - } - params[p].name = NULL; - - log_message("\tgot %d args", p); -} - - /* spawns a shell on console #2 */ void spawn_shell(void) { @@ -184,17 +126,20 @@ enum return_type method_select_and_prepare(void) return results; if (!strcmp(choice, cdrom_install)) - return cdrom_prepare(); + results = cdrom_prepare(); else if (!strcmp(choice, disk_install)) - return disk_prepare(); + results = disk_prepare(); else if (!strcmp(choice, network_nfs_install)) - return nfs_prepare(); + results = nfs_prepare(); else if (!strcmp(choice, network_ftp_install)) - return ftp_prepare(); + results = ftp_prepare(); else if (!strcmp(choice, network_http_install)) - return http_prepare(); + results = http_prepare(); + + if (results != RETURN_OK) + method_select_and_prepare(); - return RETURN_ERROR; + return RETURN_OK; } @@ -204,51 +149,49 @@ int main(int argc, char **argv) char ** argptr; char * stage2_args[30]; - if (getpid() > 50) - stage1_mode |= MODE_TESTING; + set_param(MODE_TESTING); open_log(); - log_message("welcome to the Linux-Mandrake install (stage1, version " VERSION " built " __DATE__ " " __TIME__")"); - process_cmdline(); spawn_shell(); if (load_modules_dependencies()) fatal_error("could not open and parse modules dependencies"); - init_frontend(); - if (IS_CDROM) + if (IS_CDROM) { + /* try as automatic as possible with cdrom bootdisk */ ret = cdrom_prepare(); + if (ret != RETURN_OK) + ret = method_select_and_prepare(); + } else ret = method_select_and_prepare(); - while (ret == RETURN_BACK) - ret = method_select_and_prepare(); - finish_frontend(); + close_log(); - if (ret == RETURN_ERROR) + if (ret != RETURN_OK) fatal_error("could not select an installation method"); - if (!IS_LIVE) { + if (!IS_RAMDISK) { if (symlink("/tmp/image/Mandrake/mdkinst", "/tmp/stage2") != 0) fatal_error("symlink to /tmp/stage2 failed"); } - close_log(); + if (IS_TESTING) + return 0; argptr = stage2_args; *argptr++ = "/usr/bin/runinstall2"; - *argptr++ = "--method"; *argptr++ = method_name; *argptr++ = NULL; execv(stage2_args[0], stage2_args); - printf("error in exec of stage2 :-("); + printf("error in exec of stage2 :-(\n"); fatal_error(strerror(errno)); - return 0; /* shut up compiler (we can't get here) */ + return 0; /* shut up compiler (we can't get here anyway!) */ } diff --git a/mdk-stage1/stage1.h b/mdk-stage1/stage1.h index 2f193a065..d224babea 100644 --- a/mdk-stage1/stage1.h +++ b/mdk-stage1/stage1.h @@ -22,21 +22,14 @@ #ifndef _STAGE1_H_ #define _STAGE1_H_ +#include "config-stage1.h" +#include "tools.h" -/* Some global stuff */ - -struct cmdline_elem -{ - char * name; - char * value; -}; - -extern struct cmdline_elem params[500]; +/* Some global stuff */ enum return_type { RETURN_OK, RETURN_BACK, RETURN_ERROR }; -extern int stage1_mode; extern char * method_name; #define MODE_TESTING (1 << 0) @@ -47,16 +40,19 @@ extern char * method_name; #define MODE_PCMCIA (1 << 5) #define MODE_CDROM (1 << 6) #define MODE_LIVE (1 << 7) - -#define IS_TESTING ((stage1_mode) & MODE_TESTING) -#define IS_EXPERT ((stage1_mode) & MODE_EXPERT) -#define IS_TEXT ((stage1_mode) & MODE_TEXT) -#define IS_RESCUE ((stage1_mode) & MODE_RESCUE) -#define IS_KICKSTART ((stage1_mode) & MODE_KICKSTART) -#define IS_PCMCIA ((stage1_mode) & MODE_PCMCIA) -#define IS_CDROM ((stage1_mode) & MODE_CDROM) -#define IS_LIVE ((stage1_mode) & MODE_LIVE) - +#define MODE_SPECIAL_STAGE2 (1 << 8) +#define MODE_RAMDISK (1 << 9) + +#define IS_TESTING (get_param(MODE_TESTING)) +#define IS_EXPERT (get_param(MODE_EXPERT)) +#define IS_TEXT (get_param(MODE_TEXT)) +#define IS_RESCUE (get_param(MODE_RESCUE)) +#define IS_KICKSTART (get_param(MODE_KICKSTART)) +#define IS_PCMCIA (get_param(MODE_PCMCIA)) +#define IS_CDROM (get_param(MODE_CDROM)) +#define IS_LIVE (get_param(MODE_LIVE)) +#define IS_SPECIAL_STAGE2 (get_param(MODE_SPECIAL_STAGE2)) +#define IS_RAMDISK (get_param(MODE_RAMDISK)) void fatal_error(char *msg); diff --git a/mdk-stage1/tools.c b/mdk-stage1/tools.c index e07fcd347..71516b354 100644 --- a/mdk-stage1/tools.c +++ b/mdk-stage1/tools.c @@ -26,11 +26,109 @@ #include #include #include +#include #include "stage1.h" #include "log.h" +#include "mount.h" +#include "frontend.h" #include "tools.h" + +struct cmdline_elem +{ + char * name; + char * value; +}; + +struct cmdline_elem * params; + +void process_cmdline(void) +{ + char buf[512]; + int fd, size, i, p; + struct cmdline_elem tmp_params[50]; + + log_message("opening /proc/cmdline... "); + + if ((fd = open("/proc/cmdline", O_RDONLY, 0)) == -1) + fatal_error("could not open /proc/cmdline"); + + size = read(fd, buf, sizeof(buf)); + buf[size-1] = 0; + close(fd); + + log_message("\t%s", buf); + + i = 0; p = 0; + while (buf[i] != 0) { + char *name, *value = NULL; + int j = i; + while (buf[i] != ' ' && buf[i] != '=' && buf[i] != 0) + i++; + if (i == j) { + i++; + continue; + } + name = (char *) malloc(i-j + 1); + memcpy(name, &buf[j], i-j); + name[i-j] = 0; + + if (buf[i] == '=') { + int k = i+1; + i++; + while (buf[i] != ' ' && buf[i] != 0) + i++; + value = (char *) malloc(i-k + 1); + memcpy(value, &buf[k], i-k); + value[i-k] = 0; + } + + tmp_params[p].name = name; + tmp_params[p].value = value; + p++; + i++; + if (!strcmp(name, "expert")) set_param(MODE_EXPERT); + if (!strcmp(name, "rescue")) set_param(MODE_RESCUE); + if (!strcmp(name, "pcmcia")) set_param(MODE_PCMCIA); + if (!strcmp(name, "cdrom")) set_param(MODE_CDROM); + if (!strcmp(name, "special_stage2")) set_param(MODE_SPECIAL_STAGE2); + } + tmp_params[p].name = NULL; + + params = (struct cmdline_elem *) malloc(sizeof(struct cmdline_elem) * (p+1)); + memcpy(params, tmp_params, sizeof(struct cmdline_elem) * (p+1)); + + log_message("\tgot %d args", p); +} + + +int stage1_mode = 0; + +int get_param(int i) +{ + return (stage1_mode & i); +} + +char * get_param_valued(char *param_name) +{ + struct cmdline_elem * ptr = params; + + while (ptr->name) { + if (!strcmp(ptr->name, param_name)) + return ptr->value; + ptr++; + } + + return NULL; +} + +void set_param(int i) +{ + stage1_mode |= i; +} + + int total_memory(void) { int fd; @@ -69,3 +167,82 @@ int total_memory(void) return memtotal; } + + +int ramdisk_possible(void) +{ + if (total_memory() > MEM_LIMIT_RAMDISK) + return 1; + else { + log_message("Warning, ramdisk is not possible due to low mem!"); + return 0; + } +} + + +enum return_type load_ramdisk(void) +{ + char * img_name; + gzFile st2; + char * ramdisk = "/dev/ram"; /* warning, verify that this file exists in the initrd (and actually is a ramdisk device file) */ + int ram_fd; + char buffer[4096]; + char * stg2_name = get_param_valued("special_stage2"); + char * begin_img = "/tmp/image/Mandrake/base/"; + char * end_img = "_stage2.gz"; + int gz_errnum; + + if (!stg2_name) + stg2_name = "mdkinst"; + + img_name = malloc(strlen(begin_img) + strlen(stg2_name) + strlen(end_img) + 1); + strcpy(img_name, begin_img); + strcat(img_name, stg2_name); + strcat(img_name, end_img); + + log_message("trying to load %s as a ramdisk", img_name); + + st2 = gzopen(img_name, "r"); + if (!st2) { + log_message("Opening compressed ramdisk: %s", gzerror(st2, &gz_errnum)); + error_message("Could not open compressed ramdisk file."); + return RETURN_ERROR; + } + + ram_fd = open(ramdisk, O_WRONLY); + if (ram_fd == -1) { + log_perror(ramdisk); + error_message("Could not open ramdisk device file."); + return RETURN_ERROR; + } + + wait_message("Loading Installation program into memory..."); + + while (!gzeof(st2)) { + int actually = gzread(st2, buffer, sizeof(buffer)); + if (actually != sizeof(buffer) && !gzeof(st2)) { + log_message("Reading compressed ramdisk: %s", gzerror(st2, &gz_errnum)); + remove_wait_message(); + return RETURN_ERROR; + } + if (write(ram_fd, buffer, actually) != actually) { + log_perror("Writing ramdisk"); + remove_wait_message(); + return RETURN_ERROR; + } + log_progression(100); + } + + log_progression_done(); + remove_wait_message(); + gzclose(st2); + close(ram_fd); + + if (my_mount(ramdisk, "/tmp/stage2", "ext2")) + return RETURN_ERROR; + + set_param(MODE_RAMDISK); + + return RETURN_OK; +} + diff --git a/mdk-stage1/tools.h b/mdk-stage1/tools.h index 21d09ec86..e975970c2 100644 --- a/mdk-stage1/tools.h +++ b/mdk-stage1/tools.h @@ -23,8 +23,12 @@ #define _TOOLS_H_ -/* returns value of MemTotal tag from /proc/meminfo */ +void process_cmdline(void); +int get_param(int i); +void set_param(int i); int total_memory(void); +int ramdisk_possible(void); +enum return_type load_ramdisk(void); #endif -- cgit v1.2.1