]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/main.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / src / main.cc
index 662c6ef629720efee60853ef60c2d47689e33e4f..b4a3c5df6e853cd65ff21360c2a5b66cb4dfa89b 100644 (file)
  *
  */
 
-#include "squid.h"
+#include "squid-old.h"
 #include "AccessLogEntry.h"
+#if USE_ADAPTATION
+#include "adaptation/Config.h"
+#endif
+#if USE_ECAP
+#include "adaptation/ecap/Config.h"
+#endif
 #if ICAP_CLIENT
+#include "adaptation/icap/Config.h"
 #include "adaptation/icap/icap_log.h"
 #endif
+#if USE_AUTH
 #include "auth/Gadgets.h"
+#endif
+#include "base/RunnersRegistry.h"
+#include "base/Subscription.h"
 #include "base/TextException.h"
 #if USE_DELAY_POOLS
 #include "ClientDelayConfig.h"
 #include "event.h"
 #include "EventLoop.h"
 #include "ExternalACL.h"
+#include "format/Token.h"
+#include "fs/Module.h"
+#include "PeerSelectState.h"
+#include "SquidDns.h"
 #include "Store.h"
 #include "ICP.h"
 #include "ident/Ident.h"
@@ -68,6 +83,7 @@
 #include "ipc/Strand.h"
 #include "ip/tools.h"
 #include "SquidTime.h"
+#include "StatCounters.h"
 #include "SwapDir.h"
 #include "forward.h"
 #include "MemPool.h"
@@ -118,7 +134,7 @@ void WINAPI WIN32_svcHandler(DWORD);
 
 #endif
 
-#ifndef SQUID_BUILD_INFO
+#if !defined(SQUID_BUILD_INFO)
 #define SQUID_BUILD_INFO ""
 #endif
 
@@ -156,7 +172,7 @@ static void SquidShutdown(void);
 static void mainSetCwd(void);
 static int checkRunningPid(void);
 
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_MSWIN_
 static const char *squid_start_script = "squid_start";
 #endif
 
@@ -231,10 +247,10 @@ SignalEngine::doShutdown(time_t wait)
 
     /* run the closure code which can be shared with reconfigure */
     serverConnectionsClose();
-
+#if USE_AUTH
     /* detach the auth components (only do this on full shutdown) */
-    AuthScheme::FreeAll();
-
+    Auth::Scheme::FreeAll();
+#endif
     eventAdd("SquidShutdown", &StopEventLoop, this, (double) (wait + 1), 1, false);
 }
 
@@ -406,26 +422,18 @@ mainParseOptions(int argc, char *argv[])
                 opt_send_signal = SIGHUP;
             else if (!strncmp(optarg, "rotate", strlen(optarg)))
                 /** \li On rotate send SIGQUIT or SIGUSR1. */
-#ifdef _SQUID_LINUX_THREADS_
-
+#if defined(_SQUID_LINUX_THREADS_)
                 opt_send_signal = SIGQUIT;
-
 #else
-
                 opt_send_signal = SIGUSR1;
-
 #endif
 
             else if (!strncmp(optarg, "debug", strlen(optarg)))
                 /** \li On debug send SIGTRAP or SIGUSR2. */
-#ifdef _SQUID_LINUX_THREADS_
-
+#if defined(_SQUID_LINUX_THREADS_)
                 opt_send_signal = SIGTRAP;
-
 #else
-
                 opt_send_signal = SIGUSR2;
-
 #endif
 
             else if (!strncmp(optarg, "shutdown", strlen(optarg)))
