From 451641fb0e3398218aa6829ac993d0521da8389d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 19 Aug 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-08-19 --- boot/boot.c | 28 ++-- boot/boot.h | 7 +- boot/bootauth.c | 74 +++++++++++ boot/bootcache.c | 2 +- boot/bootip.c | 48 ++++--- boot/dosboot.c | 8 +- boot/settime.c | 8 +- pc/dat.h | 2 +- port/auth.c | 169 +++++------------------- port/chan.c | 89 +++---------- port/dev.c | 7 - port/devcons.c | 2 +- port/devdup.c | 4 +- port/devmnt.c | 327 ++++++++++++++++++++++++++++++++++++----------- port/devproc.c | 12 +- port/devroot.c | 1 + port/devsrv.c | 2 + port/error.h | 2 +- port/fault.c | 18 ++- port/lib.h | 11 +- port/portdat.h | 7 +- port/portfns.h | 5 + port/print.c | 4 + port/proc.c | 23 +--- port/sysfile.c | 47 ++++--- port/sysproc.c | 56 ++++++-- port/systab.h | 24 ++-- 27 files changed, 579 insertions(+), 408 deletions(-) create mode 100644 boot/bootauth.c diff --git a/boot/boot.c b/boot/boot.c index 0904995c11512d0c2e07a76115d6960284476e03..674b039e513cb152ee73d088a4789f5f87a8acf9 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -34,7 +34,7 @@ rconv(va_list *arg, Fconv *fp) void boot(int argc, char *argv[]) { - int fd; + int fd, afd; Method *mp; char cmd[64]; char rootbuf[64]; @@ -43,9 +43,11 @@ boot(int argc, char *argv[]) char *rp; int n; char buf[32]; + AuthInfo *ai; sleep(1000); + fmtinstall('r', rconv); open("#c/cons", OREAD); @@ -53,6 +55,7 @@ boot(int argc, char *argv[]) open("#c/cons", OWRITE); bind("#c", "/dev", MAFTER); bind("#e", "/env", MREPL|MCREATE); + bind("#s", "/srv", MREPL|MCREATE); #ifdef DEBUG print("argc=%d\n", argc); @@ -62,9 +65,6 @@ boot(int argc, char *argv[]) #endif DEBUG ARGBEGIN{ - case 'u': - strcpy(username, ARGF()); - break; case 'k': kflag = 1; break; @@ -87,9 +87,9 @@ boot(int argc, char *argv[]) ishybrid = strcmp(mp->name, "hybrid") == 0; /* - * get/set key or password + * authentication agent */ - (*pword)(islocal, mp); + authentication(cpuflag); /* * connect to the root file system @@ -108,7 +108,6 @@ boot(int argc, char *argv[]) if(!islocal && !ishybrid){ if(cfs) fd = (*cfs)(fd); - doauthenticate(fd, mp); } srvcreate("boot", fd); @@ -120,10 +119,15 @@ boot(int argc, char *argv[]) rp = getenv("rootspec"); if(rp == nil) rp = ""; -print("boot about to mount\n"); - if(mount(fd, "/root", MREPL|MCREATE, rp) < 0) + + afd = fauth(fd, rp); + if(afd >= 0){ + ai = auth_proxy(afd, "p9any", 0, auth_getkey); + if(ai == nil) + print("authentication failed (%r), trying mount anyways\n"); + } + if(mount(fd, afd, "/root", MREPL|MCREATE, rp) < 0) fatal("mount /"); -print("mount is done\n"); rp = getenv("rootdir"); if(rp == nil) rp = rootdir; @@ -160,13 +164,13 @@ print("mount is done\n"); fd = (*mp->connect)(); if(fd < 0) break; - mount(fd, "/n/kfs", MAFTER|MCREATE, "") ; + mount(fd, -1, "/n/kfs", MAFTER|MCREATE, "") ; close(fd); break; } } - settime(islocal); + settime(islocal, afd); swapproc(); sprint(cmd, "/%s/ninit", cputype); diff --git a/boot/boot.h b/boot/boot.h index 7d5f2b27e65179f39c9731a2dc96d1d4a73ef707..7485c725f37ddd0df0a5d4c42af95fe1f2ca0767 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -3,11 +3,11 @@ struct Method { char *name; void (*config)(Method*); - int (*auth)(void); int (*connect)(void); char *arg; }; +extern void authentication(int); extern char* bootdisk; extern char* rootdir; extern int (*cfs)(int); @@ -40,7 +40,7 @@ extern int readfile(char*, char*, int); extern long readn(int, void*, long); extern int sendmsg(int, char*); extern void setenv(char*, char*); -extern void settime(int); +extern void settime(int, int); extern void srvcreate(char*, int); extern void setusername(int, Method*); extern void warning(char*); @@ -63,3 +63,6 @@ extern int connectlocal(void); extern void configsac(Method*); extern int authsac(void); extern int connectsac(void); + +/* hack for passing authentication address */ +extern char *authaddr; diff --git a/boot/bootauth.c b/boot/bootauth.c new file mode 100644 index 0000000000000000000000000000000000000000..1e553b4654e415a2678bbfa6941c99cdbaa3e0bb --- /dev/null +++ b/boot/bootauth.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include "../boot/boot.h" + +char *authaddr; + +void +authentication(int cpuflag) +{ + char *argv[16], **av; + int ac; + int factotumpid, pid; + + /* start agent */ + ac = 0; + av = argv; + av[ac++] = "factotum"; +//av[ac++] = "-dt"; + if(cpuflag) + av[ac++] = "-s"; + else + av[ac++] = "-u"; + if(authaddr != nil){ + av[ac++] = "-a"; + av[ac++] = authaddr; + } + av[ac] = 0; + switch(fork()){ + case -1: + fatal("starting factotum: %r"); + case 0: + exec("/factotum", av); + fatal("execing /factotum"); + default: + break; + } + + /* wait for agent to really be there */ + while(access("/mnt/factotum", 0) < 0) + sleep(250); + + if(cpuflag) + return; + /* ask for password */ +#ifdef quux + /* start agent */ + ac = 0; + av = argv; + av[ac++] = "factotum"; + av[ac++] = "-gd"; + av[ac++] = "p9sk1"; + av[ac++] = "cs.bell-labs.com"; + av[ac] = 0; + switch((factotumpid = fork())){ + case -1: + fatal("starting factotum: %r"); + case 0: + exec("/factotum", av); + fatal("execing /factotum"); + default: + break; + } + + for(;;){ + pid = waitpid(); + if(pid == factotumpid) + break; + if(pid == -1) + fatal("waiting for factotum"); + } +#endif quux +} diff --git a/boot/bootcache.c b/boot/bootcache.c index f3cb16c2e0e9933cfea63825e4fcf80a7b45f40a..fdcf06c80d993b820e1682b9d92d0dbe2e266194 100644 --- a/boot/bootcache.c +++ b/boot/bootcache.c @@ -65,7 +65,7 @@ cache(int fd) if(fflag) execl("/cfs", "bootcfs", "-rs", "-f", partition, 0); else - execl("/cfs", "bootcfs", "-s", "-f", partition, 0); + execl("/cfs", "bootcfs", "-ds", "-f", partition, 0); break; default: close(p[0]); diff --git a/boot/bootip.c b/boot/bootip.c index b745b226acea88cc8cce32d4a0f74f610497d544..614dda8894da5b448d64f1988e760a11ffa52800 100644 --- a/boot/bootip.c +++ b/boot/bootip.c @@ -4,9 +4,9 @@ #include "boot.h" -static uchar fsip[IPaddrlen]; -static uchar auip[IPaddrlen]; -static char mpoint[32]; +static uchar fsip[IPaddrlen]; + uchar auip[IPaddrlen]; +static char mpoint[32]; static int isvalidip(uchar*); static void netndb(char*, uchar*); @@ -15,9 +15,9 @@ static void netenv(char*, uchar*); void configip(void) { - int argc, pid, wpid; + int argc, pid; char **argv, *p; - Waitmsg w; + Waitmsg *w; char **arg; char buf[32]; @@ -66,13 +66,15 @@ configip(void) /* wait for ipconfig to finish */ for(;;){ - wpid = wait(&w); - if(wpid == pid){ - if(w.msg[0] != 0) - fatal(w.msg); + w = wait(); + if(w != nil && w->pid == pid){ + if(w->msg[0] != 0) + fatal(w->msg); + free(w); break; - } else if(wpid < 0) + } else if(w == nil) fatal("configuring ip"); + free(w); } /* if we didn't get a file and auth server, query user */ @@ -95,6 +97,15 @@ configip(void) } } +static void +setauthaddr(char *proto, int port) +{ + char buf[128]; + + snprint(buf, sizeof buf, "%s!%I!%d", proto, auip, port); + authaddr = strdup(buf); +} + void configtcp(Method*) { @@ -105,12 +116,7 @@ configtcp(Method*) sleep(100); print("."); sleep(100); -} - -int -authtcp(void) -{ - return -1; + setauthaddr("tcp", 567); } int @@ -126,15 +132,7 @@ void configil(Method*) { configip(); -} - -int -authil(void) -{ - char buf[64]; - - snprint(buf, sizeof buf, "il!%I!566", auip); - return dial(buf, 0, 0, 0); + setauthaddr("il", 566); } int diff --git a/boot/dosboot.c b/boot/dosboot.c index 203fd82e17794e6a8724f68c2548809881e20235..087bd055a46f123eb7bc6ddd78ab1b0296afdb14 100644 --- a/boot/dosboot.c +++ b/boot/dosboot.c @@ -30,13 +30,13 @@ dosboot(void) */ if(bind("/", "/", MREPL) < 0) fatal("bind /"); - if(mount(fd, "/", MAFTER|MCREATE, "#f/fd0disk") < 0) - if(mount(fd, "/", MAFTER|MCREATE, "#f/fd1disk") < 0) - if(mount(fd, "/", MAFTER|MCREATE, "#S/sdC0/dos") < 0) + if(mount(fd, -1, "/", MAFTER|MCREATE, "#f/fd0disk") < 0) + if(mount(fd, -1, "/", MAFTER|MCREATE, "#f/fd1disk") < 0) + if(mount(fd, -1, "/", MAFTER|MCREATE, "#S/sdC0/dos") < 0) fatal("mount /"); close(fd); - settime(1); + settime(1, -1); swapproc(); execl("/386/init", "init", "-mt", 0); diff --git a/boot/settime.c b/boot/settime.c index 9b0243d2bc6d02e706c58d061d40e9ec20f25070..fee09e280cc841897c926f38af2a1d7d62121cf9 100644 --- a/boot/settime.c +++ b/boot/settime.c @@ -12,7 +12,7 @@ static long lusertime(char*); char *timeserver = "#s/boot"; void -settime(int islocal) +settime(int islocal, int afd) { int n, f; int timeset; @@ -44,17 +44,17 @@ settime(int islocal) f = open(timeserver, ORDWR); if(f < 0) return; - if(mount(f, "/mnt", MREPL, "") < 0){ + if(mount(f, afd, "/tmp", MREPL, "") < 0){ warning("settime mount"); close(f); return; } close(f); - if(stat("/mnt", statbuf, sizeof statbuf) < 0) + if(stat("/tmp", statbuf, sizeof statbuf) < 0) fatal("stat"); convM2D(statbuf, sizeof statbuf, &dir[0], (char*)&dir[1]); sprint(timebuf, "%ld", dir[0].atime); - unmount(0, "/mnt"); + unmount(0, "/tmp"); } f = open("#c/time", OWRITE); diff --git a/pc/dat.h b/pc/dat.h index 2cdcabaf5fc7067ce37e20c13aa1e24c44e86d61..cdffbc803fb74c54e79331b457c909e1a3dfe602 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -17,7 +17,7 @@ typedef struct Segdesc Segdesc; typedef struct Ureg Ureg; typedef struct Vctl Vctl; -#define MAXSYSARG 5 /* for mount(fd, mpt, flag, arg, srv) */ +#define MAXSYSARG 5 /* for mount(fd, afd, mpt, flag, arg) */ /* * parameters for sysproc.c diff --git a/port/auth.c b/port/auth.c index 1bdfe04e630a0e73977b66bc975b73b6d75ae541..27267a5df5c43ac60c1a2fbfd654b13e57efe7c4 100644 --- a/port/auth.c +++ b/port/auth.c @@ -23,19 +23,16 @@ iseve(void) long sysfversion(ulong *arg) { - Fcall f; /* two Fcalls should be big enough for reply */ - uchar *msg; char *vers; - uint arglen, n, m, msize; + uint arglen, m, msize; Chan *c; - uvlong oo; msize = arg[1]; vers = (char*)arg[2]; arglen = arg[3]; validaddr(arg[2], arglen, 1); /* check there's a NUL in the version string */ - if(memchr(vers, 0, arglen) == 0) + if(arglen==0 || memchr(vers, 0, arglen)==0) error(Ebadarg); c = fdtochan(arg[0], ORDWR, 0, 1); if(waserror()){ @@ -43,68 +40,7 @@ sysfversion(ulong *arg) nexterror(); } - if((c->flag&CMSG) && c->version!=nil) /* BUG: insufficient; should check compatibility */ - goto Return; - - f.type = Tversion; - f.tag = NOTAG; - if(msize == 0) - msize = IOHDRSZ+8192; /* reasonable default */ - f.msize = msize; - if(vers[0] == '\0') - vers = VERSION9P; - f.version = vers; - msg = smalloc(8192+IOHDRSZ); - if(waserror()){ - free(msg); - nexterror(); - } - n = convS2M(&f, msg, 8192+IOHDRSZ); - if(n == 0) - error("bad fversion conversion on send"); - - lock(c); - oo = c->offset; - c->offset += n; - unlock(c); - - m = devtab[c->type]->write(c, msg, n, oo); - - if(m < n){ - lock(c); - c->offset -= n - m; - unlock(c); - error("short write in fversion"); - } - - /* message sent; receive and decode reply */ - m = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset); - if(m <= 0) - error("EOF receiving fversion reply"); - - lock(c); - c->offset += m; - unlock(c); - - n = convM2S(msg, m, &f); - if(n != m) - error("bad fversion conversion on reply"); - if(f.type != Rversion) - error("unexpected reply type in fversion"); - if(f.msize > msize) - error("server tries to increase msize in fversion"); - if(f.msize<256 || f.msize>1024*1024) - error("nonsense value of msize in fversion"); - kstrdup(&c->version, f.version); - c->iounit = f.msize; - free(msg); - poperror(); - -Return: - m = strlen(c->version); - if(m > arglen) - m = arglen; - memmove((char*)arg[2], c->version, m); + m = mntversion(c, vers, msize, arglen); cclose(c); poperror(); @@ -112,90 +48,49 @@ Return: } long -sysfsession(ulong *arg) +sys_fsession(ulong *arg) { - Fcall f; - uchar *msg; - uint authlen, n, m; - Chan *c; - uvlong oo; + /* deprecated; backwards compatibility only */ + + if(arg[2] == 0) + error(Ebadarg); + validaddr(arg[1], arg[2], 1); + ((uchar*)arg[1])[0] = '\0'; + return 0; +} + +long +sysfauth(ulong *arg) +{ + Chan *c, *ac; + char *aname; + int fd; -//BUG print("warning: stub fsession being used\n"); - authlen = arg[2]; - validaddr(arg[1], authlen, 1); + validaddr(arg[1], 1, 0); + aname = (char*)arg[1]; + validname(aname, 0); c = fdtochan(arg[0], ORDWR, 0, 1); if(waserror()){ cclose(c); nexterror(); } - if(c->flag & CMSG){ -//BUG what to do? - ((uchar*)arg[1])[0] = 0; - poperror(); - cclose(c); - return 0; - } - - f.type = Tsession; - f.tag = NOTAG; - f.nchal = 0; - f.chal = (uchar*)""; - msg = smalloc(8192+IOHDRSZ); + ac = mntauth(c, aname); if(waserror()){ - free(msg); + cclose(ac); nexterror(); } - n = convS2M(&f, msg, 8192+IOHDRSZ); - if(n == 0) - error("bad fsession conversion on send"); - - lock(c); - oo = c->offset; - c->offset += n; - unlock(c); - - m = devtab[c->type]->write(c, msg, n, oo); - - if(m < n){ - lock(c); - c->offset -= n - m; - unlock(c); - error("short write in fsession"); - } - /* message sent; receive and decode reply */ - m = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset); - if(m <= 0) - error("EOF receiving fsession reply"); + fd = newfd(ac); + if(fd < 0) + error(Enofd); + poperror(); /* ac */ + poperror(); /* c */ - lock(c); - c->offset += m; - unlock(c); + /* always mark it close on exec */ + ac->flag |= CCEXEC; - n = convM2S(msg, m, &f); - if(n != m) - error("bad fsession conversion on reply"); - if(f.type != Rsession) - error("unexpected reply type in fsession"); - m = f.nchal; - if(m > authlen) - error(Eshort); -//BUG print("auth stuff ignored; noauth by default\n"); - ((uchar*)arg[1])[0] = 0; - - free(msg); - poperror(); - poperror(); - cclose(c); - return m; -} - -long -sysfauth(ulong *) -{ - error("sysfauth unimplemented"); - return -1; + return fd; } /* diff --git a/port/chan.c b/port/chan.c index 2ca7c09d269f4edc9c69fea5243050a29abc3982..ffcd93e7dac7611c5d18ec857cf8821beaca7272 100644 --- a/port/chan.c +++ b/port/chan.c @@ -174,19 +174,6 @@ kstrdup(char **p, char *s) static Lock l; n = strlen(s)+1; -// if(n == 1){ -// ulong pc; -// int i; -// static ulong pcs[128]; -// pc = getcallerpc(&p); -// for(i=0; iaux = 0; c->mchan = 0; c->mcp = 0; + c->mux = 0; memset(&c->mqid, 0, sizeof(c->mqid)); c->name = 0; - c->version = 0; return c; } @@ -330,10 +317,6 @@ chanfree(Chan *c) { c->flag = CFREE; - if(c->version){ - free(c->version); - c->version = 0; - } if(c->umh != nil){ putmhead(c->umh); c->umh = nil; @@ -342,6 +325,14 @@ chanfree(Chan *c) cclose(c->umc); c->umc = nil; } + if(c->mux != nil){ + muxclose(c->mux); + c->mux = nil; + } + if(c->mchan != nil){ + cclose(c->mchan); + c->mchan = nil; + } cnameclose(c->name); @@ -356,6 +347,7 @@ cclose(Chan *c) { if(c->flag&CFREE) panic("cclose %lux", getcallerpc(&c)); + if(decref(c)) return; @@ -690,9 +682,6 @@ undomount(Chan *c, Cname *name) for(f = *h; f; f = f->hash) { if(strcmp(f->from->name->s, name->s) != 0) continue; -if(chandebug) -print("[%lud]\tundomount found head %s; need chan (path %.8llux dev %C %lud)\n", - up->pid, name->s, c->qid.path, devtab[c->type]->dc, c->dev); for(t = f->mount; t; t = t->next) { if(eqchan(c, t->to, 1)) { /* @@ -707,8 +696,6 @@ print("[%lud]\tundomount found head %s; need chan (path %.8llux dev %C %lud)\n", incref(nc); cclose(c); c = nc; -if(chandebug) -print("[%lud]\tundomount found %s\n", up->pid, c2name(c)); break; } } @@ -732,23 +719,12 @@ walk(Chan **cp, char **names, int nnames, int nomount) Mhead *mh, *nmh; Walkqid *wq; -//BUG: waserror? - c = *cp; incref(c); cname = c->name; incref(cname); mh = nil; -if(chandebug){ -qlock(&chanprint); -print("[%lud] walk %s to ", up->pid, c2name(c)); -for(i=0; ipid, c2name(c), c->qid.path, devtab[c->type]->dc, c->dev); -for(i=0; idev; if((wq = devtab[type]->walk(c, nil, names, ntry)) == nil){ -if(chandebug) print("[%lud]\twalk failed.\n", up->pid); /* try a union mount, if any */ if(mh == nil || nomount){ Giveup: -if(chandebug) print("[%lud]\tgive up\n", up->pid); cclose(c); cnameclose(cname); return -1; @@ -807,13 +772,8 @@ if(chandebug) print("[%lud]\tgive up\n", up->pid); nexterror(); } for(f = mh->mount; f; f = f->next) -{ -if(chandebug) - print("[%lud]\twalk from %s (path %.8llux dev %C %lud)\n", - up->pid, c2name(c), c->qid.path, devtab[c->type]->dc, c->dev); if((wq = devtab[f->to->type]->walk(f->to, nil, names, ntry)) != nil) break; -} poperror(); runlock(&mh->lock); @@ -830,11 +790,7 @@ if(chandebug) assert(wq->clone != nil); cname = addelem(cname, ".."); -if(chandebug) -print("[%lud]\tundo wq->clone %s cname %s\n", up->pid, c2name(wq->clone), cname?cname->s:""); nc = undomount(wq->clone, cname); -if(chandebug) -print("[%lud]\tundo returned %s\n", up->pid, c2name(nc)); n = 1; } else { nc = nil; @@ -843,8 +799,6 @@ print("[%lud]\tundo returned %s\n", up->pid, c2name(nc)); if(findmount(&nc, &nmh, type, dev, wq->qid[i])) break; if(nc == nil){ /* no mount points along path */ -if(chandebug) -print("[%lud]\tno mount points along path\n", up->pid); if(wq->clone == nil){ cclose(c); cnameclose(cname); @@ -854,15 +808,6 @@ print("[%lud]\tno mount points along path\n", up->pid); n = wq->nqid; nc = wq->clone; }else{ /* stopped early, at a mount point */ -if(chandebug){int j; -qlock(&chanprint); -print("[%lud]\tfound mount point: ", up->pid); -for(j=0; j<=i; j++) - print("%s%s", j?"/":"", names[j]); -print(" becomes "); -print("%s\n", c2name(nc)); -qunlock(&chanprint); -} if(wq->clone != nil){ cclose(wq->clone); wq->clone = nil; @@ -872,7 +817,6 @@ qunlock(&chanprint); for(i=0; iumh != nil){ - print("walk umh\n"); - putmhead(c->umh); - c->umh = nil; -} + + if(c->umh != nil){ //BUG + print("walk umh\n"); + putmhead(c->umh); + c->umh = nil; + } cnameclose(c->name); c->name = cname; cclose(*cp); *cp = c; -if(chandebug) -print("[%lud]\twalk succeeds; name %s chan (path %.8llux dev %C %lud)\n", up->pid, c2name(c), c->qid.path, devtab[c->type]->dc, c->dev); return 0; } diff --git a/port/dev.c b/port/dev.c index 420d68b192f5ee28b470abe9926ab9f129ffff98..628f522c93a5b3c5df71fe139b5d567a5057806b 100644 --- a/port/dev.c +++ b/port/dev.c @@ -115,7 +115,6 @@ devclone(Chan *c) nc->umh = nil; nc->mountid = c->mountid; nc->aux = c->aux; - nc->mchan = c->mchan; nc->mqid = c->mqid; nc->mcp = c->mcp; return nc; @@ -132,12 +131,6 @@ devwalk(Chan *c, Chan *nc, char **name, int nname, Dirtab *tab, int ntab, Devgen if(nname > 0) isdir(c); -// print("devwalk (%d:%c:%p) ", nname, devtab[c->type]->dc, nc); -// for(i=0; iqid.type == QTDIR){ + if(c->qid.type & QTDIR){ if(omode != 0) error(Eisdir); c->mode = 0; @@ -71,6 +71,8 @@ dupopen(Chan *c, int omode) c->offset = 0; return c; } + if(c->qid.type & QTAUTH) + error(Eperm); twicefd = c->qid.path - 1; fd = twicefd/2; if((twicefd & 1)){ diff --git a/port/devmnt.c b/port/devmnt.c index bfb041fe342bd23989f6bea5b2f8724943d51b68..7dc4f5bf596779a857c2d6f3cf9f1823403a8abe 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -5,6 +5,17 @@ #include "fns.h" #include "../port/error.h" +/* + * References are managed as follows: + * The channel to the server - a network connection or pipe - has one + * reference for every Chan open on the server. The server channel has + * c->mux set to the Mnt used for muxing control to that server. Mnts + * have no reference count; they go away when c goes away. + * Each channel derived from the mount point has mchan set to c, + * and increfs/decrefs mchan to manage references on the server + * connection. + */ + #define MAXRPC (IOHDRSZ+8192) struct Mntrpc @@ -16,6 +27,7 @@ struct Mntrpc Mnt* m; /* Mount device during rpc */ Rendez r; /* Place to hang out */ uchar* rpc; /* I/O Data buffer */ + uint rpclen; /* len of buffer */ Block *b; /* reply blocks */ char done; /* Rpc completed */ uvlong stime; /* start time for mnt statistics */ @@ -37,7 +49,6 @@ struct Mntalloc }mntalloc; void mattach(Mnt*, Chan*, char*); -void mntauth(Mnt*, Mntrpc*, char*, ushort); Mnt* mntchk(Chan*); void mntdirfix(uchar*, Chan*); Mntrpc* mntflushalloc(Mntrpc*, ulong); @@ -53,10 +64,10 @@ void mountio(Mnt*, Mntrpc*); void mountmux(Mnt*, Mntrpc*); void mountrpc(Mnt*, Mntrpc*); int rpcattn(void*); -void mclose(Mnt*, Chan*); Chan* mntchan(void); char Esbadstat[] = "invalid directory entry received from server"; +char Enoversion[] = "version not established for mount channel"; void (*mntstats)(int, Chan*, uvlong, ulong); @@ -77,43 +88,114 @@ mntreset(void) cinit(); } -static Chan* -mntattach(char *muxattach) +/* + * Version is not multiplexed: message sent only once per connection. + */ +long +mntversion(Chan *c, char *version, int msize, int returnlen) { + Fcall f; + uchar *msg; Mnt *m; - Chan *c; - struct bogus{ - Chan *chan; - char *spec; - int flags; - }bogus; + char *v; + long k, l; + uvlong oo; + char buf[128]; - bogus = *((struct bogus *)muxattach); - c = bogus.chan; + qlock(&c->umqlock); /* make sure no one else does this until we've established ourselves */ + if(waserror()){ + qunlock(&c->umqlock); + nexterror(); + } - lock(&mntalloc); - for(m = mntalloc.list; m; m = m->list) { - if(m->c == c && m->id) { - lock(m); - if(m->id && m->ref > 0 && m->c == c) { - m->ref++; - unlock(m); - unlock(&mntalloc); - c = mntchan(); - if(waserror()) { - chanfree(c); - nexterror(); - } - mattach(m, c, bogus.spec); - poperror(); - if(bogus.flags&MCACHE) - c->flag |= CCACHE; - return c; - } - unlock(m); + /* defaults */ + if(msize == 0) + msize = MAXRPC-IOHDRSZ; + v = version; + if(v == nil || v[0] == '\0') + v = VERSION9P; + + /* validity */ + if(msize < 0) + error("bad iounit in version call"); + if(strncmp(v, VERSION9P, strlen(VERSION9P)) != 0) + error("bad 9P version specification"); + + m = c->mux; + + if(m != nil){ + qunlock(&c->umqlock); + poperror(); + + strecpy(buf, buf+sizeof buf, m->version); + k = strlen(buf); + if(strncmp(buf, v, k) != 0){ + snprint(buf, sizeof buf, "incompatible 9P versions %s %s", m->version, v); + error(buf); + } + if(returnlen > 0){ + if(returnlen < k) + error(Eshort); + memmove(version, buf, k); } + return k; + } + + f.type = Tversion; + f.tag = NOTAG; + f.msize = msize; + f.version = v; + msg = malloc(8192+IOHDRSZ); + if(msg == nil) + exhausted("version memory"); + if(waserror()){ + free(msg); + nexterror(); + } + k = convS2M(&f, msg, 8192+IOHDRSZ); + if(k == 0) + error("bad fversion conversion on send"); + + lock(c); + oo = c->offset; + c->offset += k; + unlock(c); + + l = devtab[c->type]->write(c, msg, k, oo); + + if(l < k){ + lock(c); + c->offset -= k - l; + unlock(c); + error("short write in fversion"); } + /* message sent; receive and decode reply */ + k = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset); + if(k <= 0) + error("EOF receiving fversion reply"); + + lock(c); + c->offset += k; + unlock(c); + + l = convM2S(msg, k, &f); + if(l != k) + error("bad fversion conversion on reply"); + if(f.type != Rversion) + error("unexpected reply type in fversion"); + if(f.msize > msize) + error("server tries to increase msize in fversion"); + if(f.msize<256 || f.msize>1024*1024) + error("nonsense value of msize in fversion"); + if(strncmp(f.version, v, strlen(f.version)) != 0) + error("bad 9P version returned from server"); + c->iounit = f.msize; + if(c->iounit == 0) + c->iounit = MAXRPC; + + /* now build Mnt associated with this connection */ + lock(&mntalloc); m = mntalloc.mntfree; if(m != 0) mntalloc.mntfree = m->list; @@ -126,27 +208,53 @@ mntattach(char *muxattach) } m->list = mntalloc.list; mntalloc.list = m; + kstrdup(&m->version, f.version); m->id = mntalloc.id++; m->q = qopen(10*MAXRPC, 0, nil, nil); unlock(&mntalloc); + poperror(); /* msg */ + free(msg); + lock(m); - m->ref = 1; m->queue = 0; m->rip = 0; + + c->flag |= CMSG; + c->mux = m; m->c = c; - m->c->flag |= CMSG; - if(m->c->iounit == 0) - m->c->iounit = MAXRPC; - m->flags = bogus.flags & ~MCACHE; + unlock(m); - incref(m->c); + poperror(); /* c */ + qunlock(&c->umqlock); - unlock(m); + k = strlen(f.version); + if(returnlen > 0){ + if(returnlen < k) + error(Eshort); + memmove(version, f.version, k); + } + + return k; +} + +Chan* +mntauth(Chan *c, char *spec) +{ + Mnt *m; + Mntrpc *r; + + m = c->mux; + + if(m == nil){ + mntversion(c, VERSION9P, MAXRPC, 0); + m = c->mux; + if(m == nil) + error(Enoversion); + } c = mntchan(); if(waserror()) { - mclose(m, c); /* Close must not be called since it will * call mnt recursively */ @@ -154,35 +262,69 @@ mntattach(char *muxattach) nexterror(); } - mattach(m, c, bogus.spec); - poperror(); + r = mntralloc(0, m->c->iounit); - if(bogus.flags & MCACHE) - c->flag |= CCACHE; + if(waserror()) { + mntfree(r); + nexterror(); + } - return c; -} + r->request.type = Tauth; + r->request.afid = c->fid; + r->request.uname = up->user; + r->request.aname = spec; + mountrpc(m, r); -Chan* -mntchan(void) -{ - Chan *c; + c->qid = r->reply.aqid; + c->mchan = m->c; + incref(m->c); + c->mqid = c->qid; + c->mode = ORDWR; - c = devattach('M', 0); - lock(&mntalloc); - c->dev = mntalloc.id++; - unlock(&mntalloc); + poperror(); /* r */ + mntfree(r); + + poperror(); /* c */ return c; + } -void -mattach(Mnt *m, Chan *c, char *spec) +static Chan* +mntattach(char *muxattach) { + Mnt *m; + Chan *c; Mntrpc *r; + struct bogus{ + Chan *chan; + Chan *authchan; + char *spec; + int flags; + }bogus; + + bogus = *((struct bogus *)muxattach); + c = bogus.chan; + + m = c->mux; + + if(m == nil){ + mntversion(c, nil, 0, 0); + m = c->mux; + if(m == nil) + error(Enoversion); + } + + c = mntchan(); + if(waserror()) { + /* Close must not be called since it will + * call mnt recursively + */ + chanfree(c); + nexterror(); + } r = mntralloc(0, m->c->iounit); - c->mntptr = m; if(waserror()) { mntfree(r); @@ -191,18 +333,42 @@ mattach(Mnt *m, Chan *c, char *spec) r->request.type = Tattach; r->request.fid = c->fid; + if(bogus.authchan == nil) + r->request.afid = NOFID; + else + r->request.afid = bogus.authchan->fid; r->request.uname = up->user; - r->request.aname = spec; - r->request.nauth = 0; - r->request.auth = (uchar*)""; + r->request.aname = bogus.spec; mountrpc(m, r); c->qid = r->reply.qid; c->mchan = m->c; + incref(m->c); c->mqid = c->qid; - poperror(); + poperror(); /* r */ mntfree(r); + + poperror(); /* c */ + + if(bogus.flags&MCACHE) + c->flag |= CCACHE; + return c; +} + +Chan* +mntchan(void) +{ + Chan *c; + + c = devattach('M', 0); + lock(&mntalloc); + c->dev = mntalloc.id++; + unlock(&mntalloc); + + if(c->mchan) + panic("mntchan non-zero %p", c->mchan); + return c; } static Walkqid* @@ -213,6 +379,8 @@ mntwalk(Chan *c, Chan *nc, char **name, int nname) Mntrpc *r; Walkqid *wq; + if(nc != nil) + print("mntwalk: nc != nil\n"); if(nname > MAXWELEM) error("devmnt: too many name elements"); alloc = 0; @@ -268,7 +436,8 @@ mntwalk(Chan *c, Chan *nc, char **name, int nname) if(wq->clone != nil){ if(wq->clone != c){ wq->clone->type = c->type; - incref(m); + wq->clone->mchan = c->mchan; + incref(c->mchan); } if(r->reply.nwqid > 0) wq->clone->qid = r->reply.wqid[r->reply.nwqid-1]; @@ -377,7 +546,6 @@ mntclunk(Chan *c, int t) r = mntralloc(c, m->c->iounit); if(waserror()){ mntfree(r); - mclose(m, c); nexterror(); } @@ -385,24 +553,19 @@ mntclunk(Chan *c, int t) r->request.fid = c->fid; mountrpc(m, r); mntfree(r); - mclose(m, c); poperror(); } void -mclose(Mnt *m, Chan*) +muxclose(Mnt *m) { Mntrpc *q, *r; - if(decref(m) != 0) - return; - for(q = m->queue; q; q = r) { r = q->list; mntfree(q); } m->id = 0; - cclose(m->c); mntpntfree(m); } @@ -853,11 +1016,23 @@ mntralloc(Chan *c, ulong iounit) unlock(&mntalloc); exhausted("mount rpc buffer"); } + new->rpclen = iounit; new->request.tag = mntalloc.rpctag++; } else { mntalloc.rpcfree = new->list; mntalloc.nrpcfree--; + if(new->rpclen < iounit){ + free(new->rpc); + new->rpc = mallocz(iounit, 0); + if(new->rpc == nil){ + free(new); + mntalloc.nrpcused--; + unlock(&mntalloc); + exhausted("mount rpc buffer"); + } + new->rpclen = iounit; + } } mntalloc.nrpcused++; unlock(&mntalloc); @@ -911,13 +1086,21 @@ mntchk(Chan *c) { Mnt *m; - m = c->mntptr; + /* This routine is mostly vestiges of prior lives; now it's just sanity checking */ + + if(c->mchan == nil) + panic("mntchk 1: nil mchan c %s\n", c2name(c)); + + m = c->mchan->mux; + + if(m == nil) + print("mntchk 2: nil mux c %s c->mchan %s \n", c2name(c), c2name(c->mchan)); /* - * Was it closed and reused + * Was it closed and reused (was error(Eshutdown); now, it can't happen) */ if(m->id == 0 || m->id >= c->dev) - error(Eshutdown); + panic("mntchk 3: can't happen"); return m; } diff --git a/port/devproc.c b/port/devproc.c index 0b5b54d4622ea12ae7625afd5b514a70f03aeaa0..c81d0b15d521aa6322f6f87789fe3624c6514941 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -133,7 +133,7 @@ procgen(Chan *c, char *name, Dirtab *tab, int, int s, Dir *dp) len = tab->length; switch(QID(c->qid)) { case Qwait: - len = p->nwait * sizeof(Waitmsg); + len = p->nwait; /* incorrect size, but >0 means there's something to read */ break; case Qprofile: q = p->seg[TSEG]; @@ -653,9 +653,6 @@ procread(Chan *c, void *va, long n, vlong off) return n; case Qwait: - if(n < sizeof(Waitmsg)) - error(Etoosmall); - if(!canqlock(&p->qwaitr)) error(Einuse); @@ -684,9 +681,12 @@ procread(Chan *c, void *va, long n, vlong off) qunlock(&p->qwaitr); poperror(); - memmove(a, &wq->w, sizeof(Waitmsg)); + n = snprint(a, n, "%d %lud %lud %lud %q", + wq->w.pid, + wq->w.time[TUser], wq->w.time[TSys], wq->w.time[TReal], + wq->w.msg); free(wq); - return sizeof(Waitmsg); + return n; case Qns: qlock(&p->debug); diff --git a/port/devroot.c b/port/devroot.c index d8ee66dae0166df242c5e85b0f6d2f922112ff4d..56f88d7afc2ff7b9f07b3e81e6e682e219fa9253 100644 --- a/port/devroot.c +++ b/port/devroot.c @@ -69,6 +69,7 @@ rootreset(void) addrootdir("dev"); addrootdir("env"); addrootdir("fd"); + addrootdir("mnt"); addrootdir("net"); addrootdir("net.alt"); addrootdir("proc"); diff --git a/port/devsrv.c b/port/devsrv.c index 8a25a738556e36218d731958dd9358622987fa47..c087bd4b74bab598a4c7d19ee942d069e825b978 100644 --- a/port/devsrv.c +++ b/port/devsrv.c @@ -294,6 +294,8 @@ srvwrite(Chan *c, void *va, long n, vlong) } if(c1->flag & (CCEXEC|CRCLOSE)) error("posted fd has remove-on-close or close-on-exec"); + if(c1->qid.type & QTAUTH) + error("can't post auth file in srv"); sp = srvlookup(nil, c->qid.path); if(sp == 0) error(Enonexist); diff --git a/port/error.h b/port/error.h index 2a02e920f1858b7e0ee186699715c1bafdc19de7..5447e9b77ba5601af7481f6eed05ea00d52b40a7 100644 --- a/port/error.h +++ b/port/error.h @@ -3,7 +3,7 @@ extern char Emount[]; /* inconsistent mount */ extern char Eunmount[]; /* not mounted */ extern char Eunion[]; /* not in union */ extern char Emountrpc[]; /* mount rpc error */ -extern char Eshutdown[]; /* mounted device shut down */ +extern char Eshutdown[]; /* device shut down */ extern char Enocreate[]; /* mounted directory forbids creation */ extern char Enonexist[]; /* file does not exist */ extern char Eexist[]; /* file already exists */ diff --git a/port/fault.c b/port/fault.c index 39baa0296021fb9788839103037ffdf4d9ec45df..1a4dd4bd58cfe29d10230d28e05af33dd6c11ae7 100644 --- a/port/fault.c +++ b/port/fault.c @@ -38,8 +38,14 @@ fault(ulong addr, int read) } static void -faulterror(char *s, int freemem) +faulterror(char *s, Chan *c, int freemem) { + char buf[ERRMAX]; + + if(c && c->name){ + snprint(buf, sizeof buf, "%s accessing %s: %s", s, c->name->s, up->error); + s = buf; + } if(up->nerrlab) { postnote(up, 1, s, NDebug); error(s); @@ -125,7 +131,7 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) if(swapfull()){ qunlock(&s->lk); pprint("swap space full\n"); - faulterror(Enoswap, 1); + faulterror(Enoswap, nil, 1); } new = newpage(0, &s, addr); @@ -217,7 +223,7 @@ retry: continue; kunmap(k); putpage(new); - faulterror("sys: demand load I/O error", 0); + faulterror("sys: demand load I/O error", c, 0); } ask = s->flen-soff; @@ -226,7 +232,7 @@ retry: n = devtab[c->type]->read(c, kaddr, ask, daddr); if(n != ask) - faulterror(Eioload, 0); + faulterror(Eioload, c, 0); if(ask < BY2PG) memset(kaddr+ask, 0, BY2PG-ask); @@ -253,12 +259,12 @@ retry: putpage(new); qlock(&s->lk); qunlock(&s->lk); - faulterror("sys: page in I/O error", 0); + faulterror("sys: page in I/O error", c, 0); } n = devtab[c->type]->read(c, kaddr, BY2PG, daddr); if(n != BY2PG) - faulterror(Eioload, 0); + faulterror(Eioload, c, 0); poperror(); kunmap(k); diff --git a/port/lib.h b/port/lib.h index 8f9ef61a3716b569622f23a5f7695d179ea51922..c562769ff5b9394ddcaf1313a4529fd1eb529e2e 100644 --- a/port/lib.h +++ b/port/lib.h @@ -112,6 +112,7 @@ extern int tokenize(char*, char**, int); typedef struct Qid Qid; typedef struct Dir Dir; +typedef struct OWaitmsg OWaitmsg; typedef struct Waitmsg Waitmsg; #define ERRMAX 128 /* max length of error string */ @@ -122,6 +123,7 @@ typedef struct Waitmsg Waitmsg; #define QTAPPEND 0x40 /* type bit for append only files */ #define QTEXCL 0x20 /* type bit for exclusive use files */ #define QTMOUNT 0x10 /* type bit for mounted channel */ +#define QTAUTH 0x08 /* type bit for authentication file */ #define QTFILE 0x00 /* plain file */ /* bits in Dir.mode */ @@ -156,9 +158,16 @@ struct Dir { char *muid; /* last modifier name */ }; -struct Waitmsg +struct OWaitmsg { char pid[12]; /* of loved one */ char time[3*12]; /* of loved one and descendants */ char msg[64]; /* compatibility BUG */ }; + +struct Waitmsg +{ + int pid; /* of loved one */ + ulong time[3]; /* of loved one and descendants */ + char msg[ERRMAX]; /* actually variable-size in user mode */ +}; diff --git a/port/portdat.h b/port/portdat.h index 9e0bb41bb03aa83ca1b90cd81ecab07f44f3bc19..dcde3ce10a163897ffd084951efe2428a74ea9cf 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -157,16 +157,15 @@ struct Chan int uri; /* union read index */ ulong mountid; Mntcache *mcp; /* Mount cache pointer */ + Mnt *mux; /* Mnt for clients using me for messages */ union { void* aux; Qid pgrpid; /* for #p/notepg */ - Mnt* mntptr; /* for devmnt */ ulong mid; /* for ns in devproc */ }; Chan* mchan; /* channel to mounted server */ Qid mqid; /* qid of root of mount point */ Session*session; - char *version; /* 9P version */ Cname *name; }; @@ -254,13 +253,15 @@ struct Mhead struct Mnt { - Ref; /* Count of attached channels */ + Lock; + /* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */ Chan *c; /* Channel to file service */ Proc *rip; /* Reader in progress */ Mntrpc *queue; /* Queue of pending requests on this channel */ ulong id; /* Multiplexer id for channel check */ Mnt *list; /* Free list */ int flags; /* cache */ + char *version; /* 9P version */ Queue *q; /* input queue */ }; diff --git a/port/portfns.h b/port/portfns.h index 981c1d41c27a07cf934f37b0ce60b7d4f299674e..9297ecaa1caf2f011586b4e37cdd6e2454fe8fd2 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -16,6 +16,7 @@ int blocklen(Block*); void cachedel(Image*, ulong); void cachepage(Page*, Image*); void callwithureg(void(*)(Ureg*)); +char* c2name(Chan*); int cangetc(void*); int canlock(Lock*); int canpage(Proc*); @@ -163,12 +164,16 @@ void microdelay(int); void mkqid(Qid*, vlong, ulong, int); void mmurelease(Proc*); void mmuswitch(Proc*); +Chan* mntauth(Chan*, char*); void mntdump(void); +long mntversion(Chan*, char*, int, int); void mountfree(Mount*); ulong msize(void*); +void muxclose(Mnt*); Chan* namec(char*, int, int, ulong); #define nelem(x) (sizeof(x)/sizeof(x[0])) Chan* newchan(void); +int newfd(Chan*); Mount* newmount(Mhead*, Chan*, int, char*); Page* newpage(int, Segment **, ulong); Pgrp* newpgrp(void); diff --git a/port/print.c b/port/print.c index bf8544caf1d1d67db8e52ac2a3e3341402ec2929..7ba421839997c69f4e0c646d05fd02ff4d5ae310 100644 --- a/port/print.c +++ b/port/print.c @@ -665,6 +665,8 @@ needsquotes(char *s, int *quotelenp) int nextra, ok, w; Rune r; + if(*s == '\0') + return 1; nextra = 0; ok = 1; for(t=s; *t; t+=w){ @@ -692,6 +694,8 @@ runeneedsquotes(Rune *s, int *quotelenp) int nextra, ok; Rune r; + if(*s == L'\0') + return 1; nextra = 0; ok = 1; for(t=s; *t; t++){ diff --git a/port/proc.c b/port/proc.c index 901a4d0495e83225295defc0d98d81df7f0ddb13..619c53435f62044509b0df59a599acf459a0273c 100644 --- a/port/proc.c +++ b/port/proc.c @@ -717,7 +717,6 @@ freebroken(void) void pexit(char *exitstr, int freemem) { - int n; Proc *p; Segment **s, **es; long utime, stime; @@ -773,20 +772,12 @@ pexit(char *exitstr, int freemem) wq = smalloc(sizeof(Waitq)); poperror(); - readnum(0, wq->w.pid, NUMSIZE, up->pid, NUMSIZE); - utime = up->time[TUser] + up->time[TCUser]; - stime = up->time[TSys] + up->time[TCSys]; - readnum(0, &wq->w.time[TUser*12], NUMSIZE, - TK2MS(utime), NUMSIZE); - readnum(0, &wq->w.time[TSys*12], NUMSIZE, - TK2MS(stime), NUMSIZE); - readnum(0, &wq->w.time[TReal*12], NUMSIZE, - TK2MS(MACHP(0)->ticks - up->time[TReal]), NUMSIZE); - if(exitstr && exitstr[0]){ - n = sprint(wq->w.msg, "%s %lud:", up->text, up->pid); - strncpy(wq->w.msg+n, exitstr, sizeof wq->w.msg-n); - wq->w.msg[sizeof wq->w.msg-1] = 0; - } + wq->w.pid = up->pid; + wq->w.time[TUser] = utime = up->time[TUser] + up->time[TCUser]; + wq->w.time[TSys] = stime = up->time[TSys] + up->time[TCSys]; + wq->w.time[TReal] = TK2MS(MACHP(0)->ticks - up->time[TReal]); + if(exitstr && exitstr[0]) + snprint(wq->w.msg, sizeof(wq->w.msg), "%s %lud: %s", up->text, up->pid, exitstr); else wq->w.msg[0] = '\0'; @@ -900,7 +891,7 @@ pwait(Waitmsg *w) if(w) memmove(w, &wq->w, sizeof(Waitmsg)); - cpid = atoi(wq->w.pid); + cpid = wq->w.pid; free(wq); return cpid; } diff --git a/port/sysfile.c b/port/sysfile.c index 9e6f03e914e2e1c2aea7a3c8ac09fd242ad5b0a1..aae4680a140f427925892636436788cdaf26341b 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -271,6 +271,7 @@ sysopen(ulong *arg) if(fd < 0) error(Enofd); poperror(); +if(strstr(up->text, "syscall")!=0) pprint("open %s ref count %d\n", c2name(c), c->ref); // BUG return fd; } @@ -668,19 +669,17 @@ syschdir(ulong *arg) } long -bindmount(ulong *arg, int ismount) +bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec) { - ulong flag; - int fd, ret; - Chan *c0, *c1, *bc; + int ret; + Chan *c0, *c1, *ac, *bc; struct{ Chan *chan; + Chan *authchan; char *spec; int flags; }bogus; - flag = arg[2]; - fd = arg[0]; if(flag>MMASK || (flag&MORDER)==(MBEFORE|MAFTER)) error(Ebadarg); @@ -690,32 +689,41 @@ bindmount(ulong *arg, int ismount) if(up->pgrp->noattach) error(Enoattach); + ac = nil; bc = fdtochan(fd, ORDWR, 0, 1); if(waserror()) { + if(ac) + cclose(ac); cclose(bc); nexterror(); } + + if(afd >= 0) + ac = fdtochan(afd, ORDWR, 0, 1); + bogus.chan = bc; + bogus.authchan = ac; - validaddr(arg[3], 1, 0); - validname((char*)arg[3], 1); + validaddr((ulong)spec, 1, 0); + validname(spec, 1); - bogus.spec = (char*)arg[3]; + bogus.spec = spec; if(waserror()) error(Ebadspec); - validname(bogus.spec, 1); poperror(); ret = devno('M', 0); c0 = devtab[ret]->attach((char*)&bogus); poperror(); + if(ac) + cclose(ac); cclose(bc); } else { bogus.spec = 0; - validaddr(arg[0], 1, 0); - c0 = namec((char*)arg[0], Amount, 0, 0); + validaddr((ulong)arg0, 1, 0); + c0 = namec(arg0, Amount, 0, 0); } if(waserror()){ @@ -723,8 +731,8 @@ bindmount(ulong *arg, int ismount) nexterror(); } - validaddr(arg[1], 1, 0); - c1 = namec((char*)arg[1], Amount, 0, 0); + validaddr((ulong)arg1, 1, 0); + c1 = namec(arg1, Amount, 0, 0); if(waserror()){ cclose(c1); nexterror(); @@ -738,19 +746,26 @@ bindmount(ulong *arg, int ismount) cclose(c0); if(ismount) fdclose(fd, 0); + return ret; } long sysbind(ulong *arg) { - return bindmount(arg, 0); + return bindmount(0, -1, -1, (char*)arg[0], (char*)arg[1], arg[2], nil); } long sysmount(ulong *arg) { - return bindmount(arg, 1); + return bindmount(1, arg[0], arg[1], nil, (char*)arg[2], arg[3], (char*)arg[4]); +} + +long +sys_mount(ulong *arg) +{ + return bindmount(1, arg[0], -1, nil, (char*)arg[1], arg[2], (char*)arg[3]); } long diff --git a/port/sysproc.c b/port/sysproc.c index 9ba3751ceb8de87b1e2f20ef7d4f987c22c42788..5210b364a61a3820166ec53d57c52295f2cae475 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -12,13 +12,13 @@ int shargs(char*, int, char**); long sysr1(ulong *arg) { -extern int chandebug; -extern void dumpmount(void); + extern int chandebug; + extern void dumpmount(void); print("[%s %s %lud] r1 = %lud\n", up->user, up->text, up->pid, arg[0]); -chandebug=!chandebug; -if(chandebug) - dumpmount(); + chandebug=!chandebug; + if(chandebug) + dumpmount(); return 0; } @@ -567,13 +567,49 @@ sysexits(ulong *arg) } long -syswait(ulong *arg) +sys_wait(ulong *arg) { - if(arg[0]){ - validaddr(arg[0], sizeof(Waitmsg), 1); - evenaddr(arg[0]); + int pid; + Waitmsg w; + OWaitmsg *ow; + + if(arg[0] == 0) + return pwait(nil); + + validaddr(arg[0], sizeof(OWaitmsg), 1); + evenaddr(arg[0]); + pid = pwait(&w); + if(pid >= 0){ + ow = (OWaitmsg*)arg[0]; + readnum(0, ow->pid, NUMSIZE, w.pid, NUMSIZE); + readnum(0, ow->time+TUser*NUMSIZE, NUMSIZE, w.time[TUser], NUMSIZE); + readnum(0, ow->time+TSys*NUMSIZE, NUMSIZE, w.time[TSys], NUMSIZE); + readnum(0, ow->time+TReal*NUMSIZE, NUMSIZE, w.time[TReal], NUMSIZE); + strncpy(ow->msg, w.msg, sizeof(ow->msg)); + ow->msg[sizeof(ow->msg)-1] = '\0'; } - return pwait((Waitmsg*)arg[0]); + return pid; +} + +long +sysawait(ulong *arg) +{ + int i; + int pid; + Waitmsg w; + ulong n; + + n = arg[1]; + validaddr(arg[0], n, 1); + pid = pwait(&w); + if(pid < 0) + return -1; + i = snprint((char*)arg[0], n, "%d %lud %lud %lud %q", + w.pid, + w.time[TUser], w.time[TSys], w.time[TReal], + w.msg); + + return i; } long diff --git a/port/systab.h b/port/systab.h index d201490783632ba2d13369a9fe3572c5acfbb06f..4987419094208fcdabb8fcf89016339e6ad6e57e 100644 --- a/port/systab.h +++ b/port/systab.h @@ -11,11 +11,11 @@ Syscall sysdup; Syscall sysalarm; Syscall sysexec; Syscall sysexits; -Syscall sysfsession; +Syscall sys_fsession; Syscall sysfauth; Syscall sys_fstat; Syscall syssegbrk; -Syscall sysmount; +Syscall sys_mount; Syscall sysopen; Syscall sys_read; Syscall sysoseek; @@ -38,7 +38,7 @@ Syscall syssegfree; Syscall syssegflush; Syscall sysrendezvous; Syscall sysunmount; -Syscall syswait; +Syscall sys_wait; Syscall sysseek; Syscall sysfversion; Syscall syserrstr; @@ -46,6 +46,8 @@ Syscall sysstat; Syscall sysfstat; Syscall syswstat; Syscall sysfwstat; +Syscall sysmount; +Syscall sysawait; Syscall syspread; Syscall syspwrite; Syscall sysdeath; @@ -60,11 +62,11 @@ Syscall *systab[]={ [ALARM] sysalarm, [EXEC] sysexec, [EXITS] sysexits, - [FSESSION] sysfsession, + [_FSESSION] sys_fsession, [FAUTH] sysfauth, [_FSTAT] sys_fstat, [SEGBRK] syssegbrk, - [MOUNT] sysmount, + [_MOUNT] sys_mount, [OPEN] sysopen, [_READ] sys_read, [OSEEK] sysoseek, @@ -87,7 +89,7 @@ Syscall *systab[]={ [SEGFLUSH] syssegflush, [RENDEZVOUS] sysrendezvous, [UNMOUNT] sysunmount, - [WAIT] syswait, + [_WAIT] sys_wait, [SEEK] sysseek, [FVERSION] sysfversion, [ERRSTR] syserrstr, @@ -95,6 +97,8 @@ Syscall *systab[]={ [FSTAT] sysfstat, [WSTAT] syswstat, [FWSTAT] sysfwstat, + [MOUNT] sysmount, + [AWAIT] sysawait, [PREAD] syspread, [PWRITE] syspwrite, }; @@ -109,11 +113,11 @@ char *sysctab[]={ [ALARM] "Alarm", [EXEC] "Exec", [EXITS] "Exits", - [FSESSION] "Fsession", + [_FSESSION] "_fsession", [FAUTH] "Fauth", [_FSTAT] "_fstat", [SEGBRK] "Segbrk", - [MOUNT] "Mount", + [_MOUNT] "_mount", [OPEN] "Open", [_READ] "_read", [OSEEK] "Oseek", @@ -136,7 +140,7 @@ char *sysctab[]={ [SEGFLUSH] "Segflush", [RENDEZVOUS] "Rendez", [UNMOUNT] "Unmount", - [WAIT] "Wait", + [_WAIT] "_wait", [SEEK] "Seek", [FVERSION] "Fversion", [ERRSTR] "Errstr", @@ -144,6 +148,8 @@ char *sysctab[]={ [FSTAT] "Fstat", [WSTAT] "Wstat", [FWSTAT] "Fwstat", + [MOUNT] "Mount", + [AWAIT] "Await", [PREAD] "Pread", [PWRITE] "Pwrite", };