xref: /plan9/sys/src/cmd/disk/kfs/main.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
13e12c5d1SDavid du Colombier #include	"all.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier int	sfd;
47dd7cddfSDavid du Colombier int	cmdmode = 0660;
53e12c5d1SDavid du Colombier int	rfd;
63e12c5d1SDavid du Colombier int	chat;
73e12c5d1SDavid du Colombier extern	char *wrenfile;
87dd7cddfSDavid du Colombier extern	int nwren;
93e12c5d1SDavid du Colombier char	*myname;
103e12c5d1SDavid du Colombier int	cmdfd;
11bd389b36SDavid du Colombier int	writeallow;	/* never on; for compatibility with fs */
12bd389b36SDavid du Colombier int	wstatallow;
135d459b5aSDavid du Colombier int	writegroup;
149a747e4fSDavid du Colombier int	allownone;
159a747e4fSDavid du Colombier int	noatime;
167dd7cddfSDavid du Colombier int	srvfd(char*, int, int);
173e12c5d1SDavid du Colombier void	usage(void);
183e12c5d1SDavid du Colombier void	confinit(void);
193e12c5d1SDavid du Colombier Chan	*chaninit(char*);
203e12c5d1SDavid du Colombier void	consinit(void);
219a747e4fSDavid du Colombier void	forkserve(void);
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier void
main(int argc,char * argv[])243e12c5d1SDavid du Colombier main(int argc, char *argv[])
253e12c5d1SDavid du Colombier {
263e12c5d1SDavid du Colombier 	Filsys *fs;
279a747e4fSDavid du Colombier 	int ream, fsok;
283e12c5d1SDavid du Colombier 	int newbufsize, nocheck;
293e12c5d1SDavid du Colombier 	char buf[NAMELEN];
30b7b24591SDavid du Colombier 	int pid, ctl;
313e12c5d1SDavid du Colombier 
323e12c5d1SDavid du Colombier 	progname = "kfs";
333e12c5d1SDavid du Colombier 	procname = "init";
343e12c5d1SDavid du Colombier 
353e12c5d1SDavid du Colombier 	/*
36b7b24591SDavid du Colombier 	 * insulate from invoker's environment and keep it from swapping
373e12c5d1SDavid du Colombier 	 */
387dd7cddfSDavid du Colombier 	rfork(RFNAMEG|RFNOTEG|RFREND);
393e12c5d1SDavid du Colombier 
403e12c5d1SDavid du Colombier 	confinit();
413e12c5d1SDavid du Colombier 	sfd = -1;
423e12c5d1SDavid du Colombier 	ream = 0;
433e12c5d1SDavid du Colombier 	newbufsize = 0;
443e12c5d1SDavid du Colombier 	nocheck = 0;
457dd7cddfSDavid du Colombier 	wrenfile = "/dev/sdC0/fs";
46b7b24591SDavid du Colombier 
47b7b24591SDavid du Colombier 	pid = getpid();
48b7b24591SDavid du Colombier 	snprint(buf, sizeof buf, "/proc/%d/ctl", pid);
49b7b24591SDavid du Colombier 	ctl = open(buf, OWRITE);
50b7b24591SDavid du Colombier 	fprint(ctl, "noswap\n");
51b7b24591SDavid du Colombier 	close(ctl);
52b7b24591SDavid du Colombier 
533e12c5d1SDavid du Colombier 	buf[0] = '\0';
54b7b24591SDavid du Colombier 
553e12c5d1SDavid du Colombier 	ARGBEGIN{
563e12c5d1SDavid du Colombier 	case 'b':
573e12c5d1SDavid du Colombier 		newbufsize = atol(ARGF());
583e12c5d1SDavid du Colombier 		break;
593e12c5d1SDavid du Colombier 	case 'c':
603e12c5d1SDavid du Colombier 		nocheck = 1;
613e12c5d1SDavid du Colombier 		break;
623e12c5d1SDavid du Colombier 	case 'f':
633e12c5d1SDavid du Colombier 		wrenfile = ARGF();
643e12c5d1SDavid du Colombier 		break;
657dd7cddfSDavid du Colombier 	case 'm':
667dd7cddfSDavid du Colombier 		nwren = atol(ARGF());
677dd7cddfSDavid du Colombier 		break;
683e12c5d1SDavid du Colombier 	case 'n':
693e12c5d1SDavid du Colombier 		strncpy(buf, ARGF(), NAMELEN-1);
703e12c5d1SDavid du Colombier 		buf[NAMELEN-1] = '\0';
713e12c5d1SDavid du Colombier 		break;
727dd7cddfSDavid du Colombier 	case 'p':
737dd7cddfSDavid du Colombier 		cmdmode = atol(ARGF());
747dd7cddfSDavid du Colombier 		break;
753e12c5d1SDavid du Colombier 	case 'r':
763e12c5d1SDavid du Colombier 		ream = 1;
773e12c5d1SDavid du Colombier 		break;
783e12c5d1SDavid du Colombier 	case 's':
793e12c5d1SDavid du Colombier 		sfd = 0;
8080ee5cbfSDavid du Colombier 		rfd = dup(1, -1);
8180ee5cbfSDavid du Colombier 		close(1);
8280ee5cbfSDavid du Colombier 		if(open("/dev/cons", OWRITE) < 0)
8380ee5cbfSDavid du Colombier 			open("#c/cons", OWRITE);
843e12c5d1SDavid du Colombier 		break;
85219b2ee8SDavid du Colombier 	case 'B':
86219b2ee8SDavid du Colombier 		conf.niobuf = strtoul(ARGF(), 0, 0);
87219b2ee8SDavid du Colombier 		break;
883e12c5d1SDavid du Colombier 	case 'C':
893e12c5d1SDavid du Colombier 		chat = 1;
903e12c5d1SDavid du Colombier 		break;
913e12c5d1SDavid du Colombier 	default:
923e12c5d1SDavid du Colombier 		usage();
933e12c5d1SDavid du Colombier 	}ARGEND
947dd7cddfSDavid du Colombier 
957dd7cddfSDavid du Colombier 	if(argc != 0)
967dd7cddfSDavid du Colombier 		usage();
973e12c5d1SDavid du Colombier 
98bd389b36SDavid du Colombier 	cmdfd = 2;
993e12c5d1SDavid du Colombier 
10027e10919SDavid du Colombier 	if (access(wrenfile, AREAD|AWRITE) == -1)
101*14cc0f53SDavid du Colombier 		sysfatal("%s cannot access device", wrenfile);
10227e10919SDavid du Colombier 
1033e12c5d1SDavid du Colombier 	formatinit();
1047dd7cddfSDavid du Colombier 	sublockinit();
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier 	if(buf[0])
1073e12c5d1SDavid du Colombier 		sprint(service, "kfs.%s", buf);
1083e12c5d1SDavid du Colombier 	else
1093e12c5d1SDavid du Colombier 		strcpy(service, "kfs");
1103e12c5d1SDavid du Colombier 	chan = chaninit(service);
1113e12c5d1SDavid du Colombier 	consinit();
1123e12c5d1SDavid du Colombier 	tlocks = ialloc(NTLOCK * sizeof *tlocks);
1133e12c5d1SDavid du Colombier 	uid = ialloc(conf.nuid * sizeof(*uid));
1143e12c5d1SDavid du Colombier 	uidspace = ialloc(conf.uidspace * sizeof(*uidspace));
1153e12c5d1SDavid du Colombier 	gidspace = ialloc(conf.gidspace * sizeof(*gidspace));
1163e12c5d1SDavid du Colombier 
1173e12c5d1SDavid du Colombier 	/*
1183e12c5d1SDavid du Colombier 	 * init global locks
1193e12c5d1SDavid du Colombier 	 */
1203e12c5d1SDavid du Colombier 	wlock(&mainlock); wunlock(&mainlock);
1213e12c5d1SDavid du Colombier 
1223e12c5d1SDavid du Colombier 	/*
1233e12c5d1SDavid du Colombier 	 * init the file system, ream it if needed, and get the block sizes
1243e12c5d1SDavid du Colombier 	 */
1253e12c5d1SDavid du Colombier 	ream = fsinit(ream, newbufsize);
1263e12c5d1SDavid du Colombier 	iobufinit();
1277dd7cddfSDavid du Colombier 	for(fs=filesys; fs->name; fs++)
1283e12c5d1SDavid du Colombier 		if(fs->flags & FREAM){		/* set by fsinit if reamed */
1293e12c5d1SDavid du Colombier 			ream++;
1303e12c5d1SDavid du Colombier 			rootream(fs->dev, getraddr(fs->dev));
1313e12c5d1SDavid du Colombier 			superream(fs->dev, superaddr(fs->dev));
1323e12c5d1SDavid du Colombier 		}
1333e12c5d1SDavid du Colombier 
1347dd7cddfSDavid du Colombier 	boottime = time(nil);
1353e12c5d1SDavid du Colombier 
1363e12c5d1SDavid du Colombier 	consserve();
1377dd7cddfSDavid du Colombier 	fsok = superok(filesys[0].dev, superaddr(filesys[0].dev), 0);
138219b2ee8SDavid du Colombier 	if(!nocheck && !ream && !fsok)
1393e12c5d1SDavid du Colombier 		cmd_exec("check fq");
1403e12c5d1SDavid du Colombier 
1419a747e4fSDavid du Colombier 	startproc(forkserve, "srv");
1423e12c5d1SDavid du Colombier 	startproc(syncproc, "sync");
1433e12c5d1SDavid du Colombier 
1443e12c5d1SDavid du Colombier 	exits(0);
1453e12c5d1SDavid du Colombier }
1463e12c5d1SDavid du Colombier 
1473e12c5d1SDavid du Colombier void
forkserve(void)1489a747e4fSDavid du Colombier forkserve(void)
1493e12c5d1SDavid du Colombier {
1509a747e4fSDavid du Colombier 	serve(chan);
15159cc4ca5SDavid du Colombier }
15259cc4ca5SDavid du Colombier 
1533e12c5d1SDavid du Colombier static
1543e12c5d1SDavid du Colombier struct
1553e12c5d1SDavid du Colombier {
1563e12c5d1SDavid du Colombier 	int	nfilter;
1573e12c5d1SDavid du Colombier 	Filter*	filters[100];
1583e12c5d1SDavid du Colombier }f;
1593e12c5d1SDavid du Colombier 
1607dd7cddfSDavid du Colombier int alarmed;
1617dd7cddfSDavid du Colombier 
1623e12c5d1SDavid du Colombier void
catchalarm(void * regs,char * msg)1633e12c5d1SDavid du Colombier catchalarm(void *regs, char *msg)
1643e12c5d1SDavid du Colombier {
1653e12c5d1SDavid du Colombier 	USED(regs, msg);
1667dd7cddfSDavid du Colombier 	if(strcmp(msg, "alarm") == 0){
1677dd7cddfSDavid du Colombier 		alarmed = 1;
1683e12c5d1SDavid du Colombier 		noted(NCONT);
1697dd7cddfSDavid du Colombier 	} else
1703e12c5d1SDavid du Colombier 		noted(NDFLT);
1713e12c5d1SDavid du Colombier }
1723e12c5d1SDavid du Colombier 
1733e12c5d1SDavid du Colombier /*
1743e12c5d1SDavid du Colombier  * process to synch blocks
1753e12c5d1SDavid du Colombier  * it puts out a block/line every second
1763e12c5d1SDavid du Colombier  * it waits 10 seconds if catches up.
1773e12c5d1SDavid du Colombier  * in both cases, it takes about 10 seconds
1783e12c5d1SDavid du Colombier  * to get up-to-date.
1793e12c5d1SDavid du Colombier  *
1803e12c5d1SDavid du Colombier  * it also updates the filter stats
1813e12c5d1SDavid du Colombier  * and executes commands
1823e12c5d1SDavid du Colombier  */
1833e12c5d1SDavid du Colombier void
syncproc(void)1843e12c5d1SDavid du Colombier syncproc(void)
1853e12c5d1SDavid du Colombier {
1863e12c5d1SDavid du Colombier 	char buf[4*1024];
1873e12c5d1SDavid du Colombier 	Filter *ft;
1883e12c5d1SDavid du Colombier 	ulong c0, c1;
1893e12c5d1SDavid du Colombier 	long t, n, d;
1903e12c5d1SDavid du Colombier 	int i, p[2];
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier 	/*
1933e12c5d1SDavid du Colombier 	 * make a pipe for commands
1943e12c5d1SDavid du Colombier 	 */
1953e12c5d1SDavid du Colombier 	if(pipe(p) < 0)
1963e12c5d1SDavid du Colombier 		panic("command pipe");
1973e12c5d1SDavid du Colombier 	sprint(buf, "#s/%s.cmd", service);
1987dd7cddfSDavid du Colombier 	srvfd(buf, cmdmode, p[0]);
1993e12c5d1SDavid du Colombier 	close(p[0]);
2003e12c5d1SDavid du Colombier 	cmdfd = p[1];
2013e12c5d1SDavid du Colombier 	notify(catchalarm);
2023e12c5d1SDavid du Colombier 
2037dd7cddfSDavid du Colombier 	t = time(nil);
2043e12c5d1SDavid du Colombier 	for(;;){
2053e12c5d1SDavid du Colombier 		i = syncblock();
2067dd7cddfSDavid du Colombier 		alarmed = 0;
2073e12c5d1SDavid du Colombier 		alarm(i ? 1000: 10000);
2083e12c5d1SDavid du Colombier 		n = read(cmdfd, buf, sizeof buf - 1);
2097dd7cddfSDavid du Colombier 		if(n <= 0 && !alarmed)
2107dd7cddfSDavid du Colombier 			sleep(i ? 1000: 10000);
2113e12c5d1SDavid du Colombier 		alarm(0);
2123e12c5d1SDavid du Colombier 		if(n > 0){
2133e12c5d1SDavid du Colombier 			buf[n] = '\0';
2143e12c5d1SDavid du Colombier 			if(cmd_exec(buf))
2153e12c5d1SDavid du Colombier 				fprint(cmdfd, "done");
2163e12c5d1SDavid du Colombier 			else
2173e12c5d1SDavid du Colombier 				fprint(cmdfd, "unknown command");
2183e12c5d1SDavid du Colombier 		}
2197dd7cddfSDavid du Colombier 		n = time(nil);
2203e12c5d1SDavid du Colombier 		d = n - t;
2213e12c5d1SDavid du Colombier 		if(d < 0 || d > 5*60)
2223e12c5d1SDavid du Colombier 			d = 0;
2233e12c5d1SDavid du Colombier 		while(d >= 1) {
2243e12c5d1SDavid du Colombier 			d -= 1;
2253e12c5d1SDavid du Colombier 			for(i=0; i<f.nfilter; i++) {
2263e12c5d1SDavid du Colombier 				ft = f.filters[i];
2273e12c5d1SDavid du Colombier 				c0 = ft->count;
2283e12c5d1SDavid du Colombier 				c1 = c0 - ft->oldcount;
2293e12c5d1SDavid du Colombier 				ft->oldcount = c0;
2303e12c5d1SDavid du Colombier 				ft->filter[0] = famd(ft->filter[0], c1, 59, 60);
2313e12c5d1SDavid du Colombier 				ft->filter[1] = famd(ft->filter[1], c1, 599, 600);
2323e12c5d1SDavid du Colombier 				ft->filter[2] = famd(ft->filter[2], c1, 5999, 6000);
2333e12c5d1SDavid du Colombier 			}
2343e12c5d1SDavid du Colombier 		}
2353e12c5d1SDavid du Colombier 		t = n;
2363e12c5d1SDavid du Colombier 	}
2373e12c5d1SDavid du Colombier }
2383e12c5d1SDavid du Colombier 
2393e12c5d1SDavid du Colombier void
dofilter(Filter * ft)2403e12c5d1SDavid du Colombier dofilter(Filter *ft)
2413e12c5d1SDavid du Colombier {
2423e12c5d1SDavid du Colombier 	int i;
2433e12c5d1SDavid du Colombier 
2443e12c5d1SDavid du Colombier 	i = f.nfilter;
2453e12c5d1SDavid du Colombier 	if(i >= sizeof f.filters / sizeof f.filters[0]) {
2463e12c5d1SDavid du Colombier 		print("dofilter: too many filters\n");
2473e12c5d1SDavid du Colombier 		return;
2483e12c5d1SDavid du Colombier 	}
2493e12c5d1SDavid du Colombier 	f.filters[i] = ft;
2503e12c5d1SDavid du Colombier 	f.nfilter = i+1;
2513e12c5d1SDavid du Colombier }
2523e12c5d1SDavid du Colombier 
2533e12c5d1SDavid du Colombier void
startproc(void (* f)(void),char * name)2543e12c5d1SDavid du Colombier startproc(void (*f)(void), char *name)
2553e12c5d1SDavid du Colombier {
2563e12c5d1SDavid du Colombier 	switch(rfork(RFMEM|RFFDG|RFPROC)){
2573e12c5d1SDavid du Colombier 	case -1:
2583e12c5d1SDavid du Colombier 		panic("can't fork");
2593e12c5d1SDavid du Colombier 	case 0:
2603e12c5d1SDavid du Colombier 		break;
2613e12c5d1SDavid du Colombier 	default:
2623e12c5d1SDavid du Colombier 		return;
2633e12c5d1SDavid du Colombier 	}
2643e12c5d1SDavid du Colombier 	procname = name;
2653e12c5d1SDavid du Colombier 	f();
2669a747e4fSDavid du Colombier 	_exits(nil);
2673e12c5d1SDavid du Colombier }
2683e12c5d1SDavid du Colombier 
2693e12c5d1SDavid du Colombier void
confinit(void)2703e12c5d1SDavid du Colombier confinit(void)
2713e12c5d1SDavid du Colombier {
2729a747e4fSDavid du Colombier 	conf.niobuf = 0;
2739a747e4fSDavid du Colombier 	conf.nuid = 600;
2749a747e4fSDavid du Colombier 	conf.nserve = 2;
2759a747e4fSDavid du Colombier 	conf.uidspace = conf.nuid*6;
2769a747e4fSDavid du Colombier 	conf.gidspace = conf.nuid*3;
2779a747e4fSDavid du Colombier 	cons.flags = 0;
27859cc4ca5SDavid du Colombier }
27959cc4ca5SDavid du Colombier 
28059cc4ca5SDavid du Colombier static void
dochaninit(Chan * cp,int fd)28159cc4ca5SDavid du Colombier dochaninit(Chan *cp, int fd)
28259cc4ca5SDavid du Colombier {
28359cc4ca5SDavid du Colombier 	cp->chan = fd;
28459cc4ca5SDavid du Colombier 	fileinit(cp);
28559cc4ca5SDavid du Colombier 	wlock(&cp->reflock);
28659cc4ca5SDavid du Colombier 	wunlock(&cp->reflock);
28759cc4ca5SDavid du Colombier 	lock(&cp->flock);
28859cc4ca5SDavid du Colombier 	unlock(&cp->flock);
2893e12c5d1SDavid du Colombier }
2903e12c5d1SDavid du Colombier 
2913e12c5d1SDavid du Colombier Chan*
chaninit(char * server)2923e12c5d1SDavid du Colombier chaninit(char *server)
2933e12c5d1SDavid du Colombier {
2943e12c5d1SDavid du Colombier 	Chan *cp;
2953e12c5d1SDavid du Colombier 	char buf[3*NAMELEN];
2963e12c5d1SDavid du Colombier 	int p[2];
2973e12c5d1SDavid du Colombier 
2983e12c5d1SDavid du Colombier 	sprint(buf, "#s/%s", server);
2993e12c5d1SDavid du Colombier 	if(sfd < 0){
3003e12c5d1SDavid du Colombier 		if(pipe(p) < 0)
3013e12c5d1SDavid du Colombier 			panic("can't make a pipe");
3023e12c5d1SDavid du Colombier 		sfd = p[0];
3033e12c5d1SDavid du Colombier 		rfd = p[1];
3043e12c5d1SDavid du Colombier 	}
3057dd7cddfSDavid du Colombier 	srvfd(buf, 0666, sfd);
3063e12c5d1SDavid du Colombier 	close(sfd);
3073e12c5d1SDavid du Colombier 	cp = ialloc(sizeof *cp);
30859cc4ca5SDavid du Colombier 	cons.srvchan = cp;
30959cc4ca5SDavid du Colombier 	dochaninit(cp, rfd);
3103e12c5d1SDavid du Colombier 	return cp;
3113e12c5d1SDavid du Colombier }
3123e12c5d1SDavid du Colombier 
3133e12c5d1SDavid du Colombier int
netserve(char * netaddr)31459cc4ca5SDavid du Colombier netserve(char *netaddr)
31559cc4ca5SDavid du Colombier {
31659cc4ca5SDavid du Colombier 	int afd, lfd, fd;
31759cc4ca5SDavid du Colombier 	char adir[2*NAMELEN], ldir[2*NAMELEN];
3189a747e4fSDavid du Colombier 	Chan *netchan;
31959cc4ca5SDavid du Colombier 
3208c41de82SDavid du Colombier 	if(access("/net/tcp/clone", 0) < 0)
32159cc4ca5SDavid du Colombier 		bind("#I", "/net", MAFTER);
3228c41de82SDavid du Colombier 	if(access("/net.alt/tcp/clone", 0) < 0)
32359cc4ca5SDavid du Colombier 		bind("#I1", "/net.alt", MAFTER);
32459cc4ca5SDavid du Colombier 
32559cc4ca5SDavid du Colombier 	afd = announce(netaddr, adir);
32659cc4ca5SDavid du Colombier 	if (afd < 0)
32759cc4ca5SDavid du Colombier 		return -1;
32859cc4ca5SDavid du Colombier 	switch (rfork(RFMEM|RFFDG|RFPROC)) {
32959cc4ca5SDavid du Colombier 	case -1:
33059cc4ca5SDavid du Colombier 		return -1;
33159cc4ca5SDavid du Colombier 	case 0:
33259cc4ca5SDavid du Colombier 		break;
33359cc4ca5SDavid du Colombier 	default:
33459cc4ca5SDavid du Colombier 		return 0;
33559cc4ca5SDavid du Colombier 	}
33659cc4ca5SDavid du Colombier 	for (;;) {
33759cc4ca5SDavid du Colombier 		lfd = listen(adir, ldir);
33859cc4ca5SDavid du Colombier 		if (lfd < 0)
33959cc4ca5SDavid du Colombier 			continue;
34059cc4ca5SDavid du Colombier 		fd = accept(lfd, ldir);
34159cc4ca5SDavid du Colombier 		if (fd < 0) {
34259cc4ca5SDavid du Colombier 			close(lfd);
34359cc4ca5SDavid du Colombier 			continue;
34459cc4ca5SDavid du Colombier 		}
3459a747e4fSDavid du Colombier 		netchan = mallocz(sizeof(Chan), 1);
3469a747e4fSDavid du Colombier 		if(netchan == nil)
3479a747e4fSDavid du Colombier 			panic("out of memory");
3489a747e4fSDavid du Colombier 		dochaninit(netchan, fd);
34959cc4ca5SDavid du Colombier 		switch (rfork(RFMEM|RFFDG|RFPROC)) {
35059cc4ca5SDavid du Colombier 		case -1:
35159cc4ca5SDavid du Colombier 			panic("can't fork");
35259cc4ca5SDavid du Colombier 		case 0:
35359cc4ca5SDavid du Colombier 			close(afd);
35459cc4ca5SDavid du Colombier 			close(lfd);
3559a747e4fSDavid du Colombier 			serve(netchan);
3569a747e4fSDavid du Colombier 			free(netchan);
35759cc4ca5SDavid du Colombier 			exits(0);
35859cc4ca5SDavid du Colombier 		default:
35959cc4ca5SDavid du Colombier 			close(fd);
36059cc4ca5SDavid du Colombier 			close(lfd);
36159cc4ca5SDavid du Colombier 			continue;
36259cc4ca5SDavid du Colombier 		}
36359cc4ca5SDavid du Colombier 	}
36459cc4ca5SDavid du Colombier }
36559cc4ca5SDavid du Colombier 
36659cc4ca5SDavid du Colombier int
srvfd(char * s,int mode,int sfd)3677dd7cddfSDavid du Colombier srvfd(char *s, int mode, int sfd)
3683e12c5d1SDavid du Colombier {
3693e12c5d1SDavid du Colombier 	int fd;
3703e12c5d1SDavid du Colombier 	char buf[32];
3713e12c5d1SDavid du Colombier 
3729a747e4fSDavid du Colombier 	fd = create(s, ORCLOSE|OWRITE, mode);
3733e12c5d1SDavid du Colombier 	if(fd < 0){
3743e12c5d1SDavid du Colombier 		remove(s);
3759a747e4fSDavid du Colombier 		fd = create(s, ORCLOSE|OWRITE, mode);
3763e12c5d1SDavid du Colombier 		if(fd < 0)
3773e12c5d1SDavid du Colombier 			panic(s);
3783e12c5d1SDavid du Colombier 	}
3793e12c5d1SDavid du Colombier 	sprint(buf, "%d", sfd);
3803e12c5d1SDavid du Colombier 	if(write(fd, buf, strlen(buf)) != strlen(buf))
3813e12c5d1SDavid du Colombier 		panic("srv write");
3823e12c5d1SDavid du Colombier 	return sfd;
3833e12c5d1SDavid du Colombier }
3843e12c5d1SDavid du Colombier 
3853e12c5d1SDavid du Colombier void
consinit(void)3863e12c5d1SDavid du Colombier consinit(void)
3873e12c5d1SDavid du Colombier {
3883e12c5d1SDavid du Colombier 	int i;
3893e12c5d1SDavid du Colombier 
3903e12c5d1SDavid du Colombier 	cons.chan = ialloc(sizeof(Chan));
3913e12c5d1SDavid du Colombier 	wlock(&cons.chan->reflock);
3923e12c5d1SDavid du Colombier 	wunlock(&cons.chan->reflock);
3933e12c5d1SDavid du Colombier 	lock(&cons.chan->flock);
3943e12c5d1SDavid du Colombier 	unlock(&cons.chan->flock);
3953e12c5d1SDavid du Colombier 	dofilter(&cons.work);
3963e12c5d1SDavid du Colombier 	dofilter(&cons.rate);
3973e12c5d1SDavid du Colombier 	dofilter(&cons.bhit);
3983e12c5d1SDavid du Colombier 	dofilter(&cons.bread);
3993e12c5d1SDavid du Colombier 	dofilter(&cons.binit);
4003e12c5d1SDavid du Colombier 	for(i = 0; i < MAXTAG; i++)
4013e12c5d1SDavid du Colombier 		dofilter(&cons.tags[i]);
4023e12c5d1SDavid du Colombier }
4033e12c5d1SDavid du Colombier 
4043e12c5d1SDavid du Colombier /*
4053e12c5d1SDavid du Colombier  * always called with mainlock locked
4063e12c5d1SDavid du Colombier  */
4073e12c5d1SDavid du Colombier void
syncall(void)4083e12c5d1SDavid du Colombier syncall(void)
4093e12c5d1SDavid du Colombier {
4103e12c5d1SDavid du Colombier 	for(;;)
4113e12c5d1SDavid du Colombier 		if(!syncblock())
4123e12c5d1SDavid du Colombier 			return;
4133e12c5d1SDavid du Colombier }
4143e12c5d1SDavid du Colombier 
4153e12c5d1SDavid du Colombier int
askream(Filsys * fs)4163e12c5d1SDavid du Colombier askream(Filsys *fs)
4173e12c5d1SDavid du Colombier {
4183e12c5d1SDavid du Colombier 	char c;
4193e12c5d1SDavid du Colombier 
4203e12c5d1SDavid du Colombier 	print("File system %s inconsistent\n", fs->name);
4213e12c5d1SDavid du Colombier 	print("Would you like to ream it (y/n)? ");
4223e12c5d1SDavid du Colombier 	read(0, &c, 1);
4233e12c5d1SDavid du Colombier 	return c == 'y';
4243e12c5d1SDavid du Colombier }
4253e12c5d1SDavid du Colombier 
426219b2ee8SDavid du Colombier ulong
memsize(void)427219b2ee8SDavid du Colombier memsize(void)
428219b2ee8SDavid du Colombier {
429219b2ee8SDavid du Colombier 	char *p, buf[128];
430219b2ee8SDavid du Colombier 	int fd, n, by2pg, secs;
431219b2ee8SDavid du Colombier 
432219b2ee8SDavid du Colombier 	by2pg = 4*1024;
433219b2ee8SDavid du Colombier 	p = getenv("cputype");
434219b2ee8SDavid du Colombier 	if(p && strcmp(p, "68020") == 0)
435219b2ee8SDavid du Colombier 		by2pg = 8*1024;
436219b2ee8SDavid du Colombier 
437219b2ee8SDavid du Colombier 	secs = 4*1024*1024;
438219b2ee8SDavid du Colombier 
439219b2ee8SDavid du Colombier 	fd = open("/dev/swap", OREAD);
440219b2ee8SDavid du Colombier 	if(fd < 0)
441219b2ee8SDavid du Colombier 		return secs;
442219b2ee8SDavid du Colombier 	n = read(fd, buf, sizeof(buf)-1);
443219b2ee8SDavid du Colombier 	close(fd);
444219b2ee8SDavid du Colombier 	if(n <= 0)
445219b2ee8SDavid du Colombier 		return secs;
446219b2ee8SDavid du Colombier 	buf[n] = 0;
447219b2ee8SDavid du Colombier 	p = strchr(buf, '/');
448219b2ee8SDavid du Colombier 	if(p)
449219b2ee8SDavid du Colombier 		secs = strtoul(p+1, 0, 0)*by2pg;
450219b2ee8SDavid du Colombier 	return secs;
451219b2ee8SDavid du Colombier }
452219b2ee8SDavid du Colombier 
4533e12c5d1SDavid du Colombier /*
4543e12c5d1SDavid du Colombier  * init the devices
4553e12c5d1SDavid du Colombier  * wipe some of the file systems, or all if ream is set
4563e12c5d1SDavid du Colombier  * this code really assumes that only one file system exists
4573e12c5d1SDavid du Colombier  */
4583e12c5d1SDavid du Colombier int
fsinit(int ream,int newbufsize)4593e12c5d1SDavid du Colombier fsinit(int ream, int newbufsize)
4603e12c5d1SDavid du Colombier {
4613e12c5d1SDavid du Colombier 	Filsys *fs;
4623e12c5d1SDavid du Colombier 
4633e12c5d1SDavid du Colombier 	RBUFSIZE = 4 * 1024;
4647dd7cddfSDavid du Colombier 	for(fs=filesys; fs->name; fs++)
4653e12c5d1SDavid du Colombier 		(*devcall[fs->dev.type].init)(fs->dev);
4663e12c5d1SDavid du Colombier 	if(newbufsize == 0)
4673e12c5d1SDavid du Colombier 		newbufsize = RBUFSIZE;
468219b2ee8SDavid du Colombier 
469219b2ee8SDavid du Colombier 	if(conf.niobuf == 0) {
470219b2ee8SDavid du Colombier 		conf.niobuf = memsize()/10;
471219b2ee8SDavid du Colombier 		if(conf.niobuf > 2*1024*1024)
472219b2ee8SDavid du Colombier 			conf.niobuf = 2*1024*1024;
473219b2ee8SDavid du Colombier 		conf.niobuf /= newbufsize;
474219b2ee8SDavid du Colombier 		if(conf.niobuf < 30)
475219b2ee8SDavid du Colombier 			conf.niobuf = 30;
476219b2ee8SDavid du Colombier 	}
477219b2ee8SDavid du Colombier 
4783e12c5d1SDavid du Colombier 	BUFSIZE = RBUFSIZE - sizeof(Tag);
4793e12c5d1SDavid du Colombier 
4807dd7cddfSDavid du Colombier 	for(fs=filesys; fs->name; fs++)
4813e12c5d1SDavid du Colombier 		if(ream || (*devcall[fs->dev.type].check)(fs->dev) && askream(fs)){
4823e12c5d1SDavid du Colombier 			RBUFSIZE = newbufsize;
4833e12c5d1SDavid du Colombier 			BUFSIZE = RBUFSIZE - sizeof(Tag);
4843e12c5d1SDavid du Colombier 			(*devcall[fs->dev.type].ream)(fs->dev);
4853e12c5d1SDavid du Colombier 			fs->flags |= FREAM;
4863e12c5d1SDavid du Colombier 			ream = 1;
4873e12c5d1SDavid du Colombier 		}
4883e12c5d1SDavid du Colombier 
4893e12c5d1SDavid du Colombier 	/*
4903e12c5d1SDavid du Colombier 	 * set up the block size dependant variables
4913e12c5d1SDavid du Colombier 	 */
4923e12c5d1SDavid du Colombier 	BUFSIZE = RBUFSIZE - sizeof(Tag);
4933e12c5d1SDavid du Colombier 	DIRPERBUF = BUFSIZE / sizeof(Dentry);
4943e12c5d1SDavid du Colombier 	INDPERBUF = BUFSIZE / sizeof(long);
4953e12c5d1SDavid du Colombier 	INDPERBUF2 = INDPERBUF * INDPERBUF;
4963e12c5d1SDavid du Colombier 	FEPERBUF = (BUFSIZE - sizeof(Super1) - sizeof(long)) / sizeof(long);
4973e12c5d1SDavid du Colombier 	return ream;
4983e12c5d1SDavid du Colombier }
4993e12c5d1SDavid du Colombier 
5003e12c5d1SDavid du Colombier /*
5013e12c5d1SDavid du Colombier  * allocate rest of mem
5023e12c5d1SDavid du Colombier  * for io buffers.
5033e12c5d1SDavid du Colombier  */
5043e12c5d1SDavid du Colombier #define	HWIDTH	5	/* buffers per hash */
5053e12c5d1SDavid du Colombier void
iobufinit(void)5063e12c5d1SDavid du Colombier iobufinit(void)
5073e12c5d1SDavid du Colombier {
5083e12c5d1SDavid du Colombier 	long i;
5093e12c5d1SDavid du Colombier 	Iobuf *p, *q;
5103e12c5d1SDavid du Colombier 	Hiob *hp;
5113e12c5d1SDavid du Colombier 
5123e12c5d1SDavid du Colombier 	i = conf.niobuf*RBUFSIZE;
5133e12c5d1SDavid du Colombier 	niob = i / (sizeof(Iobuf) + RBUFSIZE + sizeof(Hiob)/HWIDTH);
5143e12c5d1SDavid du Colombier 	nhiob = niob / HWIDTH;
5153e12c5d1SDavid du Colombier 	while(!prime(nhiob))
5163e12c5d1SDavid du Colombier 		nhiob++;
5173e12c5d1SDavid du Colombier 	if(chat)
5183e12c5d1SDavid du Colombier 		print("	%ld buffers; %ld hashes\n", niob, nhiob);
5193e12c5d1SDavid du Colombier 	hiob = ialloc(nhiob * sizeof(Hiob));
5203e12c5d1SDavid du Colombier 	hp = hiob;
5213e12c5d1SDavid du Colombier 	for(i=0; i<nhiob; i++) {
5223e12c5d1SDavid du Colombier 		lock(hp);
5233e12c5d1SDavid du Colombier 		unlock(hp);
5243e12c5d1SDavid du Colombier 		hp++;
5253e12c5d1SDavid du Colombier 	}
5263e12c5d1SDavid du Colombier 	p = ialloc(niob * sizeof(Iobuf));
5273e12c5d1SDavid du Colombier 	hp = hiob;
5283e12c5d1SDavid du Colombier 	for(i=0; i<niob; i++) {
5293e12c5d1SDavid du Colombier 		qlock(p);
5303e12c5d1SDavid du Colombier 		qunlock(p);
5313e12c5d1SDavid du Colombier 		if(hp == hiob)
5323e12c5d1SDavid du Colombier 			hp = hiob + nhiob;
5333e12c5d1SDavid du Colombier 		hp--;
5343e12c5d1SDavid du Colombier 		q = hp->link;
5353e12c5d1SDavid du Colombier 		if(q) {
5363e12c5d1SDavid du Colombier 			p->fore = q;
5373e12c5d1SDavid du Colombier 			p->back = q->back;
5383e12c5d1SDavid du Colombier 			q->back = p;
5393e12c5d1SDavid du Colombier 			p->back->fore = p;
5403e12c5d1SDavid du Colombier 		} else {
5413e12c5d1SDavid du Colombier 			hp->link = p;
5423e12c5d1SDavid du Colombier 			p->fore = p;
5433e12c5d1SDavid du Colombier 			p->back = p;
5443e12c5d1SDavid du Colombier 		}
5453e12c5d1SDavid du Colombier 		p->dev = devnone;
5463e12c5d1SDavid du Colombier 		p->addr = -1;
5473e12c5d1SDavid du Colombier 		p->xiobuf = ialloc(RBUFSIZE);
5483e12c5d1SDavid du Colombier 		p->iobuf = (char*)-1;
5493e12c5d1SDavid du Colombier 		p++;
5503e12c5d1SDavid du Colombier 	}
5513e12c5d1SDavid du Colombier }
5523e12c5d1SDavid du Colombier 
553219b2ee8SDavid du Colombier void
usage(void)554219b2ee8SDavid du Colombier usage(void)
555219b2ee8SDavid du Colombier {
5563e12c5d1SDavid du Colombier 	fprint(2, "usage: kfs [-cCr] [-b bufsize] [-s infd outfd] [-f fsfile]\n");
5573e12c5d1SDavid du Colombier 	exits(0);
5583e12c5d1SDavid du Colombier }
559