commit 06c96392a91db65e4286fbf5b6c65a694a8c6300
parent 66c63641d116dca26d9fcfa7f7ad7de827bd8fd0
Author: Jesus Galan Lopez (yiyus) <yiyu.jgl@gmail.com>
Date:   Fri, 25 Jun 2010 00:21:49 +0200
all your root belongs to boot/boot
Diffstat:
7 files changed, 155 insertions(+), 141 deletions(-)
diff --git a/doc/9vx.1 b/doc/9vx.1
@@ -15,6 +15,9 @@
 [
 .I -u user
 ]
+[
+.I bootargs
+]
 .PP
 .B 9vx-tap
 [
@@ -29,6 +32,9 @@
 [
 .I -u user
 ]
+[
+.I bootargs
+]
 .SH DESCRIPTION
 Plan 9 VX (or
 .I 9vx
@@ -45,18 +51,22 @@ Options can be passed to
 .I 9vx
 as command line arguments or in configuration files specified with the
 .I -p
-option (see below). If no
-.I root
-argument is present, the current directory is used.
-Alternatively, a file system can be specified in a 9vx.ini file.
+option (see below). The host file server will be visible from inside as
+.I #Z.
+One or more
+.I bootargs
+arguments will be passed to boot/boot as explained in boot(8), with the addition that
+the local method also supports local directories. The
+.I -r
+option sets
+.I nobootprompt=local!#Z/localroot
+to boot from a local directory containing a Plan 9 tree.
 If an
 .I user
 is not specified, the current user in the host operating system will be used.
 Other options are:
 .nr xx \w'\fL-m\f2name\ \ '
 .TP \n(xxu
-.BI -b
-Run /boot/boot instead of bootscript
 .TP
 .BI -f
 Do not fork at init
@@ -65,7 +75,9 @@ Do not fork at init
 Do not start the gui
 .TP
 .BI -i
-Run rc instead of init
+Run rc instead of init (sets
+.I init=#Z/386/bin/rc
+)
 .TP
 .BI -t
 Use tty for input/output
@@ -101,25 +113,23 @@ A
 .I 9vx.ini
 file contains a list of
 .I parameter=value
-pairs in a similar fasion to plan9.ini(8). Available options are
-.I bootboot,
+pairs in a similar fasion to plan9.ini(8). Additional options are
 .I nofork,
 .I nogui,
 .I initrc,
 .I usetty,
 .I memsize,
-.I netdev,
-.I macaddr
-(that can also be part of a netdev line),
-.I localroot
+.I netdev
 and
-.I user.
-Other options will be passed to the boot process as environment variables.
+.I macaddr
+(that can also be part of a netdev line).
 .SH BUGS
 The menu system of plan9.ini(8) is not supported in
 .I 9vx.ini
 files.
 .P
+kfs file systems are not supported by the included boot/boot
+.P
 .I 9vx
 is not so stable as native Plan9 systems.
 .SH "SEE ALSO"
diff --git a/src/9vx/a/bootboot.ed b/src/9vx/a/bootboot.ed
@@ -0,0 +1,58 @@
+diff -e plan9/sys/src/9/boot/aux.c 9vx/sys/src/9/boot/aux.c
+73,74c
+	exits(buf);
+.
+diff -e plan9/sys/src/9/boot/boot.c 9vx/sys/src/9/boot/boot.c
+154a
+Init:
+.
+94a
+	if(localroot){
+		srvcreate("boot", fd);
+		goto Init;
+	}
+.
+6a
+char *localroot;
+.
+diff -e plan9/sys/src/9/boot/boot.h 9vx/sys/src/9/boot/boot.h
+16a
+extern char*	localroot;
+.
+diff -e plan9/sys/src/9/boot/local.c 9vx/sys/src/9/boot/local.c
+278d
+276a
+	if((fd = connectlocalroot()) < 0)
+.
+264a
+connectlocalroot(void)
+{
+	int fd;
+	char buf[1024];
+
+	if(stat(buf, statbuf, sizeof statbuf) < 0)
+		return -1;
+	localroot = disk;
+
+	/* create working fd for /srv/boot */
+	fd = open("#~/mntloop", ORDWR);
+	if(fd < 0){
+		print("open #~/mntloop: %r\n");
+		return -1;
+	}
+	write(fd, disk, strlen(disk));
+	return fd;
+}
+
+int
+.
+171c
+			return;
+.
+diff -e plan9/sys/src/9/pc/pcf 9vx/sys/src/9/pc/pcf
+119a
+	tcp
+.
+117,118c
+boot boot #Z/usr/local/9vx
+.
diff --git a/src/9vx/bootcode.9 b/src/9vx/bootcode.9
Binary files differ.
diff --git a/src/9vx/conf.c b/src/9vx/conf.c
@@ -12,8 +12,6 @@
 #include	"etherif.h"
 #include 	"vether.h"
 
-extern char*	localroot;
-
 /*
  *  read configuration file
  */
@@ -120,9 +118,7 @@ iniopt(char *name, char *value)
 
 	if(*name == '*')
 		name++;
-	if(strcmp(name, "bootboot") == 0)
-		bootboot = 1;
-	else if(strcmp(name, "initrc") == 0)
+	if(strcmp(name, "initrc") == 0)
 		initrc = 1;
 	else if(strcmp(name, "nofork") == 0)
 		nofork = 1;
@@ -155,8 +151,6 @@ iniopt(char *name, char *value)
 	}
 	else if(strcmp(name, "macaddr") == 0)
 		setmac(value);
-	else if(strcmp(name, "localroot") == 0 && !localroot)
-		localroot = value;
 	else if(strcmp(name, "user") == 0 && !username)
 		username = value;
 }
@@ -172,23 +166,26 @@ inienv(char *name, char *value)
  * Debugging: tell user what options we guessed.
 */
 void
-printconfig(char *argv0, char **inifile, int n){
+printconfig(char *argv0){
 	int i;
 
-	print("%s ", argv0);
-	for(i=0; i<n; i++)
-		print("-p %s ", inifile[i]);
-	if(bootboot | nofork | nogui | initrc | usetty)
-		print("-%s%s%s%s%s ", bootboot ? "b" : "", nofork ? "f " : "",
-			nogui ? "g" : "", initrc ? "i " : "", usetty ? "t " : "");
+	print(argv0);
+	if(inifile)
+		print(" -p %s", inifile);
+	if(nofork | nogui | initrc | usetty)
+		print(" -%s%s%s%s", nofork ? "f " : "", nogui ? "g" : "",
+			initrc ? "i " : "", usetty ? "t " : "");
 	if(memsize != 0)
-		print("-m %d ", memsize);
+		print(" -m %d", memsize);
 	for(i=0; i<nve; i++){
-		print("-n %s", ve[i].tap ? "tap ": "");
+		print(" -n %s", ve[i].tap ? "tap ": "");
 		if(ve[i].dev != nil)
-			print("%s ", ve[i].dev);
+			print(" %s", ve[i].dev);
 		if(ve[i].mac != nil)
-			print("-a %s ", ve[i].mac);
+			print(" -a %s", ve[i].mac);
 	}
-	print("-r %s -u %s\n", localroot, username);
+	print(" -u %s", username);
+	for(i = 0; i < bootargc; i++)
+		print(" %s", bootargv[i]);
+	print("\n");
 } 
\ No newline at end of file
diff --git a/src/9vx/conf.h b/src/9vx/conf.h
@@ -4,16 +4,18 @@
 
 char	inibuf[BOOTARGSLEN];
 char	*iniline[MAXCONF];
-int	bootboot;	/* run /boot/boot instead of bootscript */
 int	initrc;	/* run rc instead of init */
 int	nofork;	/* do not fork at init */
 int	nogui;	/* do not start the gui */
 int	usetty;	/* use tty for input/output */
 int	memsize;	/* memory size */
+int	bootargc;
+char**	bootargv;
+char*	inifile;
 char*	username;
 
 int	readini(char *fn);
 void	inifields(void (*fp)(char*, char*));
 void	iniopt(char*, char*);
 void	inienv(char*, char*);
-void	printconfig(char*, char**, int);
+void	printconfig(char*);
diff --git a/src/9vx/devfs-posix.c b/src/9vx/devfs-posix.c
@@ -34,8 +34,6 @@ enum
 };
 
 extern Path *addelem(Path*, char*, Chan*);
-char	*localroot;
-
 static char *uidtoname(int);
 static char *gidtoname(int);
 static int nametouid(char*);
@@ -48,12 +46,11 @@ struct UnixFd
 {
 	int	fd;
 	int	issocket;
-	int	plan9;	// rooted at localroot?
 	DIR*	dir;
 	vlong	diroffset;
 	QLock	dirlock;
 	struct dirent *nextde;
-	Path	*path;	// relative to localroot
+	Path	*path;
 };
 
 void
@@ -106,34 +103,20 @@ fsattach(char *spec)
 	struct stat st;
 	Chan *c;
 	UnixFd *ufd;
-	int plan9, dev;
+	int dev;
 	
 	dev = 1;
-	plan9 = 0;
 	if(spec && spec[0]){
-		if(strcmp(spec, "plan9") == 0) {
-			plan9 = 1;
-			dev = 2;
-		} else{
-			snprint(up->genbuf, sizeof up->genbuf, "no file system #%C%s", FsChar, spec);
-			error(up->genbuf);
-		}
+		snprint(up->genbuf, sizeof up->genbuf, "no file system #%C%s", FsChar, spec);
+		error(up->genbuf);
 	}
 
-	if(plan9){
-		if(localroot == nil)
-			error("no #Zplan9 root without -r");
-		if(stat(localroot, &st) < 0)
-			oserror();
-	}else{
-		if(stat("/", &st) < 0)
-			oserror();
-	}
+	if(stat("/", &st) < 0)
+		oserror();
 
-	c = devattach(FsChar, spec);
+	c = devattach(FsChar, 0);
 	ufd = mallocz(sizeof(UnixFd), 1);
 	ufd->path = newpath("/");
-	ufd->plan9 = plan9;
 	ufd->fd = -1;
 
 	c->aux = ufd;
@@ -182,20 +165,11 @@ fspath(Chan *c, char *suffix)
 	
 	ufd = c->aux;
 	s = ufd->path->s;
-	if(ufd->plan9){
-		len = strlen(localroot)+strlen(s)+1;
-		if(suffix)
-			len += 1+strlen(suffix);
-		t = smalloc(len);
-		strcpy(t, localroot);
-		strcat(t, s);
-	}else{
-		len = strlen(s)+1;
-		if(suffix)
-			len += 1+strlen(suffix);
-		t = smalloc(len);
-		strcpy(t, s);
-	}
+	len = strlen(s)+1;
+	if(suffix)
+		len += 1+strlen(suffix);
+	t = smalloc(len);
+	strcpy(t, s);
 	if(suffix){
 		if(s[strlen(s)-1] != '/')
 			strcat(t, "/");
diff --git a/src/9vx/main.c b/src/9vx/main.c
@@ -49,11 +49,11 @@ int	doabort = 1;	// for now
 int	abortonfault;
 char*	argv0;
 char*	conffile = "9vx";
+char*	localroot;
 Conf	conf;
 
 static Mach mach0;
 
-extern char*	localroot;
 extern int	tracemmu;
 extern int tracekdev;
 extern int nuspace;
@@ -63,12 +63,13 @@ static void	bootinit(void);
 static void	siginit(void);
 
 static char*	getuser(void);
+static char*	nobootprompt(char*);
 
 void
 usage(void)
 {
 	// TODO(yy): add debug and other options by ron
-	fprint(2, "usage: 9vx [-p file.ini] [-bfgit] [-m memsize] [-n [tap] netdev] [-a macaddr] [-r root] [-u user]\n");
+	fprint(2, "usage: 9vx [-p file.ini] [-fgit] [-m memsize] [-n [tap] netdev] [-a macaddr] [-r root] [-u user] [bootargs]\n");
 	exit(1);
 }
 
@@ -84,8 +85,6 @@ main(int argc, char **argv)
 	int i, n;
 	char *vedev;
 	char *inifile[32];
-	char cwd[1024];
-	char buf[1024];
 	
 	/* Minimal set up to make print work. */
 	setmach(&mach0);
@@ -93,7 +92,6 @@ main(int argc, char **argv)
 	quotefmtinstall();
 
 	memset(iniline, 0, MAXCONF);
-	localroot = nil;
 	memsize = 0;
 	n = 0;
 	nogui = 0;
@@ -134,9 +132,6 @@ main(int argc, char **argv)
 	case 'a':
 		setmac(EARGF(usage()));
 		break;
-	case 'b':
-		bootboot = 1;
-		break;
 	case 'f':
 		nofork = 1;
 		break;
@@ -176,30 +171,24 @@ main(int argc, char **argv)
 	default:
 		usage();
 	}ARGEND
-	
-	if(argc != 0)
-		usage();
 
 	/*
 	 * Loop in reverse direction to overwrite older options
 	 */
-	for(i=n-1; i>=0; i--)
+	for(i = n-1; i >= 0; i--)
 		if(readini(inifile[i]) != 0)
 			panic("error reading config file %s", inifile[i]);
 
-	inifields(&iniopt);
-
-	if(!bootboot){
-		if(localroot == nil){
-			if(getcwd(cwd, sizeof cwd) == nil)
-				panic("getcwd: %r");
-			localroot = cwd;
-		}
-		snprint(buf, sizeof buf, "%s/386/bin/rc", localroot);
-		if(access(buf, 0) < 0)
-			panic("%s does not exist", buf);
-	}
+	bootargc = argc;
+	bootargv = argv;
+	/*
+	 * bootargs have preference over -r
+	 */
+	if(bootargc > 0)
+		localroot = nil;
 
+	inifields(&iniopt);
+	
 	if(username == nil && (username = getuser()) == nil)
 		username = "tor";
 	eve = strdup(username);
@@ -230,7 +219,7 @@ main(int argc, char **argv)
 	 */
 	siginit();
 
-	printconfig(argv0, inifile, n);
+	printconfig(argv0);
 
 	if(nve == 0)
 		ipdevtab = pipdevtab;
@@ -266,6 +255,18 @@ main(int argc, char **argv)
 	return 0;  // Not reached
 }
 
