*
*/
-#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"
+#endif
+#include "comm.h"
#include "ConfigParser.h"
+#include "CpuAffinity.h"
+#if USE_DELAY_POOLS
+#include "DelayPools.h"
+#endif
#include "errorpage.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"
#include "htcp.h"
#include "StoreFileSystem.h"
#include "DiskIO/DiskIOModule.h"
-#include "comm.h"
#include "ipc/Kids.h"
#include "ipc/Coordinator.h"
#include "ipc/Strand.h"
-#if USE_EPOLL
-#include "comm_epoll.h"
-#endif
-#if USE_KQUEUE
-#include "comm_kqueue.h"
-#endif
-#if USE_POLL
-#include "comm_poll.h"
-#endif
-#if defined(USE_SELECT) || defined(USE_SELECT_WIN32)
-#include "comm_select.h"
-#endif
+#include "ip/tools.h"
#include "SquidTime.h"
+#include "StatCounters.h"
#include "SwapDir.h"
#include "forward.h"
#include "MemPool.h"
#include "LoadableModules.h"
#endif
+#if USE_SSL_CRTD
+#include "ssl/helper.h"
+#include "ssl/certificate_db.h"
+#endif
+
+#if USE_SSL
+#include "ssl/context_storage.h"
+#endif
+
#if ICAP_CLIENT
#include "adaptation/icap/Config.h"
#endif
#if USE_ADAPTATION
#include "adaptation/Config.h"
#endif
-
#if USE_SQUID_ESI
#include "esi/Module.h"
#endif
-
#include "fs/Module.h"
-#if USE_WIN32_SERVICE
+#if HAVE_PATHS_H
+#include <paths.h>
+#endif
+#if USE_WIN32_SERVICE
#include "squid_windows.h"
#include <process.h>
#endif
-/** for error reporting from xmalloc and friends */
-SQUIDCEXTERN void (*failure_notify) (const char *);
+#if !defined(SQUID_BUILD_INFO)
+#define SQUID_BUILD_INFO ""
+#endif
-static int opt_parse_cfg_only = 0;
static char *opt_syslog_facility = NULL;
static int icpPortNumOverride = 1; /* Want to detect "-u 0" */
static int configured_once = 0;
static void mainSetCwd(void);
static int checkRunningPid(void);
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_MSWIN_
static const char *squid_start_script = "squid_start";
#endif
/* 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);
}
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)))
case 'v':
/** \par v
* Display squid version and build information. Then exit. */
- printf("Squid Cache: Version %s\nconfigure options: %s\n", version_string, SQUID_CONFIGURE_OPTIONS);
+ printf("Squid Cache: Version %s\n" ,version_string);
+ if (strlen(SQUID_BUILD_INFO))
+ printf("%s\n",SQUID_BUILD_INFO);
+ printf( "configure options: %s\n", SQUID_CONFIGURE_OPTIONS);
#if USE_WIN32_SERVICE
{
do_rotate = 1;
RotateSignal = sig;
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_MSWIN_
#if !HAVE_SIGACTION
signal(sig, rotate_logs);
{
do_reconfigure = 1;
ReconfigureSignal = sig;
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_MSWIN_
#if !HAVE_SIGACTION
signal(sig, reconfigure);
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 */
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
htcpInit();
#endif
#if SQUID_SNMP
-
snmpConnectionOpen();
#endif
peerSelectInit();
carpInit();
+#if USE_AUTH
peerUserHashInit();
+#endif
peerSourceHashInit();
}
}
wccp2ConnectionClose();
#endif
}
- if (!IamCoordinatorProcess()) {
+ if (IamWorkerProcess()) {
clientHttpConnectionsClose();
icpConnectionShutdown();
#if USE_HTCP
icmpEngine.Close();
#if SQUID_SNMP
-
- snmpConnectionShutdown();
+ snmpConnectionClose();
#endif
asnFreeMemory();
htcpSocketClose();
#endif
-#if SQUID_SNMP
-
- snmpConnectionClose();
-#endif
-#if USE_DNSSERVERS
-
dnsShutdown();
-#else
-
- idnsShutdown();
+#if USE_SSL_CRTD
+ Ssl::Helper::GetInstance()->Shutdown();
+#endif
+#if USE_SSL
+ Ssl::TheGlobalContextStorage.reconfigureStart();
#endif
-
redirectShutdown();
+#if USE_AUTH
authenticateReset();
+#endif
externalAclShutdown();
storeDirCloseSwapLogs();
storeLogClose();
#if ICAP_CLIENT
icapLogClose();
#endif
- useragentLogClose();
- refererCloseLog();
eventAdd("mainReconfigureFinish", &mainReconfigureFinish, NULL, 0, 1,
false);
Config.workers = oldWorkers;
}
+ if (IamPrimaryProcess())
+ CpuAffinityCheck();
+ CpuAffinityReconfigure();
+
setUmask(Config.umask);
Mem::Report();
setEffectiveUser();
icapLogOpen();
#endif
storeLogOpen();
- useragentOpenLog();
- refererOpenLog();
-#if USE_DNSSERVERS
-
dnsInit();
-#else
-
- idnsInit();
+#if USE_SSL_CRTD
+ Ssl::Helper::GetInstance()->Init();
#endif
redirectInit();
+#if USE_AUTH
authenticateInit(&Auth::TheConfig);
+#endif
externalAclInit();
if (IamPrimaryProcess()) {
mimeInit(Config.mimeTablePathname);
+#if USE_UNLINKD
+ if (unlinkdNeeded())
+ unlinkdInit();
+#endif
+
+#if USE_DELAY_POOLS
+ Config.ClientDelay.finalize();
+#endif
+
if (Config.onoff.announce) {
if (!eventFind(start_announce, NULL))
eventAdd("start_announce", start_announce, NULL, 3600.0, 1);
mainRotate(void)
{
icmpEngine.Close();
-#if USE_DNSSERVERS
+#if USE_DNSHELPER
dnsShutdown();
#endif
redirectShutdown();
+#if USE_AUTH
authenticateRotate();
+#endif
externalAclShutdown();
_db_rotate_log(); /* cache.log */
storeDirWriteCleanLogs(1);
storeLogRotate(); /* store.log */
accessLogRotate(); /* access.log */
- useragentRotateLog(); /* useragent.log */
- refererRotateLog(); /* referer.log */
#if ICAP_CLIENT
icapLogRotate(); /*icap.log*/
#endif
-#if WIP_FWD_LOG
- fwdLogRotate();
-#endif
-
icmpEngine.Open();
-#if USE_DNSSERVERS
+#if USE_DNSHELPER
dnsInit();
#endif
redirectInit();
+#if USE_AUTH
authenticateInit(&Auth::TheConfig);
+#endif
externalAclInit();
}
{
keepCapabilities();
leave_suid(); /* Run as non privilegied user */
-#ifdef _SQUID_OS2_
+#if _SQUID_OS2_
return;
#endif
}
}
-#if DELAY_POOLS
-#include "DelayPools.h"
-#endif
-
static void
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);
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");
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();
- useragentOpenLog();
-
- refererOpenLog();
-
httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
httpReplyInitModule(); /* must go before accepting replies */
if (!configured_once) {
#if USE_UNLINKD
- unlinkdInit();
+ if (unlinkdNeeded())
+ unlinkdInit();
#endif
urlInitialize();
do_mallinfo = 1;
mimeInit(Config.mimeTablePathname);
refreshInit();
-#if DELAY_POOLS
-
+#if USE_DELAY_POOLS
DelayPools::Init();
#endif
if (!configured_once)
writePidFile(); /* write PID file */
-#ifdef _SQUID_LINUX_THREADS_
+#if defined(_SQUID_LINUX_THREADS_)
squid_signal(SIGQUIT, rotate_logs, SA_RESTART);
Esi::Init();
#endif
+#if USE_DELAY_POOLS
+ Config.ClientDelay.finalize();
+#endif
+
debugs(1, 1, "Ready to serve requests.");
if (!configured_once) {
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
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));
{
ConfigureCurrentKid(argv[0]);
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
int WIN32_init_err;
#endif
#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 */
/* we may want the parsing process to set this up in the future */
Store::Root(new StoreController);
+#if USE_AUTH
+ Auth::Init(); /* required for config parsing */
+#endif
+ Ip::ProbeTransport(); // determine IPv4 or IPv6 capabilities before parsing.
- InitAuthSchemes(); /* required for config parsing */
+ Format::Token::Init(); // XXX: temporary. Use a runners registry of pre-parse runners instead.
parse_err = parseConfigFile(ConfigFile);
comm_init();
- comm_select_init();
-
mainInitialize();
test_access();
/* 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);
+
if (opt_create_swap_dirs) {
/* chroot if configured to run inside chroot */
return 0;
}
- if (!opt_no_daemon && Config.workers > 0)
- watch_child(argv);
+ if (IamPrimaryProcess())
+ CpuAffinityCheck();
+ CpuAffinityInit();
setMaxFD();
/* init comm module */
comm_init();
- comm_select_init();
-
if (opt_no_daemon) {
/* we have to init fdstat here. */
fd_open(0, FD_LOG, "stdin");
mainLoop.setTimeService(&time_engine);
if (IamCoordinatorProcess())
- AsyncJob::AsyncStart(Ipc::Coordinator::Instance());
- else if (UsingSmp() && IamWorkerProcess())
- AsyncJob::AsyncStart(new Ipc::Strand);
+ AsyncJob::Start(Ipc::Coordinator::Instance());
+ else if (UsingSmp() && (IamWorkerProcess() || IamDiskProcess()))
+ AsyncJob::Start(new Ipc::Strand);
/* at this point we are finished the synchronous startup. */
starting_up = 0;
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");
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.
_exit(-1);
} else {
do {
-#ifdef _SQUID_NEXT_
+#if _SQUID_NEXT_
union wait status;
rpid = wait4(cpid, &status, 0, NULL);
#else
static void
watch_child(char *argv[])
{
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_MSWIN_
char *prog;
-#ifdef _SQUID_NEXT_
+#if _SQUID_NEXT_
union wait status;
#else
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 (;;) {
// 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) {
}
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 */
squid_signal(SIGINT, SIG_IGN, SA_RESTART);
-#ifdef _SQUID_NEXT_
+#if _SQUID_NEXT_
pid = wait3(&status, 0, NULL);
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);
#endif
debugs(1, 1, "Shutting down...");
-#if USE_DNSSERVERS
-
dnsShutdown();
-#else
-
- idnsShutdown();
+#if USE_SSL_CRTD
+ Ssl::Helper::GetInstance()->Shutdown();
#endif
-
redirectShutdown();
externalAclShutdown();
icpConnectionClose();
htcpSocketClose();
#endif
#if SQUID_SNMP
-
snmpConnectionClose();
#endif
#if USE_WCCP
Esi::Clean();
#endif
-#if DELAY_POOLS
-
+#if USE_DELAY_POOLS
DelayPools::FreePools();
#endif
-
+#if USE_AUTH
authenticateReset();
+#endif
#if USE_WIN32_SERVICE
WIN32_svcstatusupdate(SERVICE_STOP_PENDING, 10000);
Store::Root().sync(); /* Flush log writes */
storeLogClose();
accessLogClose();
- useragentLogClose();
- refererCloseLog();
-#if WIP_FWD_LOG
-
- fwdUninit();
-#endif
-
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();