summary refs log tree commit diff
path: root/gnu/build/linux-container.scm
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/build/linux-container.scm')
-rw-r--r--gnu/build/linux-container.scm17
1 files changed, 13 insertions, 4 deletions
diff --git a/gnu/build/linux-container.scm b/gnu/build/linux-container.scm
index 72e3a45422..dee6885400 100644
--- a/gnu/build/linux-container.scm
+++ b/gnu/build/linux-container.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
-;;; Copyright © 2017-2019, 2022 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2017-2019, 2022, 2023 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -404,7 +404,7 @@ load path must be adjusted as needed."
 
 (define (container-excursion pid thunk)
   "Run THUNK as a child process within the namespaces of process PID and
-return the exit status."
+return the exit status, an integer as returned by 'waitpid'."
   (define (namespace-file pid namespace)
     (string-append "/proc/" (number->string pid) "/ns/" namespace))
 
@@ -432,11 +432,20 @@ return the exit status."
                   '("user" "ipc" "uts" "net" "pid" "mnt"))
         (purify-environment)
         (chdir "/")
-        (thunk))))
+
+        ;; Per setns(2), changing the PID namespace only applies to child
+        ;; processes, not to the process itself.  Thus fork so that THUNK runs
+        ;; in the right PID namespace, which also gives it access to /proc.
+        (match (primitive-fork)
+          (0 (call-with-clean-exit thunk))
+          (pid (primitive-exit
+                (match (waitpid pid)
+                  ((_ . status)
+                   (or (status:exit-val status) 127)))))))))
     (pid
      (match (waitpid pid)
        ((_ . status)
-        (status:exit-val status))))))
+        status)))))
 
 (define (container-excursion* pid thunk)
   "Like 'container-excursion', but return the return value of THUNK."