diff options
author | cinap_lenrek <cinap_lenrek@localhost> | 2011-04-12 15:53:55 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-04-12 15:53:55 +0000 |
commit | 67e93d6a0a4f15192638e131413b9d64c4269c76 (patch) | |
tree | 88fd1d17c4be283683a96ced44159e3ce6b6f2f7 /sys/src/cmd/cwfs | |
parent | 7208d528bd42f981f2535403f72e4c0d7d8df643 (diff) |
updating cwfs and moving installer in /rc/bin
Diffstat (limited to 'sys/src/cmd/cwfs')
-rw-r--r-- | sys/src/cmd/cwfs/64xbit.h | 22 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/con.c | 7 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/config.c | 41 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/cwfs64/conf.c | 31 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/cwfs64/dat.h | 36 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/cwfs64/mkfile | 2 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/cwfs64x/conf.c | 31 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/cwfs64x/dat.h | 36 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/cwfs64x/mkfile | 2 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/iobuf.c | 34 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/main.c | 101 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/mkfile | 7 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/net.c | 358 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/pc.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/portdat.h | 1 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/portfns.h | 6 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/portmkfile | 2 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/srv.c | 209 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/sub.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/wren.c | 1 |
20 files changed, 548 insertions, 385 deletions
diff --git a/sys/src/cmd/cwfs/64xbit.h b/sys/src/cmd/cwfs/64xbit.h new file mode 100644 index 000000000..53edb78db --- /dev/null +++ b/sys/src/cmd/cwfs/64xbit.h @@ -0,0 +1,22 @@ +/* + * fundamental constants and types of the implementation + * changing any of these changes the layout on disk + */ + +/* the glorious new, incompatible (on disk) 64-bit world */ + +/* keeping NAMELEN ≤ 50 bytes permits 3 Dentrys per mag disk sector */ +enum { + NAMELEN = 144, /* max size of file name components */ + NDBLOCK = 6, /* number of direct blocks in Dentry */ + NIBLOCK = 4, /* max depth of indirect blocks */ +}; + +/* + * file offsets & sizes, in bytes & blocks. typically long or vlong. + * vlong is used in the code where would be needed if Off were just long. + */ +typedef vlong Off; + +#undef COMPAT32 +#define swaboff swab8 diff --git a/sys/src/cmd/cwfs/con.c b/sys/src/cmd/cwfs/con.c index 6448b4666..c1aa59623 100644 --- a/sys/src/cmd/cwfs/con.c +++ b/sys/src/cmd/cwfs/con.c @@ -36,13 +36,10 @@ consserve1(void *) char *conline; for (;;) { - /* conslock(); */ do { - print("%s: ", service); - if ((conline = Brdline(&bin, '\n')) == nil) - print("\n"); - else { + if ((conline = Brdline(&bin, '\n')) != nil) { conline[Blinelen(&bin)-1] = '\0'; + print("%s: %s\n", service, conline); cmd_exec(conline); } } while (conline != nil); diff --git a/sys/src/cmd/cwfs/config.c b/sys/src/cmd/cwfs/config.c index bc0d118ea..b11c53e77 100644 --- a/sys/src/cmd/cwfs/config.c +++ b/sys/src/cmd/cwfs/config.c @@ -82,6 +82,11 @@ devcmpr(Device *d1, Device *d2) case Devwren: case Devworm: case Devlworm: + if(d1->wren.file || d2->wren.file){ + if(d1->wren.file == nil || d2->wren.file == nil) + return 1; + return !!strcmp(d1->wren.file, d2->wren.file); + } if(d1->wren.ctrl == d2->wren.ctrl) if(d1->wren.targ == d2->wren.targ) if(d1->wren.lun == d2->wren.lun) @@ -222,7 +227,7 @@ config(void) { int c, m; Device *d; - char *icp; + char *icp, *s, *e; if(f.error) return devnone; @@ -248,7 +253,41 @@ config(void) d->type = Devnone; break; + case '/': /* /path/to/file mapped file */ + case '"': /* "/path/to/file" mapped file */ + case '\'': /* '/path/to/file' mapped file */ + Mapped: + d->type = Devwren; + if(c == '/'){ + s = f.charp-1; + for(e = s+1; *e; e++) + if(*e == ')' || *e == ']' || *e == '}') + break; + f.charp = e; + } else { + s = f.charp; + if((e = strchr(s, c)) == nil){ + cdiag("unterminated string", c); + return devnone; + } + f.charp = e+1; + } + d->wren.ctrl = -1; + d->wren.targ = -1; + d->wren.lun = -1; + d->wren.file = malloc((e - s) + 1); + memmove(d->wren.file, s, e - s); + d->wren.file[e - s] = 0; + break; + case 'w': /* w[#.]#[.#] wren [ctrl] unit [lun] */ + switch(*f.charp){ + case '/': + case '"': + case '\'': + c = *f.charp++; + goto Mapped; + } case 'r': /* r# worm side */ case 'l': /* l# labelled-worm side */ icp = f.charp; diff --git a/sys/src/cmd/cwfs/cwfs64/conf.c b/sys/src/cmd/cwfs/cwfs64/conf.c new file mode 100644 index 000000000..876cdee30 --- /dev/null +++ b/sys/src/cmd/cwfs/cwfs64/conf.c @@ -0,0 +1,31 @@ +/* generic old-cw configuration */ + +#include "all.h" + +#ifndef DATE +#define DATE 1170808167L +#endif + +Timet fs_mktime = DATE; /* set by mkfile */ + +Startsb startsb[] = { + "main", 2, + nil, +}; + +void +localconfinit(void) +{ + conf.nfile = 40000; + conf.nodump = 0; +// conf.nodump = 1; /* jukebox is r/o */ + conf.firstsb = 13219302; + conf.recovsb = 0; + conf.nlgmsg = 100; + conf.nsmmsg = 500; +} + +int (*fsprotocol[])(Msgbuf*) = { + serve9p2, + nil, +}; diff --git a/sys/src/cmd/cwfs/cwfs64/dat.h b/sys/src/cmd/cwfs/cwfs64/dat.h new file mode 100644 index 000000000..4c63315ca --- /dev/null +++ b/sys/src/cmd/cwfs/cwfs64/dat.h @@ -0,0 +1,36 @@ +/* generic old-cw configuration: 16K blocks, 32-bit sizes */ + +/* + * The most fundamental constant. + * The code will not compile with RBUFSIZE made a variable; + * for one thing, RBUFSIZE determines FEPERBUF, which determines + * the number of elements in a free-list-block array. + */ +#ifndef RBUFSIZE +#define RBUFSIZE (16*1024) /* raw buffer size */ +#endif +#include "64bit.h" +/* + * setting this to zero permits the use of discs of different sizes, but + * can make jukeinit() quite slow while the robotics work through each disc + * twice (once per side). + */ +enum { FIXEDSIZE = 1 }; + + +#include "portdat.h" + +enum { MAXBANK = 2 }; + +typedef struct Mbank { + ulong base; + ulong limit; +} Mbank; + +typedef struct Mconf { + Lock; + Mbank bank[MAXBANK]; + int nbank; + ulong memsize; +} Mconf; +extern Mconf mconf; diff --git a/sys/src/cmd/cwfs/cwfs64/mkfile b/sys/src/cmd/cwfs/cwfs64/mkfile new file mode 100644 index 000000000..8835ba7cd --- /dev/null +++ b/sys/src/cmd/cwfs/cwfs64/mkfile @@ -0,0 +1,2 @@ +FS='64' +<../portmkfile diff --git a/sys/src/cmd/cwfs/cwfs64x/conf.c b/sys/src/cmd/cwfs/cwfs64x/conf.c new file mode 100644 index 000000000..876cdee30 --- /dev/null +++ b/sys/src/cmd/cwfs/cwfs64x/conf.c @@ -0,0 +1,31 @@ +/* generic old-cw configuration */ + +#include "all.h" + +#ifndef DATE +#define DATE 1170808167L +#endif + +Timet fs_mktime = DATE; /* set by mkfile */ + +Startsb startsb[] = { + "main", 2, + nil, +}; + +void +localconfinit(void) +{ + conf.nfile = 40000; + conf.nodump = 0; +// conf.nodump = 1; /* jukebox is r/o */ + conf.firstsb = 13219302; + conf.recovsb = 0; + conf.nlgmsg = 100; + conf.nsmmsg = 500; +} + +int (*fsprotocol[])(Msgbuf*) = { + serve9p2, + nil, +}; diff --git a/sys/src/cmd/cwfs/cwfs64x/dat.h b/sys/src/cmd/cwfs/cwfs64x/dat.h new file mode 100644 index 000000000..e14371d43 --- /dev/null +++ b/sys/src/cmd/cwfs/cwfs64x/dat.h @@ -0,0 +1,36 @@ +/* generic old-cw configuration: 16K blocks, 32-bit sizes */ + +/* + * The most fundamental constant. + * The code will not compile with RBUFSIZE made a variable; + * for one thing, RBUFSIZE determines FEPERBUF, which determines + * the number of elements in a free-list-block array. + */ +#ifndef RBUFSIZE +#define RBUFSIZE (16*1024) /* raw buffer size */ +#endif +#include "64xbit.h" +/* + * setting this to zero permits the use of discs of different sizes, but + * can make jukeinit() quite slow while the robotics work through each disc + * twice (once per side). + */ +enum { FIXEDSIZE = 1 }; + + +#include "portdat.h" + +enum { MAXBANK = 2 }; + +typedef struct Mbank { + ulong base; + ulong limit; +} Mbank; + +typedef struct Mconf { + Lock; + Mbank bank[MAXBANK]; + int nbank; + ulong memsize; +} Mconf; +extern Mconf mconf; diff --git a/sys/src/cmd/cwfs/cwfs64x/mkfile b/sys/src/cmd/cwfs/cwfs64x/mkfile new file mode 100644 index 000000000..ab94d0fb2 --- /dev/null +++ b/sys/src/cmd/cwfs/cwfs64x/mkfile @@ -0,0 +1,2 @@ +FS='64x' +<../portmkfile diff --git a/sys/src/cmd/cwfs/iobuf.c b/sys/src/cmd/cwfs/iobuf.c index 11879f37c..577cc7c38 100644 --- a/sys/src/cmd/cwfs/iobuf.c +++ b/sys/src/cmd/cwfs/iobuf.c @@ -204,21 +204,36 @@ int checktag(Iobuf *p, int tag, Off qpath) { Tag *t; - static Off lastaddr; + ulong pc; + qpath &= ~QPDIR; t = (Tag*)(p->iobuf+BUFSIZE); + if((tag != t->tag) || ((qpath != QPNONE) && (qpath != t->path))){ + pc = getcallerpc(&p); + + if(qpath == QPNONE){ + print("checktag pc=%lux %Z(%llux) tag/path=%G/%llud; expected %G\n", + pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag); + } else { + print("checktag pc=%lux %Z(%llux) tag/path=%G/%llud; expected %G/%llud\n", + pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, qpath); + } + return 1; + } + + /* if(t->tag != tag) { if(p->flags & Bmod) { - print("\ttag = %d/%llud; expected %lld/%d -- not flushed\n", + print("\t%llux: tag = %G/%llud; expected %G/%d -- not flushed\n", t->tag, (Wideoff)t->path, (Wideoff)qpath, tag); return 2; } if(p->dev != nil && p->dev->type == Devcw) cwfree(p->dev, p->addr); if(p->addr != lastaddr) - print("\ttag = %G/%llud; expected %G/%lld -- flushed (%lld)\n", - t->tag, (Wideoff)t->path, tag, (Wideoff)qpath, - (Wideoff)p->addr); + print("\t%llux: tag = %G/%llud; expected %G/%lld -- flushed\n", + (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, (Wideoff)qpath); + lastaddr = p->addr; p->dev = devnone; p->addr = -1; @@ -226,13 +241,14 @@ checktag(Iobuf *p, int tag, Off qpath) return 2; } if(qpath != QPNONE) { - if((qpath ^ t->path) & ~QPDIR) { - if(1 || CHAT(0)) - print("\ttag/path = %llud; expected %d/%llux\n", - (Wideoff)t->path, tag, (Wideoff)qpath); + if(qpath ^ t->path) { + print("\t%llux: tag/path = %G/%llud; expected %G/%llux\n", + (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, (Wideoff)qpath); return 0; } } + */ + return 0; } diff --git a/sys/src/cmd/cwfs/main.c b/sys/src/cmd/cwfs/main.c index d1422a1f9..b7654e505 100644 --- a/sys/src/cmd/cwfs/main.c +++ b/sys/src/cmd/cwfs/main.c @@ -7,6 +7,7 @@ extern int oldcachefmt; Map *devmap; +int sfd, rfd; Biobuf bin; void @@ -148,6 +149,57 @@ confinit(void) mapinit(conf.devmap); } +static int +srvfd(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; +} + +static void +postservice(void) +{ + char buf[3*NAMELEN]; + int p[2]; + + if(sfd < 0){ + if(pipe(p) < 0) + panic("can't make a pipe"); + sfd = p[0]; + rfd = p[1]; + } + + /* post 9p service */ + snprint(buf, sizeof(buf), "#s/%s", service); + srvfd(buf, 0666, sfd); + close(sfd); + srvchan(rfd, buf); + + if(pipe(p) < 0) + panic("can't make a pipe"); + + /* post cmd service */ + snprint(buf, sizeof(buf), "#s/%s.cmd", service); + srvfd(buf, 0222, p[0]); + close(p[0]); + + /* use it as stdin */ + dup(p[1], 0); + close(p[1]); +} + /* * compute BUFSIZE*(NDBLOCK+INDPERBUF+INDPERBUF+INDPERBUF+INDPERBUF⁴) * while watching for overflow; in that case, return 0. @@ -224,8 +276,7 @@ printsizes(void) void usage(void) { - fprint(2, "usage: %s [-cf][-a ann-str][-m dev-map] config-dev\n", - argv0); + fprint(2, "usage: %s [ -csC ] [ -a ann-str ] [ -m dev-map ] [-f config-dev ]\n", argv0); exits("usage"); } @@ -234,11 +285,13 @@ main(int argc, char **argv) { int i, nets = 0; char *ann; - + rfork(RFNOTEG); formatinit(); machinit(); - conf.confdev = "n"; /* Devnone */ + conf.confdev = "/dev/sdC0/cwfs"; + + rfd = sfd = -1; ARGBEGIN{ case 'a': /* announce on this net */ @@ -250,12 +303,25 @@ main(int argc, char **argv) } annstrs[nets++] = ann; break; - case 'c': /* use new, faster cache layout */ + case 's': + sfd = dup(0, -1); + rfd = dup(1, -1); + close(0); + if(open("/dev/cons", OREAD) < 0) + open("#c/cons", OREAD); + close(1); + if(open("/dev/cons", OWRITE) < 0) + open("#c/cons", OWRITE); + break; + case 'C': /* use new, faster cache layout */ oldcachefmt = 0; break; - case 'f': /* enter configuration mode first */ + case 'c': conf.configfirst++; break; + case 'f': /* device / partition / file */ + conf.confdev = EARGF(usage()); + break; case 'm': /* name device-map file */ conf.devmap = EARGF(usage()); break; @@ -264,9 +330,8 @@ main(int argc, char **argv) break; }ARGEND - if (argc != 1) + if(argc != 0) usage(); - conf.confdev = argv[0]; /* config string for dev holding full config */ Binit(&bin, 0, OREAD); confinit(); @@ -304,6 +369,13 @@ main(int argc, char **argv) print("sysinit\n"); sysinit(); + srvinit(); + + /* + * post filedescriptors to /srv + */ + postservice(); + /* * Ethernet i/o processes */ @@ -326,16 +398,14 @@ main(int argc, char **argv) newproc(wormcopy, 0, "wcp"); /* - * processes to read the console + * "sync" copy process */ - consserve(); + newproc(synccopy, 0, "scp"); /* - * "sync" copy process - * this doesn't return. + * processes to read the console */ - procsetname("scp"); - synccopy(); + consserve(); } /* @@ -541,7 +611,7 @@ wormcopy(void *) * to get up-to-date. */ void -synccopy(void) +synccopy(void *) { int f; @@ -584,3 +654,4 @@ inqsize(char *file) free(data); return rv; } + diff --git a/sys/src/cmd/cwfs/mkfile b/sys/src/cmd/cwfs/mkfile index 6ff9c0126..19d826980 100644 --- a/sys/src/cmd/cwfs/mkfile +++ b/sys/src/cmd/cwfs/mkfile @@ -2,9 +2,14 @@ default:V: all all allall first default clean nuke install installall safeinstall safeinstallall update man:V: cd cwfs && mk $target + emelie.%:V: cd emelie && mk $stem fs64.%:V: cd fs64 && mk $stem +cwfs64.%:V: + cd cwfs64 && mk $stem +cwfs64x.%:V: + cd cwfs64x && mk $stem -cleanall:V: clean emelie.clean fs64.clean +cleanall:V: clean emelie.clean fs64.clean cwfs64.clean cwfs64x.clean diff --git a/sys/src/cmd/cwfs/net.c b/sys/src/cmd/cwfs/net.c index 97553be6a..b2f2b7272 100644 --- a/sys/src/cmd/cwfs/net.c +++ b/sys/src/cmd/cwfs/net.c @@ -2,16 +2,6 @@ #include "all.h" #include "io.h" -#include <fcall.h> /* 9p2000 */ -#include <thread.h> - -enum { - Maxfdata = 8192, - Nqueue = 200, /* queue size (tunable) */ - - Netclosed = 0, /* Connection state */ - Netopen, -}; /* * the kernel file server read packets directly from @@ -40,14 +30,11 @@ enum { */ typedef struct Network Network; -typedef struct Netconn Netconn; -typedef struct Conn9p Conn9p; /* a network, not necessarily an ethernet */ struct Network { int ctlrno; - char iname[NAMELEN]; - char oname[NAMELEN]; + char name[NAMELEN]; char *dialstr; char anndir[40]; @@ -55,295 +42,18 @@ struct Network { int annfd; /* fd from announce */ }; -/* an open tcp (or other transport) connection */ -struct Netconn { - Queue* reply; /* network output */ - char* raddr; /* remote caller's addr */ - Chan* chan; /* list of tcp channels */ - - int alloc; /* flag: allocated */ - - int state; - Conn9p* conn9p; /* not reference-counted */ - - Lock; -}; - -/* - * incoming 9P network connection from a given machine. - * typically will multiplex 9P sessions for multiple users. - */ -struct Conn9p { - QLock; - Ref; - int fd; - char* dir; - Netconn*netconn; /* cross-connection */ - char* raddr; -}; - static Network netif[Maxnets]; -static struct { - Lock; - Chan* chan; -} netchans; -static Queue *netoq; /* only one network output queue is needed */ char *annstrs[Maxnets] = { "tcp!*!9fs", }; -/* never returns nil */ -static Chan* -getchan(Conn9p *conn9p) -{ - Netconn *netconn; - Chan *cp, *xcp; - - lock(&netchans); - - /* look for conn9p's Chan */ - xcp = nil; - for(cp = netchans.chan; cp; cp = netconn->chan) { - netconn = cp->pdata; - if(!netconn->alloc) - xcp = cp; /* remember free Chan */ - else if(netconn->raddr != nil && - strcmp(conn9p->raddr, netconn->raddr) == 0) { - unlock(&netchans); - return cp; /* found conn9p's Chan */ - } - } - - /* conn9p's Chan not found; if no free Chan, allocate & fill in one */ - cp = xcp; - if(cp == nil) { - cp = fs_chaninit(Devnet, 1, sizeof(Netconn)); - netconn = cp->pdata; - netconn->chan = netchans.chan; - netconn->state = Netopen; /* a guess */ - /* cross-connect netconn and conn9p */ - netconn->conn9p = conn9p; /* not reference-counted */ - conn9p->netconn = netconn; - netchans.chan = cp; - } - - /* fill in Chan's netconn */ - netconn = cp->pdata; - netconn->raddr = strdup(conn9p->raddr); - - /* fill in Chan */ - cp->send = serveq; - if (cp->reply == nil) - cp->reply = netoq; - netconn->reply = netoq; - cp->protocol = nil; - cp->msize = 0; - cp->whotime = 0; - strncpy(cp->whochan, conn9p->raddr, sizeof cp->whochan); -// cp->whoprint = tcpwhoprint; - netconn->alloc = 1; - - unlock(&netchans); - return cp; -} - -static char * -fd2name(int fd) -{ - char data[128]; - - if (fd2path(fd, data, sizeof data) < 0) - return strdup("/GOK"); - return strdup(data); -} - -static void -hangupdfd(int dfd) -{ - int ctlfd; - char *end, *data; - - data = fd2name(dfd); - close(dfd); - - end = strstr(data, "/data"); - if (end != nil) - strcpy(end, "/ctl"); - ctlfd = open(data, OWRITE); - if (ctlfd >= 0) { - hangup(ctlfd); - close(ctlfd); - } - free(data); -} - -void -closechan(int n) -{ - Chan *cp; - - for(cp = chans; cp; cp = cp->next) - if(cp->whotime != 0 && cp->chan == n) - fileinit(cp); -} - -void -nethangup(Chan *cp, char *msg, int dolock) -{ - Netconn *netconn; - - netconn = cp->pdata; - netconn->state = Netclosed; - - if(msg != nil) - print("hangup! %s %s\n", msg, netconn->raddr); - - fileinit(cp); - cp->whotime = 0; - strcpy(cp->whoname, "<none>"); - - if(dolock) - lock(&netchans); - netconn->alloc = 0; - free(netconn->raddr); - netconn->raddr = nil; - if(dolock) - unlock(&netchans); -} - -void -chanhangup(Chan *cp, char *msg, int dolock) -{ - Netconn *netconn = cp->pdata; - Conn9p *conn9p = netconn->conn9p; - - if (conn9p->fd > 0) - hangupdfd(conn9p->fd); /* drop it */ - nethangup(cp, msg, dolock); -} - -/* - * returns length of next 9p message (including the length) and - * leaves it in the first few bytes of abuf. - */ -static long -size9pmsg(int fd, void *abuf, uint n) -{ - int m; - uchar *buf = abuf; - - if (n < BIT32SZ) - return -1; /* caller screwed up */ - - /* read count */ - m = readn(fd, buf, BIT32SZ); - if(m != BIT32SZ){ - if(m < 0) - return -1; - return 0; - } - return GBIT32(buf); -} - -static int -readalloc9pmsg(int fd, Msgbuf **mbp) -{ - int m, len; - uchar lenbuf[BIT32SZ]; - Msgbuf *mb; - - *mbp = nil; - len = size9pmsg(fd, lenbuf, BIT32SZ); - if (len <= 0) - return len; - if(len <= BIT32SZ || len > IOHDRSZ+Maxfdata){ - werrstr("bad length in 9P2000 message header"); - return -1; - } - if ((mb = mballoc(len, nil, Mbeth1)) == nil) - panic("readalloc9pmsg: mballoc failed"); - *mbp = mb; - memmove(mb->data, lenbuf, BIT32SZ); - len -= BIT32SZ; - m = readn(fd, mb->data+BIT32SZ, len); - if(m < len) - return 0; - return BIT32SZ+m; -} - -static void -connection(void *v) -{ - int n; - char buf[64]; - Chan *chan9p; - Conn9p *conn9p = v; - Msgbuf *mb; - NetConnInfo *nci; - - incref(conn9p); /* count connections */ - nci = getnetconninfo(conn9p->dir, conn9p->fd); - if (nci == nil) - panic("connection: getnetconninfo(%s, %d) failed", - conn9p->dir, conn9p->fd); - conn9p->raddr = nci->raddr; - - chan9p = getchan(conn9p); - print("new connection on %s pid %d from %s\n", - conn9p->dir, getpid(), conn9p->raddr); - - /* - * reading from a pipe or a network device - * will give an error after a few eof reads. - * however, we cannot tell the difference - * between a zero-length read and an interrupt - * on the processes writing to us, - * so we wait for the error. - */ - while (conn9p->fd > 0 && (n = readalloc9pmsg(conn9p->fd, &mb)) >= 0) { - if(n == 0) - continue; - mb->param = (uintptr)conn9p; /* has fd for replies */ - mb->chan = chan9p; - - assert(mb->magic == Mbmagic); - incref(conn9p); /* & count packets in flight */ - fs_send(serveq, mb); /* to 9P server processes */ - /* mb will be freed by receiving process */ - } - - rerrstr(buf, sizeof buf); - - qlock(conn9p); - print("connection hung up from %s\n", conn9p->dir); - if (conn9p->fd > 0) /* not poisoned yet? */ - hangupdfd(conn9p->fd); /* poison the fd */ - - nethangup(chan9p, "remote hung up", 1); - closechan(chan9p->chan); - - conn9p->fd = -1; /* poison conn9p */ - if (decref(conn9p) == 0) { /* last conn.? turn the lights off */ - free(conn9p->dir); - qunlock(conn9p); - free(conn9p); - } else - qunlock(conn9p); - - freenetconninfo(nci); - - if(buf[0] == '\0' || strstr(buf, "hungup") != nil) - exits(""); - sysfatal("mount read, pid %d", getpid()); -} - static void neti(void *v) { int lisfd, accfd; Network *net; - Conn9p *conn9p; + NetConnInfo *nci; net = v; print("net%di\n", net->ctlrno); @@ -362,77 +72,23 @@ neti(void *v) continue; } - /* accepted that call */ - conn9p = malloc(sizeof *conn9p); - conn9p->dir = strdup(net->lisdir); - conn9p->fd = accfd; - newproc(connection, conn9p, smprint("9P read %s", conn9p->dir)); + nci = getnetconninfo(net->lisdir, accfd); + srvchan(accfd, nci->raddr); + freenetconninfo(nci); close(lisfd); } } -/* only need one of these for all network connections, thus all interfaces */ -static void -neto(void *) -{ - int len, datafd; - Msgbuf *mb; - Conn9p *conn9p; - - print("neto\n"); - for(;;) { - /* receive 9P answer from 9P server processes */ - while((mb = fs_recv(netoq, 0)) == nil) - continue; - - if(mb->data == nil) { - print("neto: pkt nil cat=%d free=%d\n", - mb->category, mb->flags&FREE); - if(!(mb->flags & FREE)) - mbfree(mb); - continue; - } - - /* send answer back over the network connection in the reply */ - len = mb->count; - conn9p = (Conn9p *)mb->param; - assert(conn9p); - - qlock(conn9p); - datafd = conn9p->fd; - assert(len >= 0); - /* datafd < 0 probably indicates poisoning by the read side */ - if (datafd < 0 || write(datafd, mb->data, len) != len) { - print( "network write error (%r);"); - print(" closing connection for %s\n", conn9p->dir); - nethangup(getchan(conn9p), "network write error", 1); - if (datafd > 0) - hangupdfd(datafd); /* drop it */ - conn9p->fd = -1; /* poison conn9p */ - } - mbfree(mb); - if (decref(conn9p) == 0) - panic("neto: zero ref count"); - qunlock(conn9p); - } -} - void netstart(void) { - int netorun = 0; Network *net; - if(netoq == nil) - netoq = newqueue(Nqueue, "network reply"); for(net = &netif[0]; net < &netif[Maxnets]; net++){ if(net->dialstr == nil) continue; - sprint(net->oname, "neto"); - if (netorun++ == 0) - newproc(neto, nil, net->oname); - sprint(net->iname, "net%di", net->ctlrno); - newproc(neti, net, net->iname); + sprint(net->name, "net%di", net->ctlrno); + newproc(neti, net, net->name); } } diff --git a/sys/src/cmd/cwfs/pc.c b/sys/src/cmd/cwfs/pc.c index a4aed8530..ea817c8f7 100644 --- a/sys/src/cmd/cwfs/pc.c +++ b/sys/src/cmd/cwfs/pc.c @@ -33,7 +33,7 @@ mconfinit(void) } Bterm(bp); if (pgsize > 0 && userpgs > 0) - size = (((userpgs - userused)*3LL)/4)*pgsize; + size = (((userpgs - userused)*1LL)/4)*pgsize; } mconf.memsize = size; mbp = mconf.bank; diff --git a/sys/src/cmd/cwfs/portdat.h b/sys/src/cmd/cwfs/portdat.h index d01be6fea..a2e96b157 100644 --- a/sys/src/cmd/cwfs/portdat.h +++ b/sys/src/cmd/cwfs/portdat.h @@ -699,6 +699,7 @@ enum Devfloppy, /* floppy drive */ Devswab, /* swab data between mem and device */ Devmirr, /* mirror devices */ + Devsrv, /* pipes and network connections */ MAXDEV }; diff --git a/sys/src/cmd/cwfs/portfns.h b/sys/src/cmd/cwfs/portfns.h index e1810d869..3a2d70ac5 100644 --- a/sys/src/cmd/cwfs/portfns.h +++ b/sys/src/cmd/cwfs/portfns.h @@ -197,6 +197,7 @@ void schedinit(void); int scsiio(Device*, int, uchar*, int, void*, int); void scsiinit(void); Off scsiread(int, void*, long); +Devsize scsiseek(int, Devsize); Off scsiwrite(int, void*, long); char* sdof(Device*); void sec2rtc(Timet, Rtc *); @@ -229,7 +230,7 @@ void unlock(Lock*); void newproc(void(*)(void *), void*, char*); void wormcopy(void *); void wormprobe(void); -void synccopy(void); +void synccopy(void *); long wormsearch(Device*, int, long, long); int wormread(Device*, Off, void*); Devsize wormsize(Device*); @@ -243,3 +244,6 @@ int wrenwrite(Device*, Off, void*); void cmd_exec(char*); void cmd_install(char*, char*, void (*)(int, char*[])); ulong flag_install(char*, char*); +void srvinit(void); +Chan *srvchan(int, char *); + diff --git a/sys/src/cmd/cwfs/portmkfile b/sys/src/cmd/cwfs/portmkfile index be276aca7..0bc734183 100644 --- a/sys/src/cmd/cwfs/portmkfile +++ b/sys/src/cmd/cwfs/portmkfile @@ -27,10 +27,12 @@ OFILES=\ time.$O\ uidgid.$O\ wren.$O\ + srv.$O\ HFILES=\ ../32bit.h\ ../64bit.h\ + ../64xbit.h\ ../9p1.h\ ../all.h\ dat.h\ diff --git a/sys/src/cmd/cwfs/srv.c b/sys/src/cmd/cwfs/srv.c new file mode 100644 index 000000000..0cfafbb41 --- /dev/null +++ b/sys/src/cmd/cwfs/srv.c @@ -0,0 +1,209 @@ +#include "all.h" +#include "io.h" +#include <fcall.h> /* 9p2000 */ +#include <thread.h> + +enum { + Maxfdata = 8192, + Nqueue = 200, /* queue size (tunable) */ + Nsrvo = 8, /* number of write workers */ +}; + +typedef struct Srv Srv; +struct Srv +{ + Ref; + char *name; + Chan *chan; + int fd; + char buf[64]; +}; + +static struct { + Lock; + Chan *hd; +} freechans; + +static Queue *srvoq; + +void +chanhangup(Chan *chan, char *msg, int dolock) +{ + Srv *srv; + + USED(dolock); + USED(msg); + + fileinit(chan); + if(chan->type != Devsrv) + return; + srv = chan->pdata; + if(srv == nil || srv->chan != chan) + return; + close(srv->fd); + srv->fd = -1; +} + +static void +srvput(Srv *srv) +{ + Chan *chan; + + if(decref(srv)) + return; + + print("%s closed\n", srv->name); + + chanhangup(srv->chan, "", 0); + memset(srv->buf, 0, sizeof(srv->buf)); + chan = srv->chan; + lock(&freechans); + srv->chan = freechans.hd; + freechans.hd = chan; + unlock(&freechans); +} + +static void +srvo(void *) +{ + Srv *srv; + Msgbuf *mb; + char buf[ERRMAX]; + + print("srvo\n"); + + for(;;){ + mb = fs_recv(srvoq, 0); + if(mb == nil) + continue; + if(mb->data == nil){ + if(!(mb->flags & FREE)) + mbfree(mb); + continue; + } + srv = (Srv*)mb->param; + while((srv->fd >= 0) && (write(srv->fd, mb->data, mb->count) != mb->count)){ + rerrstr(buf, sizeof(buf)); + if(strstr(buf, "interrupt")) + continue; + + if(buf[0]) + print("srvo %s: %s\n", srv->name, buf); + chanhangup(srv->chan, buf, 0); + break; + } + mbfree(mb); + srvput(srv); + } +} + +static void +srvi(void *aux) +{ + Srv *srv = aux; + Msgbuf *mb, *ms; + uchar *b, *p, *e; + int n, m; + char buf[ERRMAX]; + + print("srvi %s\n", srv->name); + + if((mb = mballoc(IOHDRSZ+Maxfdata, srv->chan, Mbeth1)) == nil) + panic("srvi %s: mballoc failed", srv->name); + b = mb->data; + p = b; + e = b + mb->count; + +Read: + while((srv->fd >= 0) && ((n = read(srv->fd, p, e - p)) >= 0)){ + p += n; + while((p - b) >= BIT32SZ){ + m = GBIT32(b); + if((m < BIT32SZ) || (m > mb->count)){ + werrstr("bad length in 9P2000 message header"); + goto Error; + } + if((n = (p - b) - m) < 0){ + e = b + m; + goto Read; + } + if(m <= SMALLBUF){ + if((ms = mballoc(m, srv->chan, Mbeth1)) == nil) + panic("srvi %s: mballoc failed", srv->name); + memmove(ms->data, b, m); + } else { + ms = mb; + if((mb = mballoc(mb->count, srv->chan, Mbeth1)) == nil) + panic("srvi %s: mballoc failed", srv->name); + ms->count = m; + } + if(n > 0) + memmove(mb->data, b + m, n); + b = mb->data; + p = b + n; + + incref(srv); + ms->param = (uint)srv; + fs_send(serveq, ms); + } + e = b + mb->count; + } + +Error: + rerrstr(buf, sizeof(buf)); + if(strstr(buf, "interrupt")) + goto Read; + + if(buf[0]) + print("srvi %s: %s\n", srv->name, buf); + chanhangup(srv->chan, buf, 0); + srvput(srv); + + mbfree(mb); +} + +Chan* +srvchan(int fd, char *name) +{ + Chan *chan; + Srv *srv; + + lock(&freechans); + if(chan = freechans.hd){ + srv = chan->pdata; + freechans.hd = srv->chan; + unlock(&freechans); + } else { + unlock(&freechans); + chan = fs_chaninit(Devsrv, 1, sizeof(*srv)); + srv = chan->pdata; + } + chan->reply = srvoq; + if(chan->send == nil) + chan->send = serveq; + chan->protocol = nil; + chan->msize = 0; + chan->whotime = 0; + + incref(srv); + srv->chan = chan; + srv->fd = fd; + snprint(srv->buf, sizeof(srv->buf), "srvi %s", name); + srv->name = strchr(srv->buf, ' ')+1; + newproc(srvi, srv, srv->buf); + + return chan; +} + +void +srvinit(void) +{ + int i; + + if(srvoq != nil) + return; + + srvoq = newqueue(Nqueue, "srvoq"); + for(i=0; i<Nsrvo; i++) + newproc(srvo, nil, "srvo"); +} diff --git a/sys/src/cmd/cwfs/sub.c b/sys/src/cmd/cwfs/sub.c index 44f985757..bca9e5264 100644 --- a/sys/src/cmd/cwfs/sub.c +++ b/sys/src/cmd/cwfs/sub.c @@ -614,7 +614,9 @@ Zfmt(Fmt* fmt) case Devlworm: if (c == '\0') c = 'l'; - if(d->wren.ctrl == 0 && d->wren.lun == 0) + if(d->wren.file) + snprint(s, sizeof(s), "%c\"%s\"", c, d->wren.file); + else if(d->wren.ctrl == 0 && d->wren.lun == 0) sprint(s, "%c%d", c, d->wren.targ); else sprint(s, "%c%d.%d.%d", c, d->wren.ctrl, d->wren.targ, diff --git a/sys/src/cmd/cwfs/wren.c b/sys/src/cmd/cwfs/wren.c index 5f67706bc..9b8f09c8b 100644 --- a/sys/src/cmd/cwfs/wren.c +++ b/sys/src/cmd/cwfs/wren.c @@ -116,5 +116,6 @@ wrenwrite(Device *d, Off b, void *c) cons.nwrenwe++; r = 1; } + return r; } |