diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-05-16 21:41:42 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-05-16 21:41:42 +0200 |
commit | 6e284eaad57843950a54f44f02f920216dd3fc88 (patch) | |
tree | 6abd320805cff612a155b11692f73bc63cbf81db /sys/src/libndb | |
parent | 5c2b4dfc8173355629e70a6437ccfc378f0bf757 (diff) |
ndb/cs: prevent deadlock with ndb/cs by mounting /srv/dns *AFTER* /net
the dnsquery() library function should not start mouting /srv/dns on
its own. this problem arrises only for ndb/cs as it is started before
ndb/dns.
the issue with mounting /srv/dns before /net is when ndb/cs attempts
to read the list of interfaces, accessing /net/ipifc, which triggers
a rpc to ndb/dns as it is ontop of the mount. this can yield a deadlock
when ndb/dns blocks its 9p loop waiting for requests to complete on
a refresh and the requests are stuck waiting for ndb/cs to translate
a dial string for announce().
Diffstat (limited to 'sys/src/libndb')
-rw-r--r-- | sys/src/libndb/dnsquery.c | 36 |
1 files changed, 8 insertions, 28 deletions
diff --git a/sys/src/libndb/dnsquery.c b/sys/src/libndb/dnsquery.c index 634756b76..1bf1ff8b3 100644 --- a/sys/src/libndb/dnsquery.c +++ b/sys/src/libndb/dnsquery.c @@ -12,13 +12,12 @@ static Ndbtuple *doquery(int, char *dn, char *type); * search for a tuple that has the given 'attr=val' and also 'rattr=x'. * copy 'x' into 'buf' and return the whole tuple. * - * return 0 if not found. + * return nil if not found. */ Ndbtuple* dnsquery(char *net, char *val, char *type) { - char rip[128]; - char *p; + char buf[128]; Ndbtuple *t; int fd; @@ -28,37 +27,18 @@ dnsquery(char *net, char *val, char *type) if(net == nil) net = "/net"; - snprint(rip, sizeof(rip), "%s/dns", net); - fd = open(rip, ORDWR); - if(fd < 0){ - if(strcmp(net, "/net") == 0) - snprint(rip, sizeof(rip), "/srv/dns"); - else { - snprint(rip, sizeof(rip), "/srv/dns%s", net); - p = strrchr(rip, '/'); - *p = '_'; - } - fd = open(rip, ORDWR); - if(fd < 0) - return nil; - if(mount(fd, -1, net, MBEFORE, "") < 0){ - close(fd); - return nil; - } - /* fd is now closed */ - snprint(rip, sizeof(rip), "%s/dns", net); - fd = open(rip, ORDWR); - if(fd < 0) - return nil; - } + + snprint(buf, sizeof(buf), "%s/dns", net); + if((fd = open(buf, ORDWR)) < 0) + return nil; /* zero out the error string */ werrstr(""); /* if this is a reverse lookup, first lookup the domain name */ if(strcmp(type, "ptr") == 0){ - mkptrname(val, rip, sizeof rip); - t = doquery(fd, rip, "ptr"); + mkptrname(val, buf, sizeof buf); + t = doquery(fd, buf, "ptr"); } else t = doquery(fd, val, type); |