diff options
Diffstat (limited to 'linuxnamespaces')
-rw-r--r-- | linuxnamespaces/__init__.py | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/linuxnamespaces/__init__.py b/linuxnamespaces/__init__.py index a1f790e..83358b6 100644 --- a/linuxnamespaces/__init__.py +++ b/linuxnamespaces/__init__.py @@ -245,7 +245,7 @@ def populate_dev( newroot: PathConvertible, *, fuse: bool = True, - pidns: bool = True, + pts: typing.Literal["defer", "host", "new", "absent"] = "new", tun: bool = True, ) -> None: """Mount a tmpfs to the dev directory beneath newroot and populate it with @@ -255,6 +255,12 @@ def populate_dev( Even though a CAP_SYS_ADMIN-enabled process can umount components of the /dev hierarchy, they they cannot gain privileges in doing so as no hierarchies are restricted via tmpfs mounts or read-only bind mounts. + + The /dev/fuse and /dev/net/tun devices are optional and can be enabled or + disabled as desired. /dev/pts (and /dev/ptmx) can be shared with the host + or mounted as a new instance. Since a PID namespace is usually required for + mounting a new instance, it can also be deferred to a later manual mount. + If not desired, it can be left absent. """ origdev = AtLocation(origroot) / "dev" newdev = AtLocation(newroot) / "dev" @@ -278,9 +284,7 @@ def populate_dev( bind_mounts["fuse"] = exitstack.enter_context( open_tree(origdev / "fuse", OpenTreeFlags.CLONE) ) - if pidns: - symlinks["ptmx"] = "pts/ptmx" - else: + if pts == "host": bind_mounts["pts"] = exitstack.enter_context( open_tree( origdev / "pts", @@ -291,6 +295,8 @@ def populate_dev( bind_mounts["ptmx"] = exitstack.enter_context( open_tree(origdev / "ptmx", OpenTreeFlags.CLONE) ) + elif pts != "absent": + symlinks["ptmx"] = "pts/ptmx" if tun: directories.add("net") files.add("net/tun") @@ -320,7 +326,7 @@ def populate_dev( (newdev / fn).mknod(stat.S_IFREG) for fn, target in symlinks.items(): (newdev / fn).symlink_to(target) - if pidns: + if pts == "new": mount( "devpts", newdev / "pts", |