summaryrefslogtreecommitdiff
path: root/linuxnamespaces/__init__.py
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2024-06-22 22:45:52 +0200
committerHelmut Grohne <helmut@subdivi.de>2024-06-22 22:45:52 +0200
commit13be09d259f5006e19f0e770a1999b5d7c9247fe (patch)
tree4b6e10f4203fb6fd426354be91a5a19c03e94d7f /linuxnamespaces/__init__.py
parent97eada134e410a83cd024a490721dec27f45d097 (diff)
downloadpython-linuxnamespaces-13be09d259f5006e19f0e770a1999b5d7c9247fe.tar.gz
populate_sys: refactor
We now compute the actual bind mounts first and deduce the directories in need of creation from that. This makes populate_sys easier to extend.
Diffstat (limited to 'linuxnamespaces/__init__.py')
-rw-r--r--linuxnamespaces/__init__.py45
1 files changed, 27 insertions, 18 deletions
diff --git a/linuxnamespaces/__init__.py b/linuxnamespaces/__init__.py
index aff620e..8853c07 100644
--- a/linuxnamespaces/__init__.py
+++ b/linuxnamespaces/__init__.py
@@ -537,40 +537,49 @@ def populate_sys(
"""
newsys = AtLocation(newroot) / "sys"
mflags = MountFlags.NOSUID | MountFlags.NOEXEC | MountFlags.NODEV
+ bind_mounts: dict[
+ str, tuple[typing.Union[str, pathlib.PurePath], bool]
+ ] = {}
if rootcgroup is None:
- rootcgroup = ""
+ bind_mounts["fs/cgroup"] = ("fs/cgroup", True)
else:
- rootcgroup = pathlib.PurePath(rootcgroup).relative_to("/")
- with contextlib.ExitStack() as exitstack:
- cgfd = exitstack.enter_context(
- open_tree(
- AtLocation(origroot) / "sys/fs/cgroup" / rootcgroup,
- OpenTreeFlags.OPEN_TREE_CLONE | OpenTreeFlags.AT_RECURSIVE,
- ),
+ bind_mounts["fs/cgroup"] = (
+ "fs/cgroup" / pathlib.PurePath(rootcgroup).relative_to("/"), False
)
- if not rootcgroup:
- mount_setattr(cgfd, True, MountAttrFlags.RDONLY)
- if module:
- modfd = exitstack.enter_context(
+ if module:
+ bind_mounts["module"] = ("module", True)
+
+ bind_fds: dict[str, AtLocation] = {}
+ with contextlib.ExitStack() as exitstack:
+ for target, (source, rdonly) in bind_mounts.items():
+ bindfd = exitstack.enter_context(
open_tree(
- AtLocation(origroot) / "sys/module",
+ AtLocation(origroot) / "sys" / source,
OpenTreeFlags.OPEN_TREE_CLONE | OpenTreeFlags.AT_RECURSIVE,
),
)
- mount_setattr(modfd, True, MountAttrFlags.RDONLY)
+ if rdonly:
+ mount_setattr(bindfd, True, MountAttrFlags.RDONLY)
+ bind_fds[target] = bindfd
+
mount("sysfs", newsys, "tmpfs", mflags, "mode=0755")
exitstack.enter_context(
_ExceptionExitCallback(umount, newsys, UmountFlags.DETACH)
)
- for subdir in ("fs", "fs/cgroup", "module"):
+ dirs = set()
+ for subdir in bind_fds:
+ dirs.add(subdir)
+ while "/" in subdir:
+ subdir = subdir.rsplit("/", 1)[0]
+ dirs.add(subdir)
+ for subdir in sorted(dirs):
(newsys / subdir).mkdir()
(newsys / subdir).chmod(0o755)
mflags |= MountFlags.REMOUNT | MountFlags.RDONLY
mount("sysfs", newsys, "tmpfs", mflags, "mode=0755")
- move_mount(cgfd, newsys / "fs/cgroup")
- if module:
- move_mount(modfd, newsys / "module")
+ for subdir, bindfd in sorted(bind_fds.items()):
+ move_mount(bindfd, newsys / subdir)
def unshare_user_idmap(