]>
Commit | Line | Data |
---|---|---|
a47b9029 | 1 | |
30a4f2a8 | 2 | /* |
7021844c | 3 | * $Id: main.cc,v 1.231 1998/03/03 00:31:08 rousskov Exp $ |
30a4f2a8 | 4 | * |
5 | * DEBUG: section 1 Startup and Main Loop | |
6 | * AUTHOR: Harvest Derived | |
7 | * | |
42c04c16 | 8 | * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ |
30a4f2a8 | 9 | * -------------------------------------------------------- |
10 | * | |
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 | |
14 | * the National Science Foundation. | |
15 | * | |
16 | * This program is free software; you can redistribute it and/or modify | |
17 | * it under the terms of the GNU General Public License as published by | |
18 | * the Free Software Foundation; either version 2 of the License, or | |
19 | * (at your option) any later version. | |
20 | * | |
21 | * This program is distributed in the hope that it will be useful, | |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 | * GNU General Public License for more details. | |
25 | * | |
26 | * You should have received a copy of the GNU General Public License | |
27 | * along with this program; if not, write to the Free Software | |
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
29 | * | |
30 | */ | |
31 | ||
32 | /* | |
33 | * Copyright (c) 1994, 1995. All rights reserved. | |
34 | * | |
35 | * The Harvest software was developed by the Internet Research Task | |
36 | * Force Research Group on Resource Discovery (IRTF-RD): | |
37 | * | |
38 | * Mic Bowman of Transarc Corporation. | |
39 | * Peter Danzig of the University of Southern California. | |
40 | * Darren R. Hardy of the University of Colorado at Boulder. | |
41 | * Udi Manber of the University of Arizona. | |
42 | * Michael F. Schwartz of the University of Colorado at Boulder. | |
43 | * Duane Wessels of the University of Colorado at Boulder. | |
44 | * | |
45 | * This copyright notice applies to software in the Harvest | |
46 | * ``src/'' directory only. Users should consult the individual | |
47 | * copyright notices in the ``components/'' subdirectories for | |
48 | * copyright information about other software bundled with the | |
49 | * Harvest source code distribution. | |
50 | * | |
51 | * TERMS OF USE | |
52 | * | |
53 | * The Harvest software may be used and re-distributed without | |
54 | * charge, provided that the software origin and research team are | |
55 | * cited in any use of the system. Most commonly this is | |
56 | * accomplished by including a link to the Harvest Home Page | |
57 | * (http://harvest.cs.colorado.edu/) from the query page of any | |
58 | * Broker you deploy, as well as in the query result pages. These | |
59 | * links are generated automatically by the standard Broker | |
60 | * software distribution. | |
61 | * | |
62 | * The Harvest software is provided ``as is'', without express or | |
63 | * implied warranty, and with no support nor obligation to assist | |
64 | * in its use, correction, modification or enhancement. We assume | |
65 | * no liability with respect to the infringement of copyrights, | |
66 | * trade secrets, or any patents, and are not responsible for | |
67 | * consequential damages. Proper use of the Harvest software is | |
68 | * entirely the responsibility of the user. | |
69 | * | |
70 | * DERIVATIVE WORKS | |
71 | * | |
72 | * Users may make derivative works from the Harvest software, subject | |
73 | * to the following constraints: | |
74 | * | |
75 | * - You must include the above copyright notice and these | |
76 | * accompanying paragraphs in all forms of derivative works, | |
77 | * and any documentation and other materials related to such | |
78 | * distribution and use acknowledge that the software was | |
79 | * developed at the above institutions. | |
80 | * | |
81 | * - You must notify IRTF-RD regarding your distribution of | |
82 | * the derivative work. | |
83 | * | |
84 | * - You must clearly notify users that your are distributing | |
85 | * a modified version and not the original Harvest software. | |
86 | * | |
87 | * - Any derivative product is also subject to these copyright | |
88 | * and use restrictions. | |
89 | * | |
90 | * Note that the Harvest software is NOT in the public domain. We | |
91 | * retain copyright, as specified above. | |
92 | * | |
93 | * HISTORY OF FREE SOFTWARE STATUS | |
94 | * | |
95 | * Originally we required sites to license the software in cases | |
96 | * where they were going to build commercial products/services | |
97 | * around Harvest. In June 1995 we changed this policy. We now | |
98 | * allow people to use the core Harvest software (the code found in | |
99 | * the Harvest ``src/'' directory) for free. We made this change | |
100 | * in the interest of encouraging the widest possible deployment of | |
101 | * the technology. The Harvest software is really a reference | |
102 | * implementation of a set of protocols and formats, some of which | |
103 | * we intend to standardize. We encourage commercial | |
104 | * re-implementations of code complying to this set of standards. | |
105 | */ | |
44a47c6e | 106 | |
107 | #include "squid.h" | |
108 | ||
30a4f2a8 | 109 | /* for error reporting from xmalloc and friends */ |
ea3a2a69 | 110 | extern void (*failure_notify) (const char *); |
30a4f2a8 | 111 | |
f1dc9b30 | 112 | static int opt_send_signal = -1; |
f95b8144 | 113 | static int opt_no_daemon = 0; |
67508012 | 114 | static volatile int rotate_pending = 0; /* set by SIGUSR1 handler */ |
30a4f2a8 | 115 | static int httpPortNumOverride = 1; |
116 | static int icpPortNumOverride = 1; /* Want to detect "-u 0" */ | |
117 | #if MALLOC_DBG | |
4d64d74a | 118 | static int malloc_debug_level = 0; |
30a4f2a8 | 119 | #endif |
4d7add01 | 120 | |
b984c445 | 121 | static SIGHDLR rotate_logs; |
122 | static SIGHDLR reconfigure; | |
123 | #if ALARM_UPDATES_TIME | |
124 | static SIGHDLR time_tick; | |
125 | #endif | |
f5b8bbc4 | 126 | static void mainInitialize(void); |
127 | static void mainReconfigure(void); | |
128 | static void usage(void); | |
129 | static void mainParseOptions(int, char **); | |
130 | static void sendSignal(void); | |
131 | static void serverConnectionsOpen(void); | |
bbe199dc | 132 | static void watch_child(char **); |
85407535 | 133 | static void setEffectiveUser(void); |
fff6ad65 | 134 | static void normal_shutdown(void); |
36a97e19 | 135 | #if MEM_GEN_TRACE |
136 | extern void log_trace_done(); | |
137 | extern void log_trace_init(char *); | |
138 | #endif | |
85407535 | 139 | |
b8d8561b | 140 | static void |
0673c0ba | 141 | usage(void) |
ccff9601 | 142 | { |
0ee4272b | 143 | fprintf(stderr, |
969c39b9 | 144 | "Usage: %s [-dhsvzCDFNRVYX] [-f config-file] [-[au] port] [-k signal]\n" |
15df8349 | 145 | " -a port Specify HTTP port number (default: %d).\n" |
b6157f5e | 146 | " -d level Write debugging to stderr also.\n" |
0ee4272b | 147 | " -f file Use given config-file instead of\n" |
148 | " %s\n" | |
149 | " -h Print help message.\n" | |
0ee4272b | 150 | " -k reconfigure|rotate|shutdown|interrupt|kill|debug|check\n" |
151 | " Send signal to running copy and exit.\n" | |
152 | " -s Enable logging to syslog.\n" | |
153 | " -u port Specify ICP port number (default: %d), disable with 0.\n" | |
154 | " -v Print version.\n" | |
85407535 | 155 | " -z Create swap directories\n" |
0ee4272b | 156 | " -C Do not catch fatal signals.\n" |
157 | " -D Disable initial DNS tests.\n" | |
158 | " -F Foreground fast store rebuild.\n" | |
969c39b9 | 159 | " -N No daemon mode.\n" |
0ee4272b | 160 | " -R Do not set REUSEADDR on port.\n" |
0ee4272b | 161 | " -V Virtual host httpd-accelerator.\n" |
3013ac6d | 162 | " -X Force full debugging.\n" |
429fdbec | 163 | " -Y Only return UDP_HIT or UDP_MISS_NOFETCH during fast reload.\n", |
30a4f2a8 | 164 | appname, CACHE_HTTP_PORT, DefaultConfigFile, CACHE_ICP_PORT); |
77ffc99f | 165 | exit(1); |
ccff9601 | 166 | } |
167 | ||
b8d8561b | 168 | static void |
169 | mainParseOptions(int argc, char *argv[]) | |
090089c4 | 170 | { |
090089c4 | 171 | extern char *optarg; |
4d64d74a | 172 | int c; |
090089c4 | 173 | |
723e8aa3 | 174 | while ((c = getopt(argc, argv, "CDFNRSVYXa:d:f:hk:m::su:vz?")) != -1) { |
090089c4 | 175 | switch (c) { |
090089c4 | 176 | case 'C': |
1758c627 | 177 | opt_catch_signals = 0; |
090089c4 | 178 | break; |
179 | case 'D': | |
30a4f2a8 | 180 | opt_dns_tests = 0; |
090089c4 | 181 | break; |
30a4f2a8 | 182 | case 'F': |
183 | opt_foreground_rebuild = 1; | |
090089c4 | 184 | break; |
f95b8144 | 185 | case 'N': |
186 | opt_no_daemon = 1; | |
9e2225aa | 187 | break; |
090089c4 | 188 | case 'R': |
3b4be6a6 | 189 | opt_reuseaddr = 0; |
090089c4 | 190 | break; |
b109de6b | 191 | case 'S': |
192 | opt_store_doublecheck = 1; | |
193 | break; | |
30a4f2a8 | 194 | case 'V': |
195 | vhost_mode = 1; | |
196 | break; | |
e924600d | 197 | case 'X': |
198 | /* force full debugging */ | |
199 | sigusr2_handle(SIGUSR2); | |
200 | break; | |
30a4f2a8 | 201 | case 'Y': |
202 | opt_reload_hit_only = 1; | |
203 | break; | |
204 | case 'a': | |
205 | httpPortNumOverride = atoi(optarg); | |
206 | break; | |
0d90407c | 207 | case 'd': |
723e8aa3 | 208 | opt_debug_stderr = atoi(optarg); |
0d90407c | 209 | break; |
090089c4 | 210 | case 'f': |
00fac1f8 | 211 | xfree(ConfigFile); |
212 | ConfigFile = xstrdup(optarg); | |
090089c4 | 213 | break; |
30a4f2a8 | 214 | case 'h': |
215 | usage(); | |
090089c4 | 216 | break; |
7690e8eb | 217 | case 'k': |
24382924 | 218 | if ((int) strlen(optarg) < 1) |
7690e8eb | 219 | usage(); |
220 | if (!strncmp(optarg, "reconfigure", strlen(optarg))) | |
221 | opt_send_signal = SIGHUP; | |
222 | else if (!strncmp(optarg, "rotate", strlen(optarg))) | |
223 | opt_send_signal = SIGUSR1; | |
224 | else if (!strncmp(optarg, "debug", strlen(optarg))) | |
225 | opt_send_signal = SIGUSR2; | |
226 | else if (!strncmp(optarg, "shutdown", strlen(optarg))) | |
227 | opt_send_signal = SIGTERM; | |
6759a5fb | 228 | else if (!strncmp(optarg, "interrupt", strlen(optarg))) |
229 | opt_send_signal = SIGINT; | |
7690e8eb | 230 | else if (!strncmp(optarg, "kill", strlen(optarg))) |
231 | opt_send_signal = SIGKILL; | |
232 | else if (!strncmp(optarg, "check", strlen(optarg))) | |
fedac7e5 | 233 | opt_send_signal = 0; /* SIGNULL */ |
7690e8eb | 234 | else |
235 | usage(); | |
236 | break; | |
090089c4 | 237 | case 'm': |
33ab18e8 | 238 | if (optarg) { |
30a4f2a8 | 239 | #if MALLOC_DBG |
33ab18e8 | 240 | malloc_debug_level = atoi(optarg); |
241 | /* NOTREACHED */ | |
242 | break; | |
30a4f2a8 | 243 | #else |
33ab18e8 | 244 | fatal("Need to add -DMALLOC_DBG when compiling to use -mX option"); |
245 | /* NOTREACHED */ | |
246 | #endif | |
247 | } else { | |
248 | #if XMALLOC_TRACE | |
249 | xmalloc_trace = !xmalloc_trace; | |
250 | #else | |
251 | fatal("Need to configure --enable-xmalloc-debug-trace to use -m option"); | |
30a4f2a8 | 252 | #endif |
33ab18e8 | 253 | } |
30a4f2a8 | 254 | case 's': |
6e40f263 | 255 | opt_syslog_enable = 1; |
30a4f2a8 | 256 | break; |
257 | case 'u': | |
258 | icpPortNumOverride = atoi(optarg); | |
259 | if (icpPortNumOverride < 0) | |
260 | icpPortNumOverride = 0; | |
261 | break; | |
262 | case 'v': | |
263 | printf("Squid Cache: Version %s\n", version_string); | |
264 | exit(0); | |
265 | /* NOTREACHED */ | |
090089c4 | 266 | case 'z': |
85407535 | 267 | opt_create_swap_dirs = 1; |
090089c4 | 268 | break; |
269 | case '?': | |
090089c4 | 270 | default: |
ccff9601 | 271 | usage(); |
090089c4 | 272 | break; |
273 | } | |
090089c4 | 274 | } |
4d64d74a | 275 | } |
090089c4 | 276 | |
7a2f978b | 277 | /* ARGSUSED */ |
b8d8561b | 278 | static void |
279 | rotate_logs(int sig) | |
30a4f2a8 | 280 | { |
a3d5953d | 281 | debug(1, 1) ("rotate_logs: SIGUSR1 received.\n"); |
30a4f2a8 | 282 | rotate_pending = 1; |
283 | #if !HAVE_SIGACTION | |
284 | signal(sig, rotate_logs); | |
285 | #endif | |
286 | } | |
287 | ||
b984c445 | 288 | #if ALARM_UPDATES_TIME |
97c03d3c | 289 | static void |
290 | time_tick(int sig) | |
291 | { | |
292 | getCurrentTime(); | |
293 | alarm(1); | |
294 | #if !HAVE_SIGACTION | |
295 | signal(sig, time_tick); | |
296 | #endif | |
297 | } | |
38d04788 | 298 | |
b984c445 | 299 | #endif |
97c03d3c | 300 | |
7a2f978b | 301 | /* ARGSUSED */ |
b8d8561b | 302 | static void |
303 | reconfigure(int sig) | |
30a4f2a8 | 304 | { |
dbe4fd8e | 305 | reconfigure_pending = 1; |
30a4f2a8 | 306 | #if !HAVE_SIGACTION |
307 | signal(sig, reconfigure); | |
308 | #endif | |
309 | } | |
310 | ||
b8d8561b | 311 | void |
312 | shut_down(int sig) | |
30a4f2a8 | 313 | { |
f3753518 | 314 | shutdown_pending = sig == SIGINT ? -1 : 1; |
f2908497 | 315 | debug(1, 1) ("Preparing for shutdown after %d requests\n", |
316 | Counter.client_http.requests); | |
a3d5953d | 317 | debug(1, 1) ("Waiting %d seconds for active connections to finish\n", |
5c5783a2 | 318 | shutdown_pending > 0 ? Config.shutdownLifetime : 0); |
cadc2d55 | 319 | #ifdef KILL_PARENT_OPT |
88738790 | 320 | { |
321 | pid_t ppid = getppid(); | |
322 | if (ppid > 1) { | |
1c2c5abc | 323 | debug(1, 1) ("Killing RunCache, pid %d\n", ppid); |
88738790 | 324 | kill(ppid, sig); |
325 | } | |
326 | } | |
cadc2d55 | 327 | #endif |
6e40f263 | 328 | #if SA_RESETHAND == 0 |
329 | signal(SIGTERM, SIG_DFL); | |
330 | signal(SIGINT, SIG_DFL); | |
331 | #endif | |
30a4f2a8 | 332 | } |
333 | ||
24382924 | 334 | static void |
0673c0ba | 335 | serverConnectionsOpen(void) |
4d64d74a | 336 | { |
15df8349 | 337 | clientHttpConnectionsOpen(); |
338 | icpConnectionsOpen(); | |
678c6099 | 339 | #ifdef SQUID_SNMP |
3265e68d | 340 | snmpConnectionOpen(); |
2bbd722b | 341 | #endif |
5ecceaa4 | 342 | clientdbInit(); |
16b204c4 | 343 | icmpOpen(); |
67508012 | 344 | netdbInit(); |
f899fac1 | 345 | asnInit(); |
85034133 | 346 | peerSelectInit(); |
5f3f8d0e | 347 | } |
348 | ||
b8d8561b | 349 | void |
0673c0ba | 350 | serverConnectionsClose(void) |
5f3f8d0e | 351 | { |
dc835977 | 352 | /* |
353 | * NOTE, this function will be called repeatedly while shutdown | |
354 | * is pending | |
355 | */ | |
c0fbae16 | 356 | clientHttpConnectionsClose(); |
17e6c0a1 | 357 | icpConnectionShutdown(); |
c0fbae16 | 358 | icmpClose(); |
15df8349 | 359 | #ifdef SQUID_SNMP |
17e6c0a1 | 360 | snmpConnectionShutdown(); |
15df8349 | 361 | #endif |
5f3f8d0e | 362 | } |
363 | ||
b8d8561b | 364 | static void |
dbe4fd8e | 365 | mainReconfigure(void) |
5f3f8d0e | 366 | { |
a3d5953d | 367 | debug(1, 0) ("Restarting Squid Cache (version %s)...\n", version_string); |
0ffd22bc | 368 | /* Already called serverConnectionsClose and ipcacheShutdownServers() */ |
15df8349 | 369 | serverConnectionsClose(); |
17e6c0a1 | 370 | icpConnectionClose(); |
371 | #ifdef SQUID_SNMP | |
372 | snmpConnectionClose(); | |
373 | #endif | |
15df8349 | 374 | dnsShutdownServers(); |
53ad48e6 | 375 | asnCleanup(); |
15df8349 | 376 | redirectShutdownServers(); |
2db68ce5 | 377 | storeDirCloseSwapLogs(); |
53ad48e6 | 378 | errorFree(); |
00fac1f8 | 379 | parseConfigFile(ConfigFile); |
b6f794d6 | 380 | _db_init(Config.Log.log, Config.debugOptions); |
53ad48e6 | 381 | asnAclInitialize(Config.aclList); /* reload network->AS database */ |
429fdbec | 382 | ipcache_restart(); /* clear stuck entries */ |
383 | fqdncache_restart(); /* sigh, fqdncache too */ | |
53ad48e6 | 384 | errorInitialize(); /* reload error pages */ |
f88bb09c | 385 | dnsOpenServers(); |
d2af9477 | 386 | redirectOpenServers(); |
0ffd22bc | 387 | serverConnectionsOpen(); |
17a0a4ee | 388 | if (theOutIcpConnection >= 0 && (!Config2.Accel.on || Config.onoff.accel_with_proxy)) |
30a4f2a8 | 389 | neighbors_open(theOutIcpConnection); |
2db68ce5 | 390 | storeDirOpenSwapLogs(); |
a3d5953d | 391 | debug(1, 0) ("Ready to serve requests.\n"); |
5f3f8d0e | 392 | } |
393 | ||
067bea91 | 394 | static void |
85407535 | 395 | setEffectiveUser(void) |
396 | { | |
397 | leave_suid(); /* Run as non privilegied user */ | |
398 | if (geteuid() == 0) { | |
399 | debug(0, 0) ("Squid is not safe to run as root! If you must\n"); | |
400 | debug(0, 0) ("start Squid as root, then you must configure\n"); | |
401 | debug(0, 0) ("it to run as a non-priveledged user with the\n"); | |
402 | debug(0, 0) ("'cache_effective_user' option in the config file.\n"); | |
403 | fatal("Don't run Squid as root, set 'cache_effective_user'!"); | |
404 | } | |
405 | } | |
406 | ||
b8d8561b | 407 | static void |
0673c0ba | 408 | mainInitialize(void) |
5f3f8d0e | 409 | { |
1758c627 | 410 | if (opt_catch_signals) { |
30a4f2a8 | 411 | squid_signal(SIGSEGV, death, SA_NODEFER | SA_RESETHAND); |
412 | squid_signal(SIGBUS, death, SA_NODEFER | SA_RESETHAND); | |
44f99671 | 413 | } |
30a4f2a8 | 414 | squid_signal(SIGPIPE, SIG_IGN, SA_RESTART); |
415 | squid_signal(SIGCHLD, sig_child, SA_NODEFER | SA_RESTART); | |
44f99671 | 416 | |
8407afee | 417 | if (!configured_once) |
418 | cbdataInit(); | |
00fac1f8 | 419 | if (ConfigFile == NULL) |
420 | ConfigFile = xstrdup(DefaultConfigFile); | |
421 | parseConfigFile(ConfigFile); | |
5f3f8d0e | 422 | |
85407535 | 423 | setEffectiveUser(); |
270b86af | 424 | assert(Config.Port.http); |
30a4f2a8 | 425 | if (httpPortNumOverride != 1) |
270b86af | 426 | Config.Port.http->i = (u_short) httpPortNumOverride; |
30a4f2a8 | 427 | if (icpPortNumOverride != 1) |
f2052513 | 428 | Config.Port.icp = (u_short) icpPortNumOverride; |
30a4f2a8 | 429 | |
b6f794d6 | 430 | _db_init(Config.Log.log, Config.debugOptions); |
5c5783a2 | 431 | fd_open(fileno(debug_log), FD_LOG, Config.Log.log); |
71a17702 | 432 | #if MEM_GEN_TRACE |
433 | log_trace_init("/tmp/squid.alloc"); | |
434 | #endif | |
a3d5953d | 435 | debug(1, 0) ("Starting Squid Cache version %s for %s...\n", |
30a4f2a8 | 436 | version_string, |
437 | CONFIG_HOST_TYPE); | |
70364f29 | 438 | debug(1, 0) ("Process ID %d\n", (int) getpid()); |
a3d5953d | 439 | debug(1, 1) ("With %d file descriptors available\n", Squid_MaxFD); |
5f3f8d0e | 440 | |
dbe4fd8e | 441 | if (!configured_once) { |
3f6c0fb2 | 442 | memInit(); /* memInit must go before at least redirect */ |
234967c9 | 443 | disk_init(); /* disk_init must go before ipcache_init() */ |
850c4ead | 444 | } |
5f3f8d0e | 445 | ipcache_init(); |
f88bb09c | 446 | fqdncache_init(); |
447 | dnsOpenServers(); | |
d2af9477 | 448 | redirectOpenServers(); |
b012353a | 449 | useragentOpenLog(); |
2ac76861 | 450 | httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */ |
9b312a19 | 451 | errorInitialize(); |
7a2f978b | 452 | accessLogInit(); |
5f3f8d0e | 453 | |
30a4f2a8 | 454 | #if MALLOC_DBG |
5f3f8d0e | 455 | malloc_debug(0, malloc_debug_level); |
456 | #endif | |
457 | ||
dbe4fd8e | 458 | if (!configured_once) { |
429fdbec | 459 | unlinkdInit(); |
7111c86a | 460 | urlInitialize(); |
22f3fd98 | 461 | cachemgrInit(); |
a7c05555 | 462 | statInit(); |
5f3f8d0e | 463 | storeInit(); |
22f3fd98 | 464 | httpInit(); |
53ad48e6 | 465 | asnAclInitialize(Config.aclList); |
b6f794d6 | 466 | if (Config.effectiveUser) { |
234967c9 | 467 | /* we were probably started as root, so cd to a swap |
468 | * directory in case we dump core */ | |
641941c0 | 469 | if (chdir(storeSwapDir(0)) < 0) { |
a3d5953d | 470 | debug(50, 0) ("%s: %s\n", storeSwapDir(0), xstrerror()); |
234967c9 | 471 | fatal_dump("Cannot cd to swap directory?"); |
472 | } | |
473 | } | |
5f3f8d0e | 474 | /* after this point we want to see the mallinfo() output */ |
475 | do_mallinfo = 1; | |
812ed90c | 476 | mimeInit(Config.mimeTablePathname); |
603a02fd | 477 | pconnInit(); |
5f3f8d0e | 478 | } |
2285407f | 479 | serverConnectionsOpen(); |
17a0a4ee | 480 | if (theOutIcpConnection >= 0 && (!Config2.Accel.on || Config.onoff.accel_with_proxy)) |
30a4f2a8 | 481 | neighbors_open(theOutIcpConnection); |
482 | ||
dbe4fd8e | 483 | if (!configured_once) |
0a5b9b32 | 484 | writePidFile(); /* write PID file */ |
485 | ||
9fc0b4b8 | 486 | #if !(defined(_SQUID_LINUX_) && USE_ASYNC_IO) |
30a4f2a8 | 487 | squid_signal(SIGUSR1, rotate_logs, SA_RESTART); |
488 | squid_signal(SIGUSR2, sigusr2_handle, SA_RESTART); | |
9fc0b4b8 | 489 | #endif |
30a4f2a8 | 490 | squid_signal(SIGHUP, reconfigure, SA_RESTART); |
491 | squid_signal(SIGTERM, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART); | |
492 | squid_signal(SIGINT, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART); | |
b984c445 | 493 | #if ALARM_UPDATES_TIME |
97c03d3c | 494 | squid_signal(SIGALRM, time_tick, SA_RESTART); |
495 | alarm(1); | |
b984c445 | 496 | #endif |
a3d5953d | 497 | debug(1, 0) ("Ready to serve requests.\n"); |
4d7add01 | 498 | |
dbe4fd8e | 499 | if (!configured_once) { |
48f44632 | 500 | eventAdd("storeMaintain", storeMaintainSwapSpace, NULL, 1); |
501 | eventAdd("storeDirClean", storeDirClean, NULL, 15); | |
17a0a4ee | 502 | if (Config.onoff.announce) |
e924600d | 503 | eventAdd("start_announce", start_announce, NULL, 3600); |
582b6456 | 504 | eventAdd("ipcache_purgelru", ipcache_purgelru, NULL, 10); |
4d7add01 | 505 | } |
dbe4fd8e | 506 | configured_once = 1; |
2bbd722b | 507 | #ifdef SQUID_SNMP |
3265e68d | 508 | snmpInit(); |
2bbd722b | 509 | #endif |
4d64d74a | 510 | } |
511 | ||
b8d8561b | 512 | int |
513 | main(int argc, char **argv) | |
4d64d74a | 514 | { |
515 | int errcount = 0; | |
4d64d74a | 516 | int n; /* # of GC'd objects */ |
bc528c78 | 517 | time_t loop_delay; |
4d64d74a | 518 | |
88738790 | 519 | debug_log = stderr; |
e83892e9 | 520 | if (FD_SETSIZE < Squid_MaxFD) |
521 | Squid_MaxFD = FD_SETSIZE; | |
36a97e19 | 522 | |
7328e889 | 523 | /* call mallopt() before anything else */ |
0b29fe44 | 524 | #if HAVE_MALLOPT |
7328e889 | 525 | #ifdef M_GRAIN |
526 | /* Round up all sizes to a multiple of this */ | |
527 | mallopt(M_GRAIN, 16); | |
528 | #endif | |
529 | #ifdef M_MXFAST | |
530 | /* biggest size that is considered a small block */ | |
531 | mallopt(M_MXFAST, 256); | |
532 | #endif | |
533 | #ifdef M_NBLKS | |
534 | /* allocate this many small blocks at once */ | |
535 | mallopt(M_NLBLKS, 32); | |
536 | #endif | |
537 | #endif /* HAVE_MALLOPT */ | |
538 | ||
30a4f2a8 | 539 | memset(&local_addr, '\0', sizeof(struct in_addr)); |
429fdbec | 540 | safe_inet_addr(localhost, &local_addr); |
28070024 | 541 | memset(&any_addr, '\0', sizeof(struct in_addr)); |
429fdbec | 542 | safe_inet_addr("0.0.0.0", &any_addr); |
28070024 | 543 | memset(&no_addr, '\0', sizeof(struct in_addr)); |
429fdbec | 544 | safe_inet_addr("255.255.255.255", &no_addr); |
88738790 | 545 | squid_srandom(time(NULL)); |
4d64d74a | 546 | |
f2908497 | 547 | getCurrentTime(); |
548 | squid_start = current_time; | |
4d64d74a | 549 | failure_notify = fatal_dump; |
550 | ||
551 | mainParseOptions(argc, argv); | |
552 | ||
7690e8eb | 553 | /* send signal to running copy and exit */ |
554 | if (opt_send_signal != -1) { | |
555 | sendSignal(); | |
556 | /* NOTREACHED */ | |
557 | } | |
85407535 | 558 | if (opt_create_swap_dirs) { |
067bea91 | 559 | if (ConfigFile == NULL) |
560 | ConfigFile = xstrdup(DefaultConfigFile); | |
561 | cbdataInit(); | |
562 | parseConfigFile(ConfigFile); | |
563 | setEffectiveUser(); | |
564 | debug(0, 0) ("Creating Swap Directories\n"); | |
565 | storeCreateSwapDirectories(); | |
566 | return 0; | |
567 | } | |
f95b8144 | 568 | if (!opt_no_daemon) |
bbe199dc | 569 | watch_child(argv); |
4d64d74a | 570 | setMaxFD(); |
571 | ||
1758c627 | 572 | if (opt_catch_signals) |
e83892e9 | 573 | for (n = Squid_MaxFD; n > 2; n--) |
30a4f2a8 | 574 | close(n); |
4d64d74a | 575 | |
4d64d74a | 576 | /*init comm module */ |
577 | comm_init(); | |
578 | ||
579 | /* we have to init fdstat here. */ | |
5c5783a2 | 580 | fd_open(0, FD_LOG, "stdin"); |
581 | fd_open(1, FD_LOG, "stdout"); | |
582 | fd_open(2, FD_LOG, "stderr"); | |
4d64d74a | 583 | |
4d64d74a | 584 | mainInitialize(); |
585 | ||
090089c4 | 586 | /* main loop */ |
983061ed | 587 | for (;;) { |
15df8349 | 588 | if (reconfigure_pending) { |
969c39b9 | 589 | mainReconfigure(); |
590 | reconfigure_pending = 0; /* reset */ | |
15df8349 | 591 | } else if (rotate_pending) { |
e97f40f4 | 592 | icmpClose(); |
30a4f2a8 | 593 | _db_rotate_log(); /* cache.log */ |
e3ef2b09 | 594 | storeDirWriteCleanLogs(1); |
595 | storeLogRotate(); /* store.log */ | |
a4394ebd | 596 | accessLogRotate(); /* access.log */ |
b012353a | 597 | useragentRotateLog(); /* useragent.log */ |
e97f40f4 | 598 | icmpOpen(); |
30a4f2a8 | 599 | rotate_pending = 0; |
600 | } | |
48f44632 | 601 | eventRun(); |
602 | if ((loop_delay = eventNextTime()) < 0) | |
4d7add01 | 603 | loop_delay = 0; |
812ed90c | 604 | #if HAVE_POLL |
605 | switch (comm_poll(loop_delay)) { | |
606 | #else | |
9ca89c5a | 607 | switch (comm_select(loop_delay)) { |
812ed90c | 608 | #endif |
090089c4 | 609 | case COMM_OK: |
234967c9 | 610 | errcount = 0; /* reset if successful */ |
090089c4 | 611 | break; |
612 | case COMM_ERROR: | |
613 | errcount++; | |
a3d5953d | 614 | debug(1, 0) ("Select loop Error. Retry %d\n", errcount); |
090089c4 | 615 | if (errcount == 10) |
4d64d74a | 616 | fatal_dump("Select Loop failed!"); |
090089c4 | 617 | break; |
4d64d74a | 618 | case COMM_SHUTDOWN: |
43030d00 | 619 | /* delayed close so we can transmit while shutdown pending */ |
17e6c0a1 | 620 | icpConnectionClose(); |
d84eba42 | 621 | #ifdef SQUID_SNMP |
17e6c0a1 | 622 | snmpConnectionClose(); |
d84eba42 | 623 | #endif |
5f3f8d0e | 624 | if (shutdown_pending) { |
625 | normal_shutdown(); | |
15df8349 | 626 | #if 0 |
dbe4fd8e | 627 | } else if (reconfigure_pending) { |
628 | mainReconfigure(); | |
629 | reconfigure_pending = 0; /* reset */ | |
15df8349 | 630 | #endif |
5f3f8d0e | 631 | } else { |
632 | fatal_dump("MAIN: SHUTDOWN from comm_select, but nothing pending."); | |
633 | } | |
0ffd22bc | 634 | break; |
9ca89c5a | 635 | case COMM_TIMEOUT: |
6c93e119 | 636 | break; |
090089c4 | 637 | default: |
6eb42cae | 638 | fatal_dump("MAIN: Internal error -- this should never happen."); |
090089c4 | 639 | break; |
640 | } | |
641 | } | |
642 | /* NOTREACHED */ | |
983061ed | 643 | return 0; |
090089c4 | 644 | } |
7690e8eb | 645 | |
b8d8561b | 646 | static void |
0673c0ba | 647 | sendSignal(void) |
7690e8eb | 648 | { |
ff8d0ea6 | 649 | pid_t pid; |
fedac7e5 | 650 | debug_log = stderr; |
651 | if (ConfigFile == NULL) | |
652 | ConfigFile = xstrdup(DefaultConfigFile); | |
1b635117 | 653 | cbdataInit(); |
fedac7e5 | 654 | parseConfigFile(ConfigFile); |
655 | pid = readPidFile(); | |
656 | if (pid > 1) { | |
657 | if (kill(pid, opt_send_signal) && | |
658 | /* ignore permissions if just running check */ | |
659 | !(opt_send_signal == 0 && errno == EPERM)) { | |
660 | fprintf(stderr, "%s: ERROR: Could not send ", appname); | |
661 | fprintf(stderr, "signal %d to process %d: %s\n", | |
41d30aa8 | 662 | opt_send_signal, (int) pid, xstrerror()); |
7690e8eb | 663 | exit(1); |
664 | } | |
fedac7e5 | 665 | } else { |
666 | fprintf(stderr, "%s: ERROR: No running copy\n", appname); | |
667 | exit(1); | |
7690e8eb | 668 | } |
fedac7e5 | 669 | /* signal successfully sent */ |
670 | exit(0); | |
671 | } | |
f95b8144 | 672 | |
673 | static void | |
bbe199dc | 674 | watch_child(char *argv[]) |
f95b8144 | 675 | { |
676 | char *prog; | |
f95b8144 | 677 | int failcount = 0; |
678 | time_t start; | |
679 | time_t stop; | |
680 | #ifdef _SQUID_NEXT_ | |
681 | union wait status; | |
682 | #else | |
683 | int status; | |
684 | #endif | |
e3a3b845 | 685 | pid_t pid; |
f95b8144 | 686 | if (*(argv[0]) == '(') |
687 | return; | |
688 | for (;;) { | |
689 | if (fork() == 0) { | |
690 | /* child */ | |
691 | prog = xstrdup(argv[0]); | |
bbe199dc | 692 | argv[0] = xstrdup("(squid)"); |
693 | execvp(prog, argv); | |
694 | fatal("execvp failed"); | |
f95b8144 | 695 | } |
696 | /* parent */ | |
697 | time(&start); | |
e3a3b845 | 698 | do { |
0fb4fc71 | 699 | squid_signal(SIGINT, SIG_IGN, SA_RESTART); |
f95b8144 | 700 | #ifdef _SQUID_NEXT_ |
e3a3b845 | 701 | pid = wait3(&status, 0, NULL); |
f95b8144 | 702 | #else |
e3a3b845 | 703 | pid = waitpid(-1, &status, 0); |
f95b8144 | 704 | #endif |
e3a3b845 | 705 | } while (pid > 0); |
f95b8144 | 706 | time(&stop); |
707 | if (stop - start < 10) | |
708 | failcount++; | |
a8e69881 | 709 | else |
710 | failcount = 0; | |
f95b8144 | 711 | if (failcount == 5) |
712 | exit(1); | |
f95b8144 | 713 | if (WIFEXITED(status)) |
714 | if (WEXITSTATUS(status) == 0) | |
715 | exit(0); | |
0fb4fc71 | 716 | squid_signal(SIGINT, SIG_DFL, SA_RESTART); |
f95b8144 | 717 | sleep(3); |
718 | } | |
bbe199dc | 719 | /* NOTREACHED */ |
f95b8144 | 720 | } |
fff6ad65 | 721 | |
9ec1a1dc | 722 | static void |
fff6ad65 | 723 | normal_shutdown(void) |
724 | { | |
725 | debug(1, 1) ("Shutting down...\n"); | |
726 | if (Config.pidFilename && strcmp(Config.pidFilename, "none")) { | |
727 | enter_suid(); | |
728 | safeunlink(Config.pidFilename, 0); | |
729 | leave_suid(); | |
730 | } | |
731 | releaseServerSockets(); | |
732 | unlinkdClose(); | |
733 | storeDirWriteCleanLogs(0); | |
734 | PrintRusage(); | |
735 | dumpMallocStats(); | |
736 | storeLogClose(); | |
737 | accessLogClose(); | |
33ab18e8 | 738 | #if PURIFY || XMALLOC_TRACE |
fff6ad65 | 739 | configFreeMemory(); |
740 | storeFreeMemory(); | |
741 | dnsFreeMemory(); | |
742 | redirectFreeMemory(); | |
33ab18e8 | 743 | /*stmemFreeMemory(); */ |
fff6ad65 | 744 | netdbFreeMemory(); |
745 | ipcacheFreeMemory(); | |
746 | fqdncacheFreeMemory(); | |
747 | asnFreeMemory(); | |
7021844c | 748 | httpHeaderCleanModule(); |
fff6ad65 | 749 | #endif |
33ab18e8 | 750 | #if WHY_DO_THIS |
fff6ad65 | 751 | file_close(0); |
752 | file_close(1); | |
753 | file_close(2); | |
33ab18e8 | 754 | #endif |
fff6ad65 | 755 | fdDumpOpen(); |
756 | fdFreeMemory(); | |
7021844c | 757 | memClean(); |
33ab18e8 | 758 | #if XMALLOC_TRACE |
759 | { | |
760 | extern int xmalloc_total; | |
761 | extern void xmalloc_find_leaks(void); | |
33ab18e8 | 762 | xmalloc_find_leaks(); |
33ab18e8 | 763 | debug(1, 0) ("Memory used after shutdown: %d\n", xmalloc_total); |
764 | } | |
765 | #endif | |
36a97e19 | 766 | #if MEM_GEN_TRACE |
767 | log_trace_done(); | |
768 | #endif | |
769 | ||
fff6ad65 | 770 | debug(1, 0) ("Squid Cache (Version %s): Exiting normally.\n", |
771 | version_string); | |
772 | fclose(debug_log); | |
773 | exit(0); | |
774 | } |