diff options
author | Helmut Grohne <helmut@subdivi.de> | 2025-06-28 09:11:42 +0200 |
---|---|---|
committer | Helmut Grohne <helmut@subdivi.de> | 2025-06-28 09:18:36 +0200 |
commit | 823b6754d68b01a6d30431411506cc9084560e68 (patch) | |
tree | 921b01e364b660d438231db2db8a65c748ac2023 /linuxnamespaces/__init__.py | |
parent | 7d6895d7ca0fe472c64964793b12f8ea536decde (diff) | |
download | python-linuxnamespaces-823b6754d68b01a6d30431411506cc9084560e68.tar.gz |
change/improve populate_dev API
populate_dev may be used before unsharing a pid namespace with the
intention of unsharing it. Then, /dev/pts should not be mounted and
instead that mount needs to happen inside the newly created pid
namespace. To allow for this usage, rename the pidns argument to pts and
turn it into a literal. It may also be desired to have a /dev without
pts, so add that option as well. It's a breaking change, but it does add
clarity.
Diffstat (limited to 'linuxnamespaces/__init__.py')
-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", |