]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fix option --foreground to implement expected behavior
authorAndreas Weigel <andreas.weigel@securepoint.de>
Thu, 29 Jun 2017 10:53:05 +0000 (22:53 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Thu, 29 Jun 2017 10:53:05 +0000 (22:53 +1200)
... 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.

doc/release-notes/release-4.sgml
src/main.cc

index a97b1d88e698e4d279a141f1297f3f064ce218b6..f81ba993bf58bc587478d182dc9b8a727a80a30f 100644 (file)
@@ -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.
 
-<p>The squid binary now has a new <em>--foreground</em> 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 <em>-N</em> option
+<p>The squid binary now has a new <em>--foreground</em> command line option,
+   which (only) prevents daemonizing the master process.
+   Unlike the old <em>-N</em> option,
    <em>--foreground</em> supports SMP workers and multi-process features.
    <em>--foreground</em> is particularly useful for use with <em>-z</em> (disk
    cache structures creation), as it allows the caller to wait until Squid has
index 1467d3771156b53af737b58ba361503ccaecc8e6..bb7f9cee27d9eadc93d94da8faf31e424bc23249 100644 (file)
@@ -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