Browse Source

Plan 9 from Bell Labs 2011-04-22

David du Colombier 13 years ago
parent
commit
829e225521

+ 116 - 0
sys/lib/sysconfig/proto/stand-usb

@@ -0,0 +1,116 @@
+# fossil file system for installing from usb
+
+# files like NOTICE
+*	- sys sys
+
+# adm owns adm
+adm	- adm adm
+	+	- adm adm
+
+# upas owns mail
+mail	- upas upas
+	box	- upas upas
+		glenda	- glenda glenda
+			+	- glenda glenda
+	fs	- upas upas
+	lib	- upas upas
+		+	- upas upas
+	queue	- upas upas
+	tmp	- upas upas
+
+# glenda owns her home directory
+usr	- sys sys
+	glenda	- glenda glenda
+		+	- glenda glenda
+
+# architectures owned by sys
+386	- sys sys
+	+	- sys sys
+
+# everything else is owned by sys
+acme	- sys sys
+	+	- sys sys
+cron	- sys sys
+	upas	- upas sys
+		+	- upas sys
+fd	- sys sys
+	+	- sys sys
+env	- sys sys
+	+	- sys sys
+lib	- sys sys
+	*	- sys sys
+	cmap	- sys sys
+		+	- sys sys
+	face	- sys sys
+		+	- sys sys
+	font	- sys sys
+		+	- sys sys
+	ndb	- sys sys
+		+	- sys sys
+	news	- sys sys
+		+	- sys sys
+	sky	- sys sys
+		here	- sys sys
+lp	- sys sys
+	+	- sys sys
+mnt	- sys sys
+	+	- sys sys
+n	- sys sys
+	+	- sys sys
+rc	- sys sys
+	+	- sys sys
+sys	- sys sys
+	doc	- sys sys
+		+	- sys sys
+	include	- sys sys
+		+	- sys sys
+	lib	- sys sys
+		*
+		acid	- sys sys
+			+	- sys sys
+		backup	- sys sys
+			+	- sys sys
+		ghostscript	- sys sys
+			+	- sys sys
+		kbmap	- sys sys
+			+	- sys sys
+		lex	- sys sys
+			+	- sys sys
+		lp	- sys sys
+			+	- sys sys
+		man	- sys sys
+			+	- sys sys
+		plumb	- sys sys
+			+	- sys sys
+		postscript	- sys sys
+			+	- sys sys
+		ssh	- sys sys
+			+	- sys sys
+		sysconfig	- sys sys
+			+	- sys sys
+		texmf	- sys sys
+			+	- sys sys
+		tls	- sys sys
+			+	- sys sys
+		tmac	- sys sys
+			+	- sys sys
+		troff	- sys sys
+			+	- sys sys
+		wiki	- sys sys
+			+	- sys sys
+	log	- sys sys
+		+	- sys sys
+	man	- sys sys
+		+	- sys sys
+	src	- sys sys
+		+	- sys sys
+tmp	- sys sys
+	+	- sys sys
+
+# distribution metadata
+dist	- sys sys
+	replica	- sys sys
+		kfs	- sys sys
+		cd	- sys sys
+		network	- sys sys
+		plan9.proto	- sys sys

+ 16 - 0
sys/lib/sysconfig/usb/fossil.conf

@@ -0,0 +1,16 @@
+# fossil.conf
+
+# redundant
+# srv boot			# created by /boot/boot
+# srv -p fscons			# explicit in fossil invocation from /boot/boot
+
+fsys main config /dev/sdXX/fossil
+fsys main open -V -c 20000
+fsys main snaptime -a none -s none -t none
+fsys main
+
+listen tcp!*!564
+
+srv fossil
+srv -APW fossil.open
+srv -Ap fscons.open

+ 7 - 0
sys/lib/sysconfig/usb/plan9.ini

@@ -0,0 +1,7 @@
+bootfile=sdB0!9fat!9pccpuf.gz
+nobootprompt=local!/dev/sdXX/fossil
+nvram=/dev/sdXX/nvram
+
+debugboot=1
+*nodumpstack=1
+*noe820print=1

+ 54 - 0
sys/man/8/mkusbboot

