Repository navigation
Give the broker core mount trees and per-thread file-system contexts - #1837
Draft
Weidong Cui (wdcui) wants to merge 6 commits into
Draft
Weidong Cui (wdcui) wants to merge 6 commits into
Weidong Cui (wdcui) wants to merge 6 commits into
Conversation
`Composer::builder_with` builds a composer whose devices come from given allocators, and every composer now draws its virtual directories' device from its allocators too, so composers built from the same allocators, and backends made later from them, never share a node identity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5406de6-bab4-4f3b-b232-ae238032c2c2
The resolver no longer wraps one backend: it resolves paths in a mount namespace, a copy-on-write tree of mounts that each show a backend, a directory of one or a file of one, so the next steps can add per-thread roots and working directories and mount operations. A walk keeps the existing runs, symlink and permission rules, but its position is a location in a mount that starts lookups from an anchored directory handle without re-checking its ancestors, crosses into mounts it steps onto, climbs out of them on .., stops at its root, and hands its final resolution to the caller instead of walking twice. Resolver::new keeps its signature apart from losing the backend type parameter, and every existing path request still resolves from the namespace root, so hosts and shims behave as before. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5406de6-bab4-4f3b-b232-ae238032c2c2
An open file now keeps the location it was opened at and a stateless FileOps object that builds and interprets its Platform-typed state, instead of relying on the calling process's file service. Every handle operation goes through the file's own FileOps and mount, so a file passed to a process with another file service, or one whose mount was detached, keeps working, and each open file counts as a user of its mount until its last reference closes. Opens still go through the process's service; mount namespaces hold the FileOps their files get. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5406de6-bab4-4f3b-b232-ae238032c2c2
A walk stepping onto a mount point checked search permission on the directory only when the resolver enforces permissions, so a backend that enforces them itself, such as a 9P server, never saw the lookup and a denied directory above a mount point could be crossed. The walk now looks the mount point's name up in its directory's backend before entering the mount, alone rather than at the end of a longer walk, because a 9P server reports a denied final lookup of a walk only as a shorter walk. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5406de6-bab4-4f3b-b232-ae238032c2c2
Each thread now has a file-system context holding its mount namespace, root and working directory, which threads of a process share and a new process copies from the thread that creates it, while a root process starts at the root of its file service's namespace. The process keeps its initial thread's context as a default for requests that name no thread, even after that thread exits, until the process ends. Path operations resolve from a context and, for relative paths, an optional open directory, and open files through the namespace's FileOps; the existing absolute-path functions use the default context, so hosts behave as before. Every context is registered in the core for the mount operations that will move roots and working directories. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5406de6-bab4-4f3b-b232-ae238032c2c2
Add the queries the Linux shim needs on top of mount trees and contexts. mount_info reports the mount an open file is on, which the file keeps after an unmount or when passed to another process: its identifier, the type, source and options it was made with, whether it is read-only, and whether the file is the mount's root. working_directory reports a thread's working directory as a path from its root, or, when it is not below the root, as Linux's getcwd does with its unreachable marker, its path from the root of its own mount tree. The mount module becomes public for the identifier and information types, as the PID namespace module is. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5406de6-bab4-4f3b-b232-ae238032c2c2
|
ℹ️ Note: This semver check was run against the 🤖 SemverChecks 🤖 Click for details |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR gives the broker core mount trees and per-thread file-system contexts, the core half of letting guests build containers with mount namespaces, stacked on #1833. A mount namespace is now a tree of mounts, each a backend (or a bound directory or file of one) attached at a path inside its parent mount, with at most one mount per point so stacked mounts form chains as in Linux; the host's composed file system becomes the root mount of the initial namespace, so its behavior is unchanged. The resolver walks this tree from a base location (a mount plus a path inside it, anchored on an open directory handle so lookups don't re-walk its ancestors), following stacked mounts, climbing out of mount roots with
..without escaping the caller's root, restarting absolute symlinks at the root, and checking search permission as before (including, for backends that enforce it themselves, at mount points). Open files keep the mount that opened them through a stateless file-operations object, so they keep working when passed to a process in another namespace or after their mount is detached. Each thread now has a file-system context (mount namespace, root and working directory), shared by the threads that share it and copied for a new process, with a process default for requests that name no thread; queries report a handle's mount and a thread's working directory. Composers can share inode allocators (folded from #1831), so backends made later never reuse a node identity. Mount operations follow in the next PR.