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

 

Introduction

Documentation

Support

Miscellaneous