mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2025-01-11 13:49:23 -05:00
shepherd: Adjust 'fork+exec-command/container' for the Shepherd 0.9.
* gnu/build/shepherd.scm (exec-command*): New procedure, with code formerly... (make-forkexec-constructor/container): ... here. Use it. (fork+exec-command/container): Use 'fork+exec-command' only when CONTAINER-SUPPORT? is false or PID is the current process.
This commit is contained in:
parent
d4172babe0
commit
938448bf40
1 changed files with 54 additions and 29 deletions
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2017, 2018, 2019, 2020, 2022 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2020 Mathieu Othacehe <othacehe@gnu.org>
|
;;; Copyright © 2020 Mathieu Othacehe <othacehe@gnu.org>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
|
@ -103,8 +103,13 @@ (define* (read-pid-file/container pid pid-file #:key (max-delay 5))
|
||||||
separate mount and PID name space. Return the \"outer\" PID. "
|
separate mount and PID name space. Return the \"outer\" PID. "
|
||||||
(match (container-excursion* pid
|
(match (container-excursion* pid
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(read-pid-file pid-file
|
;; XXX: Trick for Shepherd 0.9: prevent 'read-pid-file' from
|
||||||
#:max-delay max-delay)))
|
;; using (@ (fibers) sleep), which would try to suspend the
|
||||||
|
;; current task, which doesn't work in this extra process.
|
||||||
|
(with-continuation-barrier
|
||||||
|
(lambda ()
|
||||||
|
(read-pid-file pid-file
|
||||||
|
#:max-delay max-delay)))))
|
||||||
(#f
|
(#f
|
||||||
;; Send SIGTERM to the whole process group.
|
;; Send SIGTERM to the whole process group.
|
||||||
(catch-system-error (kill (- pid) SIGTERM))
|
(catch-system-error (kill (- pid) SIGTERM))
|
||||||
|
@ -114,6 +119,26 @@ (define* (read-pid-file/container pid pid-file #:key (max-delay 5))
|
||||||
;; PID is always 1, but that's not what Shepherd needs to know.
|
;; PID is always 1, but that's not what Shepherd needs to know.
|
||||||
pid)))
|
pid)))
|
||||||
|
|
||||||
|
(define* (exec-command* command #:key user group log-file pid-file
|
||||||
|
directory (environment-variables (environ)))
|
||||||
|
"Like 'exec-command', but first restore signal handles modified by
|
||||||
|
shepherd (PID 1)."
|
||||||
|
;; First restore the default handlers.
|
||||||
|
(for-each (cut sigaction <> SIG_DFL) %precious-signals)
|
||||||
|
|
||||||
|
;; Unblock any signals that have been blocked by the parent process.
|
||||||
|
(unblock-signals %precious-signals)
|
||||||
|
|
||||||
|
(mkdir-p "/var/run")
|
||||||
|
(clean-up pid-file)
|
||||||
|
|
||||||
|
(exec-command command
|
||||||
|
#:user user
|
||||||
|
#:group group
|
||||||
|
#:log-file log-file
|
||||||
|
#:directory directory
|
||||||
|
#:environment-variables environment-variables))
|
||||||
|
|
||||||
(define* (make-forkexec-constructor/container command
|
(define* (make-forkexec-constructor/container command
|
||||||
#:key
|
#:key
|
||||||
(namespaces
|
(namespaces
|
||||||
|
@ -164,24 +189,14 @@ (define mounts
|
||||||
(let ((pid (run-container container-directory
|
(let ((pid (run-container container-directory
|
||||||
mounts namespaces 1
|
mounts namespaces 1
|
||||||
(lambda ()
|
(lambda ()
|
||||||
;; First restore the default handlers.
|
(exec-command* command
|
||||||
(for-each (cut sigaction <> SIG_DFL)
|
#:user user
|
||||||
%precious-signals)
|
#:group group
|
||||||
|
#:pid-file pid-file
|
||||||
;; Unblock any signals that have been blocked
|
#:log-file log-file
|
||||||
;; by the parent process.
|
#:directory directory
|
||||||
(unblock-signals %precious-signals)
|
#:environment-variables
|
||||||
|
environment-variables)))))
|
||||||
(mkdir-p "/var/run")
|
|
||||||
(clean-up pid-file)
|
|
||||||
|
|
||||||
(exec-command command
|
|
||||||
#:user user
|
|
||||||
#:group group
|
|
||||||
#:log-file log-file
|
|
||||||
#:directory directory
|
|
||||||
#:environment-variables
|
|
||||||
environment-variables)))))
|
|
||||||
(if pid-file
|
(if pid-file
|
||||||
(if (or (memq 'mnt namespaces) (memq 'pid namespaces))
|
(if (or (memq 'mnt namespaces) (memq 'pid namespaces))
|
||||||
(read-pid-file/container pid pid-file
|
(read-pid-file/container pid pid-file
|
||||||
|
@ -209,14 +224,24 @@ (define (strip-pid args)
|
||||||
((head . rest)
|
((head . rest)
|
||||||
(loop rest (cons head result))))))
|
(loop rest (cons head result))))))
|
||||||
|
|
||||||
(let ((container-support?
|
(let ((container-support? (file-exists? "/proc/self/ns")))
|
||||||
(file-exists? "/proc/self/ns"))
|
(if (and container-support?
|
||||||
(fork-proc (lambda ()
|
(not (and pid (= pid (getpid)))))
|
||||||
(apply fork+exec-command command
|
(container-excursion* pid
|
||||||
(strip-pid args)))))
|
(lambda ()
|
||||||
(if container-support?
|
;; Note: In the Shepherd 0.9, 'fork+exec-command' expects to be
|
||||||
(container-excursion* pid fork-proc)
|
;; called from the shepherd process (because it creates a pipe to
|
||||||
(fork-proc))))
|
;; capture stdout/stderr and spawns a logging fiber) so we cannot
|
||||||
|
;; use it here.
|
||||||
|
(match (primitive-fork)
|
||||||
|
(0 (dynamic-wind
|
||||||
|
(const #t)
|
||||||
|
(lambda ()
|
||||||
|
(apply exec-command* command (strip-pid args)))
|
||||||
|
(lambda ()
|
||||||
|
(primitive-_exit 127))))
|
||||||
|
(pid #t))))
|
||||||
|
(apply fork+exec-command command (strip-pid args)))))
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; eval: (put 'container-excursion* 'scheme-indent-function 1)
|
;; eval: (put 'container-excursion* 'scheme-indent-function 1)
|
||||||
|
|
Loading…
Reference in a new issue