@@ -0,0 +1,54 @@
+.TH MKUSBBOOT 8
+.SH NAME
+mkusbboot - generate bootable USB disk image
+.SH SYNOPSIS
+.B mkusbboot
+[
+.I root
+]
+.SH DESCRIPTION
+.I Mkusbboot
+generates a bootable disk image,
+called
+.BR image ,
+from the filesystem at
+.I root
+(by default
+.B /n/boot
+but often
+.BR /n/sources/plan9 ),
+and using the
+.IR mkfs (8)
+prototype file
+.BR /sys/lib/sysconfig/proto/stand-usb
+and files in
+.BR /sys/lib/sysconfig/usb .
+.PP
+The image contains a
+.IR fossil (4)
+file system and is configured to be bootable when copied to a USB disk.
+It is normally 1,900,000,000 bytes long, so it should fit on so-called 2 GB
+USB devices.
+When building from
+.BR /n/sources/plan9 ,
+the image will be 900,000,000 bytes long, to fit so-called 1 GB USB devices.
+.SH FILES
+.B /sys/lib/sysconfig/usb
+.br
+.B /sys/lib/sysconfig/proto/stand-usb
+.SH SOURCE
+.B /rc/bin/mkusbboot
+.SH SEE ALSO
+.IR usb (4),
+.IR boot (8),
+.IR diskparts (8),
+.IR partfs (8),
+.IR plan9.ini (8),
+.IR prep (8)
+.SH BUGS
+Should be run only on machines with no running
+.I fossil
+instances.
+.PP
+Not all BIOSes can reliably boot from USB devices.
+Your mileage may vary.

+ 163 - 17
sys/src/9/boot/boot.c

@@ -4,6 +4,13 @@
 #include <fcall.h>
 #include "../boot/boot.h"
 
+#define PARTSRV "partfs.sdXX"
+
+enum {
+	Dontpost,
+	Post,
+};
+
 char	cputype[64];
 char	sys[2*64];
 char 	reply[256];
@@ -11,15 +18,148 @@ int	printcol;
 int	mflag;
 int	fflag;
 int	kflag;
+int	debugboot;
 
 char	*bargv[Nbarg];
 int	bargc;
 
+static char usbdisk0[] = "/dev/sdU0.0";
+static char sdxxctl[]  = "/dev/sdXX/ctl";
+
 static void	swapproc(void);
 static Method	*rootserver(char*);
-static void	usbinit(void);
 static void	kbmap(void);
 
