<feed xmlns='http://www.w3.org/2005/Atom'>
<title>guix/gnu/build/linux-container.scm, branch master</title>
<subtitle>Transactional package manager, declarative GNU/Linux distribution, reproducible deployment tool, and more! https://guix.gnu.org</subtitle>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/'/>
<entry>
<title>linux-container: Remount / recursively as MS_PRIVATE, immediately after entering the new mount namespace.</title>
<updated>2026-06-15T09:38:46+00:00</updated>
<author>
<name>Giacomo Leidi</name>
<email>therewasa@fishinthecalculator.me</email>
</author>
<published>2026-06-07T21:45:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=518129e1130f6cc6e128af0729d678e94b7dfefd'/>
<id>518129e1130f6cc6e128af0729d678e94b7dfefd</id>
<content type='text'>
Apply the same workaround that runc, crun, and buildah apply
unconditionally: immediately after entering the new mount namespace,
remount / recursively as MS_PRIVATE. Concretely, the call we will
make in Guile mirrors the verbatim C call already present in crun at
https://github.com/containers/crun/blob/99a8512ef50c5af1b8cfff28eacddf870220ca9f/src/libcrun/linux.c#L4677:

    ret = mount (NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL);

and the Go equivalents in:

- runc (defaults to MS_SLAVE for reasons documented in its pivotRoot):
https://github.com/opencontainers/runc/blob/a7e766484c38be1f0cf9b7d960c9324316cb7204/libcontainer/rootfs_linux.go#L1106

- buildah (expands to mount("", "/", "none", MS_REC|MS_PRIVATE, "")):
https://github.com/podman-container-tools/buildah/blob/769d311d739dd4bbde496a9480879ce6aadaa1e0/bind/mount.go#L41

Our implementation:

1. Detaches the container's mount namespace from the host's propagation
peer group, so subsequent mount/umount events inside the container
do not propagate to the host.
2. Makes the kernel's pivot_root(2) preconditions satisfied: both
new_root (the tmpfs we then create) and its parent (/) have propagation
type MS_PRIVATE.
3. Should have no effect on processes outside the new mount namespace. The
host's / retains whatever propagation type it had.

mount-file-systems is only invoked from run-container when both
'mnt namespace is requested and root != "/", so we are
guaranteed to be inside a fresh mount namespace at this point and that
the remount only affects this namespace. The remount must happen before
the tmpfs is created. Once the tmpfs exists as a child of the (shared)
host /, fixing only the host / does not retroactively change the
propagation type the tmpfs already inherited. Doing the remount first
means every subsequent mount this function performs inherits MS_PRIVATE
from its parent.

* guix/build/syscalls.scm (MS_PRIVATE): New variable.
* gnu/build/linux-container.scm (mount-file-systems): Remount / recursively as MS_PRIVATE, immediately after entering the new mount namespace.
* gnu/services/containers.scm (%miniflux-create-admin-credentials,
%rootless-podman-os-with-least-authority-wrapper,
run-rootless-podman-test-with-least-authority-wrapper): New bindings.
(%test-rootless-podman-with-least-authority-wrapper): New regression
test making sure the rootless-podman-service-type does not break again
least-authority-wrapper bases services.

Fixes: https://codeberg.org/guix/guix/issues/3233
Merges: https://codeberg.org/guix/guix/pulls/9140
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Apply the same workaround that runc, crun, and buildah apply
unconditionally: immediately after entering the new mount namespace,
remount / recursively as MS_PRIVATE. Concretely, the call we will
make in Guile mirrors the verbatim C call already present in crun at
https://github.com/containers/crun/blob/99a8512ef50c5af1b8cfff28eacddf870220ca9f/src/libcrun/linux.c#L4677:

    ret = mount (NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL);

and the Go equivalents in:

- runc (defaults to MS_SLAVE for reasons documented in its pivotRoot):
https://github.com/opencontainers/runc/blob/a7e766484c38be1f0cf9b7d960c9324316cb7204/libcontainer/rootfs_linux.go#L1106

- buildah (expands to mount("", "/", "none", MS_REC|MS_PRIVATE, "")):
https://github.com/podman-container-tools/buildah/blob/769d311d739dd4bbde496a9480879ce6aadaa1e0/bind/mount.go#L41

Our implementation:

