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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors