From: wessels <> Date: Mon, 8 Apr 1996 23:07:59 +0000 (+0000) Subject: made main.c more modular X-Git-Tag: SQUID_3_0_PRE1~6267 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4d64d74a46410e9488af2bbfaa67304762c282e6;p=thirdparty%2Fsquid.git made main.c more modular Added clean shutdown to comm_select. on SIGTERM close incoming sockets and dnsserver pipes. When no sockets left to select on, return with COMM_SHUTDOWN. --- diff --git a/src/cache_cf.cc b/src/cache_cf.cc index d954f9aa68..4af0301f06 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1,4 +1,4 @@ -/* $Id: cache_cf.cc,v 1.21 1996/04/08 16:01:05 wessels Exp $ */ +/* $Id: cache_cf.cc,v 1.22 1996/04/08 17:07:59 wessels Exp $ */ /* DEBUG: Section 3 cache_cf: Configuration file parsing */ @@ -194,7 +194,6 @@ ip_access_type ip_access_check(address, list) localhost.s_addr = inet_addr("127.0.0.1"); init = 1; } - naddr.s_addr = address.s_addr; if (naddr.s_addr == localhost.s_addr) return IP_ALLOW; diff --git a/src/comm.cc b/src/comm.cc index 625efa0dc1..e54303dec5 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,5 +1,5 @@ -/* $Id: comm.cc,v 1.16 1996/04/05 17:48:27 wessels Exp $ */ +/* $Id: comm.cc,v 1.17 1996/04/08 17:08:00 wessels Exp $ */ /* DEBUG: Section 5 comm: socket level functions */ @@ -21,8 +21,10 @@ FD_ENTRY *fd_table = NULL; /* also used in disk.c */ /* STATIC */ static int *fd_lifetime = NULL; +#ifdef UNUSED_CODE static fd_set send_sockets; static fd_set receive_sockets; +#endif static int (*app_handler) (); static void checkTimeouts(); static void checkLifetimes(); @@ -31,16 +33,6 @@ static int commSetReuseAddr _PARAMS((int)); static int examine_select _PARAMS((fd_set *, fd_set *, fd_set *)); static int commSetNoLinger _PARAMS((int)); -/* EXTERN */ -extern int errno; -extern int do_reuse; -extern int getMaxFD(); -extern int theAsciiConnection; -extern int theUdpConnection; -extern int getConnectTimeout(); - -extern int fd_of_first_client _PARAMS((StoreEntry *)); - void comm_handler() { /* Call application installed handler. */ @@ -196,7 +188,9 @@ int comm_listen(sock) int sock; { int x; +#ifdef UNUSED_CODE FD_SET(sock, &receive_sockets); +#endif if ((x = listen(sock, 50)) < 0) { debug(5, 0, "comm_listen: listen(%d, 50): %s\n", sock, xstrerror()); @@ -307,7 +301,9 @@ int comm_connect_addr(sock, address) sock, lft); } /* Add new socket to list of open sockets. */ +#ifdef UNUSED_CODE FD_SET(sock, &send_sockets); +#endif conn->sender = 1; return status; } @@ -364,7 +360,9 @@ int comm_accept(fd, peer, me) conn->comm_type = listener->comm_type; strcpy(conn->ipaddr, inet_ntoa(P.sin_addr)); +#ifdef UNUSED_CODE FD_SET(sock, &receive_sockets); +#endif commSetNonBlocking(sock); return sock; @@ -384,8 +382,10 @@ int comm_close(fd) } conn = &fd_table[fd]; +#ifdef UNUSED_SOCKETS FD_CLR(fd, &receive_sockets); FD_CLR(fd, &send_sockets); +#endif comm_set_fd_lifetime(fd, -1); /* invalidate the lifetime */ debug(5, 10, "comm_close: FD %d\n", fd); @@ -502,6 +502,11 @@ int comm_select(sec, usec, failtime) struct timeval poll_time; struct timeval zero_tv; int sel_fd_width; + int nfds; + + fd_set read_mask, write_mask; + int (*tmp) () = NULL; + int maxfd; /* assume all process are very fast (less than 1 second). Call * time() only once */ @@ -519,26 +524,40 @@ int comm_select(sec, usec, failtime) FD_ZERO(&writefds); FD_ZERO(&exceptfds); - for (i = 0; i < fdstat_biggest_fd() + 1; i++) { + nfds = 0; + maxfd = fdstat_biggest_fd() + 1; + for (i = 0; i < maxfd; i++) { /* Check each open socket for a handler. */ - if (fd_table[i].read_handler && fd_table[i].stall_until <= cached_curtime) + if (fd_table[i].read_handler && fd_table[i].stall_until <= cached_curtime) { + nfds++; FD_SET(i, &readfds); - if (fd_table[i].write_handler) + } + if (fd_table[i].write_handler) { + nfds++; FD_SET(i, &writefds); - if (fd_table[i].except_handler) + } + if (fd_table[i].except_handler) { + nfds++; FD_SET(i, &exceptfds); + } } if (!fdstat_are_n_free_fd(RESERVED_FD)) { FD_CLR(theAsciiConnection, &readfds); } + debug(5, 1, "comm_select: nfds = %d\n", nfds); + if (nfds == 0) + return COMM_SHUTDOWN; while (1) { poll_time.tv_sec = 1; poll_time.tv_usec = 0; num = select(fdstat_biggest_fd() + 1, &readfds, &writefds, &exceptfds, &poll_time); + debug(0, 0, "num=%d errno=%d\n", num, errno); if (num >= 0) break; + if (errno == EINTR) + break; if (errno != EINTR) { debug(5, 0, "comm_select: select failure: %s (errno %d).\n", xstrerror(), errno); @@ -547,6 +566,8 @@ int comm_select(sec, usec, failtime) } /* if select interrupted, try again */ } + if (num < 0) + continue; debug(5, num ? 5 : 8, "comm_select: %d sockets ready at %d\n", num, cached_curtime); @@ -563,7 +584,8 @@ int comm_select(sec, usec, failtime) * limit in SunOS */ if (num) { - for (fd = 0; (fd < (fdstat_biggest_fd() + 1)) && (num > 0); fd++) { + maxfd = fdstat_biggest_fd() + 1; + for (fd = 0; fd < maxfd && num > 0; fd++) { if (!(FD_ISSET(fd, &readfds) || FD_ISSET(fd, &writefds) || FD_ISSET(fd, &exceptfds))) @@ -576,16 +598,17 @@ int comm_select(sec, usec, failtime) * Don't forget to keep the UDP acks coming and going. */ { - fd_set read_mask, write_mask; - int (*tmp) () = NULL; FD_ZERO(&read_mask); FD_ZERO(&write_mask); - if ((fdstat_are_n_free_fd(RESERVED_FD)) && (fd_table[theAsciiConnection].read_handler)) + if (theAsciiConnection >= 0) { + if ((fdstat_are_n_free_fd(RESERVED_FD)) + && (fd_table[theAsciiConnection].read_handler)) FD_SET(theAsciiConnection, &read_mask); else FD_CLR(theAsciiConnection, &read_mask); + } if (theUdpConnection >= 0) { if (fd_table[theUdpConnection].read_handler) FD_SET(theUdpConnection, &read_mask); @@ -613,13 +636,14 @@ int comm_select(sec, usec, failtime) } } } + if ((fd == theUdpConnection) || (fd == theAsciiConnection)) continue; if (FD_ISSET(fd, &readfds)) { debug(5, 6, "comm_select: FD %d ready for reading\n", fd); if (fd_table[fd].read_handler) { - int (*tmp) () = fd_table[fd].read_handler; + tmp = fd_table[fd].read_handler; fd_table[fd].read_handler = 0; debug(5, 10, "calling read handler %p(%d,%p)\n", tmp, fd, fd_table[fd].read_data); @@ -629,7 +653,7 @@ int comm_select(sec, usec, failtime) if (FD_ISSET(fd, &writefds)) { debug(5, 5, "comm_select: FD %d ready for writing\n", fd); if (fd_table[fd].write_handler) { - int (*tmp) () = fd_table[fd].write_handler; + tmp = fd_table[fd].write_handler; fd_table[fd].write_handler = 0; debug(5, 10, "calling write handler %p(%d,%p)\n", tmp, fd, fd_table[fd].write_data); @@ -639,7 +663,7 @@ int comm_select(sec, usec, failtime) if (FD_ISSET(fd, &exceptfds)) { debug(5, 5, "comm_select: FD %d has an exception\n", fd); if (fd_table[fd].except_handler) { - int (*tmp) () = fd_table[fd].except_handler; + tmp = fd_table[fd].except_handler; fd_table[fd].except_handler = 0; debug(5, 10, "calling except handler %p(%d,%p)\n", tmp, fd, fd_table[fd].except_data); @@ -943,15 +967,20 @@ char *fd_note(fd, s) static void checkTimeouts() { int fd; + int (*tmp) () = NULL; + FD_ENTRY *f = NULL; + int maxfd = fdstat_biggest_fd() + 1; + /* scan for timeout */ - for (fd = 0; fd < (fdstat_biggest_fd() + 1); ++fd) { - if ((fd_table[fd].timeout_handler) && - (fd_table[fd].timeout_time <= cached_curtime)) { - int (*tmp) () = fd_table[fd].timeout_handler; + for (fd = 0; fd < maxfd; ++fd) { + f = &fd_table[fd]; + if ((f->timeout_handler) && + (f->timeout_time <= cached_curtime)) { + tmp = f->timeout_handler; debug(5, 5, "comm_select: timeout on socket %d at %d\n", fd, cached_curtime); - fd_table[fd].timeout_handler = 0; - tmp(fd, fd_table[fd].timeout_data); + f->timeout_handler = 0; + tmp(fd, f->timeout_data); } } } diff --git a/src/ipcache.cc b/src/ipcache.cc index 503d3f63f9..85ae2e08f1 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -1,4 +1,4 @@ -/* $Id: ipcache.cc,v 1.15 1996/04/05 21:51:46 wessels Exp $ */ +/* $Id: ipcache.cc,v 1.16 1996/04/08 17:08:01 wessels Exp $ */ /* * DEBUG: Section 14 ipcache: IP Cache @@ -1343,3 +1343,24 @@ int ipcache_hash_entry_count() return local_ip_count; } + +void ipcacheShutdownServers() +{ + dnsserver_entry *dns = NULL; + int i; + static char *shutdown = "$shutdown\n"; + + debug(14, 1, "ipcacheShutdownServers:\n"); + + for (i = 0; i < getDnsChildren(); i++) { + dns = *(dns_child_table + i); + debug(14, 1, "ipcacheShutdownServers: sending '$shutdown' to dnsserver #%d\n", i); + debug(14, 1, "ipcacheShutdownServers: --> FD %d\n", dns->outpipe); + file_write(dns->outpipe, + shutdown, + strlen(shutdown), + 0, /* Lock */ + 0, /* Handler */ + 0); /* Handler-data */ + } +} diff --git a/src/main.cc b/src/main.cc index c61741751e..8b63becb95 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,4 +1,4 @@ -/* $Id: main.cc,v 1.20 1996/04/05 23:21:12 wessels Exp $ */ +/* $Id: main.cc,v 1.21 1996/04/08 17:08:02 wessels Exp $ */ /* DEBUG: Section 1 main: startup and main loop */ @@ -19,7 +19,7 @@ extern void (*failure_notify) (); /* for error reporting from xmalloc */ static int asciiPortNumOverride = 0; static int udpPortNumOverride = 0; - +static int malloc_debug_level = 0; static void usage() { @@ -40,66 +40,14 @@ Usage: cached [-Rsehvz] [-f config-file] [-[apu] port]\n\ exit(1); } -int main(argc, argv) +static void mainParseOptions(argc, argv) int argc; - char **argv; + char *argv[]; { - int c; - int malloc_debug_level = 0; extern char *optarg; - int errcount = 0; - static int neighbors = 0; - char *s = NULL; - int n; /* # of GC'd objects */ - time_t last_maintain = 0; - - errorInitialize(); - - cached_starttime = getCurrentTime(); - failure_notify = fatal_dump; - - setMaxFD(); - - for (n = getMaxFD(); n > 2; n--) - close(n); - -#if HAVE_MALLOPT - /* set malloc option */ - /* use small block algorithm for faster allocation */ - /* grain of small block */ - mallopt(M_GRAIN, 16); - /* biggest size that is considered a small block */ - mallopt(M_MXFAST, 4096); - /* number of holding small block */ - mallopt(M_NLBLKS, 100); -#endif - - /*init comm module */ - comm_init(); - - /* we have to init fdstat here. */ - fdstat_init(PREOPEN_FD); - fdstat_open(0, LOG); - fdstat_open(1, LOG); - fdstat_open(2, LOG); - fd_note(0, "STDIN"); - fd_note(1, "STDOUT"); - fd_note(2, "STDERR"); - - if ((s = getenv("HARVEST_HOME")) != NULL) { - config_file = (char *) xcalloc(1, strlen(s) + 64); - sprintf(config_file, "%s/lib/cached.conf", s); - } else { - config_file = xstrdup("/usr/local/harvest/lib/cached.conf"); - } - - /* enable syslog by default */ - syslog_enable = 0; - /* preinit for debug module */ - debug_log = stderr; - hash_init(0); + int c; - while ((c = getopt(argc, argv, "vCDRVbsif:a:p:u:m:zh?")) != -1) + while ((c = getopt(argc, argv, "vCDRVbsif:a:p:u:m:zh?")) != -1) { switch (c) { case 'v': printf("Harvest Cache: Version %s\n", SQUID_VERSION); @@ -146,23 +94,14 @@ int main(argc, argv) usage(); break; } - - if (catch_signals) { - signal(SIGSEGV, death); - signal(SIGBUS, death); } - signal(SIGPIPE, SIG_IGN); - signal(SIGCHLD, sig_child); - signal(SIGHUP, rotate_logs); - signal(SIGTERM, shut_down); - signal(SIGINT, shut_down); +} +static void mainInitialize() +{ parseConfigFile(config_file); - if (!neighbors) { - neighbors_create(); - ++neighbors; - }; + neighbors_create(); if (asciiPortNumOverride > 0) setAsciiPortNum(asciiPortNumOverride); @@ -183,7 +122,6 @@ int main(argc, argv) ftpInitialize(); - #if defined(MALLOC_DBG) malloc_debug(0, malloc_debug_level); #endif @@ -243,6 +181,80 @@ int main(argc, argv) do_mallinfo = 1; debug(1, 0, "Ready to serve requests.\n"); +} + + +int main(argc, argv) + int argc; + char **argv; +{ + int errcount = 0; + char *s = NULL; + int n; /* # of GC'd objects */ + time_t last_maintain = 0; + + errorInitialize(); + + cached_starttime = getCurrentTime(); + failure_notify = fatal_dump; + + mainParseOptions(argc, argv); + + setMaxFD(); + + for (n = getMaxFD(); n > 2; n--) + close(n); + +#if HAVE_MALLOPT + /* set malloc option */ + /* use small block algorithm for faster allocation */ + /* grain of small block */ + mallopt(M_GRAIN, 16); + /* biggest size that is considered a small block */ + mallopt(M_MXFAST, 4096); + /* number of holding small block */ + mallopt(M_NLBLKS, 100); +#endif + + /*init comm module */ + comm_init(); + + /* we have to init fdstat here. */ + fdstat_init(PREOPEN_FD); + fdstat_open(0, LOG); + fdstat_open(1, LOG); + fdstat_open(2, LOG); + fd_note(0, "STDIN"); + fd_note(1, "STDOUT"); + fd_note(2, "STDERR"); + + if (config_file == NULL) { + if ((s = getenv("HARVEST_HOME")) != NULL) { + config_file = (char *) xcalloc(1, strlen(s) + 64); + sprintf(config_file, "%s/lib/cached.conf", s); + } else { + config_file = xstrdup("/usr/local/harvest/lib/cached.conf"); + } + } + /* enable syslog by default */ + syslog_enable = 0; + + /* preinit for debug module */ + debug_log = stderr; + hash_init(0); + + if (catch_signals) { + signal(SIGSEGV, death); + signal(SIGBUS, death); + } + signal(SIGPIPE, SIG_IGN); + signal(SIGCHLD, sig_child); + signal(SIGHUP, rotate_logs); + signal(SIGTERM, shut_down); + signal(SIGINT, shut_down); + + mainInitialize(); + /* main loop */ if (getCleanRate() > 0) next_cleaning = time(0L) + getCleanRate(); @@ -260,7 +272,7 @@ int main(argc, argv) errcount++; debug(1, 0, "Select loop Error. Retry. %d\n", errcount); if (errcount == 10) - fatal_dump("Select Loop failed.!"); + fatal_dump("Select Loop failed!"); break; case COMM_TIMEOUT: /* this happens after 1 minute of idle time, or @@ -274,6 +286,9 @@ int main(argc, argv) } /* house keeping */ break; + case COMM_SHUTDOWN: + normal_shutdown(); + exit(0); default: fatal_dump("MAIN: Internal error -- this should never happen."); break; diff --git a/src/neighbors.cc b/src/neighbors.cc index ac9b3f9665..c6d65032ff 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,4 +1,11 @@ -/* $Id: neighbors.cc,v 1.10 1996/04/06 00:53:06 wessels Exp $ */ +/* $Id: neighbors.cc,v 1.11 1996/04/08 17:08:03 wessels Exp $ */ + +/* TODO: + * - change 'neighbor' to 'sibling' + * - change 'edge' to neighbor? + * - make ->flags structure + * - fix "can't continue" if DNS lookup for neighbor fails. + */ /* * DEBUG: Section 15 neighbors: @@ -252,6 +259,42 @@ void neighbors_install(host, type, ascii_port, udp_port, proxy_only, domains) friends->n++; } +static void neighborFriendsFree() +{ + edge *e = NULL; + edge *next = NULL; + + debug(15, 1, "neighborFriendsFree()\n"); + + for (e = friends->edges_head; e; e = next) { + next = e->next; + safe_free(e->host); + safe_free(e); + } + friends->edges_head = NULL; +} + +static void neighborsOpenLog(fname) + char *fname; +{ + int log_fd; + + /* Close and reopen the log. It may have been renamed "manually" + * before HUP'ing us. */ + if (cache_hierarchy_log) { + file_close(fileno(cache_hierarchy_log)); + fclose(cache_hierarchy_log); + } + log_fd = file_open(fname, NULL, O_WRONLY | O_CREAT | O_APPEND); + if (log_fd < 0) { + debug(15, 0, "rotate_logs: %s: %s\n", fname, xstrerror()); + debug(15, 1, "Hierachical logging is disabled.\n"); + } else if ((cache_hierarchy_log = fdopen(log_fd, "a")) == NULL) { + debug(15, 0, "rotate_logs: %s: %s\n", fname, xstrerror()); + debug(15, 1, "Hierachical logging is disabled.\n"); + } +} + void neighbors_open(fd) int fd; { @@ -259,7 +302,6 @@ void neighbors_open(fd) struct sockaddr_in our_socket_name; struct sockaddr_in *ap; int sock_name_length = sizeof(our_socket_name); - int log_fd; char *fname = NULL; char **list = NULL; edge *e = NULL; @@ -272,17 +314,9 @@ void neighbors_open(fd) } friends->fd = fd; - /* open log file */ - if ((fname = getHierarchyLogFile())) { - log_fd = file_open(fname, NULL, O_WRONLY | O_CREAT | O_APPEND); - if (log_fd < 0) { - debug(15, 1, "%s: %s\n", fname, xstrerror()); - debug(15, 1, "Hierachical logging is disabled.\n"); - } else if (!(cache_hierarchy_log = fdopen(log_fd, "a"))) { - debug(15, 1, "%s: %s\n", fname, xstrerror()); - debug(15, 1, "Hierachical logging is disabled.\n"); - } - } + if ((fname = getHierarchyLogFile())) + neighborsOpenLog(fname); + /* Prepare neighbor connections, one at a time */ for (e = friends->edges_head; e; e = e->next) { debug(15, 2, "Finding IP addresses for '%s'\n", e->host); @@ -707,11 +741,10 @@ void neighbors_init() void neighbors_rotate_log() { + char *fname = NULL; int i; static char from[MAXPATHLEN]; static char to[MAXPATHLEN]; - char *fname = NULL; - int log_fd; if ((fname = getHierarchyLogFile()) == NULL) return; @@ -730,16 +763,5 @@ void neighbors_rotate_log() sprintf(to, "%s.%d", fname, 0); rename(fname, to); } - /* Close and reopen the log. It may have been renamed "manually" - * before HUP'ing us. */ - fclose(cache_hierarchy_log); - log_fd = file_open(fname, NULL, O_WRONLY | O_CREAT | O_APPEND); - if (log_fd < 0) { - debug(15, 0, "rotate_logs: %s: %s\n", fname, xstrerror()); - debug(15, 1, "Hierachical logging is disabled.\n"); - } else if ((cache_hierarchy_log = fdopen(log_fd, "a")) == NULL) { - debug(15, 0, "rotate_logs: %s: %s\n", - fname, xstrerror()); - debug(15, 1, "Hierachical logging is disabled.\n"); - } + neighborsOpenLog(fname); } diff --git a/src/squid.h b/src/squid.h index a67fe21900..217710edef 100644 --- a/src/squid.h +++ b/src/squid.h @@ -1,5 +1,5 @@ -/* $Id: squid.h,v 1.8 1996/04/01 18:20:46 wessels Exp $ */ +/* $Id: squid.h,v 1.9 1996/04/08 17:08:03 wessels Exp $ */ #include "config.h" #include "autoconf.h" @@ -120,3 +120,6 @@ typedef unsigned long u_num32; extern time_t cached_starttime; /* main.c */ extern time_t next_cleaning; /* main.c */ extern int catch_signals; /* main.c */ +extern int do_reuse; +extern int theAsciiConnection; +extern int theUdpConnection; diff --git a/src/tools.cc b/src/tools.cc index bf4d35adcb..5842eca692 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,5 +1,5 @@ -/* $Id: tools.cc,v 1.23 1996/04/04 19:03:36 wessels Exp $ */ +/* $Id: tools.cc,v 1.24 1996/04/08 17:08:04 wessels Exp $ */ /* * DEBUG: Section 21 tools @@ -148,6 +148,19 @@ void rotate_logs(sig) #endif } +void normal_shutdown() +{ + debug(21, 1, "Shutting down...\n"); + if (getPidFilename()) + safeunlink(getPidFilename(), 0); + storeWriteCleanLog(); + PrintRusage(NULL, debug_log); + debug(21, 0, "Harvest Cache (Version %s): Exiting normally.\n", + SQUID_VERSION); + exit(0); +} + +#ifdef OLD_SHUTDOWN void shut_down(sig) int sig; { @@ -160,6 +173,34 @@ void shut_down(sig) SQUID_VERSION, sig); exit(1); } +#else +void shut_down(sig) + int sig; +{ + debug(21, 1, "Preparing for shutdown...\n"); + if (theAsciiConnection) { + debug(21, 1, "FD %d Closing Ascii connection\n", + theAsciiConnection); + comm_close(theAsciiConnection); + comm_set_select_handler(theAsciiConnection, + COMM_SELECT_READ, + NULL, + 0); + theAsciiConnection = -1; + } + if (theUdpConnection) { + debug(21, 1, "FD %d Closing Udp connection\n", + theUdpConnection); + comm_close(theUdpConnection); + comm_set_select_handler(theUdpConnection, + COMM_SELECT_READ, + NULL, + 0); + theUdpConnection = -1; + } + ipcacheShutdownServers(); +} +#endif void fatal_common(message) char *message;