plan 9 kernel history: overview | file list | diff list

1996/0214/boot/boot.c (diff list | history)

1996/0214/sys/src/9/boot/boot.c:1,3671997/0327/sys/src/9/boot/boot.c:1,348 (short | long | prev | next)
1992/0317    
#include <u.h> 
#include <libc.h> 
1993/0330    
#include <auth.h> 
1993/0501    
#include <fcall.h> 
1992/0318    
#include "../boot/boot.h" 
1992/0317    
 
typedef struct Net	Net; 
typedef struct Flavor	Flavor; 
                 
char	cputype[NAMELEN]; 
char	terminal[NAMELEN]; 
char	sys[2*NAMELEN]; 
char	username[NAMELEN]; 
1992/0522    
char	bootfile[3*NAMELEN]; 
1992/0530    
char	conffile[NAMELEN]; 
1994/0317    
char 	reply[256]; 
1993/0501    
int	printcol; 
int	mflag; 
int	fflag; 
int	kflag; 
int	aflag; 
1994/0317    
 
char	*bargv[Nbarg]; 
int	bargc; 
 
1992/0530    
static void	swapproc(void); 
1993/0501    
static void	recover(Method*); 
1992/0530    
static Method	*rootserver(char*); 
1992/0317    
 
1995/0301    
static int 
1996/0214    
rconv(va_list *arg, Fconv *fp) 
1995/0301    
{ 
	char s[ERRLEN]; 
 
1996/0214    
	USED(arg); 
1995/0301    
 
	s[0] = 0; 
	errstr(s); 
	strconv(s, fp); 
	return 0; 
} 
 
1992/0317    
void 
1992/0522    
boot(int argc, char *argv[]) 
1992/0317    
{ 
	int fd; 
	Method *mp; 
	char cmd[64]; 
1992/0318    
	char flags[6]; 
1992/0909    
	int islocal, ishybrid; 
1992/0317    
 
	sleep(1000); 
 
1995/0301    
	fmtinstall('r', rconv); 
 
1992/0317    
	open("#c/cons", OREAD); 
	open("#c/cons", OWRITE); 
	open("#c/cons", OWRITE); 
1994/0311    
	bind("#c", "/dev", MAFTER); 
1995/1122    
	bind("#e", "/env", MREPL|MCREATE); 
1994/0728    
 
1993/0528    
#ifdef DEBUG 
1993/0525    
	print("argc=%d\n", argc); 
1992/0813    
	for(fd = 0; fd < argc; fd++) 
1994/0728    
		print("%lux %s ", argv[fd], argv[fd]); 
1993/0528    
	print("\n"); 
#endif DEBUG 
1992/0610    
 
1992/0317    
	ARGBEGIN{ 
1992/0322    
	case 'a': 
		aflag = 1; 
		break; 
1992/0317    
	case 'u': 
		strcpy(username, ARGF()); 
		break; 
	case 'k': 
		kflag = 1; 
		break; 
	case 'm': 
		mflag = 1; 
		break; 
	case 'f': 
		fflag = 1; 
		break; 
	}ARGEND 
 
1992/0610    
	readfile("#e/cputype", cputype, sizeof(cputype)); 
	readfile("#e/terminal", terminal, sizeof(cputype)); 
1992/0530    
	getconffile(conffile, terminal); 
1992/0317    
 
	/* 
	 *  pick a method and initialize it 
	 */ 
1992/0318    
	mp = rootserver(argc ? *argv : 0); 
1992/0317    
	(*mp->config)(mp); 
1992/0318    
	islocal = strcmp(mp->name, "local") == 0; 
1992/0909    
	ishybrid = strcmp(mp->name, "hybrid") == 0; 
1992/0317    
 
	/* 
	 *  get/set key or password 
	 */ 
1992/0318    
	(*pword)(islocal, mp); 
1992/0317    
 
1993/0501    
	switch(rfork(RFPROC|RFNAMEG|RFFDG)) { 
	case -1: 
		print("failed to start recover: %r\n"); 
		break; 
	case 0: 
		recover(mp); 
		break; 
	} 
 
1992/0317    
	/* 
	 *  connect to the root file system 
	 */ 
	fd = (*mp->connect)(); 
	if(fd < 0) 
		fatal("can't connect to file server"); 
1993/0501    
	nop(fd); 
1992/0909    
	if(!islocal && !ishybrid){ 
1992/0318    
		if(cfs) 
			fd = (*cfs)(fd); 
1993/0330    
		doauthenticate(fd, mp); 
1992/0317    
	} 
	srvcreate("boot", fd); 
 
	/* 
	 *  create the name space, mount the root fs 
	 */ 
	if(bind("/", "/", MREPL) < 0) 
		fatal("bind"); 
1993/0330    
	if(mount(fd, "/", MAFTER|MCREATE, "") < 0) 
		fatal("mount"); 
1992/0317    
	close(fd); 
 
	/* 
1992/0611    
	 *  if a local file server exists and it's not 
	 *  running, start it and mount it onto /n/kfs 
1992/0317    
	 */ 
1992/1006    
	if(access("#s/kfs", 0) < 0){ 
1992/0902    
		for(mp = method; mp->name; mp++){ 
			if(strcmp(mp->name, "local") != 0) 
				continue; 
			(*mp->config)(mp); 
			fd = (*mp->connect)(); 
			if(fd < 0) 
				break; 
1993/0330    
			mount(fd, "/n/kfs", MAFTER|MCREATE, "") ; 
1992/0902    
			close(fd); 
1992/0611    
			break; 
1992/0902    
		} 
1992/0317    
	} 
 
	settime(islocal); 
	swapproc(); 
 
	sprint(cmd, "/%s/init", cputype); 
1992/0322    
	sprint(flags, "-%s%s%s", cpuflag ? "c" : "t", mflag ? "m" : "", aflag ? "a" : ""); 
1997/0327    
	sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m" : ""); 
1992/0317    
	execl(cmd, "init", flags, 0); 
	fatal(cmd); 
} 
 
