Subject: bug#63190: [Shepherd] Nested calls lead to a hang

From: Ludovic Courtès <[email-masked]>
Date: Sat, 06 May 2023 19:26:38 +0200

Hi,

Bruno Victal <[email-masked]> skribis:

> Original discussion (IRC): <https://logs.guix.gnu.org/guix/2023-04-29.log#180735>

[...]

>               (procedure
>                #~(lambda (x)
>                    ;; Scenario 1: using code from (gnu services herd), this hangs shepherd
>                    #;(start-service 'dummy)  ; hangs shepherd

(gnu services herd) provides a client to talk to the shepherd process.
However, the code of actions runs in the shepherd process itself, so
there’s no need to use the client library.  Don’t do that.  :-)

(Whether that leads to a deadlock depends; at first sight, I’d say
there’s no reason for this to deadlock in general, but you can of course
end up with a logic bug like A starts B, which spawns a client to start
A, which doesn’t start because it’s waiting for B.)

>                    ;; Scenario 2: this doesn't hang shepherd but do note that the service has to be re-enabled either manually or automatically here
>                    #;(system* #$(file-append shepherd "/bin/herd") "start" "dummy-service")

This is equivalent to the one above.

>                    ;; Scenario 3: use the already imported (shepherd service) module, doesn't hang shepherd
>                    ;;             Like Scenario 2, the service must be re-enabled since (respawn? #f) disabled this.
>                    ;;             Comment: Won't re-enabling mean that this service will relaunch once it quits?
>                    ;;                      That means the service has to disable itself on a successful exit, perhaps within the (stop ...) field?
>                    (start 'dummy-service))))))))

This should work without blocking.

However, starting a service from another one doesn’t sound great.

Could you give more context?

Thanks,
Ludo’.