summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl/mqfs
diff options
context:
space:
mode:
authorZyad A. Ali <zyad.ali.me@gmail.com>2021-07-29 17:33:45 +0200
committerZyad A. Ali <zyad.ali.me@gmail.com>2021-09-28 20:43:47 +0200
commit229c01552e2b819c2fa6bf1f5aa017cff366869e (patch)
tree9415551dea5e460433380aabb2fc381b04045ca4 /pkg/sentry/fsimpl/mqfs
parentbcef079ec24d56d37a670c4c4149c638be6fb110 (diff)
Move filesystem creation from GetFilesystem to RegistryImpl.
Move root dentry and filesystem creation from GetFilesystem to NewRegistryImpl, create IPCNamespace.InitPosixQueues to create a new mqueue filesystem for each ipc namespace, and update GetFilesystem to retreive fs and root dentry from IPCNamespace and return them. Updates #136
Diffstat (limited to 'pkg/sentry/fsimpl/mqfs')
-rw-r--r--pkg/sentry/fsimpl/mqfs/BUILD1
-rw-r--r--pkg/sentry/fsimpl/mqfs/mqfs.go61
-rw-r--r--pkg/sentry/fsimpl/mqfs/registry.go34
3 files changed, 74 insertions, 22 deletions
diff --git a/pkg/sentry/fsimpl/mqfs/BUILD b/pkg/sentry/fsimpl/mqfs/BUILD
index 6892c6c25..e688b9b48 100644
--- a/pkg/sentry/fsimpl/mqfs/BUILD
+++ b/pkg/sentry/fsimpl/mqfs/BUILD
@@ -31,6 +31,7 @@ go_library(
"//pkg/refsvfs2",
"//pkg/sentry/fsimpl/kernfs",
"//pkg/sentry/kernel/auth",
+ "//pkg/sentry/kernel/ipc",
"//pkg/sentry/kernel/mq",
"//pkg/sentry/vfs",
"//pkg/sync",
diff --git a/pkg/sentry/fsimpl/mqfs/mqfs.go b/pkg/sentry/fsimpl/mqfs/mqfs.go
index a92012deb..ed559cd13 100644
--- a/pkg/sentry/fsimpl/mqfs/mqfs.go
+++ b/pkg/sentry/fsimpl/mqfs/mqfs.go
@@ -24,6 +24,8 @@ import (
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/ipc"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/mq"
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
@@ -47,28 +49,32 @@ func (FilesystemType) Release(ctx context.Context) {}
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
func (ft FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
- devMinor, err := vfsObj.GetAnonBlockDevMinor()
- if err != nil {
- return nil, nil, err
+ // mqfs is initialized only once per ipc namespace. Each ipc namespace has
+ // a POSIX message registry with a root dentry, filesystem, and a
+ // disconnected mount. We want the fs to be consistent for all processes in
+ // the same ipc namespace, so instead of creating a new fs and root dentry,
+ // we retreive them using IPCNamespace.PosixQueues and use them.
+
+ i := ipcNamespaceFromContext(ctx)
+ if i == nil {
+ return nil, nil, fmt.Errorf("mqfs.FilesystemType.GetFilesystem: ipc namespace doesn't exist")
+ }
+ defer i.DecRef(ctx)
+
+ registry := i.PosixQueues()
+ if registry == nil {
+ return nil, nil, fmt.Errorf("mqfs.FilesystemType.GetFilesystem: ipc namespace doesn't have a POSIX registry")
}
+ impl := registry.Impl().(*RegistryImpl)
maxCachedDentries, err := maxCachedDentries(ctx, vfs.GenericParseMountOptions(opts.Data))
if err != nil {
return nil, nil, err
}
+ impl.fs.MaxCachedDentries = maxCachedDentries
- fs := &filesystem{
- devMinor: devMinor,
- Filesystem: kernfs.Filesystem{
- MaxCachedDentries: maxCachedDentries,
- },
- }
- fs.VFSFilesystem().Init(vfsObj, &ft, fs)
-
- var dentry kernfs.Dentry
- dentry.InitRoot(&fs.Filesystem, fs.newRootInode(ctx, creds))
-
- return fs.VFSFilesystem(), dentry.VFSDentry(), nil
+ impl.root.IncRef()
+ return impl.fs.VFSFilesystem(), impl.root.VFSDentry(), nil
}
// maxCachedDentries checks mopts for dentry_cache_limit. If a value is
@@ -93,15 +99,40 @@ func maxCachedDentries(ctx context.Context, mopts map[string]string) (_ uint64,
type filesystem struct {
kernfs.Filesystem
devMinor uint32
+
+ // root is the filesystem's root dentry. Since we take a reference on it in
+ // GetFilesystem, we should release it when the fs is released.
+ root *kernfs.Dentry
}
// Release implements vfs.FilesystemImpl.Release.
func (fs *filesystem) Release(ctx context.Context) {
fs.Filesystem.VFSFilesystem().VirtualFilesystem().PutAnonBlockDevMinor(fs.devMinor)
fs.Filesystem.Release(ctx)
+ fs.root.DecRef(ctx)
}
// MountOptions implements vfs.FilesystemImpl.MountOptions.
func (fs *filesystem) MountOptions() string {
return fmt.Sprintf("dentry_cache_limit=%d", fs.MaxCachedDentries)
}
+
+// ipcNamespace defines functions we need from kernel.IPCNamespace. We redefine
+// ipcNamespace along with ipcNamespaceFromContext to avoid circular dependency
+// with package sentry/kernel.
+type ipcNamespace interface {
+ // PosixQueues returns a POSIX message queue registry.
+ PosixQueues() *mq.Registry
+
+ // DecRef decrements ipcNamespace's number of references.
+ DecRef(ctx context.Context)
+}
+
+// ipcNamespaceFromContext returns the IPC namespace in which ctx is executing.
+// Copied from package sentry/kernel.
+func ipcNamespaceFromContext(ctx context.Context) ipcNamespace {
+ if v := ctx.Value(ipc.CtxIPCNamespace); v != nil {
+ return v.(ipcNamespace)
+ }
+ return nil
+}
diff --git a/pkg/sentry/fsimpl/mqfs/registry.go b/pkg/sentry/fsimpl/mqfs/registry.go
index 3875b39ee..9361b7eb4 100644
--- a/pkg/sentry/fsimpl/mqfs/registry.go
+++ b/pkg/sentry/fsimpl/mqfs/registry.go
@@ -50,12 +50,32 @@ type RegistryImpl struct {
// NewRegistryImpl returns a new, initialized RegistryImpl, and takes a
// reference on root.
-func NewRegistryImpl(root *kernfs.Dentry, fs *filesystem) *RegistryImpl {
- root.IncRef()
- return &RegistryImpl{
- root: root,
- fs: fs,
+func NewRegistryImpl(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials) (*RegistryImpl, error) {
+ devMinor, err := vfsObj.GetAnonBlockDevMinor()
+ if err != nil {
+ return nil, err
+ }
+
+ var dentry kernfs.Dentry
+ fs := &filesystem{
+ devMinor: devMinor,
+ root: &dentry,
+ }
+ fs.VFSFilesystem().Init(vfsObj, &FilesystemType{}, fs)
+
+ dentry.InitRoot(&fs.Filesystem, fs.newRootInode(ctx, creds))
+ dentry.IncRef()
+
+ mount, err := vfsObj.NewDisconnectedMount(fs.VFSFilesystem(), dentry.VFSDentry(), &vfs.MountOptions{})
+ if err != nil {
+ return nil, err
}
+
+ return &RegistryImpl{
+ root: &dentry,
+ fs: fs,
+ mount: mount,
+ }, nil
}
// Lookup implements mq.RegistryImpl.Lookup.
@@ -83,11 +103,11 @@ func (r *RegistryImpl) New(ctx context.Context, name string, q *mq.Queue, perm l
}
fd := &queueFD{queue: q}
- err = fd.Init(r.mount, r.root, qInode.data, &qInode.locks, 0 /* flags */)
+ err = fd.Init(r.mount, r.root, q, qInode.Locks(), 0 /* flags */)
if err != nil {
return nil, err
}
- return fd.VFSFileDescription(), nil
+ return &fd.vfsfd, nil
}
// Unlink implements mq.RegistryImpl.Unlink.