Browse Source

Plan 9 from Bell Labs 2007-11-14

David du Colombier 16 years ago
parent
commit
2fb5d66123

+ 6 - 6
dist/replica/_plan9.db

@@ -7507,7 +7507,7 @@ sys/man/2/0intro - 664 sys sys 1115941566 11660
 sys/man/2/9p - 664 sys sys 1175867369 15852
 sys/man/2/9pcmdbuf - 664 sys sys 1186721809 2162
 sys/man/2/9pfid - 664 sys sys 1194905671 3696
-sys/man/2/9pfile - 664 sys sys 1048637158 4408
+sys/man/2/9pfile - 664 sys sys 1194935570 4409
 sys/man/2/INDEX - 664 sys sys 1183240469 20532
 sys/man/2/INDEX.html - 664 sys sys 1183240476 27618
 sys/man/2/abort - 664 sys sys 944959693 331
@@ -12806,17 +12806,17 @@ sys/src/cmd/ndb/convM2DNS.c - 664 sys sys 1194216290 11959
 sys/src/cmd/ndb/cs.c - 664 sys sys 1188515063 32892
 sys/src/cmd/ndb/csquery.c - 664 sys sys 1174626119 1073
 sys/src/cmd/ndb/dblookup.c - 664 sys sys 1194216346 25229
-sys/src/cmd/ndb/dn.c - 664 sys sys 1194216512 37395
+sys/src/cmd/ndb/dn.c - 664 sys sys 1194996325 37423
 sys/src/cmd/ndb/dnarea.c - 664 sys sys 1175664421 2519
-sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1183866408 3217
-sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1194321818 34961
-sys/src/cmd/ndb/dns.c - 664 sys sys 1194216588 16627
+sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1194996355 3265
+sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1194996432 35393
+sys/src/cmd/ndb/dns.c - 664 sys sys 1194996490 17499
 sys/src/cmd/ndb/dns.h - 664 sys sys 1194216527 11889
 sys/src/cmd/ndb/dnsdebug.c - 664 sys sys 1194216583 8790
 sys/src/cmd/ndb/dnserver.c - 664 sys sys 1184990866 4627
 sys/src/cmd/ndb/dnsquery.c - 664 sys sys 1185315254 2507
 sys/src/cmd/ndb/dnstcp.c - 664 sys sys 1194216576 7503
-sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1194216569 5542
+sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1194996502 5612
 sys/src/cmd/ndb/ipquery.c - 664 sys sys 1124711423 773
 sys/src/cmd/ndb/mkdb.c - 664 sys sys 957402054 2886
 sys/src/cmd/ndb/mkfile - 664 sys sys 1174623575 1984

+ 6 - 6
dist/replica/plan9.db

@@ -7507,7 +7507,7 @@ sys/man/2/0intro - 664 sys sys 1115941566 11660
 sys/man/2/9p - 664 sys sys 1175867369 15852
 sys/man/2/9pcmdbuf - 664 sys sys 1186721809 2162
 sys/man/2/9pfid - 664 sys sys 1194905671 3696
-sys/man/2/9pfile - 664 sys sys 1048637158 4408
+sys/man/2/9pfile - 664 sys sys 1194935570 4409
 sys/man/2/INDEX - 664 sys sys 1183240469 20532
 sys/man/2/INDEX.html - 664 sys sys 1183240476 27618
 sys/man/2/abort - 664 sys sys 944959693 331
@@ -12806,17 +12806,17 @@ sys/src/cmd/ndb/convM2DNS.c - 664 sys sys 1194216290 11959
 sys/src/cmd/ndb/cs.c - 664 sys sys 1188515063 32892
 sys/src/cmd/ndb/csquery.c - 664 sys sys 1174626119 1073
 sys/src/cmd/ndb/dblookup.c - 664 sys sys 1194216346 25229
-sys/src/cmd/ndb/dn.c - 664 sys sys 1194216512 37395
+sys/src/cmd/ndb/dn.c - 664 sys sys 1194996325 37423
 sys/src/cmd/ndb/dnarea.c - 664 sys sys 1175664421 2519
-sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1183866408 3217
-sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1194321818 34961
-sys/src/cmd/ndb/dns.c - 664 sys sys 1194216588 16627
+sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1194996355 3265
+sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1194996432 35393
+sys/src/cmd/ndb/dns.c - 664 sys sys 1194996490 17499
 sys/src/cmd/ndb/dns.h - 664 sys sys 1194216527 11889
 sys/src/cmd/ndb/dnsdebug.c - 664 sys sys 1194216583 8790
 sys/src/cmd/ndb/dnserver.c - 664 sys sys 1184990866 4627
 sys/src/cmd/ndb/dnsquery.c - 664 sys sys 1185315254 2507
 sys/src/cmd/ndb/dnstcp.c - 664 sys sys 1194216576 7503
-sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1194216569 5542
+sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1194996502 5612
 sys/src/cmd/ndb/ipquery.c - 664 sys sys 1124711423 773
 sys/src/cmd/ndb/mkdb.c - 664 sys sys 957402054 2886
 sys/src/cmd/ndb/mkfile - 664 sys sys 1174623575 1984

+ 6 - 0
dist/replica/plan9.log

@@ -53354,3 +53354,9 @@
 1194796805 1 c sys/src/boot/pc/etherigbe.c - 664 sys sys 1194796683 41188
 1194906629 0 c sys/man/2/9pfid - 664 sys sys 1194905671 3696
 1194913805 0 c sys/src/9/port/devaoe.c - 664 sys sys 1194913595 42084
+1194937204 0 c sys/man/2/9pfile - 664 sys sys 1194935570 4409
+1194996604 0 c sys/src/cmd/ndb/dn.c - 664 sys sys 1194996325 37423
+1194996604 1 c sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1194996355 3265
+1194996604 2 c sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1194996432 35393
+1194996604 3 c sys/src/cmd/ndb/dns.c - 664 sys sys 1194996490 17499
+1194996604 4 c sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1194996502 5612

+ 1 - 1
sys/man/2/9pfile

@@ -47,7 +47,7 @@ int	removefile(File *file)
 void	closefile(File *file)
 File*	walkfile(File *dir, char *path)
 Readdir*	opendirfile(File *dir)
-long	readdirfile(Readdir *rdir, char *buf, long n)
+long	readdirfile(Readdir *rdir, uchar *buf, long n)
 void	closedirfile(Readdir *rdir)
 int	hasperm(File *file, char *uid, int p)
 .fi

+ 5 - 2
sys/src/cmd/ndb/dn.c

@@ -1425,9 +1425,12 @@ slave(Request *req)
 		return;
 	}
 
-	/* parent returns to main loop, child does the work */
+	/*
+	 * parent returns to main loop, child does the work.
+	 * don't change note group.
+	 */
 	ppid = getpid();
-	switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
+	switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
 	case -1:
 		putactivity(1);
 		break;

+ 2 - 2
sys/src/cmd/ndb/dnnotify.c

@@ -48,9 +48,9 @@ static void
 ding(void*, char *msg)
 {
 	if(strstr(msg, "alarm") != nil)
-		noted(NCONT);
+		noted(NCONT);		/* resume with system call error */
 	else
-		noted(NDFLT);
+		noted(NDFLT);		/* die */
 }
 
 /* notify a slave that an area has changed. */

+ 115 - 96
sys/src/cmd/ndb/dnresolve.c

@@ -43,6 +43,11 @@ struct Dest
 	ulong	magic;
 };
 
