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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors