diff options
Diffstat (limited to 'mdk-stage1/tools.c')
| -rw-r--r-- | mdk-stage1/tools.c | 495 | 
1 files changed, 190 insertions, 305 deletions
| diff --git a/mdk-stage1/tools.c b/mdk-stage1/tools.c index 9d0f083f6..2e27688ea 100644 --- a/mdk-stage1/tools.c +++ b/mdk-stage1/tools.c @@ -1,7 +1,7 @@  /* - * Guillaume Cottenceau (gc@mandrakesoft.com) + * Guillaume Cottenceau (gc)   * - * Copyright 2000 MandrakeSoft + * Copyright 2000 Mandriva   *   * This software may be freely redistributed under the terms of the GNU   * public license. @@ -21,16 +21,19 @@  #include <stdlib.h>  #include <unistd.h> +#include <sys/time.h>  #include <sys/types.h>  #include <sys/stat.h>  #include <fcntl.h>  #include <string.h> -#include <ctype.h>  #include <stdio.h>  #include <dirent.h>  #include <sys/types.h> -#include <bzlib.h>  #include <sys/mount.h> +#include <sys/poll.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <linux/fd.h>  #include "stage1.h"  #include "log.h"  #include "mount.h" @@ -38,373 +41,255 @@  #include "automatic.h"  #include "tools.h" +#include "utils.h" +#include "params.h" +#include "probing.h" +#include "modules.h" +#include "lomount.h" - -static struct param_elem params[50]; -static int param_number = 0; - -void process_cmdline(void) +int image_has_stage2()  { -	char buf[512]; -	int fd, size, i; -	 -	log_message("opening /proc/cmdline... "); -	 -	if ((fd = open("/proc/cmdline", O_RDONLY)) == -1) -		fatal_error("could not open /proc/cmdline"); -	 -	size = read(fd, buf, sizeof(buf)); -	buf[size-1] = '\0'; // -1 to eat the \n -	close(fd); - -	log_message("\t%s", buf); - -	i = 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 = memdup(&buf[j], i-j + 1); -		name[i-j] = '\0'; - -		if (buf[i] == '=') { -			int k = i+1; -			i++; -			while (buf[i] != ' ' && buf[i] != '\0') -				i++; -			value = memdup(&buf[k], i-k + 1); -			value[i-k] = '\0'; -		} - -		params[param_number].name = name; -		params[param_number].value = value; -		param_number++; -		if (!strcmp(name, "expert")) set_param(MODE_EXPERT); -		if (!strcmp(name, "rescue")) set_param(MODE_RESCUE); -		if (!strcmp(name, "special_stage2")) set_param(MODE_SPECIAL_STAGE2); -		if (!strcmp(name, "automatic")) { -			set_param(MODE_AUTOMATIC); -			grab_automatic_params(value); -		} -		if (buf[i] == '\0') -			break; -		i++; -	} -	 -	log_message("\tgot %d args", param_number); +	return access(COMPRESSED_FILE_REL(IMAGE_LOCATION "/"), R_OK) == 0 || +	       access(IMAGE_LOCATION "/" LIVE_LOCATION_REL, R_OK) == 0;  } - -int stage1_mode = 0; - -int get_param(int i) +enum return_type create_IMAGE_LOCATION(char *location_full)  { -#ifdef SPAWN_INTERACTIVE -	static int fd = 0; -	char buf[5000]; -	char * ptr; -	int nb; - -	if (fd <= 0) { -		fd = open(interactive_fifo, O_RDONLY); -		if (fd == -1) -			return (stage1_mode & i); -		fcntl(fd, F_SETFL, O_NONBLOCK); -	} - -	if (fd > 0) { -		if ((nb = read(fd, buf, sizeof(buf))) > 0) { -			buf[nb] = '\0'; -			ptr = buf; -			while ((ptr = strstr(ptr, "+ "))) { -				if (!strncmp(ptr+2, "expert", 6)) set_param(MODE_EXPERT); -				if (!strncmp(ptr+2, "rescue", 6)) set_param(MODE_RESCUE); -				ptr++; -			} -			ptr = buf; -			while ((ptr = strstr(ptr, "- "))) { -				if (!strncmp(ptr+2, "expert", 6)) unset_param(MODE_EXPERT); -				if (!strncmp(ptr+2, "rescue", 6)) unset_param(MODE_RESCUE); -				ptr++; -			} -		} -	} -#endif - -	return (stage1_mode & i); -} +	struct stat statbuf; +	int offset = strncmp(location_full, IMAGE_LOCATION_DIR, sizeof(IMAGE_LOCATION_DIR) - 1) == 0 ? sizeof(IMAGE_LOCATION_DIR) - 1 : 0; +	char *with_arch = asprintf_("%s/%s", location_full, ARCH); -char * get_param_valued(char *param_name) -{ -	int i; -	for (i = 0; i < param_number ; i++) -		if (!strcmp(params[i].name, param_name)) -			return params[i].value; +	log_message("trying %s", with_arch); -	return NULL; -} +	if (stat(with_arch, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) +		location_full = with_arch; -void set_param_valued(char *param_name, char *param_value) -{ -	params[param_number].name = param_name; -	params[param_number].value = param_value; -	param_number++; -} +	log_message("assuming %s is a mirror tree", location_full + offset); -void set_param(int i) -{ -	stage1_mode |= i; -	if (i == MODE_RESCUE) { -		set_param_valued("special_stage2", "rescue"); -		set_param(MODE_SPECIAL_STAGE2); -	} -} - -void unset_param(int i) -{ -	stage1_mode &= ~i; -} +	unlink(IMAGE_LOCATION); +	if (symlink(location_full + offset, IMAGE_LOCATION) != 0) +		return RETURN_ERROR; -int charstar_to_int(char * s) -{ -	int number = 0; -	while (*s && isdigit(*s)) { -		number = (number * 10) + (*s - '0'); -		s++; -	} -	return number; +	return RETURN_OK;  } -int total_memory(void) +int ramdisk_possible(void)  { -	int value; -	struct stat statr; -	if (stat("/proc/kcore", &statr)) +	if (total_memory() > (IS_RESCUE ? MEM_LIMIT_RESCUE : MEM_LIMIT_DRAKX)) +		return 1; +	else { +		log_message("warning, ramdisk is not possible due to low mem!");  		return 0; - -	/* drakx powered: use /proc/kcore and rounds every 4 Mbytes */ -	value = 4 * ((int)((float)statr.st_size / 1024 / 1024 / 4 + 0.5)); -	log_message("Total Memory: %d Mbytes", value); - -	return value; +	}  } - -int ramdisk_possible(void) +int compressed_image_preload(void)  { -	if (total_memory() > MEM_LIMIT_RAMDISK) +	if (total_memory() > (IS_RESCUE ? MEM_LIMIT_RESCUE_PRELOAD : MEM_LIMIT_DRAKX_PRELOAD))  		return 1;  	else { -		log_message("warning, ramdisk is not possible due to low mem!"); +		log_message("warning, not preloading compressed due to low mem");  		return 0;  	}  } - -static void save_stuff_for_rescue(void) +enum return_type save_fd(int from_fd, char * to, void (*callback_func)(int overall))  { -	void save_this_file(char * file) { -		char buf[5000]; -		int fd_r, fd_w, i; -		char location[100]; - -		if ((fd_r = open(file, O_RDONLY)) < 0) { -			log_message("can't open %s for read", file); -			return; -		} -		strcpy(location, STAGE2_LOCATION); -		strcat(location, file); -		if ((fd_w = open(location, O_WRONLY)) < 0) { -			log_message("can't open %s for write", location); -			close(fd_r); -			return; +        FILE * f_to; +        size_t quantity __attribute__((aligned(16))), overall = 0; +        char buf[4096] __attribute__((aligned(4096))); +        int ret = RETURN_ERROR; + +        if (!(f_to = fopen(to, "w"))) { +                log_perror(to); +                goto close_from; +        } + +        do { +		quantity = read(from_fd, buf, sizeof(buf)); +		if (quantity > 0) { +                        if (fwrite(buf, 1, quantity, f_to) != quantity) { +                                log_message("short write (%s)", strerror(errno)); +                                goto cleanup; +                        } +                } else if (quantity == -1) { +			log_message("an error occured: %s", strerror(errno)); +			goto cleanup;  		} -		if ((i = read(fd_r, buf, sizeof(buf))) <= 0) { -			log_message("can't read from %s", file); -			close(fd_r); close(fd_w); -			return; -		} -		if (write(fd_w, buf, i) != i) -			log_message("can't write %d bytes to %s", i, location); -		close(fd_r); close(fd_w); -		log_message("saved file %s for rescue (%d bytes)", file, i); -	} -	save_this_file("/etc/resolv.conf"); -} +                if (callback_func) { +                        overall += quantity; +                        callback_func(overall); +                } +        } while (quantity); -enum return_type load_ramdisk_fd(int ramdisk_fd, int size) +        ret = RETURN_OK; + + cleanup: +        fclose(f_to); + close_from: +        close(from_fd); + +        return ret; +} + +enum return_type copy_file(char * from, char * to, void (*callback_func)(int overall))  { -	BZFILE * st2; -	char * ramdisk = "/dev/ram3"; /* warning, verify that this file exists in the initrd (and actually is a ramdisk device file) */ -	int ram_fd; -	char buffer[4096]; -	int z_errnum; -	char * wait_msg = "Loading program into memory..."; -	int bytes_read = 0; -	int actually; -	int seems_ok = 0; - -	st2 = BZ2_bzdopen(ramdisk_fd, "r"); - -	if (!st2) { -		log_message("Opening compressed ramdisk: %s", BZ2_bzerror(st2, &z_errnum)); -		error_message("Could not open compressed ramdisk file."); -		return RETURN_ERROR; -	} +        int from_fd; -	ram_fd = open(ramdisk, O_WRONLY); -	if (ram_fd == -1) { -		log_perror(ramdisk); -		error_message("Could not open ramdisk device file."); -		return RETURN_ERROR; -	} -	 -	init_progression(wait_msg, size); +	log_message("copy_file: %s -> %s", from, to); -	while ((actually = BZ2_bzread(st2, buffer, sizeof(buffer))) > 0) { -		seems_ok = 1; -		if (write(ram_fd, buffer, actually) != actually) { -			log_perror("writing ramdisk"); -			remove_wait_message(); -			return RETURN_ERROR; -		} -		update_progression((int)((bytes_read += actually) / RAMDISK_COMPRESSION_RATIO)); -	} +	from_fd = open(from, O_RDONLY); +	if (from_fd != -1) { +		return save_fd(from_fd, to, callback_func); +	} else { +                log_perror(from); +                return RETURN_ERROR; +        } +} -	if (!seems_ok) { -		log_message("reading compressed ramdisk: %s", BZ2_bzerror(st2, &z_errnum)); -		remove_wait_message(); -		error_message("Could not uncompress second stage ramdisk."); -		return RETURN_ERROR; -	} +enum return_type mount_compressed_image(char *compressed_image,  char *location_mount) +{ +	if (lomount(compressed_image, location_mount, NULL, 1)) { +                stg1_error_message("Could not mount compressed loopback :(."); +                return RETURN_ERROR; +        } +	return RETURN_OK; +} +enum return_type preload_mount_compressed_fd(int compressed_fd, int image_size, char *image_name, char *location_mount) +{ +	int ret; +	char *compressed_tmpfs = asprintf_("/tmp/%s", image_name); +	char *buf = "Loading program into memory..."; +	init_progression(buf, image_size); +	ret = save_fd(compressed_fd, compressed_tmpfs, update_progression);  	end_progression(); +	if (ret != RETURN_OK) +		return ret; +	 +	return mount_compressed_image(compressed_tmpfs, location_mount); +} -	BZ2_bzclose(st2); /* opened by gzdopen, but also closes the associated fd */ -	close(ram_fd); +enum return_type mount_compressed_image_may_preload(char *image_name, char *location_mount, int preload) +{ +	char *compressed_image = asprintf_("%s/%s", COMPRESSED_LOCATION, image_name); -	if (my_mount(ramdisk, STAGE2_LOCATION, "ext2")) -		return RETURN_ERROR; +	log_message("mount_compressed_may_preload: %s into %s (preload = %d)", compressed_image, location_mount, preload); -	set_param(MODE_RAMDISK); +        if (access(compressed_image, R_OK) != 0) return RETURN_ERROR; -	if (IS_RESCUE) { -		save_stuff_for_rescue(); -		if (umount(STAGE2_LOCATION)) { -			log_perror(ramdisk); +        if (preload) { +		int compressed_fd = open(compressed_image, O_RDONLY); +		if (compressed_fd != -1) { +			return preload_mount_compressed_fd(compressed_fd, file_size(compressed_image), image_name, location_mount); +		} else { +			log_perror(compressed_image);  			return RETURN_ERROR;  		} -		return RETURN_OK; /* fucksike, I lost several hours wondering why the kernel won't see the rescue if it is alreay mounted */ +	} else { +		return mount_compressed_image(compressed_image, location_mount);  	} - -	return RETURN_OK;  } +enum return_type may_load_compressed_image(void) +{ +	if (!IS_RESCUE && access(IMAGE_LOCATION "/" LIVE_LOCATION_REL, R_OK) == 0) { +		/* LIVE install */ +		return RETURN_OK; +	} else { +		/* compressed install */ +		return mount_compressed_image_may_preload(COMPRESSED_NAME(""), STAGE2_LOCATION, compressed_image_preload()); +	} +} -char * get_ramdisk_realname(void) +enum return_type load_compressed_fd(int fd, int size)  { -	char img_name[500]; -	char * stg2_name = get_param_valued("special_stage2"); -	char * begin_img = RAMDISK_LOCATION; -	char * end_img = "_stage2.bz2"; +	return preload_mount_compressed_fd(fd, size, COMPRESSED_NAME(""), STAGE2_LOCATION); +} -	if (!stg2_name) -		stg2_name = "mdkinst"; +int try_mount(char * dev, char * location) +{ +	char device_fullname[50]; +	snprintf(device_fullname, sizeof(device_fullname), "/dev/%s", dev); -	if (IS_RESCUE) -		stg2_name = "rescue"; -	 -	strcpy(img_name, begin_img); -	strcat(img_name, stg2_name); -	strcat(img_name, end_img); +	if (my_mount(device_fullname, location, "auto", 0) == -1) { +                return 1; +        } -	return strdup(img_name); +        return 0;  } - -enum return_type load_ramdisk(void) +#ifndef DISABLE_DISK +int get_disks(char *** names, char *** models)  { -	int st2_fd; -	struct stat statr; -	char img_name[500]; - -	strcpy(img_name, IMAGE_LOCATION); -	strcat(img_name, get_ramdisk_realname()); +	char ** ptr; +	int count = 0; -	log_message("trying to load %s as a ramdisk", img_name); +	my_modprobe("ide_disk", ANY_DRIVER_TYPE, NULL); +	my_modprobe("sd_mod", ANY_DRIVER_TYPE, NULL); -	st2_fd = open(img_name, O_RDONLY); /* to be able to see the progression */ +	get_medias(DISK, names, models, BUS_ANY); -	if (st2_fd == -1) { -		log_message("open ramdisk file (%s) failed", img_name); -		error_message("Could not open compressed ramdisk file (%s).", img_name); -		return RETURN_ERROR; +	ptr = *names; +	while (ptr && *ptr) { +		count++; +		ptr++;  	} -	if (stat(img_name, &statr)) -		return RETURN_ERROR; -	else -		return load_ramdisk_fd(st2_fd, statr.st_size); +        return count;  } +#endif -/* pixel's */ -void * memdup(void *src, size_t size) +#ifndef DISABLE_CDROM +int get_cdroms(char *** names, char *** models)  { -	void * r; -	r = malloc(size); -	memcpy(r, src, size); -	return r; -} +	char ** ptr; +	int count = 0; +	my_modprobe("ide_cd_mod", ANY_DRIVER_TYPE, NULL); +	my_modprobe("sr_mod", ANY_DRIVER_TYPE, NULL); -static char ** my_env = NULL; -static int env_size = 0; +	get_medias(CDROM, names, models, BUS_ANY); -void handle_env(char ** env) -{ -	char ** ptr = env; +	ptr = *names;  	while (ptr && *ptr) { +		count++;  		ptr++; -		env_size++;  	} -	my_env = malloc(sizeof(char *) * 100); -	memcpy(my_env, env, sizeof(char *) * (env_size+1)); -} - -char ** grab_env(void) { -	return my_env; -} -void add_to_env(char * name, char * value) -{ -	char tmp[500]; -	sprintf(tmp, "%s=%s", name, value); -	my_env[env_size] = strdup(tmp); -	env_size++; -	my_env[env_size] = NULL; +	return count;  } +#endif - -char ** list_directory(char * direct) +char * floppy_device(void)  { -	char * tmp[50000]; /* in /dev there can be many many files.. */ -	int i = 0; -	struct dirent *ep; -	DIR *dp = opendir(direct); -	while (dp && (ep = readdir(dp))) { -		if (strcmp(ep->d_name, ".") && strcmp(ep->d_name, "..")) { -			tmp[i] = strdup(ep->d_name); -			i++; -		} -	} -	if (dp) -		closedir(dp); -	tmp[i] = NULL; -	return memdup(tmp, sizeof(char*) * (i+1)); +        char ** names, ** models; +        int fd; +	my_modprobe("floppy", ANY_DRIVER_TYPE, NULL); +        fd = open("/dev/fd0", O_RDONLY|O_NONBLOCK); +        if (fd != -1) { +                char drivtyp[17]; +                if (!ioctl(fd, FDGETDRVTYP, (void *)drivtyp)) { +                        struct floppy_drive_struct ds; +                        log_message("/dev/fd0 type: %s", drivtyp); +                        if (!ioctl(fd, FDPOLLDRVSTAT, &ds)) { +                                log_message("\ttrack: %d", ds.track); +                                if (ds.track >= 0) { +                                        close(fd); +                                        return "/dev/fd0"; +                                } +                        } +                } else { +                        log_perror("can't FDGETDRVTYP /dev/fd0"); +                } +                close(fd); +        } +        log_message("seems that you don't have a regular floppy drive"); +        my_modprobe("sd_mod", ANY_DRIVER_TYPE, NULL); +	get_medias(FLOPPY, &names, &models, BUS_ANY); +	if (names && *names) +                return asprintf_("/dev/%s", *names); +        else +                return NULL;  } | 
