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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors