📄 main.c
字号:
#include "all.h"int sfd;int cmdmode = 0660;int rfd;int chat;extern char *wrenfile;extern int nwren;char *myname;int cmdfd;int writeallow; /* never on; for compatibility with fs */int wstatallow;int writegroup;int allownone;int noatime;int srvfd(char*, int, int);void usage(void);void confinit(void);Chan *chaninit(char*);void consinit(void);void forkserve(void);voidmain(int argc, char *argv[]){ Filsys *fs; int ream, fsok; int newbufsize, nocheck; char buf[NAMELEN]; int pid, ctl; progname = "kfs"; procname = "init"; /* * insulate from invoker's environment and keep it from swapping */ rfork(RFNAMEG|RFNOTEG|RFREND); confinit(); sfd = -1; ream = 0; newbufsize = 0; nocheck = 0; wrenfile = "/dev/sdC0/fs"; pid = getpid(); snprint(buf, sizeof buf, "/proc/%d/ctl", pid); ctl = open(buf, OWRITE); fprint(ctl, "noswap\n"); close(ctl); buf[0] = '\0'; ARGBEGIN{ case 'b': newbufsize = atol(ARGF()); break; case 'c': nocheck = 1; break; case 'f': wrenfile = ARGF(); break; case 'm': nwren = atol(ARGF()); break; case 'n': strncpy(buf, ARGF(), NAMELEN-1); buf[NAMELEN-1] = '\0'; break; case 'p': cmdmode = atol(ARGF()); break; case 'r': ream = 1; break; case 's': sfd = 0; rfd = dup(1, -1); close(1); if(open("/dev/cons", OWRITE) < 0) open("#c/cons", OWRITE); break; case 'B': conf.niobuf = strtoul(ARGF(), 0, 0); break; case 'C': chat = 1; break; default: usage(); }ARGEND if(argc != 0) usage(); cmdfd = 2; if (access(wrenfile, AREAD|AWRITE) == -1) sysfatal("%s cannot access device\n", wrenfile); formatinit(); sublockinit(); if(buf[0]) sprint(service, "kfs.%s", buf); else strcpy(service, "kfs"); chan = chaninit(service); consinit(); tlocks = ialloc(NTLOCK * sizeof *tlocks); uid = ialloc(conf.nuid * sizeof(*uid)); uidspace = ialloc(conf.uidspace * sizeof(*uidspace)); gidspace = ialloc(conf.gidspace * sizeof(*gidspace)); /* * init global locks */ wlock(&mainlock); wunlock(&mainlock); /* * init the file system, ream it if needed, and get the block sizes */ ream = fsinit(ream, newbufsize); iobufinit(); for(fs=filesys; fs->name; fs++) if(fs->flags & FREAM){ /* set by fsinit if reamed */ ream++; rootream(fs->dev, getraddr(fs->dev)); superream(fs->dev, superaddr(fs->dev)); } boottime = time(nil); consserve(); fsok = superok(filesys[0].dev, superaddr(filesys[0].dev), 0); if(!nocheck && !ream && !fsok) cmd_exec("check fq"); startproc(forkserve, "srv"); startproc(syncproc, "sync"); exits(0);}voidforkserve(void){ serve(chan);}staticstruct{ int nfilter; Filter* filters[100];}f;int alarmed;voidcatchalarm(void *regs, char *msg){ USED(regs, msg); if(strcmp(msg, "alarm") == 0){ alarmed = 1; noted(NCONT); } else noted(NDFLT);}/* * process to synch blocks * it puts out a block/line every second * it waits 10 seconds if catches up. * in both cases, it takes about 10 seconds * to get up-to-date. * * it also updates the filter stats * and executes commands */voidsyncproc(void){ char buf[4*1024]; Filter *ft; ulong c0, c1; long t, n, d; int i, p[2]; /* * make a pipe for commands */ if(pipe(p) < 0) panic("command pipe"); sprint(buf, "#s/%s.cmd", service); srvfd(buf, cmdmode, p[0]); close(p[0]); cmdfd = p[1]; notify(catchalarm); t = time(nil); for(;;){ i = syncblock(); alarmed = 0; alarm(i ? 1000: 10000); n = read(cmdfd, buf, sizeof buf - 1); if(n <= 0 && !alarmed) sleep(i ? 1000: 10000); alarm(0); if(n > 0){ buf[n] = '\0'; if(cmd_exec(buf)) fprint(cmdfd, "done"); else fprint(cmdfd, "unknown command"); } n = time(nil); d = n - t; if(d < 0 || d > 5*60) d = 0; while(d >= 1) { d -= 1; for(i=0; i<f.nfilter; i++) { ft = f.filters[i]; c0 = ft->count; c1 = c0 - ft->oldcount; ft->oldcount = c0; ft->filter[0] = famd(ft->filter[0], c1, 59, 60); ft->filter[1] = famd(ft->filter[1], c1, 599, 600); ft->filter[2] = famd(ft->filter[2], c1, 5999, 6000); } } t = n; }}voiddofilter(Filter *ft){ int i; i = f.nfilter; if(i >= sizeof f.filters / sizeof f.filters[0]) { print("dofilter: too many filters\n"); return; } f.filters[i] = ft; f.nfilter = i+1;}voidstartproc(void (*f)(void), char *name){ switch(rfork(RFMEM|RFFDG|RFPROC)){ case -1: panic("can't fork"); case 0: break; default: return; } procname = name; f(); _exits(nil);}voidconfinit(void){ conf.niobuf = 0; conf.nuid = 600; conf.nserve = 2; conf.uidspace = conf.nuid*6; conf.gidspace = conf.nuid*3; cons.flags = 0;}static voiddochaninit(Chan *cp, int fd){ cp->chan = fd; fileinit(cp); wlock(&cp->reflock); wunlock(&cp->reflock); lock(&cp->flock); unlock(&cp->flock);}Chan*chaninit(char *server){ Chan *cp; char buf[3*NAMELEN]; int p[2]; sprint(buf, "#s/%s", server); if(sfd < 0){ if(pipe(p) < 0) panic("can't make a pipe"); sfd = p[0]; rfd = p[1]; } srvfd(buf, 0666, sfd); close(sfd); cp = ialloc(sizeof *cp); cons.srvchan = cp; dochaninit(cp, rfd); return cp;}intnetserve(char *netaddr){ int afd, lfd, fd; char adir[2*NAMELEN], ldir[2*NAMELEN]; Chan *netchan; if(access("/net/il/clone", 0) < 0) bind("#I", "/net", MAFTER); if(access("/net.alt/il/clone", 0) < 0) bind("#I1", "/net.alt", MAFTER); afd = announce(netaddr, adir); if (afd < 0) return -1; switch (rfork(RFMEM|RFFDG|RFPROC)) { case -1: return -1; case 0: break; default: return 0; } for (;;) { lfd = listen(adir, ldir); if (lfd < 0) continue; fd = accept(lfd, ldir); if (fd < 0) { close(lfd); continue; } netchan = mallocz(sizeof(Chan), 1); if(netchan == nil) panic("out of memory"); dochaninit(netchan, fd); switch (rfork(RFMEM|RFFDG|RFPROC)) { case -1: panic("can't fork"); case 0: close(afd); close(lfd); serve(netchan); free(netchan); exits(0); default: close(fd); close(lfd); continue; } }}intsrvfd(char *s, int mode, int sfd){ int fd; char buf[32]; fd = create(s, ORCLOSE|OWRITE, mode); if(fd < 0){ remove(s); fd = create(s, ORCLOSE|OWRITE, mode); if(fd < 0) panic(s); } sprint(buf, "%d", sfd); if(write(fd, buf, strlen(buf)) != strlen(buf)) panic("srv write"); return sfd;}voidconsinit(void){ int i; cons.chan = ialloc(sizeof(Chan)); wlock(&cons.chan->reflock); wunlock(&cons.chan->reflock); lock(&cons.chan->flock); unlock(&cons.chan->flock); dofilter(&cons.work); dofilter(&cons.rate); dofilter(&cons.bhit); dofilter(&cons.bread); dofilter(&cons.binit); for(i = 0; i < MAXTAG; i++) dofilter(&cons.tags[i]);}/* * always called with mainlock locked */voidsyncall(void){ for(;;) if(!syncblock()) return;}intaskream(Filsys *fs){ char c; print("File system %s inconsistent\n", fs->name); print("Would you like to ream it (y/n)? "); read(0, &c, 1); return c == 'y';}ulongmemsize(void){ char *p, buf[128]; int fd, n, by2pg, secs; by2pg = 4*1024; p = getenv("cputype"); if(p && strcmp(p, "68020") == 0) by2pg = 8*1024; secs = 4*1024*1024; fd = open("/dev/swap", OREAD); if(fd < 0) return secs; n = read(fd, buf, sizeof(buf)-1); close(fd); if(n <= 0) return secs; buf[n] = 0; p = strchr(buf, '/'); if(p) secs = strtoul(p+1, 0, 0)*by2pg; return secs;}/* * init the devices * wipe some of the file systems, or all if ream is set * this code really assumes that only one file system exists */intfsinit(int ream, int newbufsize){ Filsys *fs; RBUFSIZE = 4 * 1024; for(fs=filesys; fs->name; fs++) (*devcall[fs->dev.type].init)(fs->dev); if(newbufsize == 0) newbufsize = RBUFSIZE; if(conf.niobuf == 0) { conf.niobuf = memsize()/10; if(conf.niobuf > 2*1024*1024) conf.niobuf = 2*1024*1024; conf.niobuf /= newbufsize; if(conf.niobuf < 30) conf.niobuf = 30; } BUFSIZE = RBUFSIZE - sizeof(Tag); for(fs=filesys; fs->name; fs++) if(ream || (*devcall[fs->dev.type].check)(fs->dev) && askream(fs)){ RBUFSIZE = newbufsize; BUFSIZE = RBUFSIZE - sizeof(Tag); (*devcall[fs->dev.type].ream)(fs->dev); fs->flags |= FREAM; ream = 1; } /* * set up the block size dependant variables */ BUFSIZE = RBUFSIZE - sizeof(Tag); DIRPERBUF = BUFSIZE / sizeof(Dentry); INDPERBUF = BUFSIZE / sizeof(long); INDPERBUF2 = INDPERBUF * INDPERBUF; FEPERBUF = (BUFSIZE - sizeof(Super1) - sizeof(long)) / sizeof(long); return ream;}/* * allocate rest of mem * for io buffers. */#define HWIDTH 5 /* buffers per hash */voidiobufinit(void){ long i; Iobuf *p, *q; Hiob *hp; i = conf.niobuf*RBUFSIZE; niob = i / (sizeof(Iobuf) + RBUFSIZE + sizeof(Hiob)/HWIDTH); nhiob = niob / HWIDTH; while(!prime(nhiob)) nhiob++; if(chat) print(" %ld buffers; %ld hashes\n", niob, nhiob); hiob = ialloc(nhiob * sizeof(Hiob)); hp = hiob; for(i=0; i<nhiob; i++) { lock(hp); unlock(hp); hp++; } p = ialloc(niob * sizeof(Iobuf)); hp = hiob; for(i=0; i<niob; i++) { qlock(p); qunlock(p); if(hp == hiob) hp = hiob + nhiob; hp--; q = hp->link; if(q) { p->fore = q; p->back = q->back; q->back = p; p->back->fore = p; } else { hp->link = p; p->fore = p; p->back = p; } p->dev = devnone; p->addr = -1; p->xiobuf = ialloc(RBUFSIZE); p->iobuf = (char*)-1; p++; }}voidusage(void){ fprint(2, "usage: kfs [-cCr] [-b bufsize] [-s infd outfd] [-f fsfile]\n"); exits(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -