]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/main.cc
3 * $Id: main.cc,v 1.276 1998/11/12 06:28:14 wessels Exp $
5 * DEBUG: section 1 Startup and Main Loop
6 * AUTHOR: Harvest Derived
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
38 /* for error reporting from xmalloc and friends */
39 extern void (*failure_notify
) (const char *);
41 static int opt_send_signal
= -1;
42 static int opt_no_daemon
= 0;
43 static int httpPortNumOverride
= 1;
44 static int icpPortNumOverride
= 1; /* Want to detect "-u 0" */
46 static int malloc_debug_level
= 0;
48 static volatile int do_reconfigure
= 0;
49 static volatile int do_rotate
= 0;
50 static volatile int do_shutdown
= 0;
52 static void mainRotate(void);
53 static void mainReconfigure(void);
54 static SIGHDLR rotate_logs
;
55 static SIGHDLR reconfigure
;
56 #if ALARM_UPDATES_TIME
57 static SIGHDLR time_tick
;
59 static void mainInitialize(void);
60 static void usage(void);
61 static void mainParseOptions(int, char **);
62 static void sendSignal(void);
63 static void serverConnectionsOpen(void);
64 static void watch_child(char **);
65 static void setEffectiveUser(void);
67 extern void log_trace_done();
68 extern void log_trace_init(char *);
70 static EVH SquidShutdown
;
76 "Usage: %s [-dhsvzCDFNRVYX] [-f config-file] [-[au] port] [-k signal]\n"
77 " -a port Specify HTTP port number (default: %d).\n"
78 " -d level Write debugging to stderr also.\n"
79 " -f file Use given config-file instead of\n"
81 " -h Print help message.\n"
82 " -k reconfigure|rotate|shutdown|interrupt|kill|debug|check\n"
83 " Send signal to running copy and exit.\n"
84 " -s Enable logging to syslog.\n"
85 " -u port Specify ICP port number (default: %d), disable with 0.\n"
86 " -v Print version.\n"
87 " -z Create swap directories\n"
88 " -C Do not catch fatal signals.\n"
89 " -D Disable initial DNS tests.\n"
90 " -F Foreground fast store rebuild.\n"
91 " -N No daemon mode.\n"
92 " -R Do not set REUSEADDR on port.\n"
93 " -V Virtual host httpd-accelerator.\n"
94 " -X Force full debugging.\n"
95 " -Y Only return UDP_HIT or UDP_MISS_NOFETCH during fast reload.\n",
96 appname
, CACHE_HTTP_PORT
, DefaultConfigFile
, CACHE_ICP_PORT
);
101 mainParseOptions(int argc
, char *argv
[])
106 while ((c
= getopt(argc
, argv
, "CDFNRSVYXa:d:f:hk:m::su:vz?")) != -1) {
109 opt_catch_signals
= 0;
115 opt_foreground_rebuild
= 1;
124 opt_store_doublecheck
= 1;
130 /* force full debugging */
131 sigusr2_handle(SIGUSR2
);
134 opt_reload_hit_only
= 1;
137 httpPortNumOverride
= atoi(optarg
);
140 opt_debug_stderr
= atoi(optarg
);
144 ConfigFile
= xstrdup(optarg
);
150 if ((int) strlen(optarg
) < 1)
152 if (!strncmp(optarg
, "reconfigure", strlen(optarg
)))
153 opt_send_signal
= SIGHUP
;
154 else if (!strncmp(optarg
, "rotate", strlen(optarg
)))
155 #if (defined(_SQUID_LINUX_) && USE_ASYNC_IO)
156 opt_send_signal
= SIGQUIT
;
158 opt_send_signal
= SIGUSR1
;
160 else if (!strncmp(optarg
, "debug", strlen(optarg
)))
161 #if (defined(_SQUID_LINUX_) && USE_ASYNC_IO)
162 opt_send_signal
= SIGTRAP
;
164 opt_send_signal
= SIGUSR2
;
166 else if (!strncmp(optarg
, "shutdown", strlen(optarg
)))
167 opt_send_signal
= SIGTERM
;
168 else if (!strncmp(optarg
, "interrupt", strlen(optarg
)))
169 opt_send_signal
= SIGINT
;
170 else if (!strncmp(optarg
, "kill", strlen(optarg
)))
171 opt_send_signal
= SIGKILL
;
172 else if (!strncmp(optarg
, "check", strlen(optarg
)))
173 opt_send_signal
= 0; /* SIGNULL */
180 malloc_debug_level
= atoi(optarg
);
184 fatal("Need to add -DMALLOC_DBG when compiling to use -mX option");
189 xmalloc_trace
= !xmalloc_trace
;
191 fatal("Need to configure --enable-xmalloc-debug-trace to use -m option");
195 opt_syslog_enable
= 1;
198 icpPortNumOverride
= atoi(optarg
);
199 if (icpPortNumOverride
< 0)
200 icpPortNumOverride
= 0;
203 printf("Squid Cache: Version %s\n", version_string
);
207 opt_create_swap_dirs
= 1;
223 signal(sig
, rotate_logs
);
227 #if ALARM_UPDATES_TIME
234 signal(sig
, time_tick
);
246 signal(sig
, reconfigure
);
253 do_shutdown
= sig
== SIGINT
? -1 : 1;
254 #ifdef KILL_PARENT_OPT
256 debug(1, 1) ("Killing RunCache, pid %d\n", getppid());
257 kill(getppid(), sig
);
260 #if SA_RESETHAND == 0
261 signal(SIGTERM
, SIG_DFL
);
262 signal(SIGINT
, SIG_DFL
);
267 serverConnectionsOpen(void)
269 clientHttpConnectionsOpen();
270 icpConnectionsOpen();
275 snmpConnectionOpen();
288 serverConnectionsClose(void)
290 assert(shutting_down
|| reconfiguring
);
291 clientHttpConnectionsClose();
292 icpConnectionShutdown();
294 htcpSocketShutdown();
298 snmpConnectionShutdown();
304 mainReconfigure(void)
306 debug(1, 1) ("Restarting Squid Cache (version %s)...\n", version_string
);
308 /* Already called serverConnectionsClose and ipcacheShutdownServers() */
309 serverConnectionsClose();
310 icpConnectionClose();
315 snmpConnectionClose();
319 authenticateShutdown();
320 storeDirCloseSwapLogs();
322 parseConfigFile(ConfigFile
);
323 _db_init(Config
.Log
.log
, Config
.debugOptions
);
324 ipcache_restart(); /* clear stuck entries */
325 fqdncache_restart(); /* sigh, fqdncache too */
326 errorInitialize(); /* reload error pages */
330 serverConnectionsOpen();
331 if (theOutIcpConnection
>= 0) {
332 if (!Config2
.Accel
.on
|| Config
.onoff
.accel_with_proxy
)
333 neighbors_open(theOutIcpConnection
);
335 debug(1, 1) ("ICP port disabled in httpd_accelerator mode\n");
337 storeDirOpenSwapLogs();
338 debug(1, 1) ("Ready to serve requests.\n");
346 _db_rotate_log(); /* cache.log */
347 storeDirWriteCleanLogs(1);
348 storeLogRotate(); /* store.log */
349 accessLogRotate(); /* access.log */
350 useragentRotateLog(); /* useragent.log */
355 setEffectiveUser(void)
357 leave_suid(); /* Run as non privilegied user */
358 if (geteuid() == 0) {
359 debug(0, 0) ("Squid is not safe to run as root! If you must\n");
360 debug(0, 0) ("start Squid as root, then you must configure\n");
361 debug(0, 0) ("it to run as a non-priveledged user with the\n");
362 debug(0, 0) ("'cache_effective_user' option in the config file.\n");
363 fatal("Don't run Squid as root, set 'cache_effective_user'!");
370 if (opt_catch_signals
) {
371 squid_signal(SIGSEGV
, death
, SA_NODEFER
| SA_RESETHAND
);
372 squid_signal(SIGBUS
, death
, SA_NODEFER
| SA_RESETHAND
);
374 squid_signal(SIGPIPE
, SIG_IGN
, SA_RESTART
);
375 squid_signal(SIGCHLD
, sig_child
, SA_NODEFER
| SA_RESTART
);
377 if (!configured_once
) {
379 memInit(); /* memInit must go before config parsing */
381 if (ConfigFile
== NULL
)
382 ConfigFile
= xstrdup(DefaultConfigFile
);
383 parseConfigFile(ConfigFile
);
386 assert(Config
.Port
.http
);
387 if (httpPortNumOverride
!= 1)
388 Config
.Port
.http
->i
= (u_short
) httpPortNumOverride
;
389 if (icpPortNumOverride
!= 1)
390 Config
.Port
.icp
= (u_short
) icpPortNumOverride
;
392 _db_init(Config
.Log
.log
, Config
.debugOptions
);
393 fd_open(fileno(debug_log
), FD_LOG
, Config
.Log
.log
);
395 log_trace_init("/tmp/squid.alloc");
397 debug(1, 0) ("Starting Squid Cache version %s for %s...\n",
400 debug(1, 1) ("Process ID %d\n", (int) getpid());
401 debug(1, 1) ("With %d file descriptors available\n", Squid_MaxFD
);
403 if (!configured_once
)
404 disk_init(); /* disk_init must go before ipcache_init() */
411 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
412 httpAnonInitModule(); /* must go before accepting requests */
413 httpReplyInitModule(); /* must go before accepting replies */
421 malloc_debug(0, malloc_debug_level
);
424 if (!configured_once
) {
430 if (Config
.effectiveUser
) {
431 /* we were probably started as root, so cd to a swap
432 * directory in case we dump core */
433 if (chdir(storeSwapDir(0)) < 0) {
434 debug(50, 0) ("%s: %s\n", storeSwapDir(0), xstrerror());
435 fatal_dump("Cannot cd to swap directory?");
438 /* after this point we want to see the mallinfo() output */
440 mimeInit(Config
.mimeTablePathname
);
448 serverConnectionsOpen();
449 if (theOutIcpConnection
>= 0) {
450 if (!Config2
.Accel
.on
|| Config
.onoff
.accel_with_proxy
)
451 neighbors_open(theOutIcpConnection
);
453 debug(1, 1) ("ICP port disabled in httpd_accelerator mode\n");
455 if (!configured_once
)
456 writePidFile(); /* write PID file */
458 #if (defined(_SQUID_LINUX_) && USE_ASYNC_IO)
459 squid_signal(SIGQUIT
, rotate_logs
, SA_RESTART
);
460 squid_signal(SIGTRAP
, sigusr2_handle
, SA_RESTART
);
462 squid_signal(SIGUSR1
, rotate_logs
, SA_RESTART
);
463 squid_signal(SIGUSR2
, sigusr2_handle
, SA_RESTART
);
465 squid_signal(SIGHUP
, reconfigure
, SA_RESTART
);
466 squid_signal(SIGTERM
, shut_down
, SA_NODEFER
| SA_RESETHAND
| SA_RESTART
);
467 squid_signal(SIGINT
, shut_down
, SA_NODEFER
| SA_RESETHAND
| SA_RESTART
);
468 #if ALARM_UPDATES_TIME
469 squid_signal(SIGALRM
, time_tick
, SA_RESTART
);
472 debug(1, 1) ("Ready to serve requests.\n");
474 if (!configured_once
) {
475 eventAdd("storeMaintain", storeMaintainSwapSpace
, NULL
, 1.0, 1);
476 eventAdd("storeDirClean", storeDirClean
, NULL
, 15.0, 1);
477 if (Config
.onoff
.announce
)
478 eventAdd("start_announce", start_announce
, NULL
, 3600.0, 1);
479 eventAdd("ipcache_purgelru", ipcache_purgelru
, NULL
, 10.0, 1);
480 eventAdd("fqdncache_purgelru", fqdncache_purgelru
, NULL
, 15.0, 1);
486 main(int argc
, char **argv
)
489 int n
; /* # of GC'd objects */
493 if (FD_SETSIZE
< Squid_MaxFD
)
494 Squid_MaxFD
= FD_SETSIZE
;
496 /* call mallopt() before anything else */
499 /* Round up all sizes to a multiple of this */
500 mallopt(M_GRAIN
, 16);
503 /* biggest size that is considered a small block */
504 mallopt(M_MXFAST
, 256);
507 /* allocate this many small blocks at once */
508 mallopt(M_NLBLKS
, 32);
510 #endif /* HAVE_MALLOPT */
512 memset(&local_addr
, '\0', sizeof(struct in_addr
));
513 safe_inet_addr(localhost
, &local_addr
);
514 memset(&any_addr
, '\0', sizeof(struct in_addr
));
515 safe_inet_addr("0.0.0.0", &any_addr
);
516 memset(&no_addr
, '\0', sizeof(struct in_addr
));
517 safe_inet_addr("255.255.255.255", &no_addr
);
518 squid_srandom(time(NULL
));
521 squid_start
= current_time
;
522 failure_notify
= fatal_dump
;
524 mainParseOptions(argc
, argv
);
526 /* send signal to running copy and exit */
527 if (opt_send_signal
!= -1) {
531 if (opt_create_swap_dirs
) {
532 if (ConfigFile
== NULL
)
533 ConfigFile
= xstrdup(DefaultConfigFile
);
535 memInit(); /* memInit is required for config parsing */
536 parseConfigFile(ConfigFile
);
538 debug(0, 0) ("Creating Swap Directories\n");
539 storeCreateSwapDirectories();
546 if (opt_catch_signals
)
547 for (n
= Squid_MaxFD
; n
> 2; n
--)
550 /*init comm module */
554 /* we have to init fdstat here. */
555 fd_open(0, FD_LOG
, "stdin");
556 fd_open(1, FD_LOG
, "stdout");
557 fd_open(2, FD_LOG
, "stderr");
563 if (do_reconfigure
) {
566 } else if (do_rotate
) {
569 } else if (do_shutdown
) {
570 time_t wait
= do_shutdown
> 0 ? (int) Config
.shutdownLifetime
: 0;
571 debug(1, 1) ("Preparing for shutdown after %d requests\n",
572 Counter
.client_http
.requests
);
573 debug(1, 1) ("Waiting %d seconds for active connections to finish\n",
577 serverConnectionsClose();
580 authenticateShutdown();
581 eventAdd("SquidShutdown", SquidShutdown
, NULL
, (double) (wait
+ 1), 1);
584 if ((loop_delay
= eventNextTime()) < 0)
587 switch (comm_poll(loop_delay
)) {
589 switch (comm_select(loop_delay
)) {
592 errcount
= 0; /* reset if successful */
596 debug(1, 0) ("Select loop Error. Retry %d\n", errcount
);
598 fatal_dump("Select Loop failed!");
606 fatal_dump("MAIN: Internal error -- this should never happen.");
619 if (ConfigFile
== NULL
)
620 ConfigFile
= xstrdup(DefaultConfigFile
);
623 parseConfigFile(ConfigFile
);
626 if (kill(pid
, opt_send_signal
) &&
627 /* ignore permissions if just running check */
628 !(opt_send_signal
== 0 && errno
== EPERM
)) {
629 fprintf(stderr
, "%s: ERROR: Could not send ", appname
);
630 fprintf(stderr
, "signal %d to process %d: %s\n",
631 opt_send_signal
, (int) pid
, xstrerror());
635 fprintf(stderr
, "%s: ERROR: No running copy\n", appname
);
638 /* signal successfully sent */
643 watch_child(char *argv
[])
655 if (*(argv
[0]) == '(')
660 prog
= xstrdup(argv
[0]);
661 argv
[0] = xstrdup("(squid)");
663 fatal("execvp failed");
665 /* parent */ time(&start
);
667 squid_signal(SIGINT
, SIG_IGN
, SA_RESTART
);
669 pid
= wait3(&status
, 0, NULL
);
671 pid
= waitpid(-1, &status
, 0);
675 if (stop
- start
< 10)
681 if (WIFEXITED(status
))
682 if (WEXITSTATUS(status
) == 0)
684 squid_signal(SIGINT
, SIG_DFL
, SA_RESTART
);
691 SquidShutdown(void *unused
)
693 debug(1, 1) ("Shutting down...\n");
694 if (Config
.pidFilename
&& strcmp(Config
.pidFilename
, "none")) {
696 safeunlink(Config
.pidFilename
, 0);
699 icpConnectionClose();
704 snmpConnectionClose();
706 releaseServerSockets();
707 commCloseAllSockets();
709 storeDirWriteCleanLogs(0);
714 #if PURIFY || XMALLOC_TRACE
717 /*stmemFreeMemory(); */
720 fqdncacheFreeMemory();
722 clientdbFreeMemory();
723 httpHeaderCleanModule();
738 xmalloc_find_leaks();
739 debug(1, 0) ("Memory used after shutdown: %d\n", xmalloc_total
);
744 debug(1, 1) ("Squid Cache (Version %s): Exiting normally.\n",