M boot/boot.c => boot/boot.c +16 -12
@@ 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);
M boot/boot.h => boot/boot.h +5 -2
@@ 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;
A boot/bootauth.c => boot/bootauth.c +74 -0
@@ 0,0 1,74 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+#include <fcall.h>
+#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
+}
M boot/bootcache.c => boot/bootcache.c +1 -1
@@ 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]);
M boot/bootip.c => boot/bootip.c +23 -25
@@ 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
M boot/dosboot.c => boot/dosboot.c +4 -4
@@ 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);
M boot/settime.c => boot/settime.c +4 -4
@@ 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);
M pc/dat.h => pc/dat.h +1 -1
@@ 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
M port/auth.c => port/auth.c +32 -137
@@ 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;
}
/*
M port/chan.c => port/chan.c +16 -73
@@ 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; i<nelem(pcs) && pcs[i]; i++)
-// if(pc == pcs[i])
-// break;
-// if(up!=nil && i<nelem(pcs) && pcs[i]==0){
-// pcs[i] = pc;
-// print("kstrdup(null string) called from 0x%lux\n", pc);
-// }
-// }
/* if it's a user, we can wait for memory; if not, something's very wrong */
if(up){
t = smalloc(n);
@@ 253,9 240,9 @@ newchan(void)
c->aux = 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; i<nnames; i++)
- print("%s%s", i?"/":"", names[i]);
-print("\n");
-qunlock(&chanprint);
-}
-
/*
* While we haven't gotten all the way down the path:
* 1. step through a mount point, if any
@@ 775,15 751,6 @@ qunlock(&chanprint);
}
}
-if(chandebug){
-qlock(&chanprint);
-print("[%lud]\twalk from %s (path %.8llux dev %C %lud) to ",
- up->pid, c2name(c), c->qid.path, devtab[c->type]->dc, c->dev);
-for(i=0; i<ntry; i++)
- print("%s%s", i?"/":"", names[i]);
-print("\n");
-qunlock(&chanprint);
-}
if(!dotdot && !nomount)
domount(&c, &mh);
@@ 791,11 758,9 @@ qunlock(&chanprint);
dev = c->dev;
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:"<nil name>");
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; i<n; i++)
cname = addelem(cname, names[i]);
}
-
cclose(c);
c = nc;
putmhead(mh);
@@ 886,19 830,18 @@ qunlock(&chanprint);
putmhead(mh);
c = cunique(c);
-if(c->umh != 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;
}
M port/dev.c => port/dev.c +0 -7
@@ 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; i<nname; i++)
-// print("%s/", name[i]);
-// print("\n");
-//delay(500);
-
alloc = 0;
wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
if(waserror()){
M port/devcons.c => port/devcons.c +1 -1
@@ 241,7 241,7 @@ panic(char *fmt, ...)
spllo();
prflush();
putstrn(buf, n+1);
- dumpstack();
+// dumpstack();
exit(1);
}
M port/devdup.c => port/devdup.c +3 -1
@@ 63,7 63,7 @@ dupopen(Chan *c, int omode)
Chan *f;
int fd, twicefd;
- if(c->qid.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)){
M port/devmnt.c => port/devmnt.c +255 -72
@@ 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;
}
M port/devproc.c => port/devproc.c +6 -6
@@ 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);
M port/devroot.c => port/devroot.c +1 -0
@@ 69,6 69,7 @@ rootreset(void)
addrootdir("dev");
addrootdir("env");
addrootdir("fd");
+ addrootdir("mnt");
addrootdir("net");
addrootdir("net.alt");
addrootdir("proc");
M port/devsrv.c => port/devsrv.c +2 -0
@@ 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);
M port/error.h => port/error.h +1 -1
@@ 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 */
M port/fault.c => port/fault.c +12 -6
@@ 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);
M port/lib.h => port/lib.h +10 -1
@@ 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 */
+};
M port/portdat.h => port/portdat.h +4 -3
@@ 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 */
};
M port/portfns.h => port/portfns.h +5 -0
@@ 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);
M port/print.c => port/print.c +4 -0
@@ 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++){
M port/proc.c => port/proc.c +7 -16
@@ 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;
}
M port/sysfile.c => port/sysfile.c +31 -16
@@ 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
M port/sysproc.c => port/sysproc.c +46 -10
@@ 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
M port/systab.h => port/systab.h +15 -9
@@ 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",
};