From: wessels <> Date: Wed, 29 Jul 1998 09:57:37 +0000 (+0000) Subject: Fixed some restart bugs with dnsservers. Because of switch to X-Git-Tag: SQUID_3_0_PRE1~2964 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6a78c18e34cfeeb6ec4e045145dd3d1c32c1e773;p=thirdparty%2Fsquid.git Fixed some restart bugs with dnsservers. Because of switch to events, we were calling the dnsShutdownServers func AFTER the new dnsservers had been allocated. Using a non-NULL callback data when registering the event fixes this. Also added fatal() checks for too few running dnsservers and too many queued IP/FQDN lookups. --- diff --git a/src/dns.cc b/src/dns.cc index 6920ca6bdb..1c7d6f8ebd 100644 --- a/src/dns.cc +++ b/src/dns.cc @@ -1,6 +1,6 @@ /* - * $Id: dns.cc,v 1.62 1998/07/25 00:16:26 wessels Exp $ + * $Id: dns.cc,v 1.63 1998/07/29 03:57:37 wessels Exp $ * * DEBUG: section 34 Dnsserver interface * AUTHOR: Harvest Derived @@ -41,7 +41,22 @@ struct dnsQueueData { }; static PF dnsShutdownRead; +static PF dnsFDClosed; static dnsserver_t **dns_child_table = NULL; +static int NDnsServersRunning = 0; + +static void +dnsFDClosed(int fd, void *data) +{ + dnsserver_t *dns = data; + NDnsServersRunning--; + if (shutting_down || reconfiguring) + return; + debug(34, 0) ("WARNING: DNSSERVER #%d (FD %d) exited\n", + dns->id, fd); + if (NDnsServersRunning < Config.dnsChildren / 2) + fatal("Too few DNSSERVER processes are running"); +} dnsserver_t * dnsGetFirstAvailable(void) @@ -92,6 +107,7 @@ dnsOpenServers(void) dnsFreeMemory(); dns_child_table = xcalloc(N, sizeof(dnsserver_t *)); NDnsServersAlloc = 0; + NDnsServersRunning = 0; args[nargs++] = "(dnsserver)"; if (Config.onoff.res_defnames) args[nargs++] = "-D"; @@ -137,12 +153,17 @@ dnsOpenServers(void) snprintf(fd_note_buf, FD_DESC_SZ, "%s #%d", s, dns_child_table[k]->id); fd_note(dns_child_table[k]->inpipe, fd_note_buf); commSetNonBlocking(dns_child_table[k]->inpipe); - debug(34, 3) ("dnsOpenServers: 'dns_server' %d started\n", k + 1); + comm_add_close_handler(dns_child_table[k]->inpipe, dnsFDClosed, + dns_child_table[k]); + debug(34, 3) ("dnsOpenServers: DNSSERVER #%d started\n", k + 1); NDnsServersAlloc++; + NDnsServersRunning++; } } if (NDnsServersAlloc == 0 && Config.dnsChildren > 0) fatal("Failed to start any dnsservers"); + if (NDnsServersRunning < Config.dnsChildren / 2) + fatal("Too few DNSSERVER processes are running"); cachemgrRegister("dns", "dnsserver child process information", dnsStats, 0, 1); debug(34, 1) ("Started %d 'dnsserver' processes\n", NDnsServersAlloc); @@ -213,8 +234,17 @@ dnsShutdownServers(void *notused) } dnsShutdownServer(dns); } + /* + * Here we pass in 'dns_child_table[0]' as callback data so that + * if the dns_child_table[] array gets freed, the event will + * never execute. + */ if (na) - eventAdd("dnsShutdownServers", dnsShutdownServers, NULL, 1.0, 1); + eventAdd("dnsShutdownServers", + dnsShutdownServers, + dns_child_table[0], + 1.0, + 1); } void diff --git a/src/fqdncache.cc b/src/fqdncache.cc index 4bfcc301df..a308871e5b 100644 --- a/src/fqdncache.cc +++ b/src/fqdncache.cc @@ -1,7 +1,7 @@ /* - * $Id: fqdncache.cc,v 1.109 1998/07/23 19:57:49 wessels Exp $ + * $Id: fqdncache.cc,v 1.110 1998/07/29 03:57:38 wessels Exp $ * * DEBUG: section 35 FQDN Cache * AUTHOR: Harvest Derived @@ -82,6 +82,7 @@ static FREE fqdncacheFreeEntry; static hash_table *fqdn_table = NULL; static struct fqdncacheQueueData *fqdncacheQueueHead = NULL; static struct fqdncacheQueueData **fqdncacheQueueTailP = &fqdncacheQueueHead; +static int queue_length = 0; static char fqdncache_status_char[] = { @@ -97,10 +98,24 @@ static long fqdncache_high = 200; static void fqdncacheEnqueue(fqdncache_entry * f) { + static time_t last_warning = 0; struct fqdncacheQueueData *new = xcalloc(1, sizeof(struct fqdncacheQueueData)); new->f = f; *fqdncacheQueueTailP = new; fqdncacheQueueTailP = &new->next; + queue_length++; + if (queue_length < NDnsServersAlloc) + return; + if (squid_curtime - last_warning < 600) + return; + last_warning = squid_curtime; + debug(35, 0) ("fqdncacheEnqueue: WARNING: All dnsservers are busy.\n"); + debug(35, 0) ("fqdncacheEnqueue: WARNING: %d DNS lookups queued\n", queue_length); + if (queue_length > NDnsServersAlloc * 2) + fatal("Too many queued DNS lookups"); + if (Config.dnsChildren >= DefaultDnsChildrenMax) + return; + debug(35, 1) ("fqdncacheEnqueue: Consider increasing 'dns_children' in your config file.\n"); } static void * @@ -115,6 +130,7 @@ fqdncacheDequeue(void) if (fqdncacheQueueHead == NULL) fqdncacheQueueTailP = &fqdncacheQueueHead; safe_free(old); + queue_length--; } if (f && f->status != FQDN_PENDING) debug_trap("fqdncacheDequeue: status != FQDN_PENDING"); @@ -193,7 +209,7 @@ fqdncache_purgelru(void *notused) fqdncache_release(f); removed++; } - debug(14, 3) ("fqdncache_purgelru: removed %d entries\n", removed); + debug(35, 3) ("fqdncache_purgelru: removed %d entries\n", removed); } @@ -228,7 +244,7 @@ fqdncacheAddNew(const char *name, const struct hostent *hp, fqdncache_status_t s { fqdncache_entry *f; assert(fqdncache_get(name) == NULL); - debug(14, 10) ("fqdncacheAddNew: Adding '%s', status=%c\n", + debug(35, 10) ("fqdncacheAddNew: Adding '%s', status=%c\n", name, fqdncache_status_char[status]); f = fqdncache_create(name); @@ -274,13 +290,13 @@ fqdncacheParse(const char *inbuf, dnsserver_t * dnsData) static fqdncache_entry f; int ttl; xstrncpy(buf, inbuf, DNS_INBUF_SZ); - debug(14, 5) ("fqdncacheParse: parsing:\n%s", buf); + debug(35, 5) ("fqdncacheParse: parsing:\n%s", buf); memset(&f, '\0', sizeof(f)); f.expires = squid_curtime; f.status = FQDN_NEGATIVE_CACHED; token = strtok(buf, w_space); if (NULL == token) { - debug(14, 1) ("fqdncacheParse: Got , expecting '$name'\n"); + debug(35, 1) ("fqdncacheParse: Got , expecting '$name'\n"); return &f; } if (0 == strcmp(token, "$fail")) { @@ -291,12 +307,12 @@ fqdncacheParse(const char *inbuf, dnsserver_t * dnsData) return &f; } if (0 != strcmp(token, "$name")) { - debug(14, 1) ("fqdncacheParse: Got '%s', expecting '$name'\n", token); + debug(35, 1) ("fqdncacheParse: Got '%s', expecting '$name'\n", token); return &f; } token = strtok(NULL, w_space); if (NULL == token) { - debug(14, 1) ("fqdncacheParse: Got , expecting TTL\n"); + debug(35, 1) ("fqdncacheParse: Got , expecting TTL\n"); return &f; } f.status = FQDN_CACHED; @@ -383,7 +399,7 @@ fqdncache_dnsHandleRead(int fd, void *data) } fqdncacheUnlockEntry(f); /* unlock from FQDN_DISPATCHED */ } else { - debug(14, 5) ("fqdncache_dnsHandleRead: Incomplete reply\n"); + debug(35, 5) ("fqdncache_dnsHandleRead: Incomplete reply\n"); commSetSelect(fd, COMM_SELECT_READ, fqdncache_dnsHandleRead, @@ -459,7 +475,7 @@ fqdncache_nbgethostbyaddr(struct in_addr addr, FQDNH * handler, void *handlerDat FqdncacheStats.pending_hits++; fqdncacheAddPending(f, handler, handlerData); if (squid_curtime - f->expires > 600) { - debug(14, 0) ("fqdncache_nbgethostbyname: '%s' PENDING for %d seconds, aborting\n", name, + debug(35, 0) ("fqdncache_nbgethostbyname: '%s' PENDING for %d seconds, aborting\n", name, (int) (squid_curtime + Config.negativeDnsTtl - f->expires)); fqdncacheChangeKey(f); fqdncache_call_pending(f); @@ -536,7 +552,7 @@ fqdncache_init(void) fqdncache_low = (long) (((float) MAX_FQDN * (float) FQDN_LOW_WATER) / (float) 100); n = hashPrime(fqdncache_high / 4); - fqdn_table = hash_create((HASHCMP*) strcmp, n, hash4); + fqdn_table = hash_create((HASHCMP *) strcmp, n, hash4); cachemgrRegister("fqdncache", "FQDN Cache Stats and Contents", fqdnStats, 0, 1); @@ -629,6 +645,7 @@ fqdnStats(StoreEntry * sentry) FqdncacheStats.misses); storeAppendPrintf(sentry, "Blocking calls to gethostbyaddr(): %d\n", FqdncacheStats.ghba_calls); + storeAppendPrintf(sentry, "pending queue length: %d\n", queue_length); storeAppendPrintf(sentry, "FQDN Cache Contents:\n\n"); hash_first(fqdn_table); @@ -736,7 +753,7 @@ fqdncacheChangeKey(fqdncache_entry * f) LOCAL_ARRAY(char, new_key, 256); hash_link *table_entry = hash_lookup(fqdn_table, f->name); if (table_entry == NULL) { - debug(14, 0) ("fqdncacheChangeKey: Could not find key '%s'\n", f->name); + debug(35, 0) ("fqdncacheChangeKey: Could not find key '%s'\n", f->name); return; } if (f != (fqdncache_entry *) table_entry) { @@ -746,7 +763,7 @@ fqdncacheChangeKey(fqdncache_entry * f) hash_remove_link(fqdn_table, table_entry); snprintf(new_key, 256, "%d/", ++index); strncat(new_key, f->name, 128); - debug(14, 1) ("fqdncacheChangeKey: from '%s' to '%s'\n", f->name, new_key); + debug(35, 1) ("fqdncacheChangeKey: from '%s' to '%s'\n", f->name, new_key); safe_free(f->name); f->name = xstrdup(new_key); hash_join(fqdn_table, (hash_link *) f); diff --git a/src/ipcache.cc b/src/ipcache.cc index e6738d00ea..b4aa1a799a 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -1,6 +1,6 @@ /* - * $Id: ipcache.cc,v 1.195 1998/07/23 19:57:50 wessels Exp $ + * $Id: ipcache.cc,v 1.196 1998/07/29 03:57:39 wessels Exp $ * * DEBUG: section 14 IP Cache * AUTHOR: Harvest Derived @@ -112,8 +112,10 @@ ipcacheEnqueue(ipcache_entry * i) if (squid_curtime - last_warning < 600) return; last_warning = squid_curtime; - debug(14, 1) ("ipcacheEnqueue: WARNING: All dnsservers are busy.\n"); - debug(14, 1) ("ipcacheEnqueue: WARNING: %d DNS lookups queued\n", queue_length); + debug(14, 0) ("ipcacheEnqueue: WARNING: All dnsservers are busy.\n"); + debug(14, 0) ("ipcacheEnqueue: WARNING: %d DNS lookups queued\n", queue_length); + if (queue_length > NDnsServersAlloc * 2) + fatal("Too many queued DNS lookups"); if (Config.dnsChildren >= DefaultDnsChildrenMax) return; debug(14, 1) ("ipcacheEnqueue: Consider increasing 'dns_children' in your config file.\n"); @@ -604,7 +606,7 @@ ipcache_init(void) ipcache_low = (long) (((float) Config.ipcache.size * (float) Config.ipcache.low) / (float) 100); n = hashPrime(ipcache_high / 4); - ip_table = hash_create((HASHCMP*) strcmp, n, hash4); + ip_table = hash_create((HASHCMP *) strcmp, n, hash4); cachemgrRegister("ipcache", "IP Cache Stats and Contents", stat_ipcache_get, 0, 1);