diff options
author | Helmut Grohne <helmut@subdivi.de> | 2024-06-22 22:45:52 +0200 |
---|---|---|
committer | Helmut Grohne <helmut@subdivi.de> | 2024-06-22 22:45:52 +0200 |
commit | 13be09d259f5006e19f0e770a1999b5d7c9247fe (patch) | |
tree | 4b6e10f4203fb6fd426354be91a5a19c03e94d7f /linuxnamespaces | |
parent | 97eada134e410a83cd024a490721dec27f45d097 (diff) | |
download | python-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')
-rw-r--r-- | linuxnamespaces/__init__.py | 45 |
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( |