aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2025-03-25 16:51:59 +0100
committerLudovic Courtès <ludo@gnu.org>2025-04-20 18:50:51 +0200
commitc990405607f3692420ed94e75a7046feff3e28ce (patch)
tree0c98e41a457f929795c7e1119b9da1e511912116
parent78f493dcf82b37c4147f303c4fef8140640d56f2 (diff)
downloadguix-c990405607f3692420ed94e75a7046feff3e28ce.tar.gz
guix-c990405607f3692420ed94e75a7046feff3e28ce.zip
syscalls: Add ‘unshare’.
* guix/build/syscalls.scm (unshare): New procedure. Change-Id: I344273b8bdeaa9366334e6e20ee7efc37eb6c8f7
-rw-r--r--guix/build/syscalls.scm18
-rw-r--r--tests/syscalls.scm9
2 files changed, 27 insertions, 0 deletions
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index 42232fc7f1..cf09cae3a4 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -145,6 +145,7 @@
CLONE_NEWPID
CLONE_NEWNET
clone
+ unshare
setns
kexec-load-file
@@ -1213,6 +1214,23 @@ are shared between the parent and child processes."
(list err))
ret)))))
+(define unshare
+ (let ((proc (syscall->procedure int "unshare" (list int))))
+ (lambda (flags)
+ "Disassociate the current process from parts of its execution context
+according to FLAGS, which must be a logical or of CLONE_NEW* constants.
+
+Note that CLONE_NEWUSER requires that the calling process be single-threaded,
+which is possible if and only if libgc is running a single marker thread; this
+can be achieved by setting the GC_MARKERS environment variable to 1. If the
+calling process is multi-threaded, this throws to 'system-error' with EINVAL."
+ (let-values (((ret err)
+ (without-automatic-finalization (proc flags))))
+ (unless (zero? ret)
+ (throw 'system-error "unshare" "~a: ~A"
+ (list flags (strerror err))
+ (list err)))))))
+
(define setns
;; Some systems may be using an old (pre-2.14) version of glibc where there
;; is no 'setns' function available.
diff --git a/tests/syscalls.scm b/tests/syscalls.scm
index d2848879d7..879c3e4f25 100644
--- a/tests/syscalls.scm
+++ b/tests/syscalls.scm
@@ -149,6 +149,15 @@
((_ . status)
(= 42 (status:exit-val status))))))))
+(test-equal "unshare"
+ EPERM
+ ;; Unless running as root, (unshare CLONE_NEWNS) returns EPERM.
+ (catch 'system-error
+ (lambda ()
+ (unshare CLONE_NEWNS))
+ (lambda args
+ (system-error-errno args))))
+
(unless perform-container-tests?
(test-skip 1))
(test-assert "setns"