From 13be09d259f5006e19f0e770a1999b5d7c9247fe Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 22 Jun 2024 22:45:52 +0200 Subject: 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. --- linuxnamespaces/__init__.py | 45 +++++++++++++++++++++++++++------------------ 1 file 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( -- cgit v1.2.3