main.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 01 Startup and Main Loop */
10 
11 #include "squid.h"
12 #include "AccessLogEntry.h"
13 //#include "acl/Acl.h"
14 #include "acl/Asn.h"
15 #include "acl/forward.h"
16 #include "anyp/UriScheme.h"
17 #include "auth/Config.h"
18 #include "auth/Gadgets.h"
19 #include "AuthReg.h"
20 #include "base/RunnersRegistry.h"
21 #include "base/Subscription.h"
22 #include "base/TextException.h"
23 #include "cache_cf.h"
24 #include "CachePeer.h"
25 #include "carp.h"
26 #include "client_db.h"
27 #include "client_side.h"
28 #include "comm.h"
29 #include "CommandLine.h"
30 #include "ConfigParser.h"
31 #include "CpuAffinity.h"
32 #include "debug/Messages.h"
33 #include "DiskIO/DiskIOModule.h"
34 #include "dns/forward.h"
35 #include "errorpage.h"
36 #include "event.h"
37 #include "EventLoop.h"
38 #include "ExternalACL.h"
39 #include "fd.h"
40 #include "format/Token.h"
41 #include "fqdncache.h"
42 #include "fs/Module.h"
43 #include "fs_io.h"
44 #include "FwdState.h"
45 #include "globals.h"
46 #include "htcp.h"
47 #include "http/Stream.h"
48 #include "HttpHeader.h"
49 #include "HttpReply.h"
50 #include "icmp/IcmpSquid.h"
51 #include "icmp/net_db.h"
52 #include "ICP.h"
53 #include "Instance.h"
54 #include "ip/tools.h"
55 #include "ipc/Coordinator.h"
56 #include "ipc/Kids.h"
57 #include "ipc/Strand.h"
58 #include "ipcache.h"
59 #include "mime.h"
60 #include "neighbors.h"
61 #include "parser/Tokenizer.h"
62 #include "Parsing.h"
63 #include "pconn.h"
64 #include "peer_sourcehash.h"
65 #include "peer_userhash.h"
66 #include "PeerSelectState.h"
67 #include "protos.h"
68 #include "redirect.h"
69 #include "refresh.h"
70 #include "sbuf/Stream.h"
71 #include "SBufStatsAction.h"
72 #include "send-announce.h"
73 #include "SquidConfig.h"
74 #include "stat.h"
75 #include "StatCounters.h"
76 #include "Store.h"
77 #include "store/Disks.h"
78 #include "store_log.h"
79 #include "StoreFileSystem.h"
80 #include "time/Engine.h"
81 #include "tools.h"
82 #include "unlinkd.h"
83 #include "wccp.h"
84 #include "wccp2.h"
85 #include "WinSvc.h"
86 
87 #if USE_ADAPTATION
88 #include "adaptation/Config.h"
89 #endif
90 #if USE_ECAP
91 #include "adaptation/ecap/Config.h"
92 #endif
93 #if ICAP_CLIENT
94 #include "adaptation/icap/Config.h"
96 #endif
97 #if USE_DELAY_POOLS
98 #include "ClientDelayConfig.h"
99 #endif
100 #if USE_DELAY_POOLS
101 #include "DelayPools.h"
102 #endif
103 #if USE_LOADABLE_MODULES
104 #include "LoadableModules.h"
105 #endif
106 #if USE_OPENSSL
107 #include "ssl/context_storage.h"
108 #include "ssl/helper.h"
109 #endif
110 #if ICAP_CLIENT
111 #include "adaptation/icap/Config.h"
112 #endif
113 #if USE_ECAP
114 #include "adaptation/ecap/Config.h"
115 #endif
116 #if USE_ADAPTATION
117 #include "adaptation/Config.h"
118 #endif
119 #if SQUID_SNMP
120 #include "snmp_core.h"
121 #endif
122 
123 #include <cerrno>
124 #if HAVE_GETOPT_H
125 #include <getopt.h>
126 #endif
127 #if HAVE_PATHS_H
128 #include <paths.h>
129 #endif
130 #if HAVE_SYS_WAIT_H
131 #include <sys/wait.h>
132 #endif
133 
134 #if USE_WIN32_SERVICE
135 #include <process.h>
136 
139 static int opt_command_line = FALSE;
140 void WIN32_svcstatusupdate(DWORD, DWORD);
141 void WINAPI WIN32_svcHandler(DWORD);
142 #endif
143 
145 static char *opt_syslog_facility = NULL;
146 static int icpPortNumOverride = 1; /* Want to detect "-u 0" */
147 static int configured_once = 0;
148 #if MALLOC_DBG
149 static int malloc_debug_level = 0;
150 #endif
151 static volatile int do_reconfigure = 0;
152 static volatile int do_rotate = 0;
153 static volatile int do_shutdown = 0;
154 static volatile int do_revive_kids = 0;
155 static volatile int shutdown_status = EXIT_SUCCESS;
156 static volatile int do_handle_stopped_child = 0;
157 
158 static int RotateSignal = -1;
159 static int ReconfigureSignal = -1;
160 static int ShutdownSignal = -1;
161 static int ReviveKidsSignal = -1;
162 
163 static void mainRotate(void);
164 static void mainReconfigureStart(void);
165 static void mainReconfigureFinish(void*);
166 static void mainInitialize(void);
167 static void usage(void);
168 static void mainHandleCommandLineOption(const int optId, const char *optValue);
169 static void sendSignal(void);
170 static void serverConnectionsOpen(void);
171 static void serverConnectionsClose(void);
172 static void watch_child(const CommandLine &);
173 static void setEffectiveUser(void);
174 static void SquidShutdown(void);
175 static void mainSetCwd(void);
176 
177 #if !_SQUID_WINDOWS_
178 static const char *squid_start_script = "squid_start";
179 #endif
180 
181 #if TEST_ACCESS
182 #include "test_access.c"
183 #endif
184 
188 {
189 
190 public:
191  int checkEvents(int) {
192  Store::Root().callback();
193  return EVENT_IDLE;
194  };
195 };
196 
198 {
199 
200 public:
201 #if KILL_PARENT_OPT
202  SignalEngine(): parentKillNotified(false) {
203  parentPid = getppid();
204  }
205 #endif
206 
207  virtual int checkEvents(int timeout);
208 
209 private:
210  static void StopEventLoop(void *) {
211  if (EventLoop::Running)
213  }
214 
215  static void FinalShutdownRunners(void *) {
217 
218  // XXX: this should be a Runner.
219 #if USE_AUTH
220  /* detach the auth components (only do this on full shutdown) */
222 #endif
223 
224  eventAdd("SquidTerminate", &StopEventLoop, NULL, 0, 1, false);
225  }
226 
227  void doShutdown(time_t wait);
228  void handleStoppedChild();
229 
230 #if KILL_PARENT_OPT
231  bool parentKillNotified;
232  pid_t parentPid;
233 #endif
234 };
235 
236 int
238 {
239  if (do_reconfigure)
241  else if (do_rotate)
242  mainRotate();
243  else if (do_shutdown)
247  return EVENT_IDLE;
248 }
249 
252 static bool
253 AvoidSignalAction(const char *description, volatile int &signalVar)
254 {
255  const char *avoiding = "delaying";
256  const char *currentEvent = "none";
257  if (shutting_down) {
258  currentEvent = "shutdown";
259  avoiding = "canceling";
260  // do not avoid repeated shutdown signals
261  // which just means the user wants to skip/abort shutdown timeouts
262  if (strcmp(currentEvent, description) == 0)
263  return false;
264  signalVar = 0;
265  }
266  else if (!configured_once)
267  currentEvent = "startup";
268  else if (reconfiguring)
269  currentEvent = "reconfiguration";
270  else {
271  signalVar = 0;
272  return false; // do not avoid (i.e., execute immediately)
273  // the caller may produce a signal-specific debugging message
274  }
275 
276  debugs(1, DBG_IMPORTANT, avoiding << ' ' << description <<
277  " request during " << currentEvent);
278  return true;
279 }
280 
281 void
283 {
284  if (AvoidSignalAction("shutdown", do_shutdown))
285  return;
286 
287  debugs(1, Important(2), "Preparing for shutdown after " << statCounter.client_http.requests << " requests");
288  debugs(1, Important(3), "Waiting " << wait << " seconds for active connections to finish");
289 
290 #if KILL_PARENT_OPT
291  if (!IamMasterProcess() && !parentKillNotified && ShutdownSignal > 0 && parentPid > 1) {
292  debugs(1, DBG_IMPORTANT, "Killing master process, pid " << parentPid);
293  if (kill(parentPid, ShutdownSignal) < 0) {
294  int xerrno = errno;
295  debugs(1, DBG_IMPORTANT, "kill " << parentPid << ": " << xstrerr(xerrno));
296  }
297  parentKillNotified = true;
298  }
299 #endif
300 
301  if (shutting_down) {
302 #if !KILL_PARENT_OPT
303  // Already a shutdown signal has received and shutdown is in progress.
304  // Shutdown as soon as possible.
305  wait = 0;
306 #endif
307  } else {
308  shutting_down = 1;
309 
310  /* run the closure code which can be shared with reconfigure */
312 
314  }
315 
316 #if USE_WIN32_SERVICE
317  WIN32_svcstatusupdate(SERVICE_STOP_PENDING, (wait + 1) * 1000);
318 #endif
319 
320  eventAdd("SquidShutdown", &FinalShutdownRunners, this, (double) (wait + 1), 1, false);
321 }
322 
323 void
325 {
326  // no AvoidSignalAction() call: This code can run at any time because it
327  // does not depend on Squid state. It does not need debugging because it
328  // handles an "internal" signal, not an external/admin command.
330 #if !_SQUID_WINDOWS_
331  PidStatus status;
332  pid_t pid;
333 
334  do {
335  pid = WaitForAnyPid(status, WNOHANG);
336 
337 #if HAVE_SIGACTION
338 
339  } while (pid > 0);
340 
341 #else
342 
343  }
344  while (pid > 0 || (pid < 0 && errno == EINTR));
345 #endif
346 #endif
347 }
348 
349 static void
350 usage(void)
351 {
352  fprintf(stderr,
353  "Usage: %s [-cdzCFNRVYX] [-n name] [-s | -l facility] [-f config-file] [-[au] port] [-k signal]"
354 #if USE_WIN32_SERVICE
355  "[-ir] [-O CommandLine]"
356 #endif
357  "\n"
358  " -h | --help Print help message.\n"
359  " -v | --version Print version details.\n"
360  "\n"
361  " -a port Specify HTTP port number (default: %d).\n"
362  " -d level Write debugging to stderr also.\n"
363  " -f file Use given config-file instead of\n"
364  " %s\n"
365 #if USE_WIN32_SERVICE
366  " -i Installs as a Windows Service (see -n option).\n"
367 #endif
368  " -k reconfigure|rotate|shutdown|"
369 #ifdef SIGTTIN
370  "restart|"
371 #endif
372  "interrupt|kill|debug|check|parse\n"
373  " Parse configuration file, then send signal to \n"
374  " running copy (except -k parse) and exit.\n"
375  " -n name Specify service name to use for service operations\n"
376  " default is: " APP_SHORTNAME ".\n"
377 #if USE_WIN32_SERVICE
378  " -r Removes a Windows Service (see -n option).\n"
379 #endif
380  " -s | -l facility\n"
381  " Enable logging to syslog.\n"
382  " -u port Specify ICP port number (default: %d), disable with 0.\n"
383  " -z Create missing swap directories and then exit.\n"
384  " -C Do not catch fatal signals.\n"
385  " -D OBSOLETE. Scheduled for removal.\n"
386  " -F Don't serve any requests until store is rebuilt.\n"
387  " -N Master process runs in foreground and is a worker. No kids.\n"
388  " --foreground\n"
389  " Master process runs in foreground and creates worker kids.\n"
390  " --kid role-ID\n"
391  " Play a given SMP kid process role, with a given ID. Do not use\n"
392  " this option. It is meant for the master process use only.\n"
393 #if USE_WIN32_SERVICE
394  " -O options\n"
395  " Set Windows Service Command line options in Registry.\n"
396 #endif
397  " -R Do not set REUSEADDR on port.\n"
398  " -S Double-check swap during rebuild.\n"
399  " -X Force full debugging.\n"
400  " Add -d9 to also write full debugging to stderr.\n"
401  " -Y Only return UDP_HIT or UDP_MISS_NOFETCH during fast reload.\n",
402  APP_SHORTNAME, CACHE_HTTP_PORT, DEFAULT_CONFIG_FILE, CACHE_ICP_PORT);
403  exit(EXIT_FAILURE);
404 }
405 
407 enum {
408  // The absolute values do not matter except that the following values should
409  // not be used: Values below 2 are for special getopt_long(3) use cases, and
410  // values in the [33,126] range are reserved for short options (-x).
412  optKid
413 };
414 
415 // short options
416 // TODO: consider prefixing with ':' for better logging
417 // (distinguish missing required argument cases)
418 static const char *shortOpStr =
419 #if USE_WIN32_SERVICE
420  "O:Vir"
421 #endif
422  "CDFNRSYXa:d:f:hk:m::n:sl:u:vz?";
423 
424 // long options
425 static struct option squidOptions[] = {
426  {"foreground", no_argument, 0, optForeground},
427  {"kid", required_argument, 0, optKid},
428  {"help", no_argument, 0, 'h'},
429  {"version", no_argument, 0, 'v'},
430  {0, 0, 0, 0}
431 };
432 
433 // handle a command line parameter
434 static void
435 mainHandleCommandLineOption(const int optId, const char *optValue)
436 {
437  switch (optId) {
438 
439  case 'C':
442  opt_catch_signals = 0;
443  break;
444 
445  case 'D':
448  debugs(1,DBG_CRITICAL, "WARNING: -D command-line option is obsolete.");
449  break;
450 
451  case 'F':
455  break;
456 
457  case 'N':
460  opt_no_daemon = 1;
461  break;
462 
463 #if USE_WIN32_SERVICE
464 
465  case 'O':
468  opt_command_line = 1;
469  WIN32_Command_Line = xstrdup(optValue);
470  break;
471 #endif
472 
473  case 'R':
476  opt_reuseaddr = 0;
477  break;
478 
479  case 'S':
483  break;
484 
485  case 'X':
488  Debug::parseOptions("rotate=0 ALL,9");
489  Debug::override_X = 1;
490  sigusr2_handle(SIGUSR2);
491  break;
492 
493  case 'Y':
497  break;
498 
499 #if USE_WIN32_SERVICE
500 
501  case 'i':
505  break;
506 #endif
507 
508  case 'a':
509  {
512  char *port = xstrdup(optValue);
513  // use a copy to avoid optValue modification
515  xfree(port);
516  break;
517  }
518 
519  case 'd':
523  Debug::ResetStderrLevel(xatoi(optValue));
524  break;
525 
526  case 'f':
529  xfree(ConfigFile);
530  ConfigFile = xstrdup(optValue);
531  break;
532 
533  case 'k':
538  if (!optValue || strlen(optValue) < 1)
539  usage();
540 
541  else if (!strncmp(optValue, "reconfigure", strlen(optValue)))
543  opt_send_signal = SIGHUP;
544  else if (!strncmp(optValue, "rotate", strlen(optValue)))
546 #if defined(_SQUID_LINUX_THREADS_)
547  opt_send_signal = SIGQUIT;
548 #else
549  opt_send_signal = SIGUSR1;
550 #endif
551 
552  else if (!strncmp(optValue, "debug", strlen(optValue)))
554 #if defined(_SQUID_LINUX_THREADS_)
555  opt_send_signal = SIGTRAP;
556 #else
557  opt_send_signal = SIGUSR2;
558 #endif
559 
560  else if (!strncmp(optValue, "shutdown", strlen(optValue)))
562  opt_send_signal = SIGTERM;
563  else if (!strncmp(optValue, "interrupt", strlen(optValue)))
565  opt_send_signal = SIGINT;
566  else if (!strncmp(optValue, "kill", strlen(optValue)))
567  // XXX: In SMP mode, uncatchable SIGKILL only kills the master process
569  opt_send_signal = SIGKILL;
570 
571 #ifdef SIGTTIN
572 
573  else if (!strncmp(optValue, "restart", strlen(optValue)))
575  opt_send_signal = SIGTTIN;
576 
577 #endif
578 
579  else if (!strncmp(optValue, "check", strlen(optValue)))
581  opt_send_signal = 0; /* SIGNULL */
582  else if (!strncmp(optValue, "parse", strlen(optValue)))
584  opt_parse_cfg_only = 1;
585  else
586  usage();
587 
588  // Cannot use cache.log: use stderr for important messages (by default)
589  // and stop expecting a Debug::UseCacheLog() call.
592  break;
593 
594  case 'm':
598  if (optValue) {
599 #if MALLOC_DBG
600  malloc_debug_level = xatoi(optValue);
601 #else
602  fatal("Need to add -DMALLOC_DBG when compiling to use -mX option");
603 #endif
604 
605  }
606  break;
607 
608  case 'n':
612  if (optValue && *optValue != '\0') {
613  const SBuf t(optValue);
616  if (!tok.prefix(service_name, chr))
617  fatalf("Expected alphanumeric service name for the -n option but got: %s", optValue);
618  if (!tok.atEnd())
619  fatalf("Garbage after alphanumeric service name in the -n option value: %s", optValue);
620  if (service_name.length() > 32)
621  fatalf("Service name (-n option) must be limited to 32 characters but got %u", service_name.length());
622  opt_signal_service = true;
623  } else {
624  fatal("A service name is required for the -n option");
625  }
626  break;
627 
628 #if USE_WIN32_SERVICE
629 
630  case 'r':
634 
635  break;
636 
637 #endif
638 
639  case 'l':
643  xfree(opt_syslog_facility); // ignore any previous options sent
644  opt_syslog_facility = xstrdup(optValue);
646  break;
647 
648  case 's':
652  break;
653 
654  case 'u':
658  icpPortNumOverride = atoi(optValue);
659 
660  if (icpPortNumOverride < 0)
661  icpPortNumOverride = 0;
662 
663  break;
664 
665  case 'v':
668  printf("Squid Cache: Version %s\n",version_string);
669  printf("Service Name: " SQUIDSBUFPH "\n", SQUIDSBUFPRINT(service_name));
670  if (strlen(SQUID_BUILD_INFO))
671  printf("%s\n",SQUID_BUILD_INFO);
672 #if USE_OPENSSL
673  printf("\nThis binary uses %s. ", OpenSSL_version(OPENSSL_VERSION));
674  printf("For legal restrictions on distribution see https://www.openssl.org/source/license.html\n\n");
675 #endif
676  printf( "configure options: %s\n", SQUID_CONFIGURE_OPTIONS);
677 
678 #if USE_WIN32_SERVICE
679 
680  printf("Compiled as Windows System Service.\n");
681 
682 #endif
683 
684  exit(EXIT_SUCCESS);
685 
686  /* NOTREACHED */
687 
688  case 'z':
692  // We will use cache.log, but this command is often executed on the
693  // command line, so use stderr to show important messages (by default).
694  // TODO: Generalize/fix this -z-specific and sometimes faulty logic with
695  // "use stderr when it is a tty [until we GoIntoBackground()]" logic.
697  break;
698 
699  case optForeground:
702  opt_foreground = 1;
703  break;
704 
705  case optKid:
706  // already processed in ConfigureCurrentKid()
707  break;
708 
709  case 'h':
710 
711  case '?':
712 
713  default:
716  usage();
717 
718  break;
719  }
720 }
721 
722 /* ARGSUSED */
723 void
724 rotate_logs(int sig)
725 {
726  do_rotate = 1;
727  RotateSignal = sig;
728 #if !_SQUID_WINDOWS_
729 #if !HAVE_SIGACTION
730 
731  signal(sig, rotate_logs);
732 #endif
733 #endif
734 }
735 
736 /* ARGSUSED */
737 void
738 reconfigure(int sig)
739 {
740  do_reconfigure = 1;
741  ReconfigureSignal = sig;
742 #if !_SQUID_WINDOWS_
743 #if !HAVE_SIGACTION
744 
745  signal(sig, reconfigure);
746 #endif
747 #endif
748 }
749 
750 static void
752 {
753  ReviveKidsSignal = sig;
754  do_revive_kids = true;
755 
756 #if !_SQUID_WINDOWS_
757 #if !HAVE_SIGACTION
758  signal(sig, master_revive_kids);
759 #endif
760 #endif
761 }
762 
764 static void
766 {
767  do_shutdown = 1;
768  ShutdownSignal = sig;
769 
770 #if !_SQUID_WINDOWS_
771 #if !HAVE_SIGACTION
772  signal(sig, master_shutdown);
773 #endif
774 #endif
775 
776 }
777 
778 void
779 shut_down(int sig)
780 {
781  do_shutdown = sig == SIGINT ? -1 : 1;
782  ShutdownSignal = sig;
783 #if defined(SIGTTIN)
784  if (SIGTTIN == sig)
785  shutdown_status = EXIT_FAILURE;
786 #endif
787 
788 #if !defined(_SQUID_WINDOWS_) && !defined(HAVE_SIGACTION)
789  signal(sig, shut_down);
790 #endif
791 }
792 
793 void
794 sig_child(int sig)
795 {
797 
798 #if !defined(_SQUID_WINDOWS_) && !defined(HAVE_SIGACTION)
799  signal(sig, sig_child);
800 #else
801  (void)sig;
802 #endif
803 }
804 
805 static void
807 {
808  if (IamPrimaryProcess()) {
809 #if USE_WCCP
811 #endif
812 
813 #if USE_WCCPv2
814 
816 #endif
817  }
818  // start various proxying services if we are responsible for them
819  if (IamWorkerProcess()) {
821  icpOpenPorts();
822 #if USE_HTCP
823  htcpOpenPorts();
824 #endif
825 #if SQUID_SNMP
826  snmpOpenPorts();
827 #endif
828 
829  icmpEngine.Open();
830  netdbInit();
831  asnInit();
832  ACL::Initialize();
833  peerSelectInit();
834 
835  carpInit();
836 #if USE_AUTH
838 #endif
840  }
841 }
842 
843 static void
845 {
847 
848  if (IamPrimaryProcess()) {
849 #if USE_WCCP
850 
852 #endif
853 #if USE_WCCPv2
854 
856 #endif
857  }
858  if (IamWorkerProcess()) {
861 #if USE_HTCP
863 #endif
864 
865  icmpEngine.Close();
866 #if SQUID_SNMP
867  snmpClosePorts();
868 #endif
869 
870  asnFreeMemory();
871  }
872 }
873 
874 static void
876 {
877  if (AvoidSignalAction("reconfiguration", do_reconfigure))
878  return;
879 
880  debugs(1, DBG_IMPORTANT, "Reconfiguring Squid Cache (version " << version_string << ")...");
881  reconfiguring = 1;
882 
884 
885  // Initiate asynchronous closing sequence
887  icpClosePorts();
888 #if USE_HTCP
889  htcpClosePorts();
890 #endif
891 #if USE_OPENSSL
893 #endif
894 #if USE_AUTH
896 #endif
899  storeLogClose();
900  accessLogClose();
901 #if ICAP_CLIENT
902  icapLogClose();
903 #endif
905 
906  eventAdd("mainReconfigureFinish", &mainReconfigureFinish, NULL, 0, 1,
907  false);
908 }
909 
910 static void
912 {
913  debugs(1, 3, "finishing reconfiguring");
914 
915  errorClean();
916  enter_suid(); /* root to read config file */
917 
918  // we may have disabled the need for PURGE
921 
922  // parse the config returns a count of errors encountered.
923  const int oldWorkers = Config.workers;
924  try {
925  if (parseConfigFile(ConfigFile) != 0) {
926  // for now any errors are a fatal condition...
927  self_destruct();
928  }
929  } catch (...) {
930  // for now any errors are a fatal condition...
931  debugs(1, DBG_CRITICAL, "FATAL: Unhandled exception parsing config file. " <<
932  " Run squid -k parse and check for errors.");
933  self_destruct();
934  }
935 
936  if (oldWorkers != Config.workers) {
937  debugs(1, DBG_CRITICAL, "WARNING: Changing 'workers' (from " <<
938  oldWorkers << " to " << Config.workers <<
939  ") requires a full restart. It has been ignored by reconfigure.");
940  Config.workers = oldWorkers;
941  }
942 
944 
945  if (IamPrimaryProcess())
948 
950  Mem::Report();
953  ipcache_restart(); /* clear stuck entries */
954  fqdncache_restart(); /* sigh, fqdncache too */
955  parseEtcHosts();
956  errorInitialize(); /* reload error pages */
957  accessLogInit();
958 
959 #if USE_LOADABLE_MODULES
961 #endif
962 
963 #if USE_ADAPTATION
964  bool enableAdaptation = false;
965 #if ICAP_CLIENT
967  enableAdaptation = Adaptation::Icap::TheConfig.onoff || enableAdaptation;
968 #endif
969 #if USE_ECAP
970  Adaptation::Ecap::TheConfig.finalize(); // must be after we load modules
971  enableAdaptation = Adaptation::Ecap::TheConfig.onoff || enableAdaptation;
972 #endif
973  Adaptation::Config::Finalize(enableAdaptation);
974 #endif
975 
977 #if ICAP_CLIENT
978  icapLogOpen();
979 #endif
980  storeLogOpen();
981  Dns::Init();
982 #if USE_SSL_CRTD
984 #endif
985 #if USE_OPENSSL
987 #endif
988 
990 #if USE_AUTH
992 #endif
993  externalAclInit();
994 
995  if (IamPrimaryProcess()) {
996 #if USE_WCCP
997 
998  wccpInit();
999 #endif
1000 #if USE_WCCPv2
1001 
1002  wccp2Init();
1003 #endif
1004  }
1005 
1007 
1008  neighbors_init();
1009 
1011 
1013 
1014  if (unlinkdNeeded())
1015  unlinkdInit();
1016 
1017 #if USE_DELAY_POOLS
1019 #endif
1020 
1021  if (Config.onoff.announce) {
1022  if (!eventFind(start_announce, NULL))
1023  eventAdd("start_announce", start_announce, NULL, 3600.0, 1);
1024  } else {
1027  }
1028 
1029  reconfiguring = 0;
1030 }
1031 
1032 static void
1034 {
1035  if (AvoidSignalAction("log rotation", do_rotate))
1036  return;
1037 
1038  icmpEngine.Close();
1039  redirectShutdown();
1040 #if USE_AUTH
1042 #endif
1044 
1045  _db_rotate_log(); /* cache.log */
1047  storeLogRotate(); /* store.log */
1048  accessLogRotate(); /* access.log */
1050 #if ICAP_CLIENT
1051  icapLogRotate(); /*icap.log*/
1052 #endif
1053  icmpEngine.Open();
1054  redirectInit();
1055 #if USE_AUTH
1057 #endif
1058  externalAclInit();
1059 }
1060 
1061 static void
1063 {
1064  keepCapabilities();
1065  leave_suid(); /* Run as non privilegied user */
1066 #if _SQUID_OS2_
1067 
1068  return;
1069 #endif
1070 
1071  if (geteuid() == 0) {
1072  debugs(0, DBG_CRITICAL, "Squid is not safe to run as root! If you must");
1073  debugs(0, DBG_CRITICAL, "start Squid as root, then you must configure");
1074  debugs(0, DBG_CRITICAL, "it to run as a non-priveledged user with the");
1075  debugs(0, DBG_CRITICAL, "'cache_effective_user' option in the config file.");
1076  fatal("Don't run Squid as root, set 'cache_effective_user'!");
1077  }
1078 }
1079 
1081 static bool
1082 mainChangeDir(const char *dir)
1083 {
1084  if (chdir(dir) == 0)
1085  return true;
1086 
1087  int xerrno = errno;
1088  debugs(50, DBG_CRITICAL, "ERROR: cannot change current directory to " << dir <<
1089  ": " << xstrerr(xerrno));
1090  return false;
1091 }
1092 
1095 bool Chrooted = false;
1096 
1098 static void
1100 {
1101  if (Config.chroot_dir && !Chrooted) {
1102  Chrooted = true;
1103 
1104  if (chroot(Config.chroot_dir) != 0) {
1105  int xerrno = errno;
1106  fatalf("chroot to %s failed: %s", Config.chroot_dir, xstrerr(xerrno));
1107  }
1108 
1109  if (!mainChangeDir("/"))
1110  fatalf("chdir to / after chroot to %s failed", Config.chroot_dir);
1111  }
1112 
1113  if (Config.coredump_dir && strcmp("none", Config.coredump_dir) != 0) {
1115  debugs(0, Important(4), "Set Current Directory to " << Config.coredump_dir);
1116  return;
1117  }
1118  }
1119 
1120  /* If we don't have coredump_dir or couldn't cd there, report current dir */
1121  char pathbuf[MAXPATHLEN];
1122  if (getcwd(pathbuf, MAXPATHLEN)) {
1123  debugs(0, DBG_IMPORTANT, "Current Directory is " << pathbuf);
1124  } else {
1125  int xerrno = errno;
1126  debugs(50, DBG_CRITICAL, "WARNING: Can't find current directory, getcwd: " << xstrerr(xerrno));
1127  }
1128 }
1129 
1130 static void
1132 {
1133  if (opt_catch_signals) {
1136  }
1137 
1138  squid_signal(SIGPIPE, SIG_IGN, SA_RESTART);
1141 
1142  setEffectiveUser();
1143 
1144  if (icpPortNumOverride != 1)
1145  Config.Port.icp = (unsigned short) icpPortNumOverride;
1146 
1147  debugs(1, DBG_CRITICAL, "Starting Squid Cache version " << version_string << " for " << CONFIG_HOST_TYPE << "...");
1148  debugs(1, Critical(5), "Service Name: " << service_name);
1149 
1150 #if _SQUID_WINDOWS_
1151  if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
1152  debugs(1, DBG_CRITICAL, "Service command line is: " << WIN32_Service_Command_Line);
1153  } else
1154  debugs(1, DBG_CRITICAL, "Running on " << WIN32_OS_string);
1155 #endif
1156 
1157  debugs(1, Important(6), "Process ID " << getpid());
1158 
1159  debugs(1, Important(7), "Process Roles:" << ProcessRoles());
1160 
1161  setSystemLimits();
1162  debugs(1, Important(8), "With " << Squid_MaxFD << " file descriptors available");
1163 
1164 #if _SQUID_WINDOWS_
1165 
1166  debugs(1, DBG_IMPORTANT, "With " << _getmaxstdio() << " CRT stdio descriptors available");
1167 
1168  if (WIN32_Socks_initialized)
1169  debugs(1, DBG_IMPORTANT, "Windows sockets initialized");
1170 
1171  if (WIN32_OS_version > _WIN_OS_WINNT) {
1173  }
1174 
1175 #endif
1176 
1177  ipcache_init();
1178 
1179  fqdncache_init();
1180 
1181  parseEtcHosts();
1182 
1183  Dns::Init();
1184 
1185 #if USE_SSL_CRTD
1187 #endif
1188 
1189 #if USE_OPENSSL
1191 #endif
1192 
1193  redirectInit();
1194 #if USE_AUTH
1196 #endif
1197  externalAclInit();
1198 
1199  httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
1200 
1201  errorInitialize();
1202 
1203  accessLogInit();
1204 
1206 
1207 #if ICAP_CLIENT
1208  icapLogOpen();
1209 #endif
1210 
1211 #if SQUID_SNMP
1212 
1213  snmpInit();
1214 
1215 #endif
1216 #if MALLOC_DBG
1217 
1218  malloc_debug(0, malloc_debug_level);
1219 
1220 #endif
1221 
1222  if (unlinkdNeeded())
1223  unlinkdInit();
1224 
1225  urlInitialize();
1226  statInit();
1227  storeInit();
1228  mainSetCwd();
1230  refreshInit();
1231 #if USE_DELAY_POOLS
1232  DelayPools::Init();
1233 #endif
1234 
1236  /* register the modules in the cache manager menus */
1237 
1240 
1241  /* These use separate calls so that the comm loops can eventually
1242  * coexist.
1243  */
1244 
1245  eventInit();
1246 
1247  // TODO: pconn is a good candidate for new-style registration
1248  // PconnModule::GetInstance()->registerWithCacheManager();
1249  // moved to PconnModule::PconnModule()
1250 
1251  if (IamPrimaryProcess()) {
1252 #if USE_WCCP
1253  wccpInit();
1254 
1255 #endif
1256 #if USE_WCCPv2
1257 
1258  wccp2Init();
1259 
1260 #endif
1261  }
1262 
1264 
1265  neighbors_init();
1266 
1267  // neighborsRegisterWithCacheManager(); //moved to neighbors_init()
1268 
1269  if (Config.chroot_dir)
1270  no_suid();
1271 
1272 #if defined(_SQUID_LINUX_THREADS_)
1273 
1274  squid_signal(SIGQUIT, rotate_logs, SA_RESTART);
1275 
1277 
1278 #else
1279 
1280  squid_signal(SIGUSR1, rotate_logs, SA_RESTART);
1281 
1283 
1284 #endif
1285 
1286  squid_signal(SIGTERM, shut_down, SA_RESTART);
1287 
1288  squid_signal(SIGINT, shut_down, SA_RESTART);
1289 
1290 #ifdef SIGTTIN
1291 
1292  squid_signal(SIGTTIN, shut_down, SA_RESTART);
1293 
1294 #endif
1295 
1296  memCheckInit();
1297 
1298 #if USE_LOADABLE_MODULES
1300 #endif
1301 
1302 #if USE_ADAPTATION
1303  bool enableAdaptation = false;
1304 
1305  // We can remove this dependency on specific adaptation mechanisms
1306  // if we create a generic Registry of such mechanisms. Should we?
1307 #if ICAP_CLIENT
1309  enableAdaptation = Adaptation::Icap::TheConfig.onoff || enableAdaptation;
1310 #endif
1311 #if USE_ECAP
1312  Adaptation::Ecap::TheConfig.finalize(); // must be after we load modules
1313  enableAdaptation = Adaptation::Ecap::TheConfig.onoff || enableAdaptation;
1314 #endif
1315  // must be the last adaptation-related finalize
1316  Adaptation::Config::Finalize(enableAdaptation);
1317 #endif
1318 
1319 #if USE_DELAY_POOLS
1321 #endif
1322 
1323  eventAdd("storeMaintain", Store::Maintain, nullptr, 1.0, 1);
1324 
1325  if (Config.onoff.announce)
1326  eventAdd("start_announce", start_announce, nullptr, 3600.0, 1);
1327 
1328  eventAdd("ipcache_purgelru", ipcache_purgelru, nullptr, 10.0, 1);
1329 
1330  eventAdd("fqdncache_purgelru", fqdncache_purgelru, nullptr, 15.0, 1);
1331 
1332  eventAdd("memPoolCleanIdlePools", Mem::CleanIdlePools, nullptr, 15.0, 1);
1333 
1334  configured_once = 1;
1335 }
1336 
1337 static void
1339 {
1340  // ignore recursive calls to avoid termination loops
1341  static bool terminating = false;
1342  if (terminating)
1343  return;
1344  terminating = true;
1345 
1346  debugs(1, DBG_CRITICAL, "FATAL: Dying from an exception handling failure; exception: " << CurrentException);
1347 
1349  abort();
1350 }
1351 
1353 int SquidMain(int argc, char **argv);
1355 static int SquidMainSafe(int argc, char **argv);
1356 
1357 #if USE_WIN32_SERVICE
1358 /* Entry point for Windows services */
1359 extern "C" void WINAPI
1360 SquidWinSvcMain(int argc, char **argv)
1361 {
1362  SquidMainSafe(argc, argv);
1363 }
1364 #endif
1365 
1366 int
1367 main(int argc, char **argv)
1368 {
1369 #if USE_WIN32_SERVICE
1370  SetErrorMode(SEM_NOGPFAULTERRORBOX);
1371  if ((argc == 2) && strstr(argv[1], _WIN_SQUID_SERVICE_OPTION))
1372  return WIN32_StartService(argc, argv);
1373  else {
1374  WIN32_run_mode = _WIN_SQUID_RUN_MODE_INTERACTIVE;
1375  opt_no_daemon = 1;
1376  }
1377 #endif
1378 
1379  return SquidMainSafe(argc, argv);
1380 }
1381 
1382 static int
1383 SquidMainSafe(int argc, char **argv)
1384 {
1385  (void)std::set_terminate(&OnTerminate);
1386  // XXX: This top-level catch works great for startup, but, during runtime,
1387  // it erases valuable stack info. TODO: Let stack-preserving OnTerminate()
1388  // handle FATAL runtime errors by splitting main code into protected
1389  // startup, unprotected runtime, and protected termination sections!
1390  try {
1391  return SquidMain(argc, argv);
1392  } catch (...) {
1393  debugs(1, DBG_CRITICAL, "FATAL: " << CurrentException);
1394  }
1395  return EXIT_FAILURE;
1396 }
1397 
1399 static void
1401 {
1402  const char *kidParams = nullptr;
1403  if (cmdLine.hasOption(optKid, &kidParams)) {
1404  SBuf processName(kidParams);
1405  SBuf kidId;
1406  Parser::Tokenizer tok(processName);
1407  tok.suffix(kidId, CharacterSet::DIGIT);
1408  KidIdentifier = xatoi(kidId.c_str());
1409  tok.skipSuffix(SBuf("-"));
1410  TheKidName = tok.remaining();
1411  if (TheKidName.cmp("squid-coord") == 0)
1413  else if (TheKidName.cmp("squid") == 0)
1415  else if (TheKidName.cmp("squid-disk") == 0)
1417  else
1418  TheProcessKind = pkOther; // including coordinator
1419  } else {
1421  KidIdentifier = 0;
1422  }
1424 }
1425 
1427 static void
1429 {
1430  if (opt_no_daemon) {
1431  fd_open(0, FD_LOG, "stdin");
1432  fd_open(1, FD_LOG, "stdout");
1433  fd_open(2, FD_LOG, "stderr");
1434  }
1435  // we should not create cache.log outside chroot environment, if any
1436  // XXX: With Config.chroot_dir set, SMP master process calls Debug::BanCacheLogUse().
1437  if (!Config.chroot_dir || Chrooted)
1439  else
1441 }
1442 
1443 static void
1445 {
1448 }
1449 
1450 static void
1452 {
1453  setMaxFD();
1454  fde::Init();
1455  const auto skipCwdAdjusting = IamMasterProcess() && InDaemonMode();
1456  if (skipCwdAdjusting) {
1458  RunConfigUsers();
1459  } else if (Config.chroot_dir) {
1460  RunConfigUsers();
1461  enter_suid();
1462  // TODO: don't we need to RunConfigUsers() in the configured
1463  // chroot environment?
1464  mainSetCwd();
1465  leave_suid();
1467  } else {
1469  RunConfigUsers();
1470  enter_suid();
1471  // TODO: since RunConfigUsers() may use a relative path, we
1472  // need to change the process root first
1473  mainSetCwd();
1474  leave_suid();
1475  }
1476 }
1477 
1478 int
1479 SquidMain(int argc, char **argv)
1480 {
1481  const CommandLine cmdLine(argc, argv, shortOpStr, squidOptions);
1482 
1483  ConfigureCurrentKid(cmdLine);
1484 
1485 #if defined(SQUID_MAXFD_LIMIT)
1486 
1489 
1490 #endif
1491 
1492  /* NOP under non-windows */
1493  int WIN32_init_err=0;
1494  if ((WIN32_init_err = WIN32_Subsystem_Init(&argc, &argv)))
1495  return WIN32_init_err;
1496 
1497  /* call mallopt() before anything else */
1498 #if HAVE_MALLOPT
1499 #ifdef M_GRAIN
1500  /* Round up all sizes to a multiple of this */
1501  mallopt(M_GRAIN, 16);
1502 
1503 #endif
1504 #ifdef M_MXFAST
1505  /* biggest size that is considered a small block */
1506  mallopt(M_MXFAST, 256);
1507 
1508 #endif
1509 #ifdef M_NBLKS
1510  /* allocate this many small blocks at once */
1511  mallopt(M_NLBLKS, 32);
1512 
1513 #endif
1514 #endif /* HAVE_MALLOPT */
1515 
1516  getCurrentTime();
1517 
1519 
1521 
1522 #if USE_WIN32_SERVICE
1523 
1524  WIN32_svcstatusupdate(SERVICE_START_PENDING, 10000);
1525 
1526 #endif
1527 
1529 
1532 
1533  if (opt_foreground && opt_no_daemon) {
1534  debugs(1, DBG_CRITICAL, "WARNING: --foreground command-line option has no effect with -N.");
1535  }
1536 
1537 #if USE_WIN32_SERVICE
1538 
1539  if (opt_install_service) {
1541  return 0;
1542  }
1543 
1544  if (opt_remove_service) {
1546  return 0;
1547  }
1548 
1549  if (opt_command_line) {
1551  return 0;
1552  }
1553 
1554 #endif
1555 
1556  /* parse configuration file
1557  * note: in "normal" case this used to be called from mainInitialize() */
1558  {
1559  int parse_err;
1560 
1561  if (!ConfigFile)
1562  ConfigFile = xstrdup(DEFAULT_CONFIG_FILE);
1563 
1565 
1566  Mem::Init();
1567 
1569 
1570  storeFsInit(); /* required for config parsing */
1571 
1572  /* TODO: call the FS::Clean() in shutdown to do Fs cleanups */
1573  Fs::Init();
1574 
1575  /* May not be needed for parsing, have not audited for such */
1577 
1578  /* Shouldn't be needed for config parsing, but have not audited for such */
1580 
1581  /* we may want the parsing process to set this up in the future */
1582  Store::Init();
1583  Acl::Init();
1584  Auth::Init(); /* required for config parsing. NOP if !USE_AUTH */
1585  Ip::ProbeTransport(); // determine IPv4 or IPv6 capabilities before parsing.
1586 
1587  Format::Token::Init(); // XXX: temporary. Use a runners registry of pre-parse runners instead.
1588 
1590 
1591  try {
1592  parse_err = parseConfigFile(ConfigFile);
1593  } catch (...) {
1594  // for now any errors are a fatal condition...
1595  debugs(1, DBG_CRITICAL, "FATAL: Unhandled exception parsing config file." <<
1596  (opt_parse_cfg_only ? " Run squid -k parse and check for errors." : ""));
1597  parse_err = 1;
1598  }
1599 
1600  Mem::Report();
1601 
1602  if (opt_parse_cfg_only || parse_err > 0)
1603  return parse_err;
1604  }
1606 
1607  // Master optimization: Where possible, avoid pointless daemon fork() and/or
1608  // pointless wait for the exclusive PID file lock. This optional/weak check
1609  // is not applicable to kids because they always co-exist with their master.
1610  if (opt_send_signal == -1 && IamMasterProcess())
1612 
1613  /* send signal to running copy and exit */
1614  if (opt_send_signal != -1) {
1615  /* chroot if configured to run inside chroot */
1616  mainSetCwd();
1617  if (Config.chroot_dir) {
1618  no_suid();
1619  } else {
1620  leave_suid();
1621  }
1622 
1623  sendSignal();
1624  return 0;
1625  }
1626 
1627  debugs(1,2, "Doing post-config initialization");
1628  leave_suid();
1630 
1631  if (IamMasterProcess()) {
1632  if (InDaemonMode()) {
1633  watch_child(cmdLine);
1634  // NOTREACHED
1635  } else {
1637  }
1638  }
1639 
1640  StartUsingConfig();
1641  enter_suid();
1642 
1643  if (opt_create_swap_dirs) {
1644  setEffectiveUser();
1645  debugs(0, DBG_CRITICAL, "Creating missing swap directories");
1646  Store::Root().create();
1647 
1648  return 0;
1649  }
1650 
1651  if (IamPrimaryProcess())
1652  CpuAffinityCheck();
1653  CpuAffinityInit();
1654 
1655  /* init comm module */
1656  comm_init();
1657 
1658 #if USE_WIN32_SERVICE
1659 
1660  WIN32_svcstatusupdate(SERVICE_START_PENDING, 10000);
1661 
1662 #endif
1663 
1664  mainInitialize();
1665 
1666 #if USE_WIN32_SERVICE
1667 
1668  WIN32_svcstatusupdate(SERVICE_RUNNING, 0);
1669 
1670 #endif
1671 
1672  /* main loop */
1673  EventLoop mainLoop;
1674 
1675  SignalEngine signalEngine;
1676 
1677  mainLoop.registerEngine(&signalEngine);
1678 
1679  /* TODO: stop requiring the singleton here */
1681 
1682  StoreRootEngine store_engine;
1683 
1684  mainLoop.registerEngine(&store_engine);
1685 
1686  CommSelectEngine comm_engine;
1687 
1688  mainLoop.registerEngine(&comm_engine);
1689 
1690  mainLoop.setPrimaryEngine(&comm_engine);
1691 
1692  /* use the standard time service */
1693  Time::Engine time_engine;
1694 
1695  mainLoop.setTimeService(&time_engine);
1696 
1697  if (IamCoordinatorProcess())
1699  else if (UsingSmp() && (IamWorkerProcess() || IamDiskProcess()))
1701 
1702  /* at this point we are finished the synchronous startup. */
1703  starting_up = 0;
1704 
1705  mainLoop.run();
1706 
1707  if (mainLoop.errcount == 10)
1708  fatal_dump("Event loop exited with failure.");
1709 
1710  /* shutdown squid now */
1711  SquidShutdown();
1712 
1713  /* NOTREACHED */
1714  return 0;
1715 }
1716 
1717 static void
1719 {
1720 #if USE_WIN32_SERVICE
1721  // WIN32_sendSignal() does not need the PID value to signal,
1722  // but we must exit if there is no valid PID (TODO: Why?).
1723  (void)Instance::Other();
1724  if (!opt_signal_service)
1725  throw TexcHere("missing -n command line switch");
1727 #else
1728  const auto pid = Instance::Other();
1729  if (kill(pid, opt_send_signal) &&
1730  /* ignore permissions if just running check */
1731  !(opt_send_signal == 0 && errno == EPERM)) {
1732  const auto savedErrno = errno;
1733  throw TexcHere(ToSBuf("failed to send signal ", opt_send_signal,
1734  " to Squid instance with PID ", pid, ": ", xstrerr(savedErrno)));
1735  }
1736 #endif
1737  /* signal successfully sent */
1738 }
1739 
1740 #if !_SQUID_WINDOWS_
1741 /*
1742  * This function is run when Squid is in daemon mode, just
1743  * before the parent forks and starts up the child process.
1744  * It can be used for admin-specific tasks, such as notifying
1745  * someone that Squid is (re)started.
1746  */
1747 static void
1748 mainStartScript(const char *prog)
1749 {
1750  char script[MAXPATHLEN];
1751  char *t;
1752  size_t sl = 0;
1753  pid_t cpid;
1754  pid_t rpid;
1755  xstrncpy(script, prog, MAXPATHLEN);
1756 
1757  if ((t = strrchr(script, '/'))) {
1758  *(++t) = '\0';
1759  sl = strlen(script);
1760  }
1761 
1762  xstrncpy(&script[sl], squid_start_script, MAXPATHLEN - sl);
1763 
1764  if ((cpid = fork()) == 0) {
1765  /* child */
1766  execl(script, squid_start_script, (char *)NULL);
1767  _exit(-1);
1768  } else {
1769  do {
1770  PidStatus status;
1771  rpid = WaitForOnePid(cpid, status, 0);
1772  } while (rpid != cpid);
1773  }
1774 }
1775 
1777 static void
1779 {
1780  if (AvoidSignalAction("shutdown", do_shutdown))
1781  return;
1782  debugs(1, 2, "received shutdown command");
1783  shutting_down = 1;
1784 }
1785 
1787 static void
1789 {
1790  if (AvoidSignalAction("reconfiguration", do_reconfigure))
1791  return;
1792  debugs(1, 2, "received reconfiguration command");
1793  reconfiguring = 1;
1795  // TODO: hot-reconfiguration of the number of kids, kids revival delay,
1796  // PID file location, etc.
1797 }
1798 
1800 static void
1802 {
1803  reconfiguring = 0;
1804 }
1805 
1807 static void
1809 {
1810  if (AvoidSignalAction("kids revival", do_revive_kids))
1811  return;
1812  debugs(1, 2, "woke up after ~" << Config.hopelessKidRevivalDelay << "s");
1813  // nothing to do here -- actual revival happens elsewhere in the main loop
1814  // the alarm was needed just to wake us up so that we do a loop iteration
1815 }
1816 
1817 static void
1819 {
1820  if (do_shutdown)
1822  if (do_reconfigure)
1824  if (do_revive_kids)
1825  masterReviveKids();
1826 
1827  // emulate multi-step reconfiguration assumed by AvoidSignalAction()
1828  if (reconfiguring)
1830 
1835  ReviveKidsSignal = -1; // alarms are not broadcasted
1836 }
1837 
1840 static void
1842 {
1843  const auto nextCheckDelay = TheKids.forgetOldFailures();
1844  assert(nextCheckDelay >= 0);
1845  (void)alarm(static_cast<unsigned int>(nextCheckDelay)); // resets or cancels
1846  if (nextCheckDelay)
1847  debugs(1, 2, "will recheck hopeless kids in " << nextCheckDelay << " seconds");
1848 }
1849 
1850 static inline bool
1852 {
1853  return (DebugSignal > 0 || RotateSignal > 0 || ReconfigureSignal > 0 ||
1854  ShutdownSignal > 0 || ReviveKidsSignal > 0);
1855 }
1856 
1858 static void
1860 {
1861  pid_t pid;
1862  if ((pid = fork()) < 0) {
1863  int xerrno = errno;
1864  throw TexcHere(ToSBuf("failed to fork(2) the master process: ", xstrerr(xerrno)));
1865  } else if (pid > 0) {
1866  // parent
1867  // The fork() effectively duped any saved debugs() messages. For
1868  // simplicity sake, let the child process deal with them.
1870  exit(EXIT_SUCCESS);
1871  }
1872  // child, running as a background daemon
1873  Must(setsid() > 0); // ought to succeed after fork()
1874 }
1875 
1876 static void
1878 {
1879  if (TheKids.someSignaled(SIGINT) || TheKids.someSignaled(SIGTERM)) {
1880  syslog(LOG_ALERT, "Exiting due to unexpected forced shutdown");
1881  exit(EXIT_FAILURE);
1882  }
1883 
1884  if (TheKids.allHopeless()) {
1885  syslog(LOG_ALERT, "Exiting due to repeated, frequent failures");
1886  exit(EXIT_FAILURE);
1887  }
1888 
1889  exit(EXIT_SUCCESS);
1890 }
1891 
1892 #endif /* !_SQUID_WINDOWS_ */
1893 
1894 static void
1895 watch_child(const CommandLine &masterCommand)
1896 {
1897 #if !_SQUID_WINDOWS_
1898  pid_t pid;
1899 #ifdef TIOCNOTTY
1900 
1901  int i;
1902 #endif
1903 
1904  int nullfd;
1905 
1906  // TODO: zero values are not supported because they result in
1907  // misconfigured SMP Squid instances running forever, endlessly
1908  // restarting each dying kid.
1910  throw TexcHere("hopeless_kid_revival_delay must be positive");
1911 
1912  enter_suid();
1913 
1914  openlog(APP_SHORTNAME, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4);
1915 
1916  if (!opt_foreground)
1917  GoIntoBackground();
1918 
1919  closelog();
1920 
1921 #ifdef TIOCNOTTY
1922 
1923  if ((i = open("/dev/tty", O_RDWR | O_TEXT)) >= 0) {
1924  ioctl(i, TIOCNOTTY, NULL);
1925  close(i);
1926  }
1927 
1928 #endif
1929 
1930  /*
1931  * RBCOLLINS - if cygwin stackdumps when squid is run without
1932  * -N, check the cygwin1.dll version, it needs to be AT LEAST
1933  * 1.1.3. execvp had a bit overflow error in a loop..
1934  */
1935  /* Connect stdio to /dev/null in daemon mode */
1936  nullfd = open(_PATH_DEVNULL, O_RDWR | O_TEXT);
1937 
1938  if (nullfd < 0) {
1939  int xerrno = errno;
1940  fatalf(_PATH_DEVNULL " %s\n", xstrerr(xerrno));
1941  }
1942 
1943  dup2(nullfd, 0);
1944 
1945  if (!Debug::StderrEnabled()) {
1946  dup2(nullfd, 1);
1947  dup2(nullfd, 2);
1948  }
1949 
1950  leave_suid();
1952  StartUsingConfig();
1953  enter_suid();
1954 
1955 #if defined(_SQUID_LINUX_THREADS_)
1956  squid_signal(SIGQUIT, rotate_logs, 0);
1957  squid_signal(SIGTRAP, sigusr2_handle, 0);
1958 #else
1959  squid_signal(SIGUSR1, rotate_logs, 0);
1960  squid_signal(SIGUSR2, sigusr2_handle, 0);
1961 #endif
1962 
1963  squid_signal(SIGHUP, reconfigure, 0);
1964 
1965  squid_signal(SIGTERM, master_shutdown, 0);
1966  squid_signal(SIGALRM, master_revive_kids, 0);
1967  squid_signal(SIGINT, master_shutdown, 0);
1968 #ifdef SIGTTIN
1969  squid_signal(SIGTTIN, master_shutdown, 0);
1970 #endif
1971 
1972  if (Config.workers > 128) {
1973  syslog(LOG_ALERT, "Suspiciously high workers value: %d",
1974  Config.workers);
1975  // but we keep going in hope that user knows best
1976  }
1977  TheKids.init();
1978 
1979  configured_once = 1;
1980 
1981  syslog(LOG_NOTICE, "Squid Parent: will start %d kids", (int)TheKids.count());
1982 
1983  // keep [re]starting kids until it is time to quit
1984  for (;;) {
1985  bool mainStartScriptCalled = false;
1986  // start each kid that needs to be [re]started; once
1987  for (int i = TheKids.count() - 1; i >= 0 && !shutting_down; --i) {
1988  Kid& kid = TheKids.get(i);
1989  if (!kid.shouldRestart())
1990  continue;
1991 
1992  if (!mainStartScriptCalled) {
1993  mainStartScript(masterCommand.arg0());
1994  mainStartScriptCalled = true;
1995  }
1996 
1997  // These are only needed by the forked child below, but let's keep
1998  // them out of that "no man's land" between fork() and execvp().
1999  auto kidCommand = masterCommand;
2000  kidCommand.resetArg0(kid.processName().c_str());
2001  assert(!kidCommand.hasOption(optKid));
2002  kidCommand.pushFrontOption("--kid", kid.gist().c_str());
2003 
2004  if ((pid = fork()) == 0) {
2005  /* child */
2006  openlog(APP_SHORTNAME, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4);
2007  (void)execvp(masterCommand.arg0(), kidCommand.argv());
2008  int xerrno = errno;
2009  syslog(LOG_ALERT, "execvp failed: %s", xstrerr(xerrno));
2010  }
2011 
2012  kid.start(pid);
2013  syslog(LOG_NOTICE, "Squid Parent: %s process %d started",
2014  kid.processName().c_str(), pid);
2015  }
2016 
2017  /* parent */
2018  openlog(APP_SHORTNAME, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4);
2019 
2020  // If Squid received a signal while checking for dying kids (below) or
2021  // starting new kids (above), then do a fast check for a new dying kid
2022  // (WaitForAnyPid with the WNOHANG option) and continue to forward
2023  // signals to kids. Otherwise, wait for a kid to die or for a signal
2024  // to abort the blocking WaitForAnyPid() call.
2025  // With the WNOHANG option, we could check whether WaitForAnyPid() was
2026  // aborted by a dying kid or a signal, but it is not required: The
2027  // next do/while loop will check again for any dying kids.
2028  int waitFlag = 0;
2029  if (masterSignaled())
2030  waitFlag = WNOHANG;
2031  PidStatus status;
2032  pid = WaitForAnyPid(status, waitFlag);
2033  getCurrentTime();
2034 
2035  // check for a stopped kid
2036  if (Kid *kid = pid > 0 ? TheKids.find(pid) : nullptr)
2037  kid->stop(status);
2038  else if (pid > 0)
2039  syslog(LOG_NOTICE, "Squid Parent: unknown child process %d exited", pid);
2040 
2043 
2045  leave_suid();
2046  // XXX: Master process has no main loop and, hence, should not call
2047  // RegisteredRunner::startShutdown which promises a loop iteration.
2049  enter_suid();
2050  masterExit();
2051  }
2052  }
2053 
2054  /* NOTREACHED */
2055 #endif /* _SQUID_WINDOWS_ */
2056 
2057 }
2058 
2059 static void
2061 {
2062  /* XXX: This function is called after the main loop has quit, which
2063  * means that no AsyncCalls would be called, including close handlers.
2064  * TODO: We need to close/shut/free everything that needs calls before
2065  * exiting the loop.
2066  */
2067 
2068 #if USE_WIN32_SERVICE
2069  WIN32_svcstatusupdate(SERVICE_STOP_PENDING, 10000);
2070 #endif
2071 
2072  debugs(1, Important(9), "Shutting down...");
2073 #if USE_SSL_CRTD
2075 #endif
2076 #if USE_OPENSSL
2078 #endif
2079  redirectShutdown();
2081  icpClosePorts();
2082 #if USE_HTCP
2083  htcpClosePorts();
2084 #endif
2085 #if SQUID_SNMP
2086  snmpClosePorts();
2087 #endif
2088 #if USE_WCCP
2089 
2091 #endif
2092 #if USE_WCCPv2
2093 
2095 #endif
2096 
2099 
2100 #if USE_DELAY_POOLS
2102 #endif
2103 #if USE_AUTH
2105 #endif
2106 #if USE_WIN32_SERVICE
2107 
2108  WIN32_svcstatusupdate(SERVICE_STOP_PENDING, 10000);
2109 #endif
2110 #if ICAP_CLIENT
2112 #endif
2113 
2114  Store::Root().sync(); /* Flush pending object writes/unlinks */
2115 
2116  unlinkdClose(); /* after sync/flush. NOP if !USE_UNLINKD */
2117 
2119  PrintRusage();
2120  dumpMallocStats();
2121  Store::Root().sync(); /* Flush log writes */
2122  storeLogClose();
2123  accessLogClose();
2124  Store::Root().sync(); /* Flush log close */
2127 #if LEAK_CHECK_MODE && 0 /* doesn't work at the moment */
2128 
2129  configFreeMemory();
2130  storeFreeMemory();
2131  /*stmemFreeMemory(); */
2132  netdbFreeMemory();
2135  asnFreeMemory();
2137  statFreeMemory();
2138  eventFreeMemory();
2139  mimeFreeMemory();
2140  errorClean();
2141 #endif
2143 
2144  fdDumpOpen();
2145 
2146  comm_exit();
2147 
2149 
2150  memClean();
2151 
2152  debugs(1, Important(10), "Squid Cache (Version " << version_string << "): Exiting normally.");
2153 
2154  exit(shutdown_status);
2155 }
2156 
static int ReviveKidsSignal
Definition: main.cc:161
void clientdbFreeMemory(void)
Definition: client_db.cc:350
event class for doing synthetic time etc
Definition: Engine.h:16
void fatal(const char *message)
Definition: fatal.cc:28
void comm_exit(void)
Definition: comm.cc:1161
const char * xstrerr(int error)
Definition: xstrerror.cc:83
void icapLogOpen()
Definition: icap_log.cc:23
int eventFind(EVH *func, void *arg)
Definition: event.cc:153
static void FreeAllModules()
struct timeval squid_start
void accessLogClose(void)
Definition: access_log.cc:202
void Maintain(void *unused)
Definition: store.cc:1108
@ optKid
Definition: main.cc:412
void accessLogInit(void)
Definition: access_log.cc:364
static int configured_once
Definition: main.cc:147
void dumpMallocStats(void)
Definition: tools.cc:163
static void mainInitialize(void)
Definition: main.cc:1131
void externalAclShutdown(void)
int opt_send_signal
#define DBG_CRITICAL
Definition: Stream.h:40
SBuf & assign(const SBuf &S)
Definition: SBuf.cc:83
struct SquidConfig::@97 Port
void(* failure_notify)(const char *)
Definition: compat.cc:12
virtual void Close()
Shutdown pinger helper and control channel.
Definition: IcmpSquid.cc:254
#define SA_NODEFER
void memClean(void)
Main cleanup handler.
Definition: old_api.cc:494
static void SquidShutdown(void)
Definition: main.cc:2060
void clientConnectionsClose()
void releaseServerSockets(void) STUB_NOP void dumpMallocStats(void) STUB void squid_getrusage(struct rusage *) STUB double rusage_cputime(struct rusage *) STUB_RETVAL(0) int rusage_maxrss(struct rusage *) STUB_RETVAL(0) int rusage_pagefaults(struct rusage *) STUB_RETVAL(0) void PrintRusage(void) STUB void death(int) STUB void BroadcastSignalIfAny(int &) STUB void sigusr2_handle(int) STUB void debug_trap(const char *) STUB void sig_child(int) STUB const char *getMyHostname(void) STUB_RETVAL(NULL) const char *uniqueHostname(void) STUB_RETVAL(NULL) void leave_suid(void) STUB_NOP void enter_suid(void) STUB void no_suid(void) STUB bool IamMasterProcess()
Definition: stub_tools.cc:18
#define Critical(id)
Definition: Messages.h:90
#define FALSE
Definition: std-includes.h:56
void rotate_logs(int sig)
Definition: main.cc:724
void netdbFreeMemory(void)
Definition: net_db.cc:957
Config TheConfig
Definition: Config.cc:19
static EventLoop * Running
Definition: EventLoop.h:73
static void usage(void)
Definition: main.cc:350
virtual void create() override
create system resources needed for this store to operate in the future
Definition: Controller.cc:78
static void RunConfigUsers()
Definition: main.cc:1444
static void NameThisKid(int kidIdentifier)
Definition: debug.cc:405
static bool masterSignaled()
Definition: main.cc:1851
void eventDelete(EVH *func, void *arg)
Definition: event.cc:129
static void sendSignal(void)
Definition: main.cc:1718
static void masterReconfigureFinish()
Ends reconfiguration sequence started by masterReconfigureStart().
Definition: main.cc:1801
virtual void sync() override
prepare for shutdown
Definition: Controller.cc:218
SBuf TheKidName
current Squid process name (e.g., "squid-coord")
Definition: Kids.cc:19
static void mainHandleCommandLineOption(const int optId, const char *optValue)
Definition: main.cc:435
int opt_store_doublecheck
static void StopEventLoop(void *)
Definition: main.cc:210
static int ReconfigureSignal
Definition: main.cc:159
void wccp2ConnectionOpen(void)
Definition: wccp2.cc:952
void run()
Definition: EventLoop.cc:76
static void initModule()
Definition: FwdState.cc:1433
static void masterReviveKids()
Reacts to the kid revival alarm.
Definition: main.cc:1808
int TheProcessKind
ProcessKind for the current process.
Definition: Kid.cc:21
static const char * shortOpStr
Definition: main.cc:418
#define CACHE_HTTP_PORT
Definition: squid.h:16
int KidIdentifier
void storeInit(void)
Definition: store.cc:1233
static void watch_child(const CommandLine &)
Definition: main.cc:1895
unsigned short icp
Definition: SquidConfig.h:139
static volatile int do_shutdown
Definition: main.cc:153
SBuf gist() const
Definition: Kid.cc:171
#define O_TEXT
Definition: defines.h:140
SBuf ProcessRoles()
a string describing this process roles such as worker or coordinator
Definition: tools.cc:736
void Init(void)
Definition: Kid.h:18
IcmpSquid icmpEngine
Definition: IcmpSquid.cc:26
char * coredump_dir
Definition: SquidConfig.h:488
void FreeMemory()
undo Init()
Definition: Controller.cc:947
static void masterExit()
Definition: main.cc:1877
bool someSignaled(const int sgnl) const
whether some kids died from a given signal
Definition: Kids.cc:116
void handleStoppedChild()
Definition: main.cc:324
static void ResetStderrLevel(int maxLevel)
Definition: debug.cc:699
void WIN32_sendSignal(int WIN32_signal)
Definition: WinSvc.cc:799
static bool mainChangeDir(const char *dir)
changes working directory, providing error reporting
Definition: main.cc:1082
static volatile int do_handle_stopped_child
Definition: main.cc:156
void start(pid_t cpid)
called when this kid got started, records PID
Definition: Kid.cc:34
void OpenLogs()
opens logs enabled in the current configuration
Definition: KeyLog.cc:71
void storeLogClose(void)
Definition: store_log.cc:105
Definition: SBuf.h:87
struct SquidConfig2::@125 onoff
void finalize()
checks pools configuration
void htcpOpenPorts(void)
Definition: htcp.cc:1442
#define OPENSSL_VERSION
Definition: openssl.h:133
static void serverConnectionsOpen(void)
Definition: main.cc:806
static void Shutdown()
Shutdown helper structure.
Definition: helper.cc:232
void death(int sig)
Definition: tools.cc:342
bool hasOption(const int optId, const char **optValue=nullptr) const
Definition: CommandLine.cc:71
#define xstrdup
@ FD_LOG
Definition: enums.h:14
void authenticateInit(Auth::ConfigVector *config)
Definition: Gadgets.cc:70
static void StartUsingConfig()
Definition: main.cc:1451
void start_announce(void *)
void snmpClosePorts(void)
Definition: snmp_core.cc:319
static bool AvoidSignalAction(const char *description, volatile int &signalVar)
Definition: main.cc:253
virtual int callback() override
called once every main loop iteration; TODO: Move to UFS code.
Definition: Controller.cc:229
SBuf service_name(APP_SHORTNAME)
time_t shutdownLifetime
Definition: SquidConfig.h:105
void forEachOption(Visitor) const
calls Visitor for each of the configured command line option
Definition: CommandLine.cc:89
bool shouldRestartSome() const
whether some kids should be restarted by master
Definition: Kids.cc:136
char * xstrncpy(char *dst, const char *src, size_t n)
Definition: xstring.cc:37
Auth::Config TheConfig
Definition: Config.cc:15
static void ConfigureSyslog(const char *facility)
enables logging to syslog (using the specified facility, when not nil)
Definition: debug.cc:1078
static int opt_signal_service
Definition: main.cc:144
bool IamWorkerProcess()
whether the current process handles HTTP transactions and such
Definition: stub_tools.cc:47
void LoadableModulesConfigure(const wordlist *names)
void ipcache_restart(void)
Definition: ipcache.cc:1102
#define SA_RESETHAND
#define CACHE_ICP_PORT
Definition: squid.h:17
size_t count() const
returns the number of kids
Definition: Kids.cc:146
void fd_open(const int fd, unsigned int, const char *description)
Definition: minimal.cc:14
virtual void startReconfigure()
void authenticateRotate(void)
Definition: Gadgets.cc:85
virtual void syncConfig()
void WIN32_InstallService()
Definition: WinSvc.cc:719
void storeFsInit(void)
Definition: store.cc:1614
void fqdncache_init(void)
Definition: fqdncache.cc:703
static int SquidMainSafe(int argc, char **argv)
unsafe main routine wrapper to catch exceptions
Definition: main.cc:1383
static int port
Definition: ldap_backend.cc:69
void snmpInit(void)
Definition: snmp_core.cc:68
static void UseCacheLog()
Definition: debug.cc:1120
void self_destruct(void)
Definition: cache_cf.cc:276
virtual bool finalize()
Definition: Config.cc:184
static const CharacterSet ALPHA
Definition: CharacterSet.h:76
int WIN32_Subsystem_Init(int *argc, char ***argv)
Definition: WinSvc.cc:459
#define RunRegisteredHere(m)
convenience macro to describe/debug the caller and the method being called
int opt_no_daemon
static EventScheduler * GetInstance()
Definition: event.cc:302
time_t hopelessKidRevivalDelay
hopeless_kid_revival_delay
Definition: SquidConfig.h:107
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
Definition: TextException.h:59
Kid & get(size_t i)
returns the kid by index, useful for kids iteration
Definition: Kids.cc:60
static void mimeFreeMemory(void)
Definition: mime.cc:339
bool Chrooted
Definition: main.cc:1095
virtual bool finalize()
Definition: Config.cc:27
static void FreeAllFs()
static pid_t pid
Definition: IcmpSquid.cc:34
#define APP_SHORTNAME
Definition: version.h:22
static volatile int shutdown_status
Definition: main.cc:155
static void FreePools()
Definition: delay_pools.cc:555
static int RotateSignal
Definition: main.cc:158
void commCloseAllSockets(void)
Definition: comm.cc:1442
virtual int Open()
Start pinger helper and initiate control channel.
Definition: IcmpSquid.cc:189
bool allHopeless() const
whether all kids are hopeless
Definition: Kids.cc:67
static volatile int do_revive_kids
Definition: main.cc:154
void forgetAllFailures()
forgets all failures in all kids
Definition: Kids.cc:77
class SquidConfig2 Config2
Definition: SquidConfig.cc:14
void stop()
Definition: EventLoop.cc:168
const char * version_string
static void Reconfigure()
Definition: helper.cc:249
void netdbInit(void)
Definition: net_db.cc:883
void storeFreeMemory(void)
Definition: store.cc:1312
int DebugSignal
Definition: stub_tools.cc:16
int WIN32_StartService(int argc, char **argv)
Definition: WinSvc.cc:894
void WINAPI WIN32_svcHandler(DWORD)
Definition: WinSvc.cc:578
pid_t Other()
Definition: Instance.cc:128
static void RegisterWithCacheManager(void)
void leave_suid(void)
Definition: tools.cc:556
static void ConfigureDebugging()
Start directing debugs() messages to the configured cache.log.
Definition: main.cc:1428
void memCheckInit(void)
Definition: stub_libmem.cc:84
void comm_init(void)
Definition: comm.cc:1138
void cbdataRegisterWithCacheManager(void)
Definition: cbdata.cc:209
static void master_revive_kids(int sig)
Definition: main.cc:751
void wccpInit(void)
Definition: wccp.cc:91
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
Definition: gadgets.cc:17
void sigusr2_handle(int sig)
Definition: tools.cc:430
static void Init()
Init helper structure.
Definition: helper.cc:76
void Init()
Definition: Module.cc:33
#define NULL
Definition: types.h:166
DWORD WIN32_IpAddrChangeMonitorInit()
Definition: WinSvc.cc:441
wordlist * loadable_module_names
Definition: SquidConfig.h:538
void WIN32_SetServiceCommandLine()
Definition: WinSvc.cc:704
void wccp2ConnectionClose(void)
Definition: wccp2.cc:1040
void RotateLogs()
rotates logs opened by OpenLogs()
Definition: KeyLog.cc:78
static void Init()
Init helper structure.
Definition: helper.cc:171
#define SQUIDSBUFPRINT(s)
Definition: SBuf.h:32
#define OpenSSL_version
Definition: openssl.h:134
struct StatCounters::@127 client_http
static void SetupAllModules()
Definition: DiskIOModule.cc:45
void resetArg0(const char *programName)
replaces argv[0] with the new value
Definition: CommandLine.cc:115
void PrintRusage(void)
Definition: tools.cc:326
static void serverConnectionsClose(void)
Definition: main.cc:844
void unlinkdClose(void)
Definition: unlinkd.cc:131
time_t getCurrentTime() STUB_RETVAL(0) int tvSubUsec(struct timeval
bool IamDiskProcess() STUB_RETVAL_NOP(false) bool InDaemonMode() STUB_RETVAL_NOP(false) bool UsingSmp() STUB_RETVAL_NOP(false) bool IamCoordinatorProcess() STUB_RETVAL(false) bool IamPrimaryProcess() STUB_RETVAL(false) int NumberOfKids() STUB_RETVAL(0) void setMaxFD(void) STUB void setSystemLimits(void) STUB void squid_signal(int
whether the current process is dedicated to managing a cache_dir
pid_t WaitForOnePid(pid_t pid, PidStatus &status, int flags)
Definition: tools.cc:1177
void fdDumpOpen(void)
Definition: fd.cc:242
void mimeInit(char *filename)
Definition: mime.cc:231
void asnFreeMemory(void)
Definition: Asn.cc:210
static char * opt_syslog_facility
Definition: main.cc:145
static void ForgetSaved()
silently erases saved early debugs() messages (if any)
Definition: debug.cc:552
static void Shutdown()
Shutdown helper structure.
Definition: helper.cc:107
static volatile int do_reconfigure
Definition: main.cc:151
static void mainRotate(void)
Definition: main.cc:1033
void snmpOpenPorts(void)
Definition: snmp_core.cc:256
void eventFreeMemory(void)
Definition: event.cc:147
void WINAPI SquidWinSvcMain(int argc, char **argv)
Definition: main.cc:1360
static void Init()
initializes down-cased protocol scheme names array
Definition: UriScheme.cc:38
static void masterCheckAndBroadcastSignals()
Definition: main.cc:1818
void fqdncache_purgelru(void *)
Definition: fqdncache.cc:201
void htcpClosePorts(void)
Definition: htcp.cc:1646
Manages arguments passed to a program (i.e., main(argc, argv) parameters).
Definition: CommandLine.h:35
void CpuAffinityCheck()
check CPU affinity configuration and print warnings if needed
Definition: CpuAffinity.cc:49
void squid_signal(int sig, SIGHDLR *func, int flags)
Definition: tools.cc:870
void Report()
Definition: old_api.cc:460
static void Init()
Definition: delay_pools.cc:458
Kids TheKids
All kids being maintained.
Definition: Kids.cc:18
static void EnsureDefaultStderrLevel(int maxDefault)
Definition: debug.cc:691
char * chroot_dir
Definition: SquidConfig.h:489
void WriteOurPid()
creates a PID file; throws on error
Definition: Instance.cc:186
int starting_up
void WIN32_svcstatusupdate(DWORD, DWORD)
Definition: WinSvc.cc:567
static void Init()
Definition: fde.cc:141
static void FinalShutdownRunners(void *)
Definition: main.cc:215
Config TheConfig
Definition: Config.cc:16
bool SIGHDLR int STUB void const char void ObjPackMethod STUB void const char *STUB void keepCapabilities(void) STUB pid_t WaitForOnePid(pid_t
void httpHeaderInitModule(void)
Definition: HttpHeader.cc:119
int reconfiguring
int xatoi(const char *token)
Definition: Parsing.cc:44
void CpuAffinityInit()
set CPU affinity for this process on startup
Definition: CpuAffinity.cc:26
static void GoIntoBackground()
makes the caller a daemon process running in the background
Definition: main.cc:1859
void icapLogClose()
Definition: icap_log.cc:38
void icpConnectionShutdown(void)
Definition: icp_v2.cc:779
static bool StderrEnabled()
Definition: debug.cc:725
void clientOpenListenSockets(void)
virtual void endingShutdown()
#define assert(EX)
Definition: assert.h:19
static void mainStartScript(const char *prog)
Definition: main.cc:1748
static const char * squid_start_script
Definition: main.cc:178
int parseConfigFile(const char *file_name)
Definition: cache_cf.cc:634
static void PrepareToDie()
Definition: debug.cc:561
int opt_create_swap_dirs
static void Init()
Initialize the format token registrations.
Definition: Token.cc:251
static void parseOptions(char const *)
Definition: debug.cc:1090
void fatalf(const char *fmt,...)
Definition: fatal.cc:68
int errcount
Definition: EventLoop.h:69
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
static void Reconfigure()
Definition: helper.cc:118
void peerSelectInit(void)
Definition: peer_select.cc:918
void _db_rotate_log(void)
Definition: debug.cc:1155
int opt_reuseaddr
static const CharacterSet DIGIT
Definition: CharacterSet.h:84
static void mainReconfigureFinish(void *)
Definition: main.cc:911
void configFreeMemory(void)
Definition: cache_cf.cc:3945
#define SA_RESTART
pid_t WaitForAnyPid(PidStatus &status, int flags)
Definition: tools.h:107
const char * c_str()
Definition: SBuf.cc:516
void fatal_dump(const char *message)
Definition: fatal.cc:78
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:408
static void mainSetCwd(void)
set the working directory.
Definition: main.cc:1099
int opt_foreground
virtual void useConfig()
void ipcacheFreeMemory(void)
Definition: ipcache.cc:1087
int Squid_MaxFD
#define SQUID_MAXFD_LIMIT
Definition: compat_shared.h:84
#define xfree
Receives coordination messages on behalf of its process or thread.
Definition: Strand.h:28
void storeDirCloseSwapLogs()
Definition: Disks.cc:680
void reconfigure(int sig)
Definition: main.cc:738
bool shouldRestart() const
returns true if master should restart this kid
Definition: Kid.cc:97
void storeLogRotate(void)
Definition: store_log.cc:96
void Init(Controller *root=nullptr)
initialize the storage module; a custom root is used by unit tests only
Definition: Controller.cc:941
void redirectReconfigure()
Definition: redirect.cc:435
bool IamMasterProcess()
whether the current process is the parent of all other Squid processes
Definition: tools.cc:665
virtual void finalizeConfig()
void setTimeService(Time::Engine *)
Definition: EventLoop.cc:162
static void Initialize()
Definition: Acl.cc:412
@ optForeground
Definition: main.cc:411
int main(int argc, char **argv)
Definition: main.cc:1367
static void masterReconfigureStart()
Initiates reconfiguration sequence. See also: masterReconfigureFinish().
Definition: main.cc:1788
time_t forgetOldFailures()
Definition: Kids.cc:84
#define TRUE
Definition: std-includes.h:55
void BroadcastSignalIfAny(int &sig)
Definition: tools.cc:415
char * mimeTablePathname
Definition: SquidConfig.h:224
int storeDirWriteCleanLogs(int reopen)
Definition: Disks.cc:696
void refreshInit(void)
Definition: refresh.cc:755
void ipcache_init(void)
Definition: ipcache.cc:686
void htcpSocketShutdown(void)
Definition: htcp.cc:1617
int opt_reload_hit_only
GlobalContextStorage TheGlobalContextStorage
Global cache for store all SSL server certificates.
void urlInitialize(void)
Definition: Uri.cc:137
@ pkOther
we do not know or do not care
Definition: Kid.h:103
static void mainReconfigureStart(void)
Definition: main.cc:875
static Coordinator * Instance()
Definition: Coordinator.cc:291
void icpOpenPorts(void)
Definition: icp_v2.cc:696
void reconfigureStart()
When reconfigring should be called this method.
void setUmask(mode_t mask)
Definition: tools.cc:1066
static void SettleStderr()
Definition: debug.cc:705
static volatile int do_rotate
Definition: main.cc:152
static int ShutdownSignal
Definition: main.cc:160
Definition: parse.c:160
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
Definition: SBuf.h:268
char * ConfigFile
@ pkWorker
general-purpose worker bee
Definition: Kid.h:105
struct SquidConfig::@110 onoff
void fqdncacheFreeMemory(void)
Definition: fqdncache.cc:623
virtual void finishShutdown()
Meant for cleanup of services needed by the already destroyed objects.
int SquidMain(int argc, char **argv)
unsafe main routine – may throw
Definition: main.cc:1479
int PidStatus
Definition: tools.h:91
static void masterMaintainKidRevivalSchedule()
Definition: main.cc:1841
void authenticateReset(void)
Definition: Gadgets.cc:94
bool IamCoordinatorProcess()
whether the current process coordinates worker processes
Definition: tools.cc:699
void init()
initialize all kid records based on Config
Definition: Kids.cc:26
void wccp2Init(void) STUB void wccp2ConnectionOpen(void) STUB void wccp2ConnectionClose(void) STUB void dump_wccp2_method(StoreEntry *
void icpClosePorts(void)
Definition: icp_v2.cc:804
void Init()
Definition: old_api.cc:425
void accessLogRotate(void)
Definition: access_log.cc:182
void CloseLogs()
closes logs opened by OpenLogs()
Definition: KeyLog.cc:85
static void SettleSyslog()
Definition: debug.cc:1140
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
Definition: Stream.h:63
int opt_parse_cfg_only
void setPrimaryEngine(AsyncEngine *engine)
Definition: EventLoop.cc:149
Kid * find(pid_t pid)
returns kid by pid
Definition: Kids.cc:47
#define Must(condition)
Definition: TextException.h:71
void asnInit(void)
Definition: Asn.cc:194
virtual void bootstrapConfig()
#define Important(id)
Definition: Messages.h:91
void enter_suid(void)
Definition: tools.cc:620
bool someRunning() const
whether some kids are running
Definition: Kids.cc:126
int checkEvents(int)
Definition: main.cc:191
#define DBG_IMPORTANT
Definition: Stream.h:41
virtual void claimMemoryNeeds()
void redirectInit(void)
Definition: redirect.cc:333
static int override_X
Definition: Stream.h:88
void setSystemLimits(void)
Definition: tools.cc:808
void doShutdown(time_t wait)
Definition: main.cc:282
static void ConfigureCurrentKid(const CommandLine &cmdLine)
computes name and ID for the current kid process
Definition: main.cc:1400
void CleanIdlePools(void *unused)
Definition: old_api.cc:399
void wccpConnectionOpen(void)
Definition: wccp.cc:109
static void masterShutdownStart()
Initiates shutdown sequence. Shutdown ends when the last running kids stops.
Definition: main.cc:1778
void registerEngine(AsyncEngine *engine)
Definition: EventLoop.cc:70
int shutting_down
void setMaxFD(void)
Definition: tools.cc:759
const char * arg0() const
Definition: CommandLine.h:58
optimized set of C chars, with quick membership test and merge support
Definition: CharacterSet.h:18
int opt_foreground_rebuild
void redirectShutdown(void)
Definition: redirect.cc:406
static int opt_remove_service
Definition: main.cc:138
void storeDirOpenSwapLogs()
Definition: Disks.cc:673
void fqdncache_restart(void)
Definition: fqdncache.cc:638
static void SetupAllFs()
void no_suid(void)
Definition: tools.cc:643
static void OnTerminate()
Definition: main.cc:1338
#define MAXPATHLEN
Definition: stdio.h:62
void peerUserHashInit(void)
int opt_catch_signals
SBuf processName() const
returns kid name
Definition: Kid.cc:163
bool UsingSmp()
Whether there should be more than one worker process running.
Definition: tools.cc:693
static int opt_command_line
Definition: main.cc:139
static void FreeAll()
Definition: Scheme.cc:60
void storeLogOpen(void)
Definition: store_log.cc:123
void ipcache_purgelru(void *)
Definition: ipcache.cc:350
void neighbors_init(void)
Definition: neighbors.cc:554
static void BanCacheLogUse()
Definition: debug.cc:1113
void eventInit(void)
Definition: event.cc:135
static void setEffectiveUser(void)
Definition: main.cc:1062
void unlinkdInit(void)
Definition: unlinkd.cc:191
void WIN32_RemoveService()
Definition: WinSvc.cc:648
void ProbeTransport(void)
Probe to discover IPv6 capabilities.
static int opt_install_service
Definition: main.cc:137
void errorClean(void)
Definition: errorpage.cc:315
void sig_child(int sig)
Definition: main.cc:794
@ pkCoordinator
manages all other kids
Definition: Kid.h:104
bool SIGHDLR int STUB void const char void ObjPackMethod STUB void parseEtcHosts(void) STUB int getMyPort(void) STUB_RETVAL(0) void setUmask(mode_t) STUB void strwordquote(MemBuf *
static struct option squidOptions[]
Definition: main.cc:425
void statFreeMemory(void)
Definition: stat.cc:1592
void peerSourceHashInit(void)
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
void Init(void)
prepares to parse ACLs configuration
Definition: AclRegs.cc:114
virtual void startShutdown()
void wccpConnectionClose(void)
Definition: wccp.cc:161
void freeService(void)
Definition: Config.cc:146
void ThrowIfAlreadyRunning()
Definition: Instance.cc:139
bool unlinkdNeeded(void)
Definition: unlinkd.cc:178
static void Finalize(bool enable)
Definition: Config.cc:230
void eventAdd(const char *name, EVH *func, void *arg, double when, int weight, bool cbdata)
Definition: event.cc:107
void icapLogRotate()
Definition: icap_log.cc:51
virtual int checkEvents(int timeout)
Definition: main.cc:237
void CpuAffinityReconfigure()
reconfigure CPU affinity for this process
Definition: CpuAffinity.cc:38
void errorInitialize(void)
Definition: errorpage.cc:253
#define SQUIDSBUFPH
Definition: SBuf.h:31
void Init(void)
Initialize Auth subsystem.
Definition: AuthReg.cc:34
static int icpPortNumOverride
Definition: main.cc:146
void carpInit(void)
Definition: carp.cc:44
class SquidConfig Config
Definition: SquidConfig.cc:12
@ pkDisker
cache_dir manager
Definition: Kid.h:106
void add_http_port(char *portspec)
Definition: cache_cf.cc:3744
bool IamPrimaryProcess()
Definition: tools.cc:705
void shut_down(int sig)
Definition: main.cc:779
StatCounters statCounter
Definition: StatCounters.cc:12
void externalAclInit(void)
static void Start(const Pointer &job)
Definition: AsyncJob.cc:24
static void master_shutdown(int sig)
Shutdown signal handler for master process.
Definition: main.cc:765
void statInit(void)
Definition: stat.cc:1266
ClientDelayConfig ClientDelay
Definition: SquidConfig.h:452
Controller & Root()
safely access controller singleton
Definition: Controller.cc:934
bool InDaemonMode()
Whether we are running in daemon mode.
Definition: tools.cc:687

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors