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

From: [email-masked] (Ludovic Courtès)
Date: Wed, 28 Feb 2018 23:06:06 +0100

Hi Carlo,

Carlo Zancanaro <[email-masked]> skribis:

> Another patch for shepherd!

Always welcome!  :-)

> The problem is that shepherd, when run as a user process, can "lose"
> services which fork away. Shepherd can still kill them, but a SIGCHLD
> won't be delivered if they die, so shepherd can't restart/disable
> them. My prime example is emacs, which I run with --daemon. If I then
> kill emacs, shepherd will still think that it is running.

There are two issues here, I think.

  1. shepherd cannot lose SIGCHLD: if a process dies immediately once
     it’s been spawned, as is the case with “emacs --daemon” or any
     other daemon-style program, it should receive SIGCHLD and process
     it.

     However, there could be a race condition: if SIGCHLD is handled
     before the ‘running’ value has been set, then we’ll still get the
     non-#f ‘running’ value even though the process died in the
     meantime.

     The code tries to prevent that (see (shepherd service) around line
     320), but looking more closely, I think the race is still there.
     Namely, the whole ‘let’ block, including the call to ‘start’,
     should be in ‘call-with-blocked-asyncs’, I think.  Could you check
     if that helps for you?

  2. shepherd currently can’t do much with real daemons.  So what we do
     in GuixSD is to either start programs in non-daemon mode, when
     that’s an option, or pass #:pid-file to retrieve the forked process
     PID.  I think you should do one of these as well.

WDYT?

Thanks,
Ludo’.