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