container: Allow 'container-excursion' to the same namespaces.
Before that, 'container-excursion' would call 'setns' even when the target namespace is the one the caller is already in, which would fail. * gnu/build/linux-container.scm (container-excursion): Introduce 'source' and 'target'. Compare the result of 'readlink' on these instead of comparing file descriptors to decide whether to call 'setns'. * tests/containers.scm ("container-excursion, same namespace"): New test.
This commit is contained in:
parent
99df12cd19
commit
7fee5b5397
|
@ -291,15 +291,17 @@ return the exit status."
|
|||
(call-with-clean-exit
|
||||
(lambda ()
|
||||
(for-each (lambda (ns)
|
||||
(call-with-input-file (namespace-file (getpid) ns)
|
||||
(lambda (current-ns-port)
|
||||
(call-with-input-file (namespace-file pid ns)
|
||||
(lambda (new-ns-port)
|
||||
;; Joining the namespace that the process
|
||||
;; already belongs to would throw an error.
|
||||
(unless (= (port->fdes current-ns-port)
|
||||
(port->fdes new-ns-port))
|
||||
(setns (port->fdes new-ns-port) 0)))))))
|
||||
(let ((source (namespace-file (getpid) ns))
|
||||
(target (namespace-file pid ns)))
|
||||
;; Joining the namespace that the process already
|
||||
;; belongs to would throw an error so avoid that.
|
||||
;; XXX: This /proc interface leads to TOCTTOU.
|
||||
(unless (string=? (readlink source) (readlink target))
|
||||
(call-with-input-file source
|
||||
(lambda (current-ns-port)
|
||||
(call-with-input-file target
|
||||
(lambda (new-ns-port)
|
||||
(setns (fileno new-ns-port) 0))))))))
|
||||
;; It's important that the user namespace is joined first,
|
||||
;; so that the user will have the privileges to join the
|
||||
;; other namespaces. Furthermore, it's important that the
|
||||
|
|
|
@ -162,4 +162,13 @@
|
|||
(waitpid pid)
|
||||
(zero? result)))))))
|
||||
|
||||
(skip-if-unsupported)
|
||||
(test-equal "container-excursion, same namespaces"
|
||||
42
|
||||
;; The parent and child are in the same namespaces. 'container-excursion'
|
||||
;; should notice that and avoid calling 'setns' since that would fail.
|
||||
(container-excursion (getpid)
|
||||
(lambda ()
|
||||
(primitive-exit 42))))
|
||||
|
||||
(test-end)
|
||||
|
|
Loading…
Reference in New Issue