1
Fork 0
mirror of https://https.git.savannah.gnu.org/git/guix.git/ synced 2025-07-10 16:50:43 +02:00

syscalls: Add ‘unshare’.

* guix/build/syscalls.scm (unshare): New procedure.

Change-Id: I344273b8bdeaa9366334e6e20ee7efc37eb6c8f7
This commit is contained in:
Ludovic Courtès 2025-03-25 16:51:59 +01:00
parent 78f493dcf8
commit c990405607
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
2 changed files with 27 additions and 0 deletions

View file

@ -145,6 +145,7 @@
CLONE_NEWPID CLONE_NEWPID
CLONE_NEWNET CLONE_NEWNET
clone clone
unshare
setns setns
kexec-load-file kexec-load-file
@ -1213,6 +1214,23 @@ are shared between the parent and child processes."
(list err)) (list err))
ret))))) 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 (define setns
;; Some systems may be using an old (pre-2.14) version of glibc where there ;; Some systems may be using an old (pre-2.14) version of glibc where there
;; is no 'setns' function available. ;; is no 'setns' function available.

View file

@ -149,6 +149,15 @@
((_ . status) ((_ . status)
(= 42 (status:exit-val 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? (unless perform-container-tests?
(test-skip 1)) (test-skip 1))
(test-assert "setns" (test-assert "setns"