1. Detaches the container's mount namespace from the host's propagation
peer group, so subsequent mount/umount events inside the container
do not propagate to the host.
2. Makes the kernel's pivot_root(2) preconditions satisfied: both
new_root (the tmpfs we then create) and its parent (/) have propagation
type MS_PRIVATE.
3. Should have no effect on processes outside the new mount namespace. The
host's / retains whatever propagation type it had.

mount-file-systems is only invoked from run-container when both
'mnt namespace is requested and root != "/", so we are
guaranteed to be inside a fresh mount namespace at this point and that
the remount only affects this namespace. The remount must happen before
the tmpfs is created. Once the tmpfs exists as a child of the (shared)
host /, fixing only the host / does not retroactively change the
propagation type the tmpfs already inherited. Doing the remount first
means every subsequent mount this function performs inherits MS_PRIVATE
from its parent.

* guix/build/syscalls.scm (MS_PRIVATE): New variable.
* gnu/build/linux-container.scm (mount-file-systems): Remount / recursively as MS_PRIVATE, immediately after entering the new mount namespace.
* gnu/services/containers.scm (%miniflux-create-admin-credentials,
%rootless-podman-os-with-least-authority-wrapper,
run-rootless-podman-test-with-least-authority-wrapper): New bindings.
(%test-rootless-podman-with-least-authority-wrapper): New regression
test making sure the rootless-podman-service-type does not break again
least-authority-wrapper bases services.

Fixes: https://codeberg.org/guix/guix/issues/3233
Merges: https://codeberg.org/guix/guix/pulls/9140
</pre>
</div>
</content>
</entry>
<entry>
<title>linux-container: Fix hang when #:child-is-pid1? is true.</title>
<updated>2026-04-27T08:03:04+00:00</updated>
<author>
<name>Johannes Christ</name>
<email>jc@jchri.st</email>
</author>
<published>2026-04-21T20:09:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=d1d079739b989d1b8430733c46879a6d61626750'/>
<id>d1d079739b989d1b8430733c46879a6d61626750</id>
<content type='text'>
* gnu/build/linux-container.scm (call-with-container): Use `safe-clone`
  instead of `primitive-fork` as the latter suffers from a Guile
  regression causing the child to hang up.

Change-Id: I6da65991fdec6b4403ebdcde618a87ba39e802b3
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* gnu/build/linux-container.scm (call-with-container): Use `safe-clone`
  instead of `primitive-fork` as the latter suffers from a Guile
  regression causing the child to hang up.

Change-Id: I6da65991fdec6b4403ebdcde618a87ba39e802b3
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>build/syscalls: Introduce new safe-clone and use it.</title>
<updated>2025-10-29T02:34:28+00:00</updated>
<author>
<name>Maxim Cournoyer</name>
<email>maxim@guixotic.coop</email>
</author>
<published>2025-10-17T14:12:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=1eccea7ffb7eac43670d5fd76e8afa8ecfe6b0b9'/>
<id>1eccea7ffb7eac43670d5fd76e8afa8ecfe6b0b9</id>
<content type='text'>
* guix/build/syscalls.scm (without-automatic-finalization): Accept multiple
expressions.
(without-garbage-collection): New syntax.
(without-threads): Likewise.
(ensure-signal-delivery-thread, safe-clone): New procedures.
* tests/syscalls.scm: ("clone and unshare triggers EINVAL")
("safe-clone and unshare succeeds"): New tests.
* gnu/build/linux-container.scm (run-container): Adjust to use 'safe-clone'.

Relates-to: #1169
Change-Id: I044c11a899e24e547a7aed97f30c8e7250ab5363
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* guix/build/syscalls.scm (without-automatic-finalization): Accept multiple
expressions.
(without-garbage-collection): New syntax.
(without-threads): Likewise.
(ensure-signal-delivery-thread, safe-clone): New procedures.
* tests/syscalls.scm: ("clone and unshare triggers EINVAL")
("safe-clone and unshare succeeds"): New tests.
* gnu/build/linux-container.scm (run-container): Adjust to use 'safe-clone'.

