summaryrefslogtreecommitdiffstats
path: root/docs/README
diff options
context:
space:
mode:
authorGuillaume Cottenceau <gc@mandriva.com>2001-01-24 11:08:27 +0000
committerGuillaume Cottenceau <gc@mandriva.com>2001-01-24 11:08:27 +0000
commit858c9ef570496b951bfaf33091960d4dd683fa40 (patch)
tree7f8579ada4fc634727c2e1fbb609f530320eaa8d /docs/README
parenta00183fbaf87973aca2dcd95e605f4fb0a92c9da (diff)
downloaddrakx-858c9ef570496b951bfaf33091960d4dd683fa40.tar
drakx-858c9ef570496b951bfaf33091960d4dd683fa40.tar.gz
drakx-858c9ef570496b951bfaf33091960d4dd683fa40.tar.bz2
drakx-858c9ef570496b951bfaf33091960d4dd683fa40.tar.xz
drakx-858c9ef570496b951bfaf33091960d4dd683fa40.zip
- fix anonymous CVS
- fix gendistrib - fix multi-cd installs - comply to mdk-stage1 - rpmsrate - now stage2 ramdisk is no more 14 Mb but 22 Mb ;-)
Diffstat (limited to 'docs/README')
-rw-r--r--docs/README93
1 files changed, 55 insertions, 38 deletions
diff --git a/docs/README b/docs/README
index f1b187fa5..1a2534c4c 100644
--- a/docs/README
+++ b/docs/README
@@ -7,7 +7,7 @@ to the standard newt install.
Like all good free software, DrakX is in CVS :)
You can access it using:
-% export CVSROOT=:pserver:anoncvs@cvs.mandrakesoft.com:/home/cvs/cooker
+% export CVSROOT=:pserver:anoncvs@mandrakesoft.com:/home/cvs/cooker
% cvs login
% Passwd: cvs
% cvs checkout gi
@@ -22,28 +22,43 @@ sometimes wonder what the whole make does :-%
Instead, changing some .pm files is quite easy (nice interpreted language)
********************************************************************************
-* Making your custom install cdrom *********************************************
+* Making your custom install ***************************************************
********************************************************************************
If you have your own rpms you want to add, or make your own updated cdrom, you
-just have to update:
-- Mandrake/base/hdlist.cz2: use ``misc/genhdlists --distrib .''
-- Mandrake/base/depslist: use ``misc/gendepslist2 -o Mandrake/base/depslist Mandrake/base/hdlist.cz2''
+just have to issue:
+
+% gendistrib --noclean --distrib <DIRS>
+
+Where <DIRS> is the root of all the media that the install will see:
+
+(1) network or 1-cdrom installs
+ DIRS == the root directory of the Distribution
+
+(2) multi-cdrom install
+ DIRS == the root directories of all the media that the install will see
+
+``gendistrib'' will scan, from the DIRS you provide, for some
+Mandrake/RPMS* directories containing some RPM packages. For multi-cd,
+please use Mandrake/RPMS, Mandrake/RPMS2, etc. For one CD or a network/hd
+volume, please use Mandrake/RPMS.
+
+Optionnally, you can modify ``Mandrake/base/rpmsrate''; this file manages
+the relative importance of the files, and thus their installation or not.
-Optionnally, you can modify Mandrake/base/compssList and compssUsers.
Also, mdkinst_stage2.gz must be remade if you modify files in Mandrake/mdkinst.
See below for information about these files.
********************************************************************************
* FILES ************************************************************************
********************************************************************************
-First he are the different things needed :
+First here are the different things needed :
-Mandrake/base/hdlist
- obsolete in 7.1
+Mandrake/base/hdlists
+ description of the available install media
-Mandrake/base/hdlist.cz2
- table of rpm's headers.
- ! Need to be remade when Mandrake/RPMS changes (with ``misc/genhdlists --distrib .'') !
+Mandrake/base/hdlist*.cz
+ table of rpm's headers, referred by ``hdlists''
+ ! Need to be remade when Mandrake/RPMS changes (with ``gendistrib'') !
Mandrake/base/depslist
for each packages, tell which package it depends on. Also contains the
@@ -57,14 +72,9 @@ Mandrake/base/depslist.ordered
Mandrake/base/compss
obsolete in 7.1
-Mandrake/base/compssUsers
- obsoletes comps. It contains the different user classes like ``Graphics
- Manipulation'' and ``Games''
-
-Mandrake/base/compssList
- for each packages, it gives the appreciation for each type of user.
- used to choose packages
- (see beginning of perl-install/pkgs.pm for more)
+Mandrake/base/rpmsrate
+ ranks and classify packages, so that the installer will know which
+ ones to install (see beginning of perl-install/pkgs.pm for more)
Mandrake/mdkinst
live system used on certain installs. See ``Ramdisk or not'' below for
@@ -77,10 +87,10 @@ Mandrake/base/mdkinst_stage2.gz
images/*.img
boot images to use with DrakX. Use:
- - all for everything, but need 2.88MB media (like el torito cdrom boot)
- - hd for hard-disk install
- cdrom for cdrom install
- network for ftp/nfs install (non-pcmcia devices)
+ - hd for hard-disk install
+ - hdreiser for hard-disk install on a reiserfs partition
- pcmcia for pcmcia install (see ``PCMCIA install'' below for more)
the following modules have been removed from:
@@ -109,7 +119,7 @@ rebooting. ``rpm -qa'' works for example.
- alt-F3: a lot of interesting things. Be carefull, some ``ERROR'' messages are
not interesting.
- alt-F4: kernel's place. aka the output of dmesg.
-- alt-F7: the graphical install lives there (may switch to console 7 one day :)
+- alt-F7: the graphical install lives there
- command "bug" puts on floppy lots of interesting stuff.
- /tmp/ddebug.log: same (or nearly the same) as alt-F3
@@ -138,11 +148,7 @@ not'' to know if you have to regenerate the mdkinst_stage2.gz)
********************************************************************************
* PCMCIA install ***************************************************************
********************************************************************************
-If the media you use to install is a pcmcia device, you have two choices:
-- use the pcmcia boot disk
-- use another boot disk and it will ask you a supplementary disk. Give it the
-pcmcia disk.
-
+If the media you use to install is a pcmcia device, use the pcmcia boot disk.
********************************************************************************
* Ramdisk or not ***************************************************************
@@ -150,6 +156,7 @@ pcmcia disk.
The DrakX install is much bigger than the newt one. So the ramdisk which was
used is getting big, and costs a lot in memory
(eg: the mdkinst_stage2 is 14MB - 23/09/99)
+(update! now size is 22MB - 24/01/01)
| | newt | DrakX
|-------+---------+----------------------------------------------------------
@@ -160,7 +167,12 @@ used is getting big, and costs a lot in memory
| | | ramdisk otherwise
| cdrom | ramdisk | live if memory < 52MB, ramdisk otherwise
-When i say live, it means that the install1 stage will *mount* the
+Where ramdisk is needed, if detected memory is below the limit allowed for
+ramdisk (maintained in file gi/mdk-stage1/config-stage1.h; currently 52 Mb),
+a failure dialog will be printed explaining that there is not enough memory
+to perform the installation.
+
+When i say live, it means that the stage1 will *mount* the
Mandrake/mdkinst and use it that way.
The ramdisk is used in place of the live in some cases. This ramdisk is filled
@@ -176,12 +188,15 @@ For pcmcia, it depends on the type of install.
* modules **********************************************************************
********************************************************************************
Modules can be found in at least 2 places:
-- in /modules/modules.cgz
+- in /modules/modules.mar
- in /lib/modules.cz2
-/modules/modules.cgz is used in stage1. It contains only modules interesting for
-one kind of install. For example in an hd install, it contains scsi modules.
-For an network install, it contains network card modules.
+/modules/modules.mar is used in mdk-stage1. It contains only modules
+interesting for one kind of install. For example in an hd install, it
+contains scsi modules. For a network install, it contains network card
+modules. (To create, extract or view files in a ``mar'' archive, please
+use gi/mdk-stage1/mar/mar; this is basically an archive format meant to
+be minimalistic)
/lib/modules.cz2 contains every module, it is used in stage2.
@@ -245,11 +260,13 @@ sub selectAlawindows {}
* Miscellaneous ****************************************************************
********************************************************************************
> o Media access methods: nfs, ftp, http, hd, cdrom
-> o Stages: install1, stage1, stage2
+> o Stages: init, stage1, stage2
> - What exactly each stage does
-the stage1 takes care of loading the stage2 :)
-the stage2 is too big to fit on a floppy, that's why stage1 exists.
+init loads stage1
+stage1 loads stage2, on various medium type
+
+stage2 is too big to fit on a floppy, that's why stage1 exists
> - How each stage relates to the various media access methods
@@ -260,8 +277,8 @@ doesn't contain scsi modules nor ide.
> - How one stage terminates and another begins. i.e., How does
> stage1 find, mount, and launch stage2?
-/sbin/init just starts /sbin/install
-/sbin/install takes care of mounting stage2 (in ramdisk if necessary)
+/sbin/init just starts /sbin/stage1
+/sbin/stage1 takes care of mounting stage2 (in ramdisk if necessary)
then it runs /usr/bin/runinstall2
> o Text and Graphic mode installers
8'>518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
/*
 * Guillaume Cottenceau (gc@mandrakesoft.com)
 *
 * Copyright 2000 MandrakeSoft
 *
 * This software may be freely redistributed under the terms of the GNU
 * public license.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/*
 * Portions from Erik Troan (ewt@redhat.com)
 *
 * Copyright 1996 Red Hat Software 
 *
 */

#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/utsname.h>
#include <sys/ioctl.h>
#include <linux/fd.h>
#include "stage1.h"
#include "log.h"
#include "mount.h"
#include "frontend.h"
#include "automatic.h"

#include "tools.h"
#include "probing.h"
#include "modules.h"

static struct param_elem params[50];
static int param_number = 0;

void process_cmdline(void)
{
	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, "changedisk")) set_param(MODE_CHANGEDISK);
		if (!strcmp(name, "updatemodules")) set_param(MODE_UPDATEMODULES);
		if (!strcmp(name, "rescue")) set_param(MODE_RESCUE);
		if (!strcmp(name, "noauto")) set_param(MODE_NOAUTO);
		if (!strcmp(name, "netauto")) set_param(MODE_NETAUTO);
		if (!strcmp(name, "recovery")) set_param(MODE_RECOVERY);
		if (!strcmp(name, "special_stage2")) set_param(MODE_SPECIAL_STAGE2);
		if (!strcmp(name, "debugstage1")) set_param(MODE_DEBUGSTAGE1);
		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);
}


int stage1_mode = 0;

int get_param(int i)
{
#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);
}

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;

	return NULL;
}

void set_param_valued(char *param_name, char *param_value)
{
	params[param_number].name = param_name;
	params[param_number].value = param_value;
	param_number++;
}

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;
}

