Subject: Re: [bug#30637] [WIP] shepherd: Poll every 0.5s to find dead forked services

From: [email-masked] (Ludovic Courtès)
Date: Mon, 05 Mar 2018 15:15:10 +0100

Carlo Zancanaro <[email-masked]> skribis:

> From be442ea64e4fd8e235378a5f04d38296c0af9cf3 Mon Sep 17 00:00:00 2001
> From: Carlo Zancanaro <[email-masked]>
> Date: Wed, 21 Feb 2018 22:57:59 +1100
> Subject: [PATCH] Poll every 0.5s to find dead forked services if prctl fails.
>
> * modules/shepherd.scm (open-server-socket): Set socket to be
>   non-blocking.
>   (main): If we are unable to use prctl/PR_SET_CHILD_SUBREAPER, then poll for
>   service processes between client connections, or every 0.5 seconds.
> * modules/shepherd/service.scm (fork+exec-command): Install handle-SIGCHLD as
>   signal handler.
>   (respawn-service): Separate logic for respawning services from handling
>   SIGCHLD.
>   (handle-SIGCHLD, check-for-dead-services): New exported procedures.
> * tests/basic.sh, tests/status-sexp.sh: Replace constant integers with
>   symbols.
> * doc/shepherd.texi (Slots of services): Add note about service running slot
>   being a process id.

Awesome.  Applied with minor cosmetic changes (see below).

Thank you!

Ludo’.

diff --git a/modules/shepherd.scm b/modules/shepherd.scm
index 9d94881..2b4a7b5 100644
--- a/modules/shepherd.scm
+++ b/modules/shepherd.scm
@@ -52,7 +52,8 @@
 ;; Main program.
 (define (main . args)
   (define poll-services?
-    (and (not (= 1 (getpid))) ;; if we're pid 1 we don't need to do anything
+    ;; Do we need polling to find out whether services died?
+    (and (not (= 1 (getpid)))                     ;if we're pid 1, we don't
          (catch 'system-error
            (lambda ()
              ;; Register for orphaned processes to be reparented onto us when
@@ -60,14 +61,13 @@
              ;; daemon processes that would otherwise have been reparented
              ;; under pid 1. Obviously this is unnecessary when we are pid 1.
              (prctl PR_SET_CHILD_SUBREAPER 1)
-             #f) ;; don't poll
+             #f)                                  ;don't poll
            (lambda args
              ;; We fall back to polling for services on systems that don't
-             ;; support prctl/PR_SET_CHILD_SUBREAPER
+             ;; support prctl/PR_SET_CHILD_SUBREAPER.
              (let ((errno (system-error-errno args)))
-               (if (or (= ENOSYS errno) ;; prctl not available
-                       (= EINVAL errno)) ;; PR_SET_CHILD_SUBREAPER not available
-                   #t ;; poll
+               (or (= ENOSYS errno)        ;prctl unavailable
+                   (= EINVAL errno)        ;PR_SET_CHILD_SUBREAPER unavailable
                    (apply throw args)))))))
 
   (initialize-cli)