Relates-to: #1169
Change-Id: I044c11a899e24e547a7aed97f30c8e7250ab5363
</pre>
</div>
</content>
</entry>
<entry>
<title>linux-container: Inhibit GC thread creation in child.</title>
<updated>2025-10-29T02:34:28+00:00</updated>
<author>
<name>W. Kosior</name>
<email>koszko@koszko.org</email>
</author>
<published>2025-10-15T14:18:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=3966f7629723c68e49b66fdf05feab901f8741ac'/>
<id>3966f7629723c68e49b66fdf05feab901f8741ac</id>
<content type='text'>
The `unshare' system call with `CLONE_NEWUSER' cannot be used in multithreaded
programs.  Guile VM's automatic GC thread creation used to lead to
nondeterministic failures in container creation, which uses this system call.

* gnu/build/linux-container.scm (run-container): Disable GC in child after
`(clone)' and re-enable after `(unshare)'.

Fixes: #1169
Change-Id: I9df5412102509c13f74ab9911f6f06c0152d0a4f
Signed-off-by: Maxim Cournoyer &lt;maxim@guixotic.coop&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The `unshare' system call with `CLONE_NEWUSER' cannot be used in multithreaded
programs.  Guile VM's automatic GC thread creation used to lead to
nondeterministic failures in container creation, which uses this system call.

* gnu/build/linux-container.scm (run-container): Disable GC in child after
`(clone)' and re-enable after `(unshare)'.

Fixes: #1169
Change-Id: I9df5412102509c13f74ab9911f6f06c0152d0a4f
Signed-off-by: Maxim Cournoyer &lt;maxim@guixotic.coop&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Reinstate "linux-container: Remove #:lock-mounts? and related code."</title>
<updated>2025-10-29T02:34:28+00:00</updated>
<author>
<name>Maxim Cournoyer</name>
<email>maxim@guixotic.coop</email>
</author>
<published>2025-10-16T07:36:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=10edda5aa5f92e7bfcff4902d4f3c11373d1e725'/>
<id>10edda5aa5f92e7bfcff4902d4f3c11373d1e725</id>
<content type='text'>
This reverts commit e0e64be8de3d220a12612b3a2e4aee428277d865.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit e0e64be8de3d220a12612b3a2e4aee428277d865.
</pre>
</div>
</content>
</entry>
<entry>
<title>linux-container: Remove #:lock-mounts? and related code.</title>
<updated>2025-10-13T12:48:26+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2025-10-13T08:39:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=e0e64be8de3d220a12612b3a2e4aee428277d865'/>
<id>e0e64be8de3d220a12612b3a2e4aee428277d865</id>
<content type='text'>
This reverts commits 437bb9ece55f37d4b5a62cafc98c0c3b848a53ce and
a57ed987ffd1452ba5a4d70feb54893e99b8e076, which were reported in
guix/guix#1169 to occasionally cause errors like:

  guix shell: error: unshare : 268566528: Invalid argument
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commits 437bb9ece55f37d4b5a62cafc98c0c3b848a53ce and
a57ed987ffd1452ba5a4d70feb54893e99b8e076, which were reported in
guix/guix#1169 to occasionally cause errors like:

  guix shell: error: unshare : 268566528: Invalid argument
</pre>
</div>
</content>
</entry>
<entry>
<title>linux-container: Export ‘%writable-/tmp’ and use it.</title>
<updated>2025-09-17T09:55:13+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2025-08-29T09:13:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=c52a9cee53db1e16df0c23ec10e352248e5372f8'/>
<id>c52a9cee53db1e16df0c23ec10e352248e5372f8</id>
<content type='text'>
Fixes guix/guix#1994.

* gnu/build/linux-container.scm (%writable-/tmp): New variable.
* guix/scripts/environment.scm (launch-environment/container): Remove ‘tmpfs’
and use it.  Adjust ‘file-system’ declaration for /run/user/$UID.
* guix/scripts/home.scm (spawn-home-container): Likewise.

Reported-by: Romain GARBAGE &lt;romain.garbage@inria.fr&gt;
Change-Id: Ia8289fb5386971738caf2ccc1e815daa6ac28459
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes guix/guix#1994.

* gnu/build/linux-container.scm (%writable-/tmp): New variable.
* guix/scripts/environment.scm (launch-environment/container): Remove ‘tmpfs’
and use it.  Adjust ‘file-system’ declaration for /run/user/$UID.
* guix/scripts/home.scm (spawn-home-container): Likewise.