@@ -579,7 +587,7 @@ rotate_logs(int sig)
 {
     do_rotate = 1;
     RotateSignal = sig;
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_MSWIN_
 #if !HAVE_SIGACTION
 
     signal(sig, rotate_logs);
@@ -593,7 +601,7 @@ reconfigure(int sig)
 {
     do_reconfigure = 1;
     ReconfigureSignal = sig;
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_MSWIN_
 #if !HAVE_SIGACTION
 
     signal(sig, reconfigure);
@@ -612,14 +620,24 @@ shut_down(int sig)
         shutdown_status = 1;
 
 #endif
-#ifndef _SQUID_MSWIN_
+
+    const pid_t ppid = getppid();
+
+    if (!IamMasterProcess() && ppid > 1) {
+        // notify master that we are shutting down
+        if (kill(ppid, SIGUSR1) < 0)
+            debugs(1, DBG_IMPORTANT, "Failed to send SIGUSR1 to master process,"
+                   " pid " << ppid << ": " << xstrerror());
+    }
+
+#if !_SQUID_MSWIN_
 #if KILL_PARENT_OPT
 
-    if (getppid() > 1) {
-        debugs(1, 1, "Killing master process, pid " << getppid());
+    if (!IamMasterProcess() && ppid > 1) {
+        debugs(1, DBG_IMPORTANT, "Killing master process, pid " << ppid);
 
-        if (kill(getppid(), sig) < 0)
-            debugs(1, 1, "kill " << getppid() << ": " << xstrerror());
+        if (kill(ppid, sig) < 0)
+            debugs(1, DBG_IMPORTANT, "kill " << ppid << ": " << xstrerror());
     }
 
 #endif /* KILL_PARENT_OPT */
@@ -646,8 +664,8 @@ serverConnectionsOpen(void)
         wccp2ConnectionOpen();
 #endif
     }
-    // Coordinator does not start proxying services
-    if (!IamCoordinatorProcess()) {
+    // start various proxying services if we are responsible for them
+    if (IamWorkerProcess()) {
         clientOpenListenSockets();
         icpConnectionsOpen();
 #if USE_HTCP
@@ -655,7 +673,6 @@ serverConnectionsOpen(void)
         htcpInit();
 #endif
 #if SQUID_SNMP
-
         snmpConnectionOpen();
 #endif
 
@@ -667,7 +684,9 @@ serverConnectionsOpen(void)
         peerSelectInit();
 
         carpInit();
+#if USE_AUTH
         peerUserHashInit();
+#endif
         peerSourceHashInit();
     }
 }
@@ -687,7 +706,7 @@ serverConnectionsClose(void)
         wccp2ConnectionClose();
 #endif
     }
-    if (!IamCoordinatorProcess()) {
+    if (IamWorkerProcess()) {
         clientHttpConnectionsClose();
         icpConnectionShutdown();
 #if USE_HTCP
@@ -697,8 +716,7 @@ serverConnectionsClose(void)
 
         icmpEngine.Close();
 #if SQUID_SNMP
-
-        snmpConnectionShutdown();
+        snmpConnectionClose();
 #endif
 
         asnFreeMemory();
@@ -718,17 +736,7 @@ mainReconfigureStart(void)
 
     htcpSocketClose();
 #endif
-#if SQUID_SNMP
-
-    snmpConnectionClose();
-#endif
-#if USE_DNSSERVERS
-
     dnsShutdown();
-#else
-
-    idnsShutdown();
-#endif
 #if USE_SSL_CRTD
     Ssl::Helper::GetInstance()->Shutdown();
 #endif
@@ -736,7 +744,9 @@ mainReconfigureStart(void)
     Ssl::TheGlobalContextStorage.reconfigureStart();
 #endif
     redirectShutdown();
+#if USE_AUTH
     authenticateReset();
+#endif
     externalAclShutdown();
     storeDirCloseSwapLogs();
     storeLogClose();
@@ -809,19 +819,15 @@ mainReconfigureFinish(void *)
     icapLogOpen();
 #endif
     storeLogOpen();
-#if USE_DNSSERVERS
-
     dnsInit();
-#else
-
-    idnsInit();
-#endif
 #if USE_SSL_CRTD
     Ssl::Helper::GetInstance()->Init();
 #endif
 
     redirectInit();
+#if USE_AUTH
     authenticateInit(&Auth::TheConfig);
+#endif
     externalAclInit();
 
     if (IamPrimaryProcess()) {
@@ -843,6 +849,11 @@ mainReconfigureFinish(void *)
 
     mimeInit(Config.mimeTablePathname);
 
+#if USE_UNLINKD
+    if (unlinkdNeeded())
+        unlinkdInit();
+#endif
+
 #if USE_DELAY_POOLS
     Config.ClientDelay.finalize();
 #endif
@@ -866,11 +877,13 @@ static void
 mainRotate(void)
 {
     icmpEngine.Close();
-#if USE_DNSSERVERS
+#if USE_DNSHELPER
     dnsShutdown();
 #endif
     redirectShutdown();
+#if USE_AUTH
     authenticateRotate();
+#endif
     externalAclShutdown();
 
     _db_rotate_log();          /* cache.log */
@@ -881,11 +894,13 @@ mainRotate(void)
     icapLogRotate();               /*icap.log*/
 #endif
     icmpEngine.Open();
-#if USE_DNSSERVERS
+#if USE_DNSHELPER
     dnsInit();
 #endif
     redirectInit();
+#if USE_AUTH
     authenticateInit(&Auth::TheConfig);
+#endif
     externalAclInit();
 }
 
@@ -894,7 +909,7 @@ setEffectiveUser(void)
 {
     keepCapabilities();
     leave_suid();              /* Run as non privilegied user */
-#ifdef _SQUID_OS2_
+#if _SQUID_OS2_
 
     return;
 #endif
@@ -952,7 +967,7 @@ mainInitialize(void)
     setEffectiveUser();
 
     if (icpPortNumOverride != 1)
-        Config.Port.icp = (u_short) icpPortNumOverride;
+        Config.Port.icp = (unsigned short) icpPortNumOverride;
 
     _db_init(Debug::cache_log, Debug::debugOptions);
 
@@ -966,21 +981,22 @@ mainInitialize(void)
 
     debugs(1, 0, "Starting Squid Cache version " << version_string << " for " << CONFIG_HOST_TYPE << "...");
 
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
         debugs(1, 0, "Running as " << WIN32_Service_name << " Windows System Service on " << WIN32_OS_string);
         debugs(1, 0, "Service command line is: " << WIN32_Service_Command_Line);
     } else
         debugs(1, 0, "Running on " << WIN32_OS_string);
-
 #endif
 
     debugs(1, 1, "Process ID " << getpid());
+
+    debugs(1, 1, "Process Roles:" << ProcessRoles());
+
     setSystemLimits();
     debugs(1, 1, "With " << Squid_MaxFD << " file descriptors available");
 
-#ifdef _SQUID_MSWIN_
+#if _SQUID_MSWIN_
 
     debugs(1, 1, "With " << _getmaxstdio() << " CRT stdio descriptors available");
 
@@ -1002,20 +1018,16 @@ mainInitialize(void)
 
     parseEtcHosts();
 
-#if USE_DNSSERVERS
-
     dnsInit();
 
-#else
-
-    idnsInit();
-
+#if USE_SSL_CRTD
+    Ssl::Helper::GetInstance()->Init();
 #endif
 
     redirectInit();
-
+#if USE_AUTH
     authenticateInit(&Auth::TheConfig);
-
+#endif
     externalAclInit();
 
     httpHeaderInitModule();    /* must go before any header processing (e.g. the one in errorInitialize) */
@@ -1047,7 +1059,8 @@ mainInitialize(void)
 
     if (!configured_once) {
 #if USE_UNLINKD
-        unlinkdInit();
+        if (unlinkdNeeded())
+            unlinkdInit();
 #endif
 
         urlInitialize();
@@ -1101,7 +1114,7 @@ mainInitialize(void)
     if (!configured_once)
         writePidFile();                /* write PID file */
 
-#ifdef _SQUID_LINUX_THREADS_
+#if defined(_SQUID_LINUX_THREADS_)
 
     squid_signal(SIGQUIT, rotate_logs, SA_RESTART);
 
@@ -1208,10 +1221,11 @@ SquidMainSafe(int argc, char **argv)
     try {
         return SquidMain(argc, argv);
     } catch (const std::exception &e) {
-        std::cerr << "dying from an unhandled exception: " << e.what() << std::endl;
+        debugs(1, DBG_CRITICAL, "FATAL: dying from an unhandled exception: " <<
+               e.what());
         throw;
     } catch (...) {
-        std::cerr << "dying from an unhandled exception." << std::endl;
+        debugs(1, DBG_CRITICAL, "FATAL: dying from an unhandled exception.");
         throw;
     }
     return -1; // not reached
@@ -1228,6 +1242,14 @@ ConfigureCurrentKid(const char *processName)
             const size_t nameLen = idStart - (processName + 1);
             assert(nameLen < sizeof(TheKidName));
             xstrncpy(TheKidName, processName + 1, nameLen + 1);
+            if (!strcmp(TheKidName, "squid-coord"))
+                TheProcessKind = pkCoordinator;
+            else if (!strcmp(TheKidName, "squid"))
+                TheProcessKind = pkWorker;
+            else if (!strcmp(TheKidName, "squid-disk"))
+                TheProcessKind = pkDisker;
+            else
+                TheProcessKind = pkOther; // including coordinator
         }
     } else {
         xstrncpy(TheKidName, APP_SHORTNAME, sizeof(TheKidName));
@@ -1240,8 +1262,7 @@ SquidMain(int argc, char **argv)
 {
     ConfigureCurrentKid(argv[0]);
 
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     int WIN32_init_err;
 #endif
 
@@ -1260,11 +1281,9 @@ SquidMain(int argc, char **argv)
 
 #endif
 
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     if ((WIN32_init_err = WIN32_Subsystem_Init(&argc, &argv)))
         return WIN32_init_err;
-
 #endif
 
     /* call mallopt() before anything else */
@@ -1350,11 +1369,13 @@ SquidMain(int argc, char **argv)
 
         /* we may want the parsing process to set this up in the future */
         Store::Root(new StoreController);
-
-        InitAuthSchemes();      /* required for config parsing */
-
+#if USE_AUTH
+        Auth::Init();      /* required for config parsing */
+#endif
         Ip::ProbeTransport(); // determine IPv4 or IPv6 capabilities before parsing.
 
+        Format::Token::Init(); // XXX: temporary. Use a runners registry of pre-parse runners instead.
+
         parse_err = parseConfigFile(ConfigFile);
 
         Mem::Report();
@@ -1396,6 +1417,12 @@ SquidMain(int argc, char **argv)
         /* NOTREACHED */
     }
 
+    debugs(1,2, HERE << "Doing post-config initialization\n");
+    leave_suid();
+    ActivateRegistered(rrClaimMemoryNeeds);
+    ActivateRegistered(rrAfterConfig);
+    enter_suid();
+
     if (!opt_no_daemon && Config.workers > 0)
         watch_child(argv);
 
@@ -1470,7 +1497,7 @@ SquidMain(int argc, char **argv)
 
     if (IamCoordinatorProcess())
         AsyncJob::Start(Ipc::Coordinator::Instance());
-    else if (UsingSmp() && IamWorkerProcess())
+    else if (UsingSmp() && (IamWorkerProcess() || IamDiskProcess()))
         AsyncJob::Start(new Ipc::Strand);
 
     /* at this point we are finished the synchronous startup. */
@@ -1507,7 +1534,7 @@ sendSignal(void)
             WIN32_sendSignal(opt_send_signal);
             exit(0);
         } else
-#ifdef _SQUID_MSWIN_
+#if _SQUID_MSWIN_
         {
             fprintf(stderr, "%s: ERROR: Could not send ", APP_SHORTNAME);
             fprintf(stderr, "signal to Squid Service:\n");
@@ -1542,7 +1569,7 @@ sendSignal(void)
     exit(0);
 }
 
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_MSWIN_
 /*
  * This function is run when Squid is in daemon mode, just
  * before the parent forks and starts up the child process.
@@ -1572,7 +1599,7 @@ mainStartScript(const char *prog)
         _exit(-1);
     } else {
         do {
-#ifdef _SQUID_NEXT_
+#if _SQUID_NEXT_
             union wait status;
             rpid = wait4(cpid, &status, 0, NULL);
 #else
@@ -1615,9 +1642,9 @@ checkRunningPid(void)
 static void
 watch_child(char *argv[])
 {
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_MSWIN_
     char *prog;
-#ifdef _SQUID_NEXT_
+#if _SQUID_NEXT_
 
     union wait status;
 #else
@@ -1675,12 +1702,17 @@ watch_child(char *argv[])
         dup2(nullfd, 2);
     }
 
+    // handle shutdown notifications from kids
+    squid_signal(SIGUSR1, sig_shutdown, SA_RESTART);
+
     if (Config.workers > 128) {
         syslog(LOG_ALERT, "Suspiciously high workers value: %d",
                Config.workers);
         // but we keep going in hope that user knows best
     }
-    TheKids.init(Config.workers);
+    TheKids.init();
+
+    syslog(LOG_NOTICE, "Squid Parent: will start %d kids", (int)TheKids.count());
 
     // keep [re]starting kids until it is time to quit
     for (;;) {
@@ -1689,7 +1721,7 @@ watch_child(char *argv[])
         // start each kid that needs to be [re]started; once
         for (int i = TheKids.count() - 1; i >= 0; --i) {
             Kid& kid = TheKids.get(i);
-            if (kid.hopeless() || kid.exitedHappy() || kid.running())
+            if (!kid.shouldRestart())
                 continue;
 
             if ((pid = fork()) == 0) {
@@ -1702,7 +1734,8 @@ watch_child(char *argv[])
             }
 
             kid.start(pid);
-            syslog(LOG_NOTICE, "Squid Parent: child process %d started", pid);
+            syslog(LOG_NOTICE, "Squid Parent: %s process %d started",
+                   kid.name().termedBuf(), pid);
         }
 
         /* parent */
@@ -1710,7 +1743,7 @@ watch_child(char *argv[])
 
         squid_signal(SIGINT, SIG_IGN, SA_RESTART);
 
-#ifdef _SQUID_NEXT_
+#if _SQUID_NEXT_
 
         pid = wait3(&status, 0, NULL);
 
@@ -1726,41 +1759,50 @@ watch_child(char *argv[])
                 kid->stop(status);
                 if (kid->calledExit()) {
                     syslog(LOG_NOTICE,
-                           "Squid Parent: child process %d exited with status %d",
+                           "Squid Parent: %s process %d exited with status %d",
+                           kid->name().termedBuf(),
                            kid->getPid(), kid->exitStatus());
                 } else if (kid->signaled()) {
                     syslog(LOG_NOTICE,
-                           "Squid Parent: child process %d exited due to signal %d with status %d",
+                           "Squid Parent: %s process %d exited due to signal %d with status %d",
+                           kid->name().termedBuf(),
                            kid->getPid(), kid->termSignal(), kid->exitStatus());
                 } else {
-                    syslog(LOG_NOTICE, "Squid Parent: child process %d exited", kid->getPid());
+                    syslog(LOG_NOTICE, "Squid Parent: %s process %d exited",
+                           kid->name().termedBuf(), kid->getPid());
+                }
+                if (kid->hopeless()) {
+                    syslog(LOG_NOTICE, "Squid Parent: %s process %d will not"
+                           " be restarted due to repeated, frequent failures",
+                           kid->name().termedBuf(), kid->getPid());
                 }
             } else {
                 syslog(LOG_NOTICE, "Squid Parent: unknown child process %d exited", pid);
             }
-#ifdef _SQUID_NEXT_
+#if _SQUID_NEXT_
         } while ((pid = wait3(&status, WNOHANG, NULL)) > 0);
 #else
         }
         while ((pid = waitpid(-1, &status, WNOHANG)) > 0);
 #endif
 
