Subject: Re: bug#53580: /var/run/shepherd/socket is missing on an otherwise functional system

From: Maxime Devos <[email-masked]>
Date: Tue, 01 Feb 2022 19:28:03 +0000

Attila Lendvai schreef op do 27-01-2022 om 11:32 [+0000]:
> (define (call-with-server-socket file-name proc)
>   "Call PROC, passing it a listening socket at FILE-NAME and deleting the
> socket file at FILE-NAME upon exit of PROC.  Return the values of PROC."
>   (let ((sock (open-server-socket file-name)))
>     (dynamic-wind
>       noop
>       (lambda () (proc sock))
>       (lambda ()
>         (close sock)
>         (catch-system-error (delete-file file-name))))))
> ```
> 
> maybe this is caused by some call/cc magic that causes an unwind that deletes the file, but then continues?

Shepherd doesn't use call/cc anywhere.  However, it does use
_delimited_ continuations, even though only through let/ec and
'guard'/'catch'/...  More generally, call/cc is typically unused in
(Guile) Scheme code, and call-with-prompt / abort-to-prompt / shift /
reset / % are used instead.

My guess what happens: the start code of a shepherd service
fails between 'fork' and 'exec', with an exception.  The exception
isn't caught (or is caught and reraised), so the 'out' guard of the
'dynamic-wind' is entered and the file representing the socket is
deleted.

If that's indeed the case, it might be a good idea to install
some exception handlers in fork+exec-command and friends (including
make-forkexec-constructor/container), to make shepherd more robust
w.r.t. services failing to start.

Greetings,
Maxime.