+/*
+ * run argv[0] (short name is name) and wait awhile for file to appear.
+ * file must be generated by running argv[0]; if it already exists, we're done.
+ */
+static int
+start(char *name, char **argv, char *file)
+{
+	int cnt;
+
+	if(access(file, AEXIST) >= 0)
+		return 0;
+	if(access(argv[0], AEXIST) < 0) {
+		fprint(2, "no %s...", argv[0]);
+		return -1;
+	}
+
+	if(debugboot)
+		fprint(2, "%s...", name);
+	runv(argv);
+	for(cnt = 10; cnt > 0 && access(file, AEXIST) < 0; cnt--)
+		sleep(100);
+	if (cnt <= 0) {
+		fprint(2, "no %s...", name);
+		return -1;
+	}
+	return 0;
+}
+
+static int
+chmod(char *file, int mode)
+{
+	Dir *dir;
+
+	dir = dirstat(file);
+	if (dir == nil) {
+		if(debugboot)
+			fprint(2, "can't stat %s: %r\n", file);
+		return -1;
+	}
+	dir->mode &= ~0777;
+	dir->mode |= mode & 0777;
+	dirwstat("/srv/" PARTSRV, dir);
+	free(dir);
+	return 0;
+}
+
+/* start partfs on first usb disk, if any */
+static int
+startpartfs(int post)
+{
+	int r, i;
+	char *parts;
+	char *partfsv[32];
+
+	if(access(usbdisk0, AEXIST) < 0)
+		return -1;	/* can't run partfs until usbd is mounted */
+
+	if (post)
+		remove("/srv/" PARTSRV);
+
+	i = 0;
+	partfsv[i++] = "/boot/partfs";
+	/*
+	 * hack for booting from usb: if /env/sdB0part (from 9load) exists,
+	 * pass it to partfs for sdXX.
+	 */
+	parts = getenv("sdB0part");
+	if (parts != nil) {
+		partfsv[i++] = "-p";
+		partfsv[i++] = parts;
+	}
+	if (post) {
+		partfsv[i++] = "-s";
+		partfsv[i++] = PARTSRV;
+	}
+	partfsv[i++] = usbdisk0;
+	partfsv[i] = nil;
+	r = start("partfs", partfsv, sdxxctl);
+
+	if (post)
+		chmod("/srv/" PARTSRV, 0666);
+	return r;
+}
+
+static int
+mountusb(void)
+{
+	int fd;
+
+	if(debugboot)
+		fprint(2, "mount usbd...");
+	fd = open("/srv/usb", ORDWR);
+	if(fd < 0)
+		warning("can't open /srv/usb");
+	else if(mount(fd, -1, "/dev", MBEFORE, "") < 0) {
+		warning("mount -a /srv/usb /dev");
+		close(fd);
+	} else
+		return 0;		/* mount closed fd */
+	return -1;
+}
+
+int
+mountusbparts(void)
+{
+	mountusb();
+	return startpartfs(Post);
+}
+
+static void
+usbinit(int post)
+{
+	int cnt;
+	static char *usbdv[] = { "/boot/usbd", nil };
+
+	if(access("#u/usb/ctl", 0) < 0 || bind("#u", "/dev", MAFTER) < 0)
+		return;
+	if(debugboot)
+		fprint(2, "usbinit...");
+	start("usbd", usbdv, "/srv/usb");
+
+	/* allow a little time for usbd's device discovery */
+	for(cnt = 20; cnt > 0 && access(usbdisk0, AEXIST) < 0; cnt--)
+		sleep(100);
+	if(cnt > 0)
+		startpartfs(post);
+	else if(debugboot)
+		fprint(2, "no usb disk...");
+}
+
 void
 boot(int argc, char *argv[])
 {
@@ -52,13 +192,15 @@ boot(int argc, char *argv[])
 	 */
 	bind("#ec", "/env", MREPL);
 	bind("#e", "/env", MBEFORE|MCREATE);
-	bind("#s", "/srv", MREPL|MCREATE);
+	bind("#s", "/srv/", MREPL|MCREATE);
+	if(getenv("debugboot"))
+		debugboot = 1;
 #ifdef DEBUG
 	print("argc=%d\n", argc);
 	for(fd = 0; fd < argc; fd++)
 		print("%#p %s ", argv[fd], argv[fd]);
 	print("\n");
-#endif DEBUG
+#endif	/* DEBUG */
 
 	ARGBEGIN{
 	case 'k':
@@ -75,9 +217,11 @@ boot(int argc, char *argv[])
 	readfile("#e/cputype", cputype, sizeof(cputype));
 
 	/*
-	 *  set up usb keyboard, mouse and disk, if any.
+	 *  set up usb keyboard & mouse, if any.
+	 *  starts usbd, which mounts itself on /dev.
+	 *  starts partfs on first disk, if any, to permit nvram on usb.
 	 */
-	usbinit();
+	usbinit(Dontpost);
 
 	/*
 	 *  pick a method and initialize it
@@ -96,9 +240,20 @@ boot(int argc, char *argv[])
 
 	/*
  	 *  authentication agent
+	 *  sets hostowner, creating an auth discontinuity
 	 */
+	if(debugboot)
+		fprint(2, "auth...");
 	authentication(cpuflag);
 
+	/* leave existing subprocesses in their own namespace */
+	rfork(RFNAMEG);
+
+	/*
+	 * restart partfs under the new hostowner id
+	 */
+	usbinit(Post);
+
 	/*
 	 *  connect to the root file system
 	 */
@@ -182,6 +337,7 @@ boot(int argc, char *argv[])
 
 	iargv[iargc] = nil;
 
+	chmod("/srv/" PARTSRV, 0600);
 	exec(cmd, iargv);
 	fatal(cmd);
 }
@@ -307,16 +463,6 @@ old9p(int fd)
 	return p[1];
 }
 
-static void
-usbinit(void)
-{
-	static char usbd[] = "/boot/usbd";
-
-	if(access("#u/usb/ctl", 0) >= 0 && bind("#u", "/dev", MAFTER) >= 0 &&
-	    access(usbd, AEXIST) >= 0)
-		run(usbd, nil);
-}
-
 static void
 kbmap(void)
 {
@@ -334,12 +480,12 @@ kbmap(void)
 
 	in = open(f, OREAD);
 	if(in < 0){
-		warning("can't open kbd map: %r");
+		warning("can't open kbd map");
 		return;
 	}
 	out = open("/dev/kbmap", OWRITE);
 	if(out < 0) {
-		warning("can't open /dev/kbmap: %r");
+		warning("can't open /dev/kbmap");
 		close(in);
 		return;
 	}

+ 24 - 14
sys/src/9/boot/local.c

@@ -9,9 +9,10 @@ static char **args;
 void
 configlocal(Method *mp)
 {
-	char *p;
+	char *p, *inibootdisk;
 	int n;
 
+	inibootdisk = getenv("bootdisk");
 	if(*sys == '/' || *sys == '#'){
 		/*
 		 *  if the user specifies the disk in the boot cmd or
@@ -29,10 +30,13 @@ configlocal(Method *mp)
 		disk = diskname;
 	} else if(mp->arg){
 		/*
-		 *  a default is supplied when the kernel is made
+		 *  a default is optionally supplied when the kernel is made
 		 */
 		disk = mp->arg;
-	} else if(*bootdisk){
+	} else if(inibootdisk != nil && *inibootdisk)
+		/* plan9.ini overrides default from config file */
+		disk = inibootdisk;
+	else if(bootdisk != nil && *bootdisk){
 		/*
 		 *  an environment variable from a pc's plan9.ini or
 		 *  from the mips nvram or generated by the kernel
@@ -42,10 +46,10 @@ configlocal(Method *mp)
 	}
 
 	/* if we've decided on one, pass it on to all programs */
-	if(disk)
-		setenv("bootdisk", disk);
-
-	USED(mp);
+	if(disk) {
+		bootdisk = disk;
+		setenv("bootdisk", bootdisk);
+	}
 }
 
 int
@@ -130,7 +134,7 @@ connectlocalkfs(void)
 }
 
 void
-run(char *file, ...)
+runv(char **argv)
 {
 	int i, pid;
 
@@ -138,16 +142,22 @@ run(char *file, ...)
 	case -1:
 		fatal("fork");
 	case 0:
-		exec(file, &file);
-		fatal(smprint("can't exec %s: %r", file));
+		exec(argv[0], argv);
+		fatal(smprint("can't exec %s: %r", argv[0]));
 	default:
 		while ((i = waitpid()) != pid && i != -1)
 			;
 		if(i == -1)
-			fatal(smprint("wait failed running %s", file));
+			fatal(smprint("wait failed running %s", argv[0]));
 	}
 }
 
+void
+run(char *file, ...)
+{
+	runv(&file);
+}
+
 static int
 print1(int fd, char *s)
 {
@@ -251,7 +261,7 @@ connectlocalfossil(void)
 		warning("open #s/fboot");
 		return -1;
 	}
-	remove("#s/fboot");	/* we'll repost as #s/boot */
+	remove("#s/fboot");  /* we'll repost fd as #s/boot after fversion(fd) */
 	return fd;
 }
 
@@ -268,9 +278,9 @@ connectlocal(void)
 	bind("#k", "/dev", MAFTER);
 	bind("#u", "/dev", MAFTER);
 	bind("#æ", "/dev", MAFTER);
+	mountusbparts();	/* make partfs partitions visible again */
 
 	if((fd = connectlocalfossil()) < 0)
-	if((fd = connectlocalkfs()) < 0)
-		return -1;
+		fd = connectlocalkfs();
 	return fd;
 }

+ 1 - 1
sys/src/cmd/ramfs.c

@@ -13,7 +13,7 @@
 enum
 {
 	OPERM	= 0x3,		/* mask of all permission types in open mode */
-	Nram	= 2048,
+	Nram	= 4096,
 	Maxsize	= 768*1024*1024,
 	Maxfdata	= 8192,
 	Maxulong= (1ULL << 32) - 1,