-        if (TheKids.allExitedHappy()) {
-            exit(0);
-        }
+        if (!TheKids.someRunning() && !TheKids.shouldRestartSome()) {
+            leave_suid();
+            DeactivateRegistered(rrAfterConfig);
+            DeactivateRegistered(rrClaimMemoryNeeds);
+            enter_suid();
 
-        if (TheKids.allHopeless()) {
-            syslog(LOG_ALERT, "Exiting due to repeated, frequent failures");
-            exit(1);
-        }
+            if (TheKids.someSignaled(SIGINT) || TheKids.someSignaled(SIGTERM)) {
+                syslog(LOG_ALERT, "Exiting due to unexpected forced shutdown");
+                exit(1);
+            }
 
-        if (TheKids.allSignaled(SIGKILL)) {
-            exit(0);
-        }
+            if (TheKids.allHopeless()) {
+                syslog(LOG_ALERT, "Exiting due to repeated, frequent failures");
+                exit(1);
+            }
 
-        if (TheKids.allSignaled(SIGINT) || TheKids.allSignaled(SIGTERM)) {
-            syslog(LOG_ALERT, "Exiting due to unexpected forced shutdown");
-            exit(1);
+            exit(0);
         }
 
         squid_signal(SIGINT, SIG_DFL, SA_RESTART);
@@ -1786,13 +1828,7 @@ SquidShutdown()
 #endif
 
     debugs(1, 1, "Shutting down...");
-#if USE_DNSSERVERS
-
     dnsShutdown();
-#else
-
-    idnsShutdown();
-#endif
 #if USE_SSL_CRTD
     Ssl::Helper::GetInstance()->Shutdown();
 #endif
@@ -1804,7 +1840,6 @@ SquidShutdown()
     htcpSocketClose();
 #endif
 #if SQUID_SNMP
-
     snmpConnectionClose();
 #endif
 #if USE_WCCP
@@ -1826,8 +1861,9 @@ SquidShutdown()
 #if USE_DELAY_POOLS
     DelayPools::FreePools();
 #endif
-
+#if USE_AUTH
     authenticateReset();
+#endif
 #if USE_WIN32_SERVICE
 
     WIN32_svcstatusupdate(SERVICE_STOP_PENDING, 10000);
@@ -1848,6 +1884,8 @@ SquidShutdown()
     Store::Root().sync();              /* Flush log close */
     StoreFileSystem::FreeAllFs();
     DiskIOModule::FreeAllModules();
+    DeactivateRegistered(rrAfterConfig);
+    DeactivateRegistered(rrClaimMemoryNeeds);
 #if LEAK_CHECK_MODE && 0 /* doesn't work at the moment */
 
     configFreeMemory();