+char*
+nobootprompt(char *root) {
+	char cwd[1024];
+
+	if(root[0] != '/'){
+		if(getcwd(cwd, sizeof cwd) == nil)
+			panic("getcwd: %r");
+		root = cleanname(smprint("%s/%s", cwd, root));
+	}
+	return smprint("local!#Z%s", root);
+}
+
 static char*
 getuser(void)
 {
@@ -298,22 +299,6 @@ confinit(void)
 	conf.ialloc = 1<<20;
 }
 
-/*
- * Simple boot script.  Init0 takes care of setting up the
- * environment variables and name space bindings that
- * are needed to run rc and /386/init. 
- * Can't use #!/386/init -t directly, because init will treat
- * the extra argument /boot/boot as a command to run,
- * which will cause a loop.
- */
-static char *bootscript =
-	"#!/386/bin/rc\n"
-	"exec /386/init -t\n";
-
-static char *rcscript =
-	"#!/386/bin/rc\n"
-	"/386/bin/rc -i\n";
-
 static void
 bootinit(void)
 {
@@ -322,7 +307,14 @@ bootinit(void)
 	 * to ask for keys, so we have to embed a factotum binary,
 	 * even if we don't execute it to provide a file system.
 	 * Also, maybe /boot/boot needs it.
+	 *
+	 * factotum, fossil and venti are the normal Plan9 binary.
+	 * bootcode.9 is the file bootpcf.out obtained applyng
+	 * the patch in a/bootboot.ed and compiling with:
+	 *	mk 'CONF=pcf' bootpcf.out
 	 */
+	extern uchar bootcode[];
+	extern long bootlen;
 	extern uchar factotumcode[];
 	extern long factotumlen;
 	extern uchar fossilcode[];
@@ -330,14 +322,7 @@ bootinit(void)
 	extern uchar venticode[];
 	extern long ventilen;
 
-	if(bootboot){
-		extern uchar bootcode[];
-		extern long bootlen;
-		addbootfile("boot", bootcode, bootlen);
-	}else if(initrc)
-		addbootfile("boot", (uchar*)rcscript, strlen(rcscript));
-	else
-		addbootfile("boot", (uchar*)bootscript, strlen(bootscript));
+	addbootfile("boot", bootcode, bootlen);
 	addbootfile("factotum", factotumcode, factotumlen);
 	addbootfile("fossil", fossilcode, fossillen);
 	addbootfile("venti", venticode, ventilen);
@@ -434,7 +419,8 @@ bootargs(void *base)
 
 	ac = 0;
 	av[ac++] = pusharg("9vx");
-	/* TODO: could use command line argc, argv here if it was useful */
+	for(i = 0; i < bootargc && ac < 32; i++)
+		av[ac++] = pusharg(bootargv[i]);
 
 	/* 4 byte word align stack */
 	sp = (uchar*)((uintptr)sp & ~3);
@@ -480,8 +466,6 @@ static void
 init0(void)
 {
 	char buf[2*KNAMELEN];
-	Chan *c, *srvc;
-	char *root;
 
 	up->nerrlab = 0;
 	if(waserror())
@@ -512,21 +496,10 @@ init0(void)
 	ksetenv("user", username, 0);
 	ksetenv("sysname", "vx32", 0);
 	inifields(&inienv);
-
-	/* if we're not running /boot/boot, mount / and create /srv/boot */
-	if(!bootboot){
-		kbind("#Zplan9/", "/", MAFTER);
-		kbind("#p", "/proc", MREPL);
-
-		/* create working /srv/boot for backward compatibility */
-		c = namec("#~/mntloop", Aopen, ORDWR, 0);
-		root = "#Zplan9/";
-		devtab[c->type]->write(c, root, strlen(root), 0);
-		srvc = namec("#s/boot", Acreate, OWRITE, 0666);
-		ksrvadd(srvc, c);
-		cclose(srvc);
-		cclose(c);
-	}
+	if(initrc != 0)
+		inienv("init", "/386/bin/rc -i");
+	if(localroot)
+		inienv("nobootprompt", nobootprompt(localroot));
 
 	poperror();