summaryrefslogtreecommitdiff
path: root/linuxnamespaces
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2024-02-24 23:02:25 +0100
committerHelmut Grohne <helmut@subdivi.de>2024-02-24 23:02:25 +0100
commit8b98dc846e7bd911360820f085a1b21307b28e89 (patch)
tree318fd5fef613dab9f097b77bc6f974ffbdbbc44a /linuxnamespaces
parent9446989a1f2f06a3829a7024231a252344fb40eb (diff)
downloadpython-linuxnamespaces-8b98dc846e7bd911360820f085a1b21307b28e89.tar.gz
populate_dev: remove assumption that newdev does not shadow origdev
In particular, one can now pass newdev = origdev.
Diffstat (limited to 'linuxnamespaces')
-rw-r--r--linuxnamespaces/__init__.py78
1 files changed, 50 insertions, 28 deletions
diff --git a/linuxnamespaces/__init__.py b/linuxnamespaces/__init__.py
index b0e5b85..63b0d21 100644
--- a/linuxnamespaces/__init__.py
+++ b/linuxnamespaces/__init__.py
@@ -307,21 +307,55 @@ def populate_dev(
"""
origdev = AtLocation(origroot) / "dev"
newdev = AtLocation(newroot) / "dev"
- bind_devices = "null zero full random urandom tty".split()
- if fuse:
- bind_devices.append("fuse")
- bind_directories = []
- mount(
- "devtmpfs",
- newdev,
- "tmpfs",
- MountFlags.NOSUID | MountFlags.NOEXEC,
- "mode=0755",
- )
- with _ExceptionExitCallback(umount, newdev, UmountFlags.DETACH):
+ directories = {"pts"}
+ files = set()
+ symlinks = {}
+ bind_mounts: dict[str, AtLocation] = {}
+ with contextlib.ExitStack() as exitstack:
+ for fn in "null zero full random urandom tty".split():
+ files.add(fn)
+ bind_mounts[fn] = exitstack.enter_context(
+ open_tree(origdev / fn, OpenTreeFlags.OPEN_TREE_CLONE)
+ )
+ if fuse:
+ files.add("fuse")
+ bind_mounts["fuse"] = exitstack.enter_context(
+ open_tree(origdev / "fuse", OpenTreeFlags.OPEN_TREE_CLONE)
+ )
+ if pidns:
+ symlinks["ptmx"] = "pts/ptmx"
+ else:
+ bind_mounts["pts"] = exitstack.enter_context(
+ open_tree(
+ origdev / "pts",
+ OpenTreeFlags.AT_RECURSIVE | OpenTreeFlags.OPEN_TREE_CLONE,
+ )
+ )
+ files.add("ptmx")
+ bind_mounts["ptmx"] = exitstack.enter_context(
+ open_tree(origdev / "ptmx", OpenTreeFlags.OPEN_TREE_CLONE)
+ )
+ if tun:
+ directories.add("net")
+ files.add("net/tun")
+ mount(
+ "devtmpfs",
+ newdev,
+ "tmpfs",
+ MountFlags.NOSUID | MountFlags.NOEXEC,
+ "mode=0755",
+ )
+ exitstack.enter_context(
+ _ExceptionExitCallback(umount, newdev, UmountFlags.DETACH)
+ )
+ for fn in directories:
+ (newdev / fn).mkdir()
+ (newdev / fn).chmod(0o755)
+ for fn in files:
+ (newdev / fn).mknod(stat.S_IFREG)
+ for fn, target in symlinks.items():
+ (newdev / fn).symlink(target)
if pidns:
- (newdev / "pts").mkdir()
- (newdev / "pts").chmod(0o755)
mount(
"devpts",
newdev / "pts",
@@ -329,20 +363,8 @@ def populate_dev(
MountFlags.NOSUID | MountFlags.NOEXEC,
"gid=5,mode=620,ptmxmode=666",
)
- (newdev / "ptmx").symlink("pts/ptmx")
- else:
- bind_devices.append("ptmx")
- bind_directories.append("pts")
- if tun:
- (newdev / "net").mkdir()
- (newdev / "net").chmod(0o755)
- bind_devices.append("net/tun")
- for node in bind_devices:
- (newdev / node).mknod(stat.S_IFREG)
- bind_mount(origdev / node, newdev / node, True)
- for node in bind_directories:
- (newdev / node).mkdir()
- bind_mount(origdev / node, newdev / node, True)
+ for fn, fd in bind_mounts.items():
+ move_mount(fd, newdev / fn)
def populate_sys(