processes: Gracefully handle daemons without clients.

Fixes <https://bugs.gnu.org/34716>.
Reported by Mark H Weaver <mhw@netris.org>.

The problem could be reproduced by running, on one hand:

  sh -c 'exec -a guix-daemon sleep 777'

and on the other hand:

  guix processes

If there is no process with PID 777, 'guix processes' would barf as it
stumbles upon a <daemon-session> record whose client is #f.

* guix/scripts/processes.scm (daemon-sessions)[child-process->session]:
New procedure, with lambda formerly passed to 'map'.  Handle #f returns
from 'lookup-process'.
Call 'child-process->session' within 'filter-map', not just 'map'.
master
Ludovic Courtès 2019-04-29 21:42:04 +02:00
parent c21d912a02
commit c20d4cac1f
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
1 changed files with 16 additions and 9 deletions

View File

@ -158,15 +158,22 @@ active sessions, and the master 'guix-daemon' process."
(= pid (process-parent-id process)))) (= pid (process-parent-id process))))
processes)) processes))
(values (map (lambda (process) (define (child-process->session process)
(match (process-command process) (match (process-command process)
((argv0 (= string->number client) _ ...) ((argv0 (= string->number client) _ ...)
(let ((files (process-open-files process))) (let ((files (process-open-files process))
(daemon-session process (client (lookup-process client)))
(lookup-process client) ;; After a client has died, there's a window during which its
(lookup-children (process-id process)) ;; corresponding 'guix-daemon' process is still alive, in which
(filter lock-file? files)))))) ;; case 'lookup-process' returns #f. In that case ignore the
children) ;; session.
(and client
(daemon-session process client
(lookup-children
(process-id process))
(filter lock-file? files)))))))
(values (filter-map child-process->session children)
master))) master)))
(define (daemon-session->recutils session port) (define (daemon-session->recutils session port)