From: Eduard Bagdasaryan Date: Tue, 23 May 2017 08:45:16 +0000 (+1200) Subject: Create PID file ASAP, before the shared memory segments. X-Git-Tag: M-staged-PR71~167 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01ac0a5b7fe21a1049a65e8b91d7fe2198cdb051;p=thirdparty%2Fsquid.git Create PID file ASAP, before the shared memory segments. PID file is created right after configuration finalization, before the allocation for any shared memory segments. Late PID file creation allowed N+1 concurrent Squid instances to create the same set of shared segments (overwriting each other segments), resulting in extremely confusing havoc because the N instances would later lose the race for the PID file (or some other critical resource) creation and remove the segments. If that removal happened before a kid of the single surviving instance started, that kid would fail to start with open() errors in Segment.cc because the shared segment it tries to open would be gone. Otherwise, that kid would fail to _restart_ after any unrelated failures (possibly many days after the conflict), with same errors, for the same reason. Shared state corruption was also possible if different kids (of the winning instance) opened (and started using) segments created (and initialized) by different instances. Situations with N+1 concurrent Squid instances are not uncommon because many Squid service management scripts (or manual admin commands!) * do not check whether another Squid is already running and/or * incorrectly assume that "squid -z" does not daemonize. This change finally makes starting N+1 Squid instances safe (AFAIK). Also made daemonized and non-daemonized Squid create the PID file at the same startup stage, reducing inconsistencies between the two modes. --- diff --git a/src/main.cc b/src/main.cc index add9cf811b..96325d21a2 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1257,9 +1257,6 @@ mainInitialize(void) if (Config.chroot_dir) no_suid(); - if (!InDaemonMode() && IamMasterProcess()) - Instance::WriteOurPid(); - #if defined(_SQUID_LINUX_THREADS_) squid_signal(SIGQUIT, rotate_logs, SA_RESTART); @@ -1406,6 +1403,12 @@ ConfigureCurrentKid(const char *processName) } } +static void StartUsingConfig() +{ + RunRegisteredHere(RegisteredRunner::claimMemoryNeeds); + RunRegisteredHere(RegisteredRunner::useConfig); +} + int SquidMain(int argc, char **argv) { @@ -1569,15 +1572,19 @@ SquidMain(int argc, char **argv) debugs(1,2, HERE << "Doing post-config initialization\n"); leave_suid(); RunRegisteredHere(RegisteredRunner::finalizeConfig); - RunRegisteredHere(RegisteredRunner::claimMemoryNeeds); - RunRegisteredHere(RegisteredRunner::useConfig); - enter_suid(); - if (InDaemonMode() && IamMasterProcess()) { - watch_child(argv); - // NOTREACHED + if (IamMasterProcess()) { + if (InDaemonMode()) { + watch_child(argv); + // NOTREACHED + } else { + Instance::WriteOurPid(); + } } + StartUsingConfig(); + enter_suid(); + if (opt_create_swap_dirs) { /* chroot if configured to run inside chroot */ mainSetCwd(); @@ -1762,6 +1769,8 @@ watch_child(char *argv[]) int nullfd; + enter_suid(); + openlog(APP_SHORTNAME, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4); if ((pid = fork()) < 0) { @@ -1815,8 +1824,10 @@ watch_child(char *argv[]) dup2(nullfd, 2); } + leave_suid(); Instance::WriteOurPid(); - enter_suid(); // writing the PID file usually involves leave_suid() + StartUsingConfig(); + enter_suid(); #if defined(_SQUID_LINUX_THREADS_) squid_signal(SIGQUIT, rotate_logs, 0);