int main(int argc, char *argv[]) { int justsetname, ch; char ext[Maxpath], servefile[Maxpath]; /* Make us an SCP with a 2LS */ parlib_wants_to_be_mcp = FALSE; register_printf_specifier('F', printf_fcall, printf_fcall_info); argv0 = argv[0]; justsetname = 0; setnetmtpt(mntpt, sizeof(mntpt), NULL); ext[0] = 0; while ((ch = getopt(argc, argv, "4df:nSx:")) != -1) { switch (ch) { case '4': ipv6lookups = 0; break; case 'd': debug = 1; break; case 'f': dbfile = optarg; break; case 'n': justsetname = 1; break; case 'S': server = 1; break; case 'x': setnetmtpt(mntpt, sizeof(mntpt), optarg); setext(ext, sizeof(ext), mntpt); break; default: usage(); break; } } snprintf(servefile, sizeof(servefile), "#srv/cs%s", ext); snprintf(netndb, sizeof(netndb), "%s/ndb", mntpt); syscall(SYS_nunmount, (unsigned long)servefile, strlen(servefile), (unsigned long)mntpt, strlen(mntpt)); remove(servefile); ndbinit(); netinit(0); if (!justsetname) { mountinit(servefile, mntpt); if (server) evnotify(0); io(); } evexit(0); }
void main(int argc, char *argv[]) { int kid, pid; char servefile[Maxpath], ext[Maxpath]; Dir *dir; setnetmtpt(mntpt, sizeof mntpt, nil); ext[0] = 0; ARGBEGIN{ case 'a': maxage = atol(EARGF(usage())); if (maxage <= 0) maxage = Defmaxage; break; case 'd': debug = 1; traceactivity = 1; break; case 'f': dbfile = EARGF(usage()); break; case 'F': cfg.justforw = cfg.resolver = 1; break; case 'n': sendnotifies = 1; break; case 'N': target = atol(EARGF(usage())); if (target < 1000) target = 1000; break; case 'o': cfg.straddle = 1; /* straddle inside & outside networks */ break; case 'r': cfg.resolver = 1; break; case 'R': norecursion = 1; break; case 's': cfg.serve = 1; /* serve network */ cfg.cachedb = 1; break; case 't': testing = 1; break; case 'T': addforwtarg(EARGF(usage())); break; case 'x': setnetmtpt(mntpt, sizeof mntpt, EARGF(usage())); setext(ext, sizeof ext, mntpt); break; case 'z': zonerefreshprogram = EARGF(usage()); break; default: usage(); break; }ARGEND if(argc != 0) usage(); if(testing) mainmem->flags |= POOL_NOREUSE | POOL_ANTAGONISM; mainmem->flags |= POOL_ANTAGONISM; rfork(RFREND|RFNOTEG); cfg.inside = (*mntpt == '\0' || strcmp(mntpt, "/net") == 0); /* start syslog before we fork */ fmtinstall('F', fcallfmt); dninit(); /* this really shouldn't be fatal */ if(myipaddr(ipaddr, mntpt) < 0) sysfatal("can't read my ip address"); dnslog("starting %s%sdns %s%s%son %I's %s", (cfg.straddle? "straddling ": ""), (cfg.cachedb? "caching ": ""), (cfg.serve? "udp server ": ""), (cfg.justforw? "forwarding-only ": ""), (cfg.resolver? "resolver ": ""), ipaddr, mntpt); opendatabase(); now = time(nil); /* open time files before we fork */ nowns = nsec(); snprint(servefile, sizeof servefile, "#s/dns%s", ext); dir = dirstat(servefile); if (dir) sysfatal("%s exists; another dns instance is running", servefile); free(dir); /* don't unmount here; could deadlock */ // while (unmount(servefile, mntpt) >= 0) // ; mountinit(servefile, mntpt); /* forks, parent exits */ srand(now*getpid()); db2cache(1); // dnageallnever(); if (cfg.straddle && !seerootns()) dnslog("straddle server misconfigured; can't resolve root name servers"); /* * 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 or too old, it kills itself and any children. * * /srv/dns remains open and valid, but /net/dns was only mounted in * a child's separate namespace from 9p service, to avoid a deadlock * from serving our own namespace, so we must remount it upon restart, * in a separate process and namespace. */ for (;;) { start = time(nil); /* don't unmount here; could deadlock */ // unmount(servefile, mntpt); kid = rfork(RFPROC|RFFDG|RFNOTEG|RFNAMEG); switch (kid) { case -1: sysfatal("fork failed: %r"); case 0: if(cfg.serve) dnudpserver(mntpt); if(sendnotifies) notifyproc(); io(); /* serve 9p; return implies restart */ _exits("restart"); } sleep(1000); /* wait for 9p service to start */ justremount(servefile, mntpt); while ((pid = waitpid()) != kid && pid != -1) continue; dnslog("restarting"); } }
void threadmain(int argc, char *argv[]) { int serveudp, servetcp; char *service; serveudp = 0; servetcp = 0; service = "dns"; ARGBEGIN{ case 'd': debug = 1; traceactivity = 1; break; case 'f': dbfile = EARGF(usage()); break; case 'x': service = EARGF(usage()); break; case 'r': resolver = 1; break; case 's': serveudp = 1; cachedb = 1; break; case 't': servetcp = 1; cachedb = 1; break; case 'a': maxage = atoi(EARGF(usage())); break; case 'z': zonerefreshprogram = EARGF(usage()); break; case 'n': sendnotifies = 1; break; case 'U': udpaddr = estrdup(netmkaddr(EARGF(usage()), "udp", "domain")); break; case 'T': tcpaddr = estrdup(netmkaddr(EARGF(usage()), "tcp", "domain")); break; default: usage(); }ARGEND if(argc) usage(); if(serveudp && servetcp) checkaddress(); rfork(RFNOTEG); /* start syslog before we fork */ fmtinstall('F', fcallfmt); dninit(); if(myipaddr(ipaddr, mntpt) < 0) sysfatal("can't read my ip address"); syslog(0, logfile, "starting dns on %I", ipaddr); opendatabase(); mountinit(service); now = time(0); srand(now*getpid()); db2cache(1); if(serveudp) proccreate(dnudpserver, nil, STACK); if(servetcp) proccreate(dntcpserver, nil, STACK); if(sendnotifies) proccreate(notifyproc, nil, STACK); io(); }