1994/0311    
Method* 
findmethod(char *a) 
{ 
	Method *mp; 
	int i, j; 
	char *cp; 
 
	i = strlen(a); 
	cp = strchr(a, '!'); 
	if(cp) 
		i = cp - a; 
	for(mp = method; mp->name; mp++){ 
		j = strlen(mp->name); 
		if(j > i) 
			j = i; 
		if(strncmp(a, mp->name, j) == 0) 
			break; 
	} 
	if(mp->name) 
		return mp; 
	return 0; 
} 
 
1992/0317    
/* 
1992/0318    
 *  ask user from whence cometh the root file system 
1992/0317    
 */ 
1995/1122    
static Method* 
1992/0317    
rootserver(char *arg) 
{ 
	char prompt[256]; 
	Method *mp; 
	char *cp; 
1994/0311    
	int n; 
1992/0317    
 
1994/0311    
	/* make list of methods */ 
1992/0317    
	mp = method; 
1992/0318    
	n = sprint(prompt, "root is from (%s", mp->name); 
1992/0317    
	for(mp++; mp->name; mp++) 
		n += sprint(prompt+n, ", %s", mp->name); 
	sprint(prompt+n, ")"); 
 
1994/0311    
	/* create default reply */ 
	readfile("#e/bootargs", reply, sizeof(reply)); 
	if(reply[0] == 0 && arg != 0) 
		strcpy(reply, arg); 
	if(reply[0]){ 
		mp = findmethod(reply); 
		if(mp == 0) 
			reply[0] = 0; 
1994/0219    
	} 
1994/0311    
	if(reply[0] == 0) 
		strcpy(reply, method->name); 
1994/0219    
 
1994/0311    
	/* parse replies */ 
1995/02021    
	for(;;){ 
		outin(prompt, reply, sizeof(reply)); 
1994/0311    
		mp = findmethod(reply); 
		if(mp){ 
1994/0713    
			for(cp = reply; bargc < Nbarg-1 && *cp;){ 
1994/0311    
				while(*cp && *cp != ' ') 
					cp++; 
				while(*cp == ' ') 
					*cp++ = 0; 
				if(*cp) 
1994/0713    
					bargv[bargc++] = cp++; 
1992/0317    
			} 
1997/0327    
			bargc = parsefields(reply, bargv, Nbarg-1, " "); 
1994/0311    
			cp = strchr(reply, '!'); 
			if(cp) 
				strcpy(sys, cp+1); 
			return mp; 
		} 
1992/0317    
	} 
1994/0311    
 
1992/0520    
	return 0;		/* not reached */ 
1992/0317    
} 
 