// warning, many things rely on the fact that:
// - when failing it returns 0
// - it stops on first non-digit char
int charstar_to_int(const char * s)
{
	int number = 0;
	while (*s && isdigit(*s)) {
		number = (number * 10) + (*s - '0');
		s++;
	}
	return number;
}

off_t file_size(const char * path)
{
	struct stat statr;
	if (stat(path, &statr))
		return -1;
        else
                return statr.st_size;
}

int total_memory(void)
{
	int value;

	/* drakx powered: use /proc/kcore and rounds every 4 Mbytes */
	value = 4 * ((int)((float)file_size("/proc/kcore") / 1024 / 1024 / 4 + 0.5));
	log_message("Total Memory: %d Mbytes", value);

	return value;
}


int ramdisk_possible(void)
{
	if (total_memory() > (IS_RESCUE ? MEM_LIMIT_RESCUE : MEM_LIMIT_RAMDISK))
		return 1;
	else {
		log_message("warning, ramdisk is not possible due to low mem!");
		return 0;
	}
}


enum return_type copy_file(char * from, char * to, void (*callback_func)(int overall))
{
        FILE * f_from, * f_to;
        size_t quantity __attribute__((aligned(16))), overall = 0;
        char buf[4096] __attribute__((aligned(4096)));
        int ret = RETURN_ERROR;

        log_message("copy_file: %s -> %s", from, to);

        if (!(f_from = fopen(from, "rb"))) {
                log_perror(from);
                return RETURN_ERROR;
        }

        if (!(f_to = fopen(to, "w"))) {
                log_perror(to);
                goto close_from;
                return RETURN_ERROR;
        }

        do {
                if ((quantity = fread(buf, 1, sizeof(buf), f_from)) > 0) {
                        if (fwrite(buf, 1, quantity, f_to) != quantity) {
                                log_message("short write (%s)", strerror(errno));
                                goto cleanup;
                        }
                }
                if (callback_func) {
                        overall += quantity;
                        callback_func(overall);
                }
        } while (!feof(f_from) && !ferror(f_from) && !ferror(f_to));

        if (ferror(f_from) || ferror(f_to)) {
                log_message("an error occured: %s", strerror(errno));
                goto cleanup;
        }

        ret = RETURN_OK;

 cleanup:
        fclose(f_to);
 close_from:
        fclose(f_from);

        return ret;
}

static void save_stuff_for_rescue(void)
{
        copy_file("/etc/resolv.conf", STAGE2_LOCATION "/etc/resolv.conf", NULL);
}