Reported-by: Romain GARBAGE &lt;romain.garbage@inria.fr&gt;
Change-Id: Ia8289fb5386971738caf2ccc1e815daa6ac28459
</pre>
</div>
</content>
</entry>
<entry>
<title>linux-container: Fix typo in docstring.</title>
<updated>2025-07-12T10:58:32+00:00</updated>
<author>
<name>cdr-shdr-wdr</name>
<email>cdr-shdr-wdr@protonmail.ch</email>
</author>
<published>2025-07-08T22:04:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=128e319496a8ef24d41f041225e9b61c867d5c6a'/>
<id>128e319496a8ef24d41f041225e9b61c867d5c6a</id>
<content type='text'>
* gnu/build/linux-container.scm (mount-file-systems): Fix typo in
  docstring.

Change-Id: I973a65a6574078bc72fd9e1aa7424a68e2b21268
Signed-off-by: Danny Milosavljevic &lt;dannym@friendly-machines.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* gnu/build/linux-container.scm (mount-file-systems): Fix typo in
  docstring.

Change-Id: I973a65a6574078bc72fd9e1aa7424a68e2b21268
Signed-off-by: Danny Milosavljevic &lt;dannym@friendly-machines.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>linux-container: Lock mounts by default.</title>
<updated>2025-05-05T12:34:00+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2025-04-08T12:03:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=a57ed987ffd1452ba5a4d70feb54893e99b8e076'/>
<id>a57ed987ffd1452ba5a4d70feb54893e99b8e076</id>
<content type='text'>
This makes it impossible to unmount or remount things from within
‘call-with-container’.

* gnu/build/linux-container.scm (initialize-user-namespace):
Add #:host-uid and #:host-gid. and honor them.
(run-container): Add #:lock-mounts?.  Honor it by calling ‘unshare’
followed by ‘initialize-user-namespace’.
(call-with-container): Add #:lock-mounts? and pass it down.
(container-excursion): Get the user namespace owning the PID namespace
and join it, then join the remaining namespaces.
* tests/containers.scm ("call-with-container, mnt namespace, locked mounts"):
New test.
("container-excursion"): Pass #:lock-mounts? #f.

Change-Id: I13be982aef99e68a653d472f0e595c81cfcfa392
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This makes it impossible to unmount or remount things from within
‘call-with-container’.

* gnu/build/linux-container.scm (initialize-user-namespace):
Add #:host-uid and #:host-gid. and honor them.
(run-container): Add #:lock-mounts?.  Honor it by calling ‘unshare’
followed by ‘initialize-user-namespace’.
(call-with-container): Add #:lock-mounts? and pass it down.
(container-excursion): Get the user namespace owning the PID namespace
and join it, then join the remaining namespaces.
* tests/containers.scm ("call-with-container, mnt namespace, locked mounts"):
New test.
("container-excursion"): Pass #:lock-mounts? #f.

Change-Id: I13be982aef99e68a653d472f0e595c81cfcfa392
</pre>
</div>
</content>
</entry>
<entry>
<title>linux-container: Set up “lo” and generate /etc/hosts by default.</title>
<updated>2025-05-05T12:34:00+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2025-04-08T11:50:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=e1a0171a56602ecba193975ea2438329abb51c94'/>
<id>e1a0171a56602ecba193975ea2438329abb51c94</id>
<content type='text'>
* gnu/build/linux-container.scm (run-container): Add #:loopback-network?
and honor it via #:populate-file-system.
(call-with-container): Add #:loopback-network? and pass it to
‘run-container’.
* guix/scripts/environment.scm (launch-environment/container): Remove
call to ‘set-network-interface-up’ and remove generation of /etc/hosts.
* guix/scripts/home.scm (spawn-home-container): Likewise.

Change-Id: I5933a4e8dc6d8e19235a79696b62299d74d1ba21
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* gnu/build/linux-container.scm (run-container): Add #:loopback-network?
and honor it via #:populate-file-system.
(call-with-container): Add #:loopback-network? and pass it to
‘run-container’.
* guix/scripts/environment.scm (launch-environment/container): Remove
call to ‘set-network-interface-up’ and remove generation of /etc/hosts.
* guix/scripts/home.scm (spawn-home-container): Likewise.

Change-Id: I5933a4e8dc6d8e19235a79696b62299d74d1ba21
</pre>
</div>
</content>
</entry>
</feed>