1993/0501    
int 
nop(int fd) 
{ 
	int n; 
	Fcall hdr; 
	char buf[128]; 
 
	print("boot: nop..."); 
	hdr.type = Tnop; 
	hdr.tag = NOTAG; 
	n = convS2M(&hdr, buf); 
	if(write(fd, buf, n) != n){ 
		fatal("write nop"); 
		return 0; 
	} 
reread: 
	n = read(fd, buf, sizeof buf); 
	if(n <= 0){ 
		fatal("read nop"); 
		return 0; 
	} 
	if(n == 2) 
		goto reread; 
	if(convM2S(buf, &hdr, n) == 0) { 
		fatal("format nop"); 
		return 0; 
	} 
	if(hdr.type != Rnop){ 
		fatal("not Rnop"); 
		return 0; 
	} 
	if(hdr.tag != NOTAG){ 
		fatal("tag not NOTAG"); 
		return 0; 
	} 
	return 1; 
} 
 
1992/0530    
static void 
1992/0317    
swapproc(void) 
{ 
	int fd; 
 
	fd = open("#c/swap", OWRITE); 
	if(fd < 0){ 
		warning("opening #c/swap"); 
		return; 
	} 
	if(write(fd, "start", 5) <= 0) 
		warning("starting swap kproc"); 
1993/0501    
	close(fd); 
} 
 
void 
reattach(int rec, Method *amp, char *buf) 
{ 
	char *mp; 
	int fd, n, sv[2]; 
	char tmp[64], *p; 
 
	mp = strchr(buf, ' '); 
	if(mp == 0) 
		goto fail; 
	*mp++ = '\0'; 
 
	p = strrchr(buf, '/'); 
	if(p == 0) 
		goto fail; 
1994/1212    
 
1993/0501    
	*p = '\0'; 
 
	sprint(tmp, "%s/remote", buf); 
	fd = open(tmp, OREAD); 
	if(fd < 0) 
		goto fail; 
1994/1212    
 
1993/0501    
	n = read(fd, tmp, sizeof(tmp)); 
	if(n < 0) 
		goto fail; 
1994/1212    
 
1993/0501    
	close(fd); 
	tmp[n-1] = '\0'; 
 
1994/0829    
	print("boot: Service %s!%s down, wait...\n", buf, tmp); 
1993/0501    
 
	p = strrchr(buf, '/'); 
	if(p == 0) 
		goto fail; 
	*p = '\0'; 
 
	while(plumb(buf, tmp, sv, 0) < 0) 
		sleep(30); 
 
	nop(sv[1]); 
	doauthenticate(sv[1], amp); 
 
1994/0829    
	print("\nboot: Service %s Ok\n", tmp); 
1993/0501    
 
	n = sprint(tmp, "%d %s", sv[1], mp); 
	if(write(rec, tmp, n) < 0) { 
		errstr(tmp); 
		print("write recover: %s\n", tmp); 
	} 
	exits(0); 
fail: 
	print("recover fail: %s\n", buf); 
	exits(0); 
} 
 
1995/1122    
static void 
1993/0501    
recover(Method *mp) 
{ 
	int fd, n; 
	char buf[256]; 
 
	fd = open("#/./recover", ORDWR); 
	if(fd < 0) 
		exits(0); 
 
	for(;;) { 
		n = read(fd, buf, sizeof(buf)); 
		if(n < 0) 
			exits(0); 
		buf[n] = '\0'; 
 
		if(fork() == 0) 
			reattach(fd, mp, buf); 
	} 
1992/0317    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)