--------------------- PatchSet 204 Date: 2002/11/27 02:37:11 Author: rbcollins Branch: external_logger Tag: (none) Log: import and initial update Members: configure.in:1.11->1.11.4.1 src/Makefile.am:1.10->1.10.4.1 src/cf.data.pre:1.6->1.6.4.1 src/debug.cc:1.3->1.3.4.1 src/globals.h:1.5->1.5.4.1 src/ipc.cc:1.5->1.5.4.1 src/logd.cc:1.1->1.1.2.1 src/logfile.cc:1.1->1.1.14.1 src/main.cc:1.7->1.7.4.1 src/protos.h:1.9->1.9.4.1 src/structs.h:1.9->1.9.4.1 src/tools.cc:1.4->1.4.4.1 src/typedefs.h:1.6->1.6.4.1 src/fs/aufs/store_io_aufs.cc:1.3->1.3.6.1 Index: squid3/configure.in =================================================================== RCS file: /cvsroot/squid-sf//squid3/configure.in,v retrieving revision 1.11 retrieving revision 1.11.4.1 diff -u -r1.11 -r1.11.4.1 --- squid3/configure.in 23 Nov 2002 03:13:04 -0000 1.11 +++ squid3/configure.in 27 Nov 2002 02:37:11 -0000 1.11.4.1 @@ -3,7 +3,7 @@ dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.11 2002/11/23 03:13:04 squidadm Exp $ +dnl $Id: configure.in,v 1.11.4.1 2002/11/27 02:37:11 rbcollins Exp $ dnl dnl dnl @@ -11,9 +11,9 @@ AC_PREREQ(2.52) AC_CONFIG_SRCDIR([src/main.cc]) AC_CONFIG_AUX_DIR(cfgaux) -AM_INIT_AUTOMAKE(squid, 3.0-DEVEL) +AM_INIT_AUTOMAKE(squid, 3.0-DEVEL-external_logger) AM_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.11 $)dnl +AC_REVISION($Revision: 1.11.4.1 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AM_MAINTAINER_MODE Index: squid3/src/Makefile.am =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Makefile.am,v retrieving revision 1.10 retrieving revision 1.10.4.1 diff -u -r1.10 -r1.10.4.1 --- squid3/src/Makefile.am 23 Nov 2002 03:12:57 -0000 1.10 +++ squid3/src/Makefile.am 27 Nov 2002 02:37:12 -0000 1.10.4.1 @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.am,v 1.10 2002/11/23 03:12:57 squidadm Exp $ +# $Id: Makefile.am,v 1.10.4.1 2002/11/27 02:37:12 rbcollins Exp $ # # Uncomment and customize the following to suit your needs: # @@ -94,13 +94,15 @@ $(PINGER) \ $(DNSSERVER) \ $(UNLINKD) \ - cachemgr$(CGIEXT) + cachemgr$(CGIEXT) \ + logd cf_gen_SOURCES = cf_gen.cc defines.h nodist_cf_gen_HEADER = cf_gen_defines.h cf_gen.$(OBJEXT): cf_gen_defines.h squidclient_SOURCES = client.cc cachemgr__CGIEXT__SOURCES = cachemgr.cc +logd_SOURCES = logd.cc EXTRA_squid_SOURCES = \ delay_pools.cc \ Index: squid3/src/cf.data.pre =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/cf.data.pre,v retrieving revision 1.6 retrieving revision 1.6.4.1 diff -u -r1.6 -r1.6.4.1 --- squid3/src/cf.data.pre 18 Nov 2002 03:12:57 -0000 1.6 +++ squid3/src/cf.data.pre 27 Nov 2002 02:37:12 -0000 1.6.4.1 @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.6 2002/11/18 03:12:57 squidadm Exp $ +# $Id: cf.data.pre,v 1.6.4.1 2002/11/27 02:37:12 rbcollins Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1228,6 +1228,14 @@ Specify the location of the executable for file deletion process. DOC_END +NAME: logd_program +TYPE: string +DEFAULT: @DEFAULT_LOGD@ +LOC: Config.Program.logd +DOC_START + Specify the location of the executable for logging process. +DOC_END + NAME: pinger_program TYPE: string DEFAULT: @DEFAULT_PINGER@ Index: squid3/src/debug.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/debug.cc,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -u -r1.3 -r1.3.4.1 --- squid3/src/debug.cc 18 Nov 2002 03:12:57 -0000 1.3 +++ squid3/src/debug.cc 27 Nov 2002 02:37:12 -0000 1.3.4.1 @@ -1,6 +1,6 @@ /* - * $Id: debug.cc,v 1.3 2002/11/18 03:12:57 squidadm Exp $ + * $Id: debug.cc,v 1.3.4.1 2002/11/27 02:37:12 rbcollins Exp $ * * DEBUG: section 0 Debug Routines * AUTHOR: Harvest Derived @@ -183,6 +183,15 @@ } void +_db_close() +{ + if (debug_log && debug_log != stderr) { + fclose(debug_log); + debug_log = NULL; + } +} + +void _db_init(const char *logfile, const char *options) { int i; Index: squid3/src/globals.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/globals.h,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -u -r1.5 -r1.5.4.1 --- squid3/src/globals.h 18 Nov 2002 03:12:57 -0000 1.5 +++ squid3/src/globals.h 27 Nov 2002 02:37:12 -0000 1.5.4.1 @@ -1,6 +1,6 @@ /* - * $Id: globals.h,v 1.5 2002/11/18 03:12:57 squidadm Exp $ + * $Id: globals.h,v 1.5.4.1 2002/11/27 02:37:12 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -35,6 +35,7 @@ #define SQUID_GLOBALS_H extern FILE *debug_log; /* NULL */ +extern Logfile *cachelog; extern SquidConfig Config; extern SquidConfig2 Config2; extern char *ConfigFile; /* NULL */ Index: squid3/src/ipc.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/ipc.cc,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -u -r1.5 -r1.5.4.1 --- squid3/src/ipc.cc 18 Nov 2002 03:12:57 -0000 1.5 +++ squid3/src/ipc.cc 27 Nov 2002 02:37:12 -0000 1.5.4.1 @@ -1,6 +1,6 @@ /* - * $Id: ipc.cc,v 1.5 2002/11/18 03:12:57 squidadm Exp $ + * $Id: ipc.cc,v 1.5.4.1 2002/11/27 02:37:12 rbcollins Exp $ * * DEBUG: section 54 Interprocess Communication * AUTHOR: Duane Wessels @@ -39,6 +39,7 @@ static const char *hello_string = "hi there\n"; #define HELLO_BUF_SZ 32 static char hello_buf[HELLO_BUF_SZ]; +static dlink_list ipc_quit_handlers; static int ipcCloseAllFD(int prfd, int pwfd, int crfd, int cwfd) @@ -56,6 +57,18 @@ return -1; } +static void +PutEnvironment() +{ +#if HAVE_PUTENV + char *env_str; + int tmp_s; + env_str = (char *)xcalloc((tmp_s = strlen(Config.debugOptions) + 32), 1); + snprintf(env_str, tmp_s, "SQUID_DEBUG=%s", Config.debugOptions); + putenv(env_str); +#endif +} + int ipcCreate(int type, const char *prog, const char *const args[], const char *name, int *rfd, int *wfd) { @@ -69,10 +82,6 @@ int fd; int t1, t2, t3; socklen_t len; - int tmp_s; -#if HAVE_PUTENV - char *env_str; -#endif int x; #if USE_POLL && defined(_SQUID_OSF_) @@ -272,11 +281,7 @@ _exit(1); } } -#if HAVE_PUTENV - env_str = (char *)xcalloc((tmp_s = strlen(Config.debugOptions) + 32), 1); - snprintf(env_str, tmp_s, "SQUID_DEBUG=%s", Config.debugOptions); - putenv(env_str); -#endif + PutEnvironment(); /* * This double-dup stuff avoids problems when one of * crfd, cwfd, or debug_log are in the rage 0-2. @@ -288,11 +293,15 @@ } while (x < 3); t1 = dup(crfd); t2 = dup(cwfd); - t3 = dup(fileno(debug_log)); + if (!cachelog) + t3 = dup(fileno(debug_log)); + else + t3 = dup(cachelog->logfd); assert(t1 > 2 && t2 > 2 && t3 > 2); close(crfd); close(cwfd); - close(fileno(debug_log)); + if (!cachelog) + close(fileno(debug_log)); dup2(t1, 0); dup2(t2, 1); dup2(t3, 2); @@ -311,3 +320,300 @@ _exit(1); return 0; } + +/* create a oneway ipc, used for logging. ipcout becomes the child process stdout + * And wfd is not reset once it has been created. + */ +int +ipcCreateOneWay(int type, const char *prog, char *const args[], const char *name, int ipcout, ipc_comm *ipccomm) +{ + pid_t pid; + struct sockaddr_in CS; + struct sockaddr_in PS; + int crfd = -1; + int prfd = -1; + int cwfd = -1; + int pwfd = -1; + int fd; + int t1, t2, t3; + socklen_t len; + int x; + +#if HAVE_POLL && defined(_SQUID_OSF_) + assert(type != IPC_FIFO); +#endif + + assert (ipcout > 0); + assert (ipccomm); + if (ipccomm->crfd == -1) { + if (type == IPC_TCP_SOCKET) { + crfd = cwfd = comm_open(SOCK_STREAM, + 0, + local_addr, + 0, + COMM_NOCLOEXEC, + name); + prfd = pwfd = comm_open(SOCK_STREAM, + 0, /* protocol */ + local_addr, + 0, /* port */ + 0, /* blocking */ + name); + } else if (type == IPC_UDP_SOCKET) { + crfd = cwfd = comm_open(SOCK_DGRAM, + 0, + local_addr, + 0, + COMM_NOCLOEXEC, + name); + prfd = pwfd = comm_open(SOCK_DGRAM, + 0, + local_addr, + 0, + 0, + name); + } else if (type == IPC_FIFO) { + int p2c[2]; + int c2p[2]; + if (pipe(p2c) < 0) { + debug(50, 0) ("ipcCreate: pipe: %s\n", xstrerror()); + return -1; + } + if (pipe(c2p) < 0) { + debug(50, 0) ("ipcCreate: pipe: %s\n", xstrerror()); + return -1; + } + fd_open(prfd = p2c[0], FD_PIPE, "IPC FIFO Parent Read"); + fd_open(cwfd = p2c[1], FD_PIPE, "IPC FIFO Child Write"); + fd_open(crfd = c2p[0], FD_PIPE, "IPC FIFO Child Read"); + fd_open(pwfd = c2p[1], FD_PIPE, "IPC FIFO Parent Write"); + } else { + assert(IPC_NONE); + } + ipccomm->prfd = prfd; + ipccomm->pwfd = pwfd; + ipccomm->crfd = crfd; + ipccomm->cwfd = cwfd; + } else { + prfd=ipccomm->prfd; + pwfd=ipccomm->pwfd; + crfd=ipccomm->crfd; + cwfd=ipccomm->cwfd; + } + debug(54, 3) ("ipcCreate: prfd FD %d\n", prfd); + debug(54, 3) ("ipcCreate: pwfd FD %d\n", pwfd); + debug(54, 3) ("ipcCreate: crfd FD %d\n", crfd); + debug(54, 3) ("ipcCreate: cwfd FD %d\n", cwfd); + + if (crfd < 0) { + debug(54, 0) ("ipcCreate: Failed to create child FD.\n"); + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } + if (pwfd < 0) { + debug(54, 0) ("ipcCreate: Failed to create server FD.\n"); + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } + if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) { + len = sizeof(PS); + memset(&PS, '\0', len); + if (getsockname(pwfd, (struct sockaddr *) &PS, &len) < 0) { + debug(50, 0) ("ipcCreate: getsockname: %s\n", xstrerror()); + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } + debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n", + pwfd, inet_ntoa(PS.sin_addr), ntohs(PS.sin_port)); + len = sizeof(CS); + memset(&CS, '\0', len); + if (getsockname(crfd, (struct sockaddr *) &CS, &len) < 0) { + debug(50, 0) ("ipcCreate: getsockname: %s\n", xstrerror()); + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } + debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n", + crfd, inet_ntoa(CS.sin_addr), ntohs(CS.sin_port)); + } + if (type == IPC_TCP_SOCKET) { + if (listen(crfd, 1) < 0) { + debug(50, 1) ("ipcCreate: listen FD %d: %s\n", crfd, xstrerror()); + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } + debug(54, 3) ("ipcCreate: FD %d listening...\n", crfd); + } + /* flush or else we get dup data if unbuffered_logs is set */ + logsFlush(); + if ((pid = fork()) < 0) { + debug(50, 1) ("ipcCreate: fork: %s\n", xstrerror()); + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } + if (pid > 0) { /* parent */ + /* don't close shared child sockets as we need them the next time around */ + /* force blocking */ + commUnsetNonBlocking(pwfd); + commUnsetNonBlocking(prfd); + if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) { + if (comm_connect_addr(pwfd, &CS) == COMM_ERROR) { + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } + } + memset(hello_buf, '\0', HELLO_BUF_SZ); + if (type == IPC_UDP_SOCKET) + x = recv(prfd, hello_buf, HELLO_BUF_SZ - 1, 0); + else + x = read(prfd, hello_buf, HELLO_BUF_SZ - 1); + if (x < 0) { + debug(50, 0) ("ipcCreate: PARENT: hello read test failed\n"); + debug(50, 0) ("--> read: %s\n", xstrerror()); + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } else if (strcmp(hello_buf, hello_string)) { + debug(54, 0) ("ipcCreate: PARENT: hello read test failed\n"); + debug(54, 0) ("--> read returned %d\n", x); + debug(54, 0) ("--> got '%s'\n", rfc1738_escape(hello_buf)); + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } + commSetTimeout(prfd, -1, NULL, NULL); + commSetNonBlocking(prfd); + commSetNonBlocking(pwfd); + fd_table[prfd].flags.ipc = 1; + fd_table[pwfd].flags.ipc = 1; + fd_table[crfd].flags.ipc = 1; + fd_table[cwfd].flags.ipc = 1; + return pid; + } + /* child */ + no_suid(); /* give up extra priviliges */ + /* close shared socket with parent */ + close(prfd); + if (pwfd != prfd) + close(pwfd); + pwfd = prfd = -1; + /* force blocking */ + commUnsetNonBlocking(crfd); + commUnsetNonBlocking(cwfd); + if (type == IPC_TCP_SOCKET) { + debug(54, 3) ("ipcCreate: calling accept on FD %d\n", crfd); + if ((fd = accept(crfd, NULL, NULL)) < 0) { + debug(50, 0) ("ipcCreate: FD %d accept: %s\n", crfd, xstrerror()); + _exit(1); + } + debug(54, 3) ("ipcCreate: CHILD accepted new FD %d\n", fd); + close(crfd); + cwfd = crfd = fd; + } else if (type == IPC_UDP_SOCKET) { + if (comm_connect_addr(crfd, &PS) == COMM_ERROR) { + memset (ipccomm, -1, sizeof(ipc_comm)); + return ipcCloseAllFD(prfd, pwfd, crfd, cwfd); + } + } + if (type == IPC_UDP_SOCKET) { + x = send(cwfd, hello_string, strlen(hello_string) + 1, 0); + if (x < 0) { + debug(50, 0) ("sendto FD %d: %s\n", cwfd, xstrerror()); + debug(50, 0) ("ipcCreate: CHILD: hello write test failed\n"); + _exit(1); + } + } else { + if (write(cwfd, hello_string, strlen(hello_string) + 1) < 0) { + debug(50, 0) ("write FD %d: %s\n", cwfd, xstrerror()); + debug(50, 0) ("ipcCreate: CHILD: hello write test failed\n"); + _exit(1); + } + } + PutEnvironment(); + /* + * This double-dup stuff avoids problems when one of + * crfd, cwfd, or debug_log are in the rage 0-2. + */ + do { + x = open(_PATH_DEVNULL, 0, 0444); + if (x > -1) + commSetCloseOnExec(x); + } while (x < 3); + t1 = dup(crfd); + t2 = dup(ipcout); + if (!cachelog) + t3 = dup(fileno(debug_log)); + else + t3 = dup(cachelog->logfd); + debug(1,1)("cachelog is %p t1 %d t2 %d t3 %d\n",cachelog, t1,t2,t3); + assert(t1 > 2 && t2 > 2 && t3 > 2); + close(crfd); + close(cwfd); + if (!cachelog) + close(fileno(debug_log)); + dup2(t1, 0); + dup2(t2, 1); + dup2(t3, 2); + close(t1); + close(t2); + close(t3); + /* Make sure all other filedescriptors are closed */ + for (x = 3; x < SQUID_MAXFD; x++) + close(x); +#if HAVE_SETSID + setsid(); +#endif + execvp(prog, args); + debug_log = fdopen(2, "a+"); + debug(50, 0) ("ipcCreate: %s: %s\n", prog, xstrerror()); + _exit(1); + return 0; +} + +CBDATA_TYPE(ipc_quit_handler); + + +/* TODO: cbdata validity checking ? */ +void +add_ipc_quit_handler(int pid, EVH event, void *data) +{ + ipc_quit_handler *handler; + CBDATA_INIT_TYPE(ipc_quit_handler); + handler = cbdataAlloc(ipc_quit_handler); + assert (handler); + handler->pid = pid; + handler->event = event; + handler->data = data; + dlinkAddTail(handler, &handler->node, &ipc_quit_handlers); +} + +void +remove_ipc_quit_handler(int pid, EVH event, void *data) +{ + ipc_quit_handler *handler; + dlink_node *node; + node = ipc_quit_handlers.head; + while (node) { + handler = (ipc_quit_handler *)node->data; + if (handler->pid == pid && + handler->event == event && + handler->data == data) { + dlinkDelete(node, &ipc_quit_handlers); + cbdataFree (handler); + } + node = node->next; + } +} + + +void +ipcCallQuitHandlers(int pid) +{ + ipc_quit_handler *handler; + dlink_node *node; + node = ipc_quit_handlers.head; + while (node) { + handler = (ipc_quit_handler *)node->data; + if (handler->pid == pid) { + handler->event (handler->data); + } + node = node->next; + } +} --- /dev/null Wed Feb 14 12:13:05 2007 +++ squid3/src/logd.cc Wed Feb 14 12:14:12 2007 @@ -0,0 +1,62 @@ +/* + * $Id: logd.cc,v 1.1.2.1 2002/11/27 02:37:12 rbcollins Exp $ + * + * DEBUG: section 50 Log file daemon + * AUTHOR: Robert Collins + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SIGNAL_H +#include +#endif + +int +main(int argc, char **argv) +{ + char buf[256]; + ssize_t incount,outcount; + setbuf (stdout, NULL); + while ((incount = read(0, buf, 256)) > 0) { + outcount = write (1, buf, incount); + if (outcount != incount) { + /* TODO: log these to syslog - after all we cannot log them :] */ + fprintf(stderr, "Error writing to the log file!?!\n"); + if (getppid() > 1) { + fprintf(stderr, "Killing squid, pid %d\n", getppid()); + kill(getppid(), SIGQUIT); + } + } + } + fflush(stdout); + exit (0); +} Index: squid3/src/logfile.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/logfile.cc,v retrieving revision 1.1 retrieving revision 1.1.14.1 diff -u -r1.1 -r1.1.14.1 --- squid3/src/logfile.cc 14 Oct 2002 00:18:19 -0000 1.1 +++ squid3/src/logfile.cc 27 Nov 2002 02:37:12 -0000 1.1.14.1 @@ -1,5 +1,5 @@ /* - * $Id: logfile.cc,v 1.1 2002/10/14 00:18:19 squidadm Exp $ + * $Id: logfile.cc,v 1.1.14.1 2002/11/27 02:37:12 rbcollins Exp $ * * DEBUG: section 50 Log file handling * AUTHOR: Duane Wessels @@ -36,11 +36,13 @@ #include "authenticate.h" static void logfileWriteWrapper(Logfile * lf, const void *buf, size_t len); +static EVH logfileHelperQuit; Logfile * logfileOpen(const char *path, size_t bufsz, int fatal_flag) { int fd; + int x; Logfile *lf; fd = file_open(path, O_WRONLY | O_CREAT | O_TEXT); if (DISK_ERROR == fd) { @@ -59,7 +61,6 @@ } } lf = static_cast(xcalloc(1, sizeof(*lf))); - lf->fd = fd; if (fatal_flag) lf->flags.fatal = 1; xstrncpy(lf->path, path, MAXPATHLEN); @@ -67,6 +68,27 @@ lf->buf = (char *) xmalloc(bufsz); lf->bufsz = bufsz; } + lf->filefd = fd; + lf->logfd = -1; + lf->ipccomm.crfd = -1; + x = ipcCreateOneWay( +#if HAVE_POLL && defined(_SQUID_OSF_) + /* pipes and poll() don't get along on DUNIX -DW */ + IPC_TCP_SOCKET, +#else + IPC_FIFO, +#endif + Config.Program.logd, + NULL, + "logd", + lf->filefd, + &lf->ipccomm); + if (x < 0) + fatalf("execl %s failed!\n", Config.Program.logd); + lf->pid = x; + lf->logfd = lf->ipccomm.pwfd; + commUnsetNonBlocking(lf->logfd); + add_ipc_quit_handler(x, logfileHelperQuit, lf); return lf; } @@ -74,9 +96,11 @@ logfileClose(Logfile * lf) { logfileFlush(lf); - file_close(lf->fd); + file_close(lf->filefd); if (lf->buf) xfree(lf->buf); + remove_ipc_quit_handler(lf->pid, logfileHelperQuit, lf); + comm_close(lf->logfd); xfree(lf); } @@ -105,22 +129,44 @@ } /* Rotate the current log to .0 */ logfileFlush(lf); - file_close(lf->fd); /* always close */ + remove_ipc_quit_handler(lf->pid, logfileHelperQuit, lf); + /* always close */ + file_close(lf->filefd); if (Config.Log.rotateNumber > 0) { snprintf(to, MAXPATHLEN, "%s.%d", lf->path, 0); xrename(lf->path, to); } /* Reopen the log. It may have been renamed "manually" */ - lf->fd = file_open(lf->path, O_WRONLY | O_CREAT | O_TEXT); - if (DISK_ERROR == lf->fd && lf->flags.fatal) { + lf->filefd = file_open(lf->path, O_WRONLY | O_CREAT | O_TEXT); + if (DISK_ERROR == lf->filefd && lf->flags.fatal) { debug(50, 1) ("logfileRotate: %s: %s\n", lf->path, xstrerror()); fatalf("Cannot open %s: %s", lf->path, xstrerror()); } + int x = ipcCreateOneWay( +#if HAVE_POLL && defined(_SQUID_OSF_) + /* pipes and poll() don't get along on DUNIX -DW */ + IPC_TCP_SOCKET, +#else + IPC_FIFO, +#endif + Config.Program.logd, + NULL, + "logd", + lf->filefd, + &lf->ipccomm); + if (x < 0) + fatalf("execl %s failed!\n", Config.Program.logd); + lf->pid = x; + assert(lf->logfd == lf->ipccomm.pwfd); + commUnsetNonBlocking(lf->logfd); + add_ipc_quit_handler(x, logfileHelperQuit, lf); } void logfileWrite(Logfile * lf, void *buf, size_t len) { + /* Debugging only - remove once the data loss reason is known */ + assert (fd_table[lf->ipccomm.crfd].bytes_read == 0); if (0 == lf->bufsz) { /* buffering disabled */ logfileWriteWrapper(lf, buf, len); @@ -181,12 +227,42 @@ static void logfileWriteWrapper(Logfile * lf, const void *buf, size_t len) { - size_t s; - s = FD_WRITE_METHOD(lf->fd, (char const *)buf, len); - fd_bytes(lf->fd, s, FD_WRITE); + /* sync io to ensure logs get written - this could (and probably should) use comm_write */ + /* TODO: force this to use write (it doesn't by default) */ + size_t s = FD_WRITE_METHOD(lf->logfd, (char const *)buf, len); + fd_bytes(lf->logfd, s, FD_WRITE); if (s == len) return; if (!lf->flags.fatal) return; fatalf("logfileWrite: %s: %s\n", lf->path, xstrerror()); } + +/* restart a log helper that has quit */ +static void +logfileHelperQuit(void *data) +{ + Logfile * lf = (Logfile *)data; + int x; + assert (lf); + /* TODO: safe logging of the restart */ + fprintf(stderr, "log helper pid %d file %s has exited unexpectedly. Starting new helper\n", lf->pid, lf->path); + x = ipcCreateOneWay( +#if HAVE_POLL && defined(_SQUID_OSF_) + /* pipes and poll() don't get along on DUNIX -DW */ + IPC_TCP_SOCKET, +#else + IPC_FIFO, +#endif + Config.Program.logd, + NULL, + "logd", + lf->filefd, + &lf->ipccomm); + if (x < 0) + fatalf("execl %s failed!\n", Config.Program.logd); + lf->pid = x; + assert(lf->logfd == lf->ipccomm.pwfd); + commUnsetNonBlocking(lf->logfd); + add_ipc_quit_handler(x, logfileHelperQuit, lf); +} Index: squid3/src/main.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/main.cc,v retrieving revision 1.7 retrieving revision 1.7.4.1 diff -u -r1.7 -r1.7.4.1 --- squid3/src/main.cc 18 Nov 2002 03:12:57 -0000 1.7 +++ squid3/src/main.cc 27 Nov 2002 02:37:12 -0000 1.7.4.1 @@ -1,6 +1,6 @@ /* - * $Id: main.cc,v 1.7 2002/11/18 03:12:57 squidadm Exp $ + * $Id: main.cc,v 1.7.4.1 2002/11/27 02:37:12 rbcollins Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -376,6 +376,7 @@ static void mainRotate(void) { +#if 0 icmpClose(); #if USE_DNSSERVERS dnsShutdown(); @@ -384,6 +385,10 @@ authenticateShutdown(); externalAclShutdown(); _db_rotate_log(); /* cache.log */ +#endif + _db_close(); /* close the debug log */ + logfileRotate (cachelog); /* rotate cache.log using global log rotate functions */ + _db_init(Config.Log.log, Config.debugOptions); /* reopen the direct-write fd */ storeDirWriteCleanLogs(1); storeLogRotate(); /* store.log */ accessLogRotate(); /* access.log */ @@ -392,6 +397,7 @@ #if WIP_FWD_LOG fwdLogRotate(); #endif +#if 0 icmpOpen(); #if USE_DNSSERVERS dnsInit(); @@ -399,6 +405,7 @@ redirectInit(); authenticateInit(&Config.authConfiguration); externalAclInit(); +#endif } static void @@ -458,7 +465,11 @@ Config.Port.icp = (u_short) icpPortNumOverride; _db_init(Config.Log.log, Config.debugOptions); + /* the log helper can potentially get killed when crashing.. causing us to lose + * the last log entries in a crash situation + * So we open the same log file *twice* */ fd_open(fileno(debug_log), FD_LOG, Config.Log.log); + cachelog = logfileOpen(Config.Log.log, 0, 1); #if MEM_GEN_TRACE log_trace_init("/tmp/squid.alloc"); #endif @@ -986,6 +997,7 @@ file_close(2); } #endif + logfileClose(cachelog); fdDumpOpen(); fdFreeMemory(); memClean(); @@ -999,6 +1011,10 @@ debug(1, 1) ("Squid Cache (Version %s): Exiting normally.\n", version_string); if (debug_log) - fclose(debug_log); + fclose (debug_log); +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) + WIN32_Exit(0); +#else exit(0); +#endif } Index: squid3/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/protos.h,v retrieving revision 1.9 retrieving revision 1.9.4.1 diff -u -r1.9 -r1.9.4.1 --- squid3/src/protos.h 18 Nov 2002 03:12:57 -0000 1.9 +++ squid3/src/protos.h 27 Nov 2002 02:37:12 -0000 1.9.4.1 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.9 2002/11/18 03:12:57 squidadm Exp $ + * $Id: protos.h,v 1.9.4.1 2002/11/27 02:37:12 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -219,6 +219,7 @@ SQUIDCEXTERN Ctx ctx_enter(const char *descr); SQUIDCEXTERN void ctx_exit(Ctx ctx); +extern void _db_close(); SQUIDCEXTERN void _db_init(const char *logfile, const char *options); SQUIDCEXTERN void _db_rotate_log(void); @@ -1110,6 +1111,10 @@ const char *name, int *rfd, int *wfd); +extern int ipcCreateOneWay(int, const char *, char *const *, const char *, int, ipc_comm *); +extern void add_ipc_quit_handler(int, EVH, void *); +extern void remove_ipc_quit_handler(int, EVH, void *); +extern void ipcCallQuitHandlers(int); /* CacheDigest */ SQUIDCEXTERN CacheDigest *cacheDigestCreate(int capacity, int bpe); Index: squid3/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/structs.h,v retrieving revision 1.9 retrieving revision 1.9.4.1 diff -u -r1.9 -r1.9.4.1 --- squid3/src/structs.h 18 Nov 2002 03:12:57 -0000 1.9 +++ squid3/src/structs.h 27 Nov 2002 02:37:12 -0000 1.9.4.1 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.9 2002/11/18 03:12:57 squidadm Exp $ + * $Id: structs.h,v 1.9.4.1 2002/11/27 02:37:12 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -389,6 +389,7 @@ char *unlinkd; #endif char *diskd; + char *logd; } Program; #if USE_DNSSERVERS int dnsChildren; @@ -1804,6 +1805,12 @@ #endif +struct _ipc_quit_handler { + dlink_node node; + int pid; + EVH *event; + void *data; +}; struct _helper_request { char *buf; @@ -1973,8 +1980,17 @@ } shm; }; +struct _ipc_comm { + int crfd; + int cwfd; + int prfd; + int pwfd; +}; + struct _Logfile { - int fd; + int filefd; + int logfd; + int pid; char path[MAXPATHLEN]; char *buf; size_t bufsz; @@ -1982,6 +1998,7 @@ struct { unsigned int fatal:1; } flags; + ipc_comm ipccomm; }; struct cache_dir_option { Index: squid3/src/tools.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/tools.cc,v retrieving revision 1.4 retrieving revision 1.4.4.1 diff -u -r1.4 -r1.4.4.1 --- squid3/src/tools.cc 18 Nov 2002 03:12:57 -0000 1.4 +++ squid3/src/tools.cc 27 Nov 2002 02:37:12 -0000 1.4.4.1 @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.4 2002/11/18 03:12:57 squidadm Exp $ + * $Id: tools.cc,v 1.4.4.1 2002/11/27 02:37:12 rbcollins Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -429,6 +429,8 @@ pid = waitpid(-1, &status, WNOHANG); #endif /* no debug() here; bad things happen if the signal is delivered during _db_print() */ + if (pid > 0) + ipcCallQuitHandlers (pid); #if HAVE_SIGACTION } while (pid > 0); #else Index: squid3/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/typedefs.h,v retrieving revision 1.6 retrieving revision 1.6.4.1 diff -u -r1.6 -r1.6.4.1 --- squid3/src/typedefs.h 18 Nov 2002 03:12:57 -0000 1.6 +++ squid3/src/typedefs.h 27 Nov 2002 02:37:12 -0000 1.6.4.1 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.6 2002/11/18 03:12:57 squidadm Exp $ + * $Id: typedefs.h,v 1.6.4.1 2002/11/27 02:37:12 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -105,6 +105,7 @@ typedef struct _HttpHeaderStat HttpHeaderStat; typedef struct _HttpBody HttpBody; typedef struct _HttpReply HttpReply; +typedef struct _ipc_comm ipc_comm; typedef struct _clientHttpRequest clientHttpRequest; typedef struct _ConnStateData ConnStateData; typedef struct _ConnCloseHelperData ConnCloseHelperData; @@ -135,6 +136,7 @@ typedef struct _MemObject MemObject; typedef struct _StoreEntry StoreEntry; typedef struct _SwapDir SwapDir; +typedef struct _ipc_quit_handler ipc_quit_handler; typedef struct _helper_flags helper_flags; typedef struct _helper_stateful_flags helper_stateful_flags; typedef struct _http_state_flags http_state_flags; Index: squid3/src/fs/aufs/store_io_aufs.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/fs/aufs/Attic/store_io_aufs.cc,v retrieving revision 1.3 retrieving revision 1.3.6.1 diff -u -r1.3 -r1.3.6.1 --- squid3/src/fs/aufs/store_io_aufs.cc 16 Nov 2002 03:13:16 -0000 1.3 +++ squid3/src/fs/aufs/store_io_aufs.cc 27 Nov 2002 02:37:12 -0000 1.3.6.1 @@ -28,6 +28,24 @@ /* === PUBLIC =========================================================== */ +squidaiostate_t * +newAIOState() +{ + squidaiostate_t *result = (squidaiostate_t *)memPoolAlloc(squidaio_state_pool); + result->fd = -1; + result->flags.opening = 1; + return result; +} + +storeIOState * +newSIO(void *fsState) +{ + CBDATA_INIT_TYPE_FREECB(storeIOState, storeAufsIOFreeEntry); + storeIOState *sio = cbdataAlloc(storeIOState); + sio->fsstate = fsState; + return sio; +} + /* open for reading */ storeIOState * storeAufsOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, @@ -35,7 +53,7 @@ { sfileno f = e->swap_filen; char *path = commonUfsDirFullPath(SD, f, NULL); - storeIOState *sio; + #if !ASYNC_OPEN int fd; #endif @@ -55,11 +73,7 @@ return NULL; } #endif - CBDATA_INIT_TYPE_FREECB(storeIOState, storeAufsIOFreeEntry); - sio = cbdataAlloc(storeIOState); - sio->fsstate = memPoolAlloc(squidaio_state_pool); - ((squidaiostate_t *) (sio->fsstate))->fd = -1; - ((squidaiostate_t *) (sio->fsstate))->flags.opening = 1; + storeIOState *sio = newSIO(newAIOState()); sio->swap_filen = f; sio->swap_dirn = SD->index; sio->mode = O_RDONLY | O_BINARY; @@ -80,7 +94,6 @@ storeAufsCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * callback, void *callback_data) { char *path; - storeIOState *sio; sfileno filn; sdirno dirn; #if !ASYNC_CREATE @@ -108,11 +121,7 @@ return NULL; } #endif - CBDATA_INIT_TYPE_FREECB(storeIOState, storeAufsIOFreeEntry); - sio = cbdataAlloc(storeIOState); - sio->fsstate = memPoolAlloc(squidaio_state_pool); - ((squidaiostate_t *) (sio->fsstate))->fd = -1; - ((squidaiostate_t *) (sio->fsstate))->flags.opening = 1; + storeIOState *sio = newSIO(newAIOState()); sio->swap_filen = filn; sio->swap_dirn = dirn; sio->mode = O_WRONLY | O_BINARY;