enum return_type load_ramdisk_fd(int ramdisk_fd, int size)
{
	BZFILE * st2;
	char * ramdisk = "/dev/ram3"; /* warning, verify that this file exists in the initrd, and that root=/dev/ram3 is actually passed to the kernel at boot time */
	int ram_fd;
	char buffer[32768];
	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));
		stg1_error_message("Could not open compressed ramdisk file.");
		return RETURN_ERROR;
	}

	ram_fd = open(ramdisk, O_WRONLY);
	if (ram_fd == -1) {
		log_perror(ramdisk);
		stg1_error_message("Could not open ramdisk device file.");
		return RETURN_ERROR;
	}
	
	init_progression(wait_msg, size);

	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));
	}

	if (!seems_ok) {
		log_message("reading compressed ramdisk: %s", BZ2_bzerror(st2, &z_errnum));
		BZ2_bzclose(st2); /* opened by gzdopen, but also closes the associated fd */
		close(ram_fd);
		remove_wait_message();
		stg1_error_message("Could not uncompress second stage ramdisk. "
				   "This is probably an hardware error while reading the data. "
				   "(this may be caused by a hardware failure or a Linux kernel bug)");
		return RETURN_ERROR;
	}

	end_progression();

	BZ2_bzclose(st2); /* opened by gzdopen, but also closes the associated fd */
	close(ram_fd);

	if (my_mount(ramdisk, STAGE2_LOCATION, "ext2", 1))
		return RETURN_ERROR;

	set_param(MODE_RAMDISK);

	if (IS_RESCUE) {
		save_stuff_for_rescue();
		if (umount(STAGE2_LOCATION)) {
			log_perror(ramdisk);
			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 */
	}

	return RETURN_OK;
}


char * get_ramdisk_realname(void)
{
	char img_name[500];
	char * stg2_name = get_param_valued("special_stage2");
	char * begin_img = RAMDISK_LOCATION;
	char * end_img = "_stage2.bz2";

	if (!stg2_name)
		stg2_name = "mdkinst";

	if (IS_RESCUE)
		stg2_name = "rescue";
	
	strcpy(img_name, begin_img);
	strcat(img_name, stg2_name);
	strcat(img_name, end_img);

	return strdup(img_name);
}


enum return_type load_ramdisk(void)
{
	int st2_fd;
        off_t size;
	char img_name[500];

	strcpy(img_name, IMAGE_LOCATION);
	strcat(img_name, get_ramdisk_realname());

	log_message("trying to load %s as a ramdisk", img_name);

	st2_fd = open(img_name, O_RDONLY); /* to be able to see the progression */

	if (st2_fd == -1) {
		log_message("open ramdisk file (%s) failed", img_name);
		stg1_error_message("Could not open compressed ramdisk file (%s).", img_name);
		return RETURN_ERROR;
	}

	if ((size = file_size(img_name)) == -1)
		return RETURN_ERROR;
	else
		return load_ramdisk_fd(st2_fd, size);
}

/* pixel's */
void * memdup(void *src, size_t size)
{
	void * r;
	r = malloc(size);
	memcpy(r, src, size);
	return r;
}


static char ** my_env = NULL;
static int env_size = 0;

void handle_env(char ** env)
{
	char ** ptr = env;
	while (ptr && *ptr) {
		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;
}


char ** list_directory(char * direct)
{
	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));
}


int string_array_length(char ** a)
{
	int i = 0;
	if (!a)
		return -1;
	while (a && *a) {
		a++;
		i++;
	}
	return i;
}

int kernel_version(void)
{
        struct utsname val;
        if (uname(&val)) {
                log_perror("uname failed");
                return -1;
        }
        return charstar_to_int(val.release + 2);
}

char * floppy_device(void)
{
        char ** names, ** models;
	my_insmod("floppy", ANY_DRIVER_TYPE, NULL, 0);
        int 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_insmod("sd_mod", ANY_DRIVER_TYPE, NULL, 0);
	get_medias(FLOPPY, &names, &models, BUS_ANY);
	if (names && *names)
                return asprintf_("/dev/%s", *names);
        else
                return "/dev/fd0";
}

char * asprintf_(const char *msg, ...)
{
        int n;
        char * s;
        va_list arg_ptr;
        va_start(arg_ptr, msg);
        n = vsnprintf(0, 1000000, msg, arg_ptr);
        va_start(arg_ptr, msg);
        if ((s = malloc(n + 1))) {
                vsnprintf(s, n + 1, msg, arg_ptr);
                va_end(arg_ptr);
                return s;
        }
        va_end(arg_ptr);
        return strdup("");
}

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;
}