from cinap: aux/listen: rfork with RFREND child processes handling the connection should be all independent of each another and not share rendezvous group. the rendezvous group sharing caused a bug in exportfs when we switched from using pid to memory address as rendezvous tag. Reference: /n/atom/patch/applied/listenrfrend Date: Thu Mar 13 14:17:25 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/aux/listen.c Thu Mar 13 14:17:14 2014 +++ /sys/src/cmd/aux/listen.c Thu Mar 13 14:17:15 2014 @@ -167,7 +167,7 @@ * changing of console environment variables * erase privileged crypt state */ - switch(rfork(RFNOTEG|RFPROC|RFFDG|RFNOWAIT|RFENVG|RFNAMEG)) { + switch(rfork(RFNOTEG|RFPROC|RFFDG|RFNOWAIT|RFENVG|RFNAMEG|RFREND)) { case -1: error("fork"); case 0: @@ -266,9 +266,15 @@ * make a list of all services to announce for */ void -addannounce(char *str) +addannounce(char *fmt, ...) { Announce *a, **l; + char str[128]; + va_list arg; + + va_start(arg, fmt); + vseprint(str, str+sizeof(str), fmt, arg); + va_end(arg); /* look for duplicate */ l = &announcements; @@ -292,10 +298,17 @@ * delete a service for announcement list */ void -delannounce(char *str) +delannounce(char *fmt, ...) { Announce *a, **l; + char str[128]; + va_list arg; + + va_start(arg, fmt); + vseprint(str, str+sizeof(str), fmt, arg); + va_end(arg); + /* look for service */ l = &announcements; for(a = announcements; a; a = a->next){ @@ -330,7 +343,6 @@ { int fd, i, n, nlen; char *nm; - char ds[128]; Dir *db; fd = open(dname, OREAD); @@ -341,15 +353,14 @@ while((n=dirread(fd, &db)) > 0){ for(i=0; iincalls); if(i == nil) return -1; - print("%s: recvp slot %d\n", l->ds, i->slot); + dprint(Dtrace, "%s: recvp slot %d\n", l->ds, i->slot); i->pid = Unset; redux: @@ -285,7 +291,7 @@ if(i->cfd == -1){ sendp(l->incalls, i); if(l->fatal){ - print("%s: fatal in listen\n", l->ds); + dprint(Dtrace, "%s: fatal in listen\n", l->ds); return -1; } llog("listen: %r"); @@ -303,7 +309,7 @@ } i->pid = recvul(l->pidchan); close(i->cfd); - print("%s: slot %d pid %d\n", l->ds, i->slot, i->pid); + dprint(Dtrace, "%s: slot %d pid %d\n", l->ds, i->slot, i->pid); if(i->pid == -1){ /* * assume the script can't be exec'd due to bad @@ -311,7 +317,8 @@ * until the script is changed. */ l->wait[i->slot] = nil; - print("pid is %d\n", i->pid); + dprint(Dtrace, "pid is %d (can't exec; penalty=1)\n", i->pid); + llog("%s/%s: can't exec: won't exec until changed", l->largs->srv, l->es); l->penalty = 1; return -1; } @@ -355,7 +362,7 @@ int i, sz; dprint(Dtrace, "newserver %s\n", l->ds); - l->nincall = Maxincall; + l->nincall = maxincall; l->incalls = chancreate(sizeof(Incall*), l->nincall); l->pidchan = chancreate(sizeof(ulong), 1); @@ -713,7 +720,7 @@ void usage(void) { - fprint(2, "usage: xlisten [-n nsfile] [-N nsfile] [-d dir] [-t trust] [netdir] ...\n"); + fprint(2, "usage: xlisten [-m maxincall] [-n nsfile] [-N nsfile] [-d dir] [-t trust] [netdir] ...\n"); threadexits(""); } @@ -746,6 +753,12 @@ if(checkdir(p->srvtab[Trust], Okdir) == -1) sysfatal("xlisten: service directory doesn't exist: %r"); break; + case 'm': + maxincall = atoi(EARGF(usage())); + if(maxincall == -1 || maxincall > Maxmaxincall) + maxincall = Maxmaxincall; + if(maxincall <= 0) + sysfatal("xlisten: maxincall must be positive"); default: usage(); }ARGEND