From: Andreas Weigel Date: Thu, 29 Jun 2017 10:53:05 +0000 (+1200) Subject: Fix option --foreground to implement expected behavior X-Git-Tag: SQUID_4_0_21~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a75ea465c59f044e73fcc0008b80225aebdf7c7e;p=thirdparty%2Fsquid.git Fix option --foreground to implement expected behavior ... and allow usage of SMP mode with service supervisors that do not work well with daemons. Currently, --foreground behavior is counter-intuitive in that the launched process, while staying in the foreground, forks another "master" process, which will create additional children (kids), depending on the number of configured workers/diskers. Furthermore, sending a SIGINT/SIGTERM signal to this foreground process terminates it, but leaves all the children running. The behavior got introduced with v4 rev.14561. From discussion on squid-dev, the following behavior is implemented: * -N: The initial process is a master and a worker process. No kids. No daemonimization. * --foreground: The initial process is the master process. One or more worker kids (depending on workers=N). No daemonimization. * neither: The initial process double-forks the master process. One or more worker kids (depending on workers=N). Daemonimization. The Release Notes for v4 were updated to reflect the corrected behavior. --- diff --git a/doc/release-notes/release-4.sgml b/doc/release-notes/release-4.sgml index a97b1d88e6..f81ba993bf 100644 --- a/doc/release-notes/release-4.sgml +++ b/doc/release-notes/release-4.sgml @@ -165,10 +165,9 @@ Most user-facing changes are reflected in squid.conf (see below). integration with daemon managers such as Upstart or systemd which assume the process they initiated is the daemon with a PID to control. -

The squid binary now has a new --foreground command line option - which prevents the process from exiting early while background workers - continue their processing. When run with this option Squid will now wait - for the worker(s) to finish before exiting. Unlike the old -N option +

The squid binary now has a new --foreground command line option, + which (only) prevents daemonizing the master process. + Unlike the old -N option, --foreground supports SMP workers and multi-process features. --foreground is particularly useful for use with -z (disk cache structures creation), as it allows the caller to wait until Squid has diff --git a/src/main.cc b/src/main.cc index 1467d37711..bb7f9cee27 100644 --- a/src/main.cc +++ b/src/main.cc @@ -388,9 +388,9 @@ usage(void) " -C Do not catch fatal signals.\n" " -D OBSOLETE. Scheduled for removal.\n" " -F Don't serve any requests until store is rebuilt.\n" - " -N No daemon mode.\n" + " -N Master process runs in foreground and is a worker. No kids.\n" " --foreground\n" - " Parent process does not exit until its children have finished.\n" + " Master process runs in foreground and creates worker kids.\n" #if USE_WIN32_SERVICE " -O options\n" " Set Windows Service Command line options in Registry.\n" @@ -1800,12 +1800,29 @@ masterSignaled() return (DebugSignal > 0 || RotateSignal > 0 || ReconfigureSignal > 0 || ShutdownSignal > 0); } +#if !_SQUID_WINDOWS_ +/// makes the caller a daemon process running in the background +static void +GoIntoBackground() +{ + pid_t pid; + if ((pid = fork()) < 0) { + int xerrno = errno; + syslog(LOG_ALERT, "fork failed: %s", xstrerr(xerrno)); + // continue anyway, mimicking --foreground mode (XXX?) + } else if (pid > 0) { + // parent + exit(EXIT_SUCCESS); + } + // child, running as a background daemon (or a failed-to-fork parent) +} +#endif /* !_SQUID_WINDOWS_ */ + static void watch_child(char *argv[]) { #if !_SQUID_WINDOWS_ char *prog; - PidStatus status_f, status; pid_t pid; #ifdef TIOCNOTTY @@ -1818,21 +1835,12 @@ watch_child(char *argv[]) openlog(APP_SHORTNAME, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4); - if ((pid = fork()) < 0) { - int xerrno = errno; - syslog(LOG_ALERT, "fork failed: %s", xstrerr(xerrno)); - } else if (pid > 0) { - // parent - if (opt_foreground) { - if (WaitForAnyPid(status_f, 0) < 0) { - int xerrno = errno; - syslog(LOG_ALERT, "WaitForAnyPid failed: %s", xstrerr(xerrno)); - } - } - - exit(0); - } + if (!opt_foreground) + GoIntoBackground(); + // TODO: Fails with --foreground if the calling process is process group + // leader, which is always (?) the case. Should probably moved to + // GoIntoBackground and executed only after successfully forking if (setsid() < 0) { int xerrno = errno; syslog(LOG_ALERT, "setsid failed: %s", xstrerr(xerrno)); @@ -1942,6 +1950,7 @@ watch_child(char *argv[]) int waitFlag = 0; if (masterSignaled()) waitFlag = WNOHANG; + PidStatus status; pid = WaitForAnyPid(status, waitFlag); // check for a stopped kid