+/*
+ * Query has a QLock in it, thus it can't be an automatic
+ * variable, since each process would see a separate copy
+ * of the lock on its stack.
+ */
 struct Query {
 	DN	*dp;		/* domain */
 	int	type;		/* and type to look up */
@@ -168,7 +173,8 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
 				if(rp == nil)
 					break;
 
-				if(rp->negative){
+				/* rp->host == nil shouldn't happen, but does */
+				if(rp->negative || rp->host == nil){
 					rrfreelist(rp);
 					rp = nil;
 					break;
@@ -288,72 +294,11 @@ noteinmem(void)
 }
 
 static RR*
-dnresolve1(char *name, int class, int type, Request *req, int depth,
-	int recurse)
+issuequery(Query *qp, RR *rp, char *name, int class, int depth, int recurse)
 {
 	char *cp;
-	Area *area;
-	DN *dp, *nsdp;
-	RR *rp, *nsrp, *dbnsrp;
-	Query query;
-
-	if(debug)
-		dnslog("[%d] dnresolve1 %s %d %d", getpid(), name, type, class);
-
-	/* only class Cin implemented so far */
-	if(class != Cin)
-		return nil;
-
-	dp = dnlookup(name, class, 1);
-
-	/*
-	 *  Try the cache first
-	 */
-	rp = rrlookup(dp, type, OKneg);
-	if(rp)
-		if(rp->db){
-			/* unauthoritative db entries are hints */
-			if(rp->auth) {
-				noteinmem();
-				return rp;
-			}
-		} else
-			/* cached entry must still be valid */
-			if(rp->ttl > now)
-				/* but Tall entries are special */
-				if(type != Tall || rp->query == Tall) {
-					noteinmem();
-					return rp;
-				}
-
-	rrfreelist(rp);
-
-	/*
-	 * try the cache for a canonical name. if found punt
-	 * since we'll find it during the canonical name search
-	 * in dnresolve().
-	 */
-	if(type != Tcname){
-		rp = rrlookup(dp, Tcname, NOneg);
-		rrfreelist(rp);
-		if(rp)
-			return nil;
-	}
-
-	/*
-	 * if the domain name is within an area of ours,
-	 * we should have found its data in memory by now.
-	 */
-	area = inmyarea(dp->name);
-	if (area || strncmp(dp->name, "local#", 6) == 0) {
-//		char buf[32];
-
-//		dnslog("%s %s: no data in area %s", dp->name,
-//			rrname(type, buf, sizeof buf), area->soarr->owner->name);
-		return nil;
-	}
-
-	queryinit(&query, dp, type, req);
+	DN *nsdp;
+	RR *nsrp, *dbnsrp;
 
 	/*
 	 *  if we're running as just a resolver, query our
@@ -362,11 +307,10 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
 	if(cfg.resolver){
 		nsrp = randomize(getdnsservers(class));
 		if(nsrp != nil) {
-			query.nsrp = nsrp;
-			if(netquery(&query, depth+1)){
+			qp->nsrp = nsrp;
+			if(netquery(qp, depth+1)){
 				rrfreelist(nsrp);
-				querydestroy(&query);
-				return rrlookup(dp, type, OKneg);
+				return rrlookup(qp->dp, qp->type, OKneg);
 			}
 			rrfreelist(nsrp);
 		}
@@ -383,9 +327,8 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
 		 */
 		dbnsrp = randomize(dblookup(cp, class, Tns, 0, 0));
 		if(dbnsrp && dbnsrp->local){
-			rp = dblookup(name, class, type, 1, dbnsrp->ttl);
+			rp = dblookup(name, class, qp->type, 1, dbnsrp->ttl);
 			rrfreelist(dbnsrp);
-			querydestroy(&query);
 			return rp;
 		}
 
@@ -415,11 +358,10 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
 			rrfreelist(dbnsrp);
 
 			/* query the name servers found in cache */
-			query.nsrp = nsrp;
-			if(netquery(&query, depth+1)){
+			qp->nsrp = nsrp;
+			if(netquery(qp, depth+1)){
 				rrfreelist(nsrp);
-				querydestroy(&query);
-				return rrlookup(dp, type, OKneg);
+				return rrlookup(qp->dp, qp->type, OKneg);
 			}
 			rrfreelist(nsrp);
 			continue;
@@ -428,17 +370,89 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
 		/* use ns from db */
 		if(dbnsrp){
 			/* try the name servers found in db */
-			query.nsrp = dbnsrp;
-			if(netquery(&query, depth+1)){
+			qp->nsrp = dbnsrp;
+			if(netquery(qp, depth+1)){
 				/* we got an answer */
 				rrfreelist(dbnsrp);
-				querydestroy(&query);
-				return rrlookup(dp, type, NOneg);
+				return rrlookup(qp->dp, qp->type, NOneg);
 			}
 			rrfreelist(dbnsrp);
 		}
 	}
-	querydestroy(&query);
+	return rp;
+}
+
+static RR*
+dnresolve1(char *name, int class, int type, Request *req, int depth,
+	int recurse)
+{
+	Area *area;
+	DN *dp;
+	RR *rp;
+	Query *qp;
+
+	if(debug)
+		dnslog("[%d] dnresolve1 %s %d %d", getpid(), name, type, class);
+
+	/* only class Cin implemented so far */
+	if(class != Cin)
+		return nil;
+
+	dp = dnlookup(name, class, 1);
+
+	/*
+	 *  Try the cache first
+	 */
+	rp = rrlookup(dp, type, OKneg);
+	if(rp)
+		if(rp->db){
+			/* unauthoritative db entries are hints */
+			if(rp->auth) {
+				noteinmem();
+				return rp;
+			}
+		} else
+			/* cached entry must still be valid */
+			if(rp->ttl > now)
+				/* but Tall entries are special */
+				if(type != Tall || rp->query == Tall) {
+					noteinmem();
+					return rp;
+				}
+	rrfreelist(rp);
+
+	/*
+	 * try the cache for a canonical name. if found punt
+	 * since we'll find it during the canonical name search
+	 * in dnresolve().
+	 */
+	if(type != Tcname){
+		rp = rrlookup(dp, Tcname, NOneg);
+		rrfreelist(rp);
+		if(rp)
+			return nil;
+	}
+
+	/*
+	 * if the domain name is within an area of ours,
+	 * we should have found its data in memory by now.
+	 */
+	area = inmyarea(dp->name);
+	if (area || strncmp(dp->name, "local#", 6) == 0) {
+//		char buf[32];
+
+//		dnslog("%s %s: no data in area %s", dp->name,
+//			rrname(type, buf, sizeof buf), area->soarr->owner->name);
+		return nil;
+	}
+
+	qp = emalloc(sizeof *qp);
+	queryinit(qp, dp, type, req);
+	rp = issuequery(qp, rp, name, class, depth, recurse);
+	querydestroy(qp);
+	free(qp);
+	if(rp)
+		return rp;
 
 	/* settle for a non-authoritative answer */
 	rp = rrlookup(dp, type, OKneg);
@@ -530,13 +544,12 @@ mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno)
 
 /* for alarms in readreply */
 static void
-ding(void *x, char *msg)
+ding(void*, char *msg)
 {
-	USED(x);
-	if(strcmp(msg, "alarm") == 0)
-		noted(NCONT);
+	if(strstr(msg, "alarm") != nil)
+		noted(NCONT);		/* resume with system call error */
 	else
-		noted(NDFLT);
+		noted(NDFLT);		/* die */
 }
 
 void
@@ -1068,7 +1081,7 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
 //	int lcktype;
 	char buf[32];
 	DN *ndp;
-	Query nquery;
+	Query *nqp;
 	RR *tp, *soarr;
 
 	if (mp->an == nil)
@@ -1179,13 +1192,15 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
 //	lcktype = qtype2lck(qp->type);
 //	qunlock(&qp->dp->querylck[lcktype]);
 
-	queryinit(&nquery, qp->dp, qp->type, qp->req);
-	nquery.nsrp = tp;
-	rv = netquery(&nquery, depth+1);
+	nqp = emalloc(sizeof *nqp);
+	queryinit(nqp, qp->dp, qp->type, qp->req);
+	nqp->nsrp = tp;
+	rv = netquery(nqp, depth+1);
 
 //	qlock(&qp->dp->querylck[lcktype]);
 	rrfreelist(tp);
-	querydestroy(&nquery);
+	querydestroy(nqp);
+	free(nqp);
 	return rv;
 }
 
@@ -1550,16 +1565,20 @@ seerootns(void)
 	int rv;
 	char root[] = "";
 	Request req;
-	Query query;
+	Query *qp;
 
 	memset(&req, 0, sizeof req);
 	req.isslave = 1;
 	req.aborttime = now + Maxreqtm;
 	req.from = "internal";
-	queryinit(&query, dnlookup(root, Cin, 1), Tns, &req);
-	query.nsrp = dblookup(root, Cin, Tns, 0, 0);
-	rv = netquery(&query, 0);
-	rrfreelist(query.nsrp);
-	querydestroy(&query);
+	qp = emalloc(sizeof *qp);
+	queryinit(qp, dnlookup(root, Cin, 1), Tns, &req);
+
+	qp->nsrp = dblookup(root, Cin, Tns, 0, 0);
+	rv = netquery(qp, 0);
+
+	rrfreelist(qp->nsrp);
+	querydestroy(qp);
+	free(qp);
 	return rv;
 }

+ 43 - 15
sys/src/cmd/ndb/dns.c

@@ -26,6 +26,7 @@ typedef struct Job	Job;
 typedef struct Network	Network;
 
 int vers;		/* incremented each clone/attach */
+volatile int stop;
 
 struct Mfile
 {
@@ -110,7 +111,8 @@ usage(void)
 void
 main(int argc, char *argv[])
 {
-	char	servefile[Maxpath], ext[Maxpath];
+	int kid, pid;
+	char servefile[Maxpath], ext[Maxpath];
 
 	setnetmtpt(mntpt, sizeof mntpt, nil);
 	ext[0] = 0;
@@ -167,7 +169,6 @@ main(int argc, char *argv[])
 
 	if(testing)
 		mainmem->flags |= POOL_NOREUSE | POOL_ANTAGONISM;
-//	mainmem->flags |= POOL_ANTAGONISM;
 	rfork(RFREND|RFNOTEG);
 
 	cfg.inside = (*mntpt == '\0' || strcmp(mntpt, "/net") == 0);
@@ -192,7 +193,7 @@ main(int argc, char *argv[])
 	snprint(servefile, sizeof servefile, "#s/dns%s", ext);
 	unmount(servefile, mntpt);
 	remove(servefile);
-	mountinit(servefile, mntpt);	/* forks */
+	mountinit(servefile, mntpt);	/* forks, parent exits */
 
 	srand(now*getpid());
 	db2cache(1);
@@ -200,14 +201,32 @@ main(int argc, char *argv[])
 
 	if (cfg.straddle && !seerootns())
 		dnslog("straddle server misconfigured; can't see root name servers");
-	if(cfg.serve)
-		dnudpserver(mntpt);
-	if(sendnotifies)
-		notifyproc();
-
-	io();
-	dnslog("io returned, exiting");
-	exits(0);
+	/*
+	 * fork without sharing heap.
+	 * parent waits around for child to die, then forks & restarts.
+	 * child may spawn udp server, notify procs, etc.; when it gets too
+	 * big, it kills itself and any children.
+	 * /srv/dns and /net/dns remain open and valid.
+	 */
+	for (;;) {
+		kid = rfork(RFPROC|RFFDG|RFNOTEG);
+		switch (kid) {
+		case -1:
+			sysfatal("fork failed: %r");
+		case 0:
+			if(cfg.serve)
+				dnudpserver(mntpt);
+			if(sendnotifies)
+				notifyproc();
+			io();
+			_exits("restart");
+		default:
+			while ((pid = waitpid()) != kid && pid != -1)
+				continue;
+			break;
+		}
+		dnslog("dns restarting");
+	}
 }
 
 /*
@@ -240,14 +259,15 @@ mountinit(char *service, char *mntpt)
 
 	if(pipe(p) < 0)
 		abort(); /* "pipe failed" */;
+	/* copy namespace to avoid a deadlock */
 	switch(rfork(RFFDG|RFPROC|RFNAMEG)){
-	case 0:
+	case 0:			/* child: hang around and (re)start main proc */
 		close(p[1]);
-		procsetname("main");
+		procsetname("restarter");
 		break;
 	case -1:
 		abort(); /* "fork failed\n" */;
-	default:
+	default:		/* parent: make /srv/dns, mount it, exit */
 		close(p[0]);
 
 		/*
@@ -289,6 +309,7 @@ newfid(int fid, int needunused)
 		sysfatal("out of memory");
 	mf->fid = fid;
 	mf->next = mfalloc.inuse;
+	mf->user = estrdup("dummy");
 	mfalloc.inuse = mf;
 	unlock(&mfalloc);
 	return mf;
@@ -392,7 +413,8 @@ io(void)
 		putactivity(0);
 	procsetname("main 9p reading loop");
 	req.isslave = 0;
-	for(;;){
+	stop = 0;
+	while(!stop){
 		n = read9pmsg(mfd[0], mdata, sizeof mdata);
 		if(n<=0){
 			dnslog("error reading mntpt: %r");
@@ -469,6 +491,9 @@ io(void)
 
 		putactivity(0);
 	}
+	/* kill any udp server, notifier, etc. processes */
+	postnote(PNGROUP, getpid(), "die");
+	sleep(1000);
 }
 
 void
@@ -691,6 +716,9 @@ rwrite(Job *job, Mfile *mf, Request *req)
 	} else if(strcmp(job->request.data, "poolcheck")==0){
 		poolcheck(mainmem);
 		goto send;
+	} else if(strcmp(job->request.data, "restart")==0){
+		stop = 1;
+		goto send;
 	} else if(strncmp(job->request.data, "target", 6)==0){
 		target = atol(job->request.data + 6);
 		dnslog("target set to %ld", target);

+ 9 - 7
sys/src/cmd/ndb/dnudpserver.c

@@ -11,13 +11,12 @@ static int	udpannounce(char*);
 static void	reply(int, uchar*, DNSmsg*, Request*);
 
 static void
-ding(void *x, char *msg)
+ding(void*, char *msg)
 {
-	USED(x);
-	if(strcmp(msg, "alarm") == 0)
-		noted(NCONT);
+	if(strstr(msg, "alarm") != nil)
+		noted(NCONT);		/* resume with system call error */
 	else
-		noted(NDFLT);
+		noted(NDFLT);		/* die */
 }
 
 typedef struct Inprogress Inprogress;
@@ -81,8 +80,11 @@ dnudpserver(char *mntpt)
 	volatile Request req;
 	Udphdr *volatile uh;
 
-	/* fork sharing text, data, and bss with parent */
-	switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
+	/*
+	 * fork sharing text, data, and bss with parent.
+	 * stay in the same note group.
+	 */
+	switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
 	case -1:
 		break;
 	case 0: