xref: /plan9/sys/src/cmd/disk/kfs/main.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include	"all.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier int	sfd;
43e12c5d1SDavid du Colombier int	rfd;
53e12c5d1SDavid du Colombier int	chat;
63e12c5d1SDavid du Colombier extern	char *wrenfile;
73e12c5d1SDavid du Colombier char	*myname;
83e12c5d1SDavid du Colombier int	cmdfd;
9bd389b36SDavid du Colombier int	writeallow;	/* never on; for compatibility with fs */
10bd389b36SDavid du Colombier int	wstatallow;
113e12c5d1SDavid du Colombier int	srvfd(char*, int);
123e12c5d1SDavid du Colombier void	usage(void);
133e12c5d1SDavid du Colombier void	confinit(void);
143e12c5d1SDavid du Colombier Chan	*chaninit(char*);
153e12c5d1SDavid du Colombier void	consinit(void);
163e12c5d1SDavid du Colombier 
173e12c5d1SDavid du Colombier void
183e12c5d1SDavid du Colombier main(int argc, char *argv[])
193e12c5d1SDavid du Colombier {
203e12c5d1SDavid du Colombier 	Filsys *fs;
21*219b2ee8SDavid du Colombier 	int i, ream, fsok;
223e12c5d1SDavid du Colombier 	int newbufsize, nocheck;
233e12c5d1SDavid du Colombier 	char buf[NAMELEN];
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier 	progname = "kfs";
263e12c5d1SDavid du Colombier 	procname = "init";
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier 	/*
293e12c5d1SDavid du Colombier 	 * insulate from invokers environment
303e12c5d1SDavid du Colombier 	 */
313e12c5d1SDavid du Colombier 	rfork(RFNAMEG|RFNOTEG);
323e12c5d1SDavid du Colombier 
333e12c5d1SDavid du Colombier 	confinit();
343e12c5d1SDavid du Colombier 	sfd = -1;
353e12c5d1SDavid du Colombier 	ream = 0;
363e12c5d1SDavid du Colombier 	newbufsize = 0;
373e12c5d1SDavid du Colombier 	nocheck = 0;
38*219b2ee8SDavid du Colombier 	wrenfile = "/dev/sd0fs";
393e12c5d1SDavid du Colombier 	buf[0] = '\0';
403e12c5d1SDavid du Colombier 	ARGBEGIN{
413e12c5d1SDavid du Colombier 	case 'b':
423e12c5d1SDavid du Colombier 		newbufsize = atol(ARGF());
433e12c5d1SDavid du Colombier 		break;
443e12c5d1SDavid du Colombier 	case 'c':
453e12c5d1SDavid du Colombier 		nocheck = 1;
463e12c5d1SDavid du Colombier 		break;
473e12c5d1SDavid du Colombier 	case 'f':
483e12c5d1SDavid du Colombier 		wrenfile = ARGF();
493e12c5d1SDavid du Colombier 		break;
503e12c5d1SDavid du Colombier 	case 'n':
513e12c5d1SDavid du Colombier 		strncpy(buf, ARGF(), NAMELEN-1);
523e12c5d1SDavid du Colombier 		buf[NAMELEN-1] = '\0';
533e12c5d1SDavid du Colombier 		break;
543e12c5d1SDavid du Colombier 	case 'r':
553e12c5d1SDavid du Colombier 		ream = 1;
563e12c5d1SDavid du Colombier 		break;
573e12c5d1SDavid du Colombier 	case 's':
583e12c5d1SDavid du Colombier 		sfd = 0;
593e12c5d1SDavid du Colombier 		rfd = 1;
603e12c5d1SDavid du Colombier 		break;
61*219b2ee8SDavid du Colombier 	case 'B':
62*219b2ee8SDavid du Colombier 		conf.niobuf = strtoul(ARGF(), 0, 0);
63*219b2ee8SDavid du Colombier 		break;
643e12c5d1SDavid du Colombier 	case 'C':
653e12c5d1SDavid du Colombier 		chat = 1;
663e12c5d1SDavid du Colombier 		break;
673e12c5d1SDavid du Colombier 	default:
683e12c5d1SDavid du Colombier 		usage();
693e12c5d1SDavid du Colombier 	}ARGEND
703e12c5d1SDavid du Colombier 	USED(argc, argv);
713e12c5d1SDavid du Colombier 
72bd389b36SDavid du Colombier 	cmdfd = 2;
733e12c5d1SDavid du Colombier 
743e12c5d1SDavid du Colombier 	formatinit();
753e12c5d1SDavid du Colombier 	lockinit();
763e12c5d1SDavid du Colombier 	lock(&newfplock);
773e12c5d1SDavid du Colombier 	unlock(&newfplock);
783e12c5d1SDavid du Colombier 
793e12c5d1SDavid du Colombier 	if(buf[0])
803e12c5d1SDavid du Colombier 		sprint(service, "kfs.%s", buf);
813e12c5d1SDavid du Colombier 	else
823e12c5d1SDavid du Colombier 		strcpy(service, "kfs");
833e12c5d1SDavid du Colombier 	chan = chaninit(service);
843e12c5d1SDavid du Colombier 	consinit();
853e12c5d1SDavid du Colombier 	files = ialloc(conf.nfile * sizeof(*files));
863e12c5d1SDavid du Colombier 	for(i=0; i<conf.nfile; i++) {
873e12c5d1SDavid du Colombier 		qlock(&files[i]);
883e12c5d1SDavid du Colombier 		qunlock(&files[i]);
893e12c5d1SDavid du Colombier 	}
903e12c5d1SDavid du Colombier 	tlocks = ialloc(NTLOCK * sizeof *tlocks);
913e12c5d1SDavid du Colombier 	wpaths = ialloc(conf.nwpath * sizeof(*wpaths));
923e12c5d1SDavid du Colombier 	uid = ialloc(conf.nuid * sizeof(*uid));
933e12c5d1SDavid du Colombier 	uidspace = ialloc(conf.uidspace * sizeof(*uidspace));
943e12c5d1SDavid du Colombier 	gidspace = ialloc(conf.gidspace * sizeof(*gidspace));
953e12c5d1SDavid du Colombier 
963e12c5d1SDavid du Colombier 	/*
973e12c5d1SDavid du Colombier 	 * init global locks
983e12c5d1SDavid du Colombier 	 */
993e12c5d1SDavid du Colombier 	wlock(&mainlock); wunlock(&mainlock);
1003e12c5d1SDavid du Colombier 	lock(&wpathlock); unlock(&wpathlock);
1013e12c5d1SDavid du Colombier 
1023e12c5d1SDavid du Colombier 	/*
1033e12c5d1SDavid du Colombier 	 * init the file system, ream it if needed, and get the block sizes
1043e12c5d1SDavid du Colombier 	 */
1053e12c5d1SDavid du Colombier 	ream = fsinit(ream, newbufsize);
1063e12c5d1SDavid du Colombier 	iobufinit();
1073e12c5d1SDavid du Colombier 	for(fs=filsys; fs->name; fs++)
1083e12c5d1SDavid du Colombier 		if(fs->flags & FREAM){		/* set by fsinit if reamed */
1093e12c5d1SDavid du Colombier 			ream++;
1103e12c5d1SDavid du Colombier 			rootream(fs->dev, getraddr(fs->dev));
1113e12c5d1SDavid du Colombier 			superream(fs->dev, superaddr(fs->dev));
1123e12c5d1SDavid du Colombier 		}
1133e12c5d1SDavid du Colombier 
1143e12c5d1SDavid du Colombier 	boottime = time();
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier 	consserve();
117*219b2ee8SDavid du Colombier 	fsok = superok(filsys[0].dev, superaddr(filsys[0].dev), 0);
118*219b2ee8SDavid du Colombier 	if(!nocheck && !ream && !fsok)
1193e12c5d1SDavid du Colombier 		cmd_exec("check fq");
1203e12c5d1SDavid du Colombier 
1213e12c5d1SDavid du Colombier 	/*
1223e12c5d1SDavid du Colombier 	 * start up procs
1233e12c5d1SDavid du Colombier 	 */
1243e12c5d1SDavid du Colombier 	for(i=0; i<conf.nserve; i++)
1253e12c5d1SDavid du Colombier 		startproc(serve, "srv");
1263e12c5d1SDavid du Colombier 
1273e12c5d1SDavid du Colombier 	startproc(syncproc, "sync");
1283e12c5d1SDavid du Colombier 
1293e12c5d1SDavid du Colombier 	exits(0);
1303e12c5d1SDavid du Colombier }
1313e12c5d1SDavid du Colombier 
1323e12c5d1SDavid du Colombier Chan *
1333e12c5d1SDavid du Colombier getmsg(char *buf, Fcall *f, int *n)
1343e12c5d1SDavid du Colombier {
1353e12c5d1SDavid du Colombier 	int fd;
1363e12c5d1SDavid du Colombier 
1373e12c5d1SDavid du Colombier 	fd = chan->chan;
1383e12c5d1SDavid du Colombier 	for(;;){
1393e12c5d1SDavid du Colombier 		*n = read(fd, buf, MAXMSG + MAXDAT);
140*219b2ee8SDavid du Colombier 		if(chat)
141*219b2ee8SDavid du Colombier 			print("read msg %d\n", *n);
1423e12c5d1SDavid du Colombier 		if(*n == 0){
1433e12c5d1SDavid du Colombier 			continue;
1443e12c5d1SDavid du Colombier 		}
1453e12c5d1SDavid du Colombier 		if(*n < 0)
1463e12c5d1SDavid du Colombier 			return 0;
1473e12c5d1SDavid du Colombier 		if(convM2S(buf, f, *n))
1483e12c5d1SDavid du Colombier 			return chan;
149*219b2ee8SDavid du Colombier 		if(chat)
150*219b2ee8SDavid du Colombier 			print("bad convM2S\n");
1513e12c5d1SDavid du Colombier 	}
152*219b2ee8SDavid du Colombier 	return 0;
1533e12c5d1SDavid du Colombier }
1543e12c5d1SDavid du Colombier 
1553e12c5d1SDavid du Colombier void
1563e12c5d1SDavid du Colombier send(Chan *c, char *buf, int n)
1573e12c5d1SDavid du Colombier {
1583e12c5d1SDavid du Colombier 	int fd, m;
1593e12c5d1SDavid du Colombier 
1603e12c5d1SDavid du Colombier 	fd = c->chan;
1613e12c5d1SDavid du Colombier 	for(;;){
1623e12c5d1SDavid du Colombier 		m = write(fd, buf, n);
1633e12c5d1SDavid du Colombier 		if(m == n)
1643e12c5d1SDavid du Colombier 			return;
1653e12c5d1SDavid du Colombier 	}
1663e12c5d1SDavid du Colombier }
1673e12c5d1SDavid du Colombier 
1683e12c5d1SDavid du Colombier /*
1693e12c5d1SDavid du Colombier  * main filesystem server loop.
1703e12c5d1SDavid du Colombier  * entered by many processes.
1713e12c5d1SDavid du Colombier  * they wait for messages and
1723e12c5d1SDavid du Colombier  * then process them.
1733e12c5d1SDavid du Colombier  */
1743e12c5d1SDavid du Colombier void
1753e12c5d1SDavid du Colombier serve(void)
1763e12c5d1SDavid du Colombier {
1773e12c5d1SDavid du Colombier 	Chan *cp;
1783e12c5d1SDavid du Colombier 	Fcall fi, fo;
1793e12c5d1SDavid du Colombier 	char msgbuf[MAXMSG + MAXDAT];
1803e12c5d1SDavid du Colombier 	int t, n;
1813e12c5d1SDavid du Colombier 
1823e12c5d1SDavid du Colombier loop:
1833e12c5d1SDavid du Colombier 	cp = getmsg(msgbuf, &fi, &n);
1843e12c5d1SDavid du Colombier 	if(!cp)
1853e12c5d1SDavid du Colombier 		panic("input channel read error");
1863e12c5d1SDavid du Colombier 
1873e12c5d1SDavid du Colombier 	/*
1883e12c5d1SDavid du Colombier 	 * simple syntax checks.
1893e12c5d1SDavid du Colombier 	 */
1903e12c5d1SDavid du Colombier 	t = fi.type;
1913e12c5d1SDavid du Colombier 	if(t < 0 || t >= MAXSYSCALL || (t&1) || !p9call[t]){
1923e12c5d1SDavid du Colombier 		print("bad message type\n");
1933e12c5d1SDavid du Colombier 		fo.tag = fi.tag;
1943e12c5d1SDavid du Colombier 		fo.type = Terror+1;
1953e12c5d1SDavid du Colombier 		strncpy(fo.ename, "unknown message type", sizeof(fo.ename));
1963e12c5d1SDavid du Colombier 		goto reply;
1973e12c5d1SDavid du Colombier 	}
1983e12c5d1SDavid du Colombier 
1993e12c5d1SDavid du Colombier 	/*
2003e12c5d1SDavid du Colombier 	 * set up reply message
2013e12c5d1SDavid du Colombier 	 */
2023e12c5d1SDavid du Colombier 	fo.err = 0;
2033e12c5d1SDavid du Colombier 	if(t == Tread)
2043e12c5d1SDavid du Colombier 		fo.data = msgbuf + 8;
2053e12c5d1SDavid du Colombier 
2063e12c5d1SDavid du Colombier 	/*
2073e12c5d1SDavid du Colombier 	 * stats
2083e12c5d1SDavid du Colombier 	 */
2093e12c5d1SDavid du Colombier 	cons.work.count++;
2103e12c5d1SDavid du Colombier 	cons.rate.count += n;
2113e12c5d1SDavid du Colombier 
2123e12c5d1SDavid du Colombier 	/*
2133e12c5d1SDavid du Colombier 	 * call the file system
2143e12c5d1SDavid du Colombier 	 */
2153e12c5d1SDavid du Colombier 	rlock(&mainlock);
2163e12c5d1SDavid du Colombier 	rlock(&cp->reflock);
2173e12c5d1SDavid du Colombier 
2183e12c5d1SDavid du Colombier 	(*p9call[t])(cp, &fi, &fo);
2193e12c5d1SDavid du Colombier 
2203e12c5d1SDavid du Colombier 	runlock(&cp->reflock);
2213e12c5d1SDavid du Colombier 	runlock(&mainlock);
2223e12c5d1SDavid du Colombier 
2233e12c5d1SDavid du Colombier 	fo.type = t + 1;
2243e12c5d1SDavid du Colombier 	fo.tag = fi.tag;
2253e12c5d1SDavid du Colombier 
2263e12c5d1SDavid du Colombier 	if(fo.err) {
2273e12c5d1SDavid du Colombier 		if(CHAT(cp))
2283e12c5d1SDavid du Colombier 			print("	error: %s\n", errstr[fo.err]);
2293e12c5d1SDavid du Colombier 		fo.type = Terror+1;
2303e12c5d1SDavid du Colombier 		strncpy(fo.ename, errstr[fo.err], sizeof(fo.ename));
2313e12c5d1SDavid du Colombier 	}
2323e12c5d1SDavid du Colombier 
2333e12c5d1SDavid du Colombier reply:
2343e12c5d1SDavid du Colombier 	n = convS2M(&fo, msgbuf);
2353e12c5d1SDavid du Colombier 	if(!n) {
2363e12c5d1SDavid du Colombier 		print("bad S2M conversion\n");
2373e12c5d1SDavid du Colombier 		print("type=%d count=%d\n", msgbuf[0], n);
2383e12c5d1SDavid du Colombier 		print(" %.2x %.2x %.2x %.2x\n",
2393e12c5d1SDavid du Colombier 			msgbuf[1]&0xff, msgbuf[2]&0xff,
2403e12c5d1SDavid du Colombier 			msgbuf[3]&0xff, msgbuf[4]&0xff);
2413e12c5d1SDavid du Colombier 		print(" %.2x %.2x %.2x %.2x\n",
2423e12c5d1SDavid du Colombier 			msgbuf[5]&0xff, msgbuf[6]&0xff,
2433e12c5d1SDavid du Colombier 			msgbuf[7]&0xff, msgbuf[8]&0xff);
2443e12c5d1SDavid du Colombier 		print(" %.2x %.2x %.2x %.2x\n",
2453e12c5d1SDavid du Colombier 			msgbuf[9]&0xff, msgbuf[10]&0xff,
2463e12c5d1SDavid du Colombier 			msgbuf[11]&0xff, msgbuf[12]&0xff);
2473e12c5d1SDavid du Colombier 	}else{
2483e12c5d1SDavid du Colombier 		send(cp, msgbuf, n);
2493e12c5d1SDavid du Colombier 		cons.rate.count += n;
2503e12c5d1SDavid du Colombier 	}
2513e12c5d1SDavid du Colombier 	goto loop;
2523e12c5d1SDavid du Colombier }
2533e12c5d1SDavid du Colombier 
2543e12c5d1SDavid du Colombier static
2553e12c5d1SDavid du Colombier struct
2563e12c5d1SDavid du Colombier {
2573e12c5d1SDavid du Colombier 	int	nfilter;
2583e12c5d1SDavid du Colombier 	Filter*	filters[100];
2593e12c5d1SDavid du Colombier }f;
2603e12c5d1SDavid du Colombier 
2613e12c5d1SDavid du Colombier void
2623e12c5d1SDavid du Colombier catchalarm(void *regs, char *msg)
2633e12c5d1SDavid du Colombier {
2643e12c5d1SDavid du Colombier 	USED(regs, msg);
2653e12c5d1SDavid du Colombier 	if(strcmp(msg, "alarm") == 0)
2663e12c5d1SDavid du Colombier 		noted(NCONT);
2673e12c5d1SDavid du Colombier 	else
2683e12c5d1SDavid du Colombier 		noted(NDFLT);
2693e12c5d1SDavid du Colombier }
2703e12c5d1SDavid du Colombier 
2713e12c5d1SDavid du Colombier /*
2723e12c5d1SDavid du Colombier  * process to synch blocks
2733e12c5d1SDavid du Colombier  * it puts out a block/line every second
2743e12c5d1SDavid du Colombier  * it waits 10 seconds if catches up.
2753e12c5d1SDavid du Colombier  * in both cases, it takes about 10 seconds
2763e12c5d1SDavid du Colombier  * to get up-to-date.
2773e12c5d1SDavid du Colombier  *
2783e12c5d1SDavid du Colombier  * it also updates the filter stats
2793e12c5d1SDavid du Colombier  * and executes commands
2803e12c5d1SDavid du Colombier  */
2813e12c5d1SDavid du Colombier void
2823e12c5d1SDavid du Colombier syncproc(void)
2833e12c5d1SDavid du Colombier {
2843e12c5d1SDavid du Colombier 	char buf[4*1024];
2853e12c5d1SDavid du Colombier 	Filter *ft;
2863e12c5d1SDavid du Colombier 	ulong c0, c1;
2873e12c5d1SDavid du Colombier 	long t, n, d;
2883e12c5d1SDavid du Colombier 	int i, p[2];
2893e12c5d1SDavid du Colombier 
2903e12c5d1SDavid du Colombier 	/*
2913e12c5d1SDavid du Colombier 	 * make a pipe for commands
2923e12c5d1SDavid du Colombier 	 */
2933e12c5d1SDavid du Colombier 	if(pipe(p) < 0)
2943e12c5d1SDavid du Colombier 		panic("command pipe");
2953e12c5d1SDavid du Colombier 	sprint(buf, "#s/%s.cmd", service);
2963e12c5d1SDavid du Colombier 	srvfd(buf, p[0]);
2973e12c5d1SDavid du Colombier 	close(p[0]);
2983e12c5d1SDavid du Colombier 	cmdfd = p[1];
2993e12c5d1SDavid du Colombier 	notify(catchalarm);
3003e12c5d1SDavid du Colombier 
3013e12c5d1SDavid du Colombier 	t = time();
3023e12c5d1SDavid du Colombier 	for(;;){
3033e12c5d1SDavid du Colombier 		i = syncblock();
3043e12c5d1SDavid du Colombier 		alarm(i ? 1000: 10000);
3053e12c5d1SDavid du Colombier 		n = read(cmdfd, buf, sizeof buf - 1);
3063e12c5d1SDavid du Colombier 		alarm(0);
3073e12c5d1SDavid du Colombier 		if(n > 0){
3083e12c5d1SDavid du Colombier 			buf[n] = '\0';
3093e12c5d1SDavid du Colombier 			if(cmd_exec(buf))
3103e12c5d1SDavid du Colombier 				fprint(cmdfd, "done");
3113e12c5d1SDavid du Colombier 			else
3123e12c5d1SDavid du Colombier 				fprint(cmdfd, "unknown command");
3133e12c5d1SDavid du Colombier 		}
3143e12c5d1SDavid du Colombier 		n = time();
3153e12c5d1SDavid du Colombier 		d = n - t;
3163e12c5d1SDavid du Colombier 		if(d < 0 || d > 5*60)
3173e12c5d1SDavid du Colombier 			d = 0;
3183e12c5d1SDavid du Colombier 		while(d >= 1) {
3193e12c5d1SDavid du Colombier 			d -= 1;
3203e12c5d1SDavid du Colombier 			for(i=0; i<f.nfilter; i++) {
3213e12c5d1SDavid du Colombier 				ft = f.filters[i];
3223e12c5d1SDavid du Colombier 				c0 = ft->count;
3233e12c5d1SDavid du Colombier 				c1 = c0 - ft->oldcount;
3243e12c5d1SDavid du Colombier 				ft->oldcount = c0;
3253e12c5d1SDavid du Colombier 				ft->filter[0] = famd(ft->filter[0], c1, 59, 60);
3263e12c5d1SDavid du Colombier 				ft->filter[1] = famd(ft->filter[1], c1, 599, 600);
3273e12c5d1SDavid du Colombier 				ft->filter[2] = famd(ft->filter[2], c1, 5999, 6000);
3283e12c5d1SDavid du Colombier 			}
3293e12c5d1SDavid du Colombier 		}
3303e12c5d1SDavid du Colombier 		t = n;
3313e12c5d1SDavid du Colombier 	}
3323e12c5d1SDavid du Colombier }
3333e12c5d1SDavid du Colombier 
3343e12c5d1SDavid du Colombier void
3353e12c5d1SDavid du Colombier dofilter(Filter *ft)
3363e12c5d1SDavid du Colombier {
3373e12c5d1SDavid du Colombier 	int i;
3383e12c5d1SDavid du Colombier 
3393e12c5d1SDavid du Colombier 	i = f.nfilter;
3403e12c5d1SDavid du Colombier 	if(i >= sizeof f.filters / sizeof f.filters[0]) {
3413e12c5d1SDavid du Colombier 		print("dofilter: too many filters\n");
3423e12c5d1SDavid du Colombier 		return;
3433e12c5d1SDavid du Colombier 	}
3443e12c5d1SDavid du Colombier 	f.filters[i] = ft;
3453e12c5d1SDavid du Colombier 	f.nfilter = i+1;
3463e12c5d1SDavid du Colombier }
3473e12c5d1SDavid du Colombier 
3483e12c5d1SDavid du Colombier void
3493e12c5d1SDavid du Colombier startproc(void (*f)(void), char *name)
3503e12c5d1SDavid du Colombier {
3513e12c5d1SDavid du Colombier 	switch(rfork(RFMEM|RFFDG|RFPROC)){
3523e12c5d1SDavid du Colombier 	case -1:
3533e12c5d1SDavid du Colombier 		panic("can't fork");
3543e12c5d1SDavid du Colombier 	case 0:
3553e12c5d1SDavid du Colombier 		break;
3563e12c5d1SDavid du Colombier 	default:
3573e12c5d1SDavid du Colombier 		return;
3583e12c5d1SDavid du Colombier 	}
3593e12c5d1SDavid du Colombier 	procname = name;
3603e12c5d1SDavid du Colombier 	f();
3613e12c5d1SDavid du Colombier }
3623e12c5d1SDavid du Colombier 
3633e12c5d1SDavid du Colombier void
3643e12c5d1SDavid du Colombier confinit(void)
3653e12c5d1SDavid du Colombier {
3663e12c5d1SDavid du Colombier 	int mul;
3673e12c5d1SDavid du Colombier 
368*219b2ee8SDavid du Colombier 	conf.niobuf = 0;
3693e12c5d1SDavid du Colombier 	conf.nuid = 300;
3703e12c5d1SDavid du Colombier 	conf.nserve = 2;
3713e12c5d1SDavid du Colombier 	conf.uidspace = conf.nuid*6;
3723e12c5d1SDavid du Colombier 	conf.gidspace = conf.nuid*3;
3733e12c5d1SDavid du Colombier 
3743e12c5d1SDavid du Colombier 	/*
3753e12c5d1SDavid du Colombier 	 * nfile should be close to conf.nchan for kernel
3763e12c5d1SDavid du Colombier 	 */
3773e12c5d1SDavid du Colombier 	mul = 1;
3783e12c5d1SDavid du Colombier 	conf.nfile = 250*mul;
3793e12c5d1SDavid du Colombier 	conf.nwpath = conf.nfile*8;
3803e12c5d1SDavid du Colombier 
3813e12c5d1SDavid du Colombier 	cons.flags = 0;
3823e12c5d1SDavid du Colombier }
3833e12c5d1SDavid du Colombier 
3843e12c5d1SDavid du Colombier Chan*
3853e12c5d1SDavid du Colombier chaninit(char *server)
3863e12c5d1SDavid du Colombier {
3873e12c5d1SDavid du Colombier 	Chan *cp;
3883e12c5d1SDavid du Colombier 	char buf[3*NAMELEN];
3893e12c5d1SDavid du Colombier 	int p[2];
3903e12c5d1SDavid du Colombier 
3913e12c5d1SDavid du Colombier 	sprint(buf, "#s/%s", server);
3923e12c5d1SDavid du Colombier 	if(sfd < 0){
3933e12c5d1SDavid du Colombier 		if(pipe(p) < 0)
3943e12c5d1SDavid du Colombier 			panic("can't make a pipe");
3953e12c5d1SDavid du Colombier 		sfd = p[0];
3963e12c5d1SDavid du Colombier 		rfd = p[1];
3973e12c5d1SDavid du Colombier 	}
3983e12c5d1SDavid du Colombier 	srvfd(buf, sfd);
3993e12c5d1SDavid du Colombier 	close(sfd);
4003e12c5d1SDavid du Colombier 	cp = ialloc(sizeof *cp);
4013e12c5d1SDavid du Colombier 	cp->chan = rfd;
4023e12c5d1SDavid du Colombier 	strncpy(cp->whoname, "<none>", sizeof(cp->whoname));
4033e12c5d1SDavid du Colombier 	fileinit(cp);
4043e12c5d1SDavid du Colombier 	wlock(&cp->reflock);
4053e12c5d1SDavid du Colombier 	wunlock(&cp->reflock);
4063e12c5d1SDavid du Colombier 	lock(&cp->flock);
4073e12c5d1SDavid du Colombier 	unlock(&cp->flock);
4083e12c5d1SDavid du Colombier 	return cp;
4093e12c5d1SDavid du Colombier }
4103e12c5d1SDavid du Colombier 
4113e12c5d1SDavid du Colombier int
4123e12c5d1SDavid du Colombier srvfd(char *s, int sfd)
4133e12c5d1SDavid du Colombier {
4143e12c5d1SDavid du Colombier 	int fd;
4153e12c5d1SDavid du Colombier 	char buf[32];
4163e12c5d1SDavid du Colombier 
4173e12c5d1SDavid du Colombier 	fd = create(s, OWRITE, 0666);
4183e12c5d1SDavid du Colombier 	if(fd < 0){
4193e12c5d1SDavid du Colombier 		remove(s);
4203e12c5d1SDavid du Colombier 		fd = create(s, OWRITE, 0666);
4213e12c5d1SDavid du Colombier 		if(fd < 0)
4223e12c5d1SDavid du Colombier 			panic(s);
4233e12c5d1SDavid du Colombier 	}
4243e12c5d1SDavid du Colombier 	sprint(buf, "%d", sfd);
4253e12c5d1SDavid du Colombier 	if(write(fd, buf, strlen(buf)) != strlen(buf))
4263e12c5d1SDavid du Colombier 		panic("srv write");
427*219b2ee8SDavid du Colombier 	close(fd);
4283e12c5d1SDavid du Colombier 	return sfd;
4293e12c5d1SDavid du Colombier }
4303e12c5d1SDavid du Colombier 
4313e12c5d1SDavid du Colombier void
4323e12c5d1SDavid du Colombier consinit(void)
4333e12c5d1SDavid du Colombier {
4343e12c5d1SDavid du Colombier 	int i;
4353e12c5d1SDavid du Colombier 
4363e12c5d1SDavid du Colombier 	cons.chan = ialloc(sizeof(Chan));
4373e12c5d1SDavid du Colombier 	wlock(&cons.chan->reflock);
4383e12c5d1SDavid du Colombier 	wunlock(&cons.chan->reflock);
4393e12c5d1SDavid du Colombier 	lock(&cons.chan->flock);
4403e12c5d1SDavid du Colombier 	unlock(&cons.chan->flock);
4413e12c5d1SDavid du Colombier 	dofilter(&cons.work);
4423e12c5d1SDavid du Colombier 	dofilter(&cons.rate);
4433e12c5d1SDavid du Colombier 	dofilter(&cons.bhit);
4443e12c5d1SDavid du Colombier 	dofilter(&cons.bread);
4453e12c5d1SDavid du Colombier 	dofilter(&cons.binit);
4463e12c5d1SDavid du Colombier 	for(i = 0; i < MAXTAG; i++)
4473e12c5d1SDavid du Colombier 		dofilter(&cons.tags[i]);
4483e12c5d1SDavid du Colombier }
4493e12c5d1SDavid du Colombier 
4503e12c5d1SDavid du Colombier /*
4513e12c5d1SDavid du Colombier  * always called with mainlock locked
4523e12c5d1SDavid du Colombier  */
4533e12c5d1SDavid du Colombier void
4543e12c5d1SDavid du Colombier syncall(void)
4553e12c5d1SDavid du Colombier {
4563e12c5d1SDavid du Colombier 	for(;;)
4573e12c5d1SDavid du Colombier 		if(!syncblock())
4583e12c5d1SDavid du Colombier 			return;
4593e12c5d1SDavid du Colombier }
4603e12c5d1SDavid du Colombier 
4613e12c5d1SDavid du Colombier int
4623e12c5d1SDavid du Colombier askream(Filsys *fs)
4633e12c5d1SDavid du Colombier {
4643e12c5d1SDavid du Colombier 	char c;
4653e12c5d1SDavid du Colombier 
4663e12c5d1SDavid du Colombier 	print("File system %s inconsistent\n", fs->name);
4673e12c5d1SDavid du Colombier 	print("Would you like to ream it (y/n)? ");
4683e12c5d1SDavid du Colombier 	read(0, &c, 1);
4693e12c5d1SDavid du Colombier 	return c == 'y';
4703e12c5d1SDavid du Colombier }
4713e12c5d1SDavid du Colombier 
472*219b2ee8SDavid du Colombier ulong
473*219b2ee8SDavid du Colombier memsize(void)
474*219b2ee8SDavid du Colombier {
475*219b2ee8SDavid du Colombier 	char *p, buf[128];
476*219b2ee8SDavid du Colombier 	int fd, n, by2pg, secs;
477*219b2ee8SDavid du Colombier 
478*219b2ee8SDavid du Colombier 	by2pg = 4*1024;
479*219b2ee8SDavid du Colombier 	p = getenv("cputype");
480*219b2ee8SDavid du Colombier 	if(p && strcmp(p, "68020") == 0)
481*219b2ee8SDavid du Colombier 		by2pg = 8*1024;
482*219b2ee8SDavid du Colombier 
483*219b2ee8SDavid du Colombier 	secs = 4*1024*1024;
484*219b2ee8SDavid du Colombier 
485*219b2ee8SDavid du Colombier 	fd = open("/dev/swap", OREAD);
486*219b2ee8SDavid du Colombier 	if(fd < 0)
487*219b2ee8SDavid du Colombier 		return secs;
488*219b2ee8SDavid du Colombier 	n = read(fd, buf, sizeof(buf)-1);
489*219b2ee8SDavid du Colombier 	close(fd);
490*219b2ee8SDavid du Colombier 	if(n <= 0)
491*219b2ee8SDavid du Colombier 		return secs;
492*219b2ee8SDavid du Colombier 	buf[n] = 0;
493*219b2ee8SDavid du Colombier 	p = strchr(buf, '/');
494*219b2ee8SDavid du Colombier 	if(p)
495*219b2ee8SDavid du Colombier 		secs = strtoul(p+1, 0, 0)*by2pg;
496*219b2ee8SDavid du Colombier 	return secs;
497*219b2ee8SDavid du Colombier }
498*219b2ee8SDavid du Colombier 
4993e12c5d1SDavid du Colombier /*
5003e12c5d1SDavid du Colombier  * init the devices
5013e12c5d1SDavid du Colombier  * wipe some of the file systems, or all if ream is set
5023e12c5d1SDavid du Colombier  * this code really assumes that only one file system exists
5033e12c5d1SDavid du Colombier  */
5043e12c5d1SDavid du Colombier int
5053e12c5d1SDavid du Colombier fsinit(int ream, int newbufsize)
5063e12c5d1SDavid du Colombier {
5073e12c5d1SDavid du Colombier 	Filsys *fs;
5083e12c5d1SDavid du Colombier 
5093e12c5d1SDavid du Colombier 	RBUFSIZE = 4 * 1024;
5103e12c5d1SDavid du Colombier 	for(fs=filsys; fs->name; fs++)
5113e12c5d1SDavid du Colombier 		(*devcall[fs->dev.type].init)(fs->dev);
5123e12c5d1SDavid du Colombier 	if(newbufsize == 0)
5133e12c5d1SDavid du Colombier 		newbufsize = RBUFSIZE;
514*219b2ee8SDavid du Colombier 
515*219b2ee8SDavid du Colombier 	if(conf.niobuf == 0) {
516*219b2ee8SDavid du Colombier 		conf.niobuf = memsize()/10;
517*219b2ee8SDavid du Colombier 		if(conf.niobuf > 2*1024*1024)
518*219b2ee8SDavid du Colombier 			conf.niobuf = 2*1024*1024;
519*219b2ee8SDavid du Colombier 		conf.niobuf /= newbufsize;
520*219b2ee8SDavid du Colombier 		if(conf.niobuf < 30)
521*219b2ee8SDavid du Colombier 			conf.niobuf = 30;
522*219b2ee8SDavid du Colombier 	}
523*219b2ee8SDavid du Colombier 
5243e12c5d1SDavid du Colombier 	BUFSIZE = RBUFSIZE - sizeof(Tag);
5253e12c5d1SDavid du Colombier 
5263e12c5d1SDavid du Colombier 	for(fs=filsys; fs->name; fs++)
5273e12c5d1SDavid du Colombier 		if(ream || (*devcall[fs->dev.type].check)(fs->dev) && askream(fs)){
5283e12c5d1SDavid du Colombier 			RBUFSIZE = newbufsize;
5293e12c5d1SDavid du Colombier 			BUFSIZE = RBUFSIZE - sizeof(Tag);
5303e12c5d1SDavid du Colombier 			(*devcall[fs->dev.type].ream)(fs->dev);
5313e12c5d1SDavid du Colombier 			fs->flags |= FREAM;
5323e12c5d1SDavid du Colombier 			ream = 1;
5333e12c5d1SDavid du Colombier 		}
5343e12c5d1SDavid du Colombier 
5353e12c5d1SDavid du Colombier 	/*
5363e12c5d1SDavid du Colombier 	 * set up the block size dependant variables
5373e12c5d1SDavid du Colombier 	 */
5383e12c5d1SDavid du Colombier 	BUFSIZE = RBUFSIZE - sizeof(Tag);
5393e12c5d1SDavid du Colombier 	DIRPERBUF = BUFSIZE / sizeof(Dentry);
5403e12c5d1SDavid du Colombier 	INDPERBUF = BUFSIZE / sizeof(long);
5413e12c5d1SDavid du Colombier 	INDPERBUF2 = INDPERBUF * INDPERBUF;
5423e12c5d1SDavid du Colombier 	FEPERBUF = (BUFSIZE - sizeof(Super1) - sizeof(long)) / sizeof(long);
5433e12c5d1SDavid du Colombier 	return ream;
5443e12c5d1SDavid du Colombier }
5453e12c5d1SDavid du Colombier 
5463e12c5d1SDavid du Colombier /*
5473e12c5d1SDavid du Colombier  * allocate rest of mem
5483e12c5d1SDavid du Colombier  * for io buffers.
5493e12c5d1SDavid du Colombier  */
5503e12c5d1SDavid du Colombier #define	HWIDTH	5	/* buffers per hash */
5513e12c5d1SDavid du Colombier void
5523e12c5d1SDavid du Colombier iobufinit(void)
5533e12c5d1SDavid du Colombier {
5543e12c5d1SDavid du Colombier 	long i;
5553e12c5d1SDavid du Colombier 	Iobuf *p, *q;
5563e12c5d1SDavid du Colombier 	Hiob *hp;
5573e12c5d1SDavid du Colombier 
5583e12c5d1SDavid du Colombier 	i = conf.niobuf*RBUFSIZE;
5593e12c5d1SDavid du Colombier 	niob = i / (sizeof(Iobuf) + RBUFSIZE + sizeof(Hiob)/HWIDTH);
5603e12c5d1SDavid du Colombier 	nhiob = niob / HWIDTH;
5613e12c5d1SDavid du Colombier 	while(!prime(nhiob))
5623e12c5d1SDavid du Colombier 		nhiob++;
5633e12c5d1SDavid du Colombier 	if(chat)
5643e12c5d1SDavid du Colombier 		print("	%ld buffers; %ld hashes\n", niob, nhiob);
5653e12c5d1SDavid du Colombier 	hiob = ialloc(nhiob * sizeof(Hiob));
5663e12c5d1SDavid du Colombier 	hp = hiob;
5673e12c5d1SDavid du Colombier 	for(i=0; i<nhiob; i++) {
5683e12c5d1SDavid du Colombier 		lock(hp);
5693e12c5d1SDavid du Colombier 		unlock(hp);
5703e12c5d1SDavid du Colombier 		hp++;
5713e12c5d1SDavid du Colombier 	}
5723e12c5d1SDavid du Colombier 	p = ialloc(niob * sizeof(Iobuf));
5733e12c5d1SDavid du Colombier 	hp = hiob;
5743e12c5d1SDavid du Colombier 	for(i=0; i<niob; i++) {
5753e12c5d1SDavid du Colombier 		qlock(p);
5763e12c5d1SDavid du Colombier 		qunlock(p);
5773e12c5d1SDavid du Colombier 		if(hp == hiob)
5783e12c5d1SDavid du Colombier 			hp = hiob + nhiob;
5793e12c5d1SDavid du Colombier 		hp--;
5803e12c5d1SDavid du Colombier 		q = hp->link;
5813e12c5d1SDavid du Colombier 		if(q) {
5823e12c5d1SDavid du Colombier 			p->fore = q;
5833e12c5d1SDavid du Colombier 			p->back = q->back;
5843e12c5d1SDavid du Colombier 			q->back = p;
5853e12c5d1SDavid du Colombier 			p->back->fore = p;
5863e12c5d1SDavid du Colombier 		} else {
5873e12c5d1SDavid du Colombier 			hp->link = p;
5883e12c5d1SDavid du Colombier 			p->fore = p;
5893e12c5d1SDavid du Colombier 			p->back = p;
5903e12c5d1SDavid du Colombier 		}
5913e12c5d1SDavid du Colombier 		p->dev = devnone;
5923e12c5d1SDavid du Colombier 		p->addr = -1;
5933e12c5d1SDavid du Colombier 		p->xiobuf = ialloc(RBUFSIZE);
5943e12c5d1SDavid du Colombier 		p->iobuf = (char*)-1;
5953e12c5d1SDavid du Colombier 		p++;
5963e12c5d1SDavid du Colombier 	}
5973e12c5d1SDavid du Colombier }
5983e12c5d1SDavid du Colombier 
599*219b2ee8SDavid du Colombier void
600*219b2ee8SDavid du Colombier usage(void)
601*219b2ee8SDavid du Colombier {
6023e12c5d1SDavid du Colombier 	fprint(2, "usage: kfs [-cCr] [-b bufsize] [-s infd outfd] [-f fsfile]\n");
6033e12c5d1SDavid du Colombier 	exits(0);
6043e12c5d1SDavid du Colombier }
605