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

 

Introduction

Documentation

Support

Miscellaneous