2020-04-01 02:15:55 +00:00
|
|
|
// Copyright 2020 The gVisor Authors.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
// Package sockfs provides a filesystem implementation for anonymous sockets.
|
|
|
|
package sockfs
|
|
|
|
|
|
|
|
import (
|
2020-04-03 21:07:42 +00:00
|
|
|
"gvisor.dev/gvisor/pkg/abi/linux"
|
2020-04-01 02:15:55 +00:00
|
|
|
"gvisor.dev/gvisor/pkg/context"
|
|
|
|
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
|
|
|
|
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
|
|
|
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
|
|
|
"gvisor.dev/gvisor/pkg/syserror"
|
|
|
|
)
|
|
|
|
|
|
|
|
// filesystemType implements vfs.FilesystemType.
|
|
|
|
type filesystemType struct{}
|
|
|
|
|
|
|
|
// GetFilesystem implements FilesystemType.GetFilesystem.
|
|
|
|
func (fsType filesystemType) GetFilesystem(_ context.Context, vfsObj *vfs.VirtualFilesystem, _ *auth.Credentials, _ string, _ vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
|
2020-04-24 17:02:22 +00:00
|
|
|
panic("sockfs.filesystemType.GetFilesystem should never be called")
|
2020-04-01 02:15:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Name implements FilesystemType.Name.
|
|
|
|
//
|
|
|
|
// Note that registering sockfs is unnecessary, except for the fact that it
|
|
|
|
// will not show up under /proc/filesystems as a result. This is a very minor
|
|
|
|
// discrepancy from Linux.
|
|
|
|
func (filesystemType) Name() string {
|
|
|
|
return "sockfs"
|
|
|
|
}
|
|
|
|
|
2020-04-24 17:02:22 +00:00
|
|
|
// NewFilesystem sets up and returns a new sockfs filesystem.
|
|
|
|
//
|
|
|
|
// Note that there should only ever be one instance of sockfs.Filesystem,
|
|
|
|
// backing a global socket mount.
|
|
|
|
func NewFilesystem(vfsObj *vfs.VirtualFilesystem) *vfs.Filesystem {
|
2020-05-05 16:18:21 +00:00
|
|
|
fs := &kernfs.Filesystem{}
|
|
|
|
fs.VFSFilesystem().Init(vfsObj, filesystemType{}, fs)
|
2020-04-24 17:02:22 +00:00
|
|
|
return fs.VFSFilesystem()
|
|
|
|
}
|
|
|
|
|
2020-04-01 02:15:55 +00:00
|
|
|
// inode implements kernfs.Inode.
|
2020-04-03 21:07:42 +00:00
|
|
|
//
|
2020-05-05 19:09:39 +00:00
|
|
|
// TODO(gvisor.dev/issue/1193): Device numbers.
|
2020-04-01 02:15:55 +00:00
|
|
|
type inode struct {
|
|
|
|
kernfs.InodeNotDirectory
|
|
|
|
kernfs.InodeNotSymlink
|
|
|
|
kernfs.InodeAttrs
|
|
|
|
kernfs.InodeNoopRefCount
|
|
|
|
}
|
|
|
|
|
|
|
|
// Open implements kernfs.Inode.Open.
|
2020-04-24 19:36:14 +00:00
|
|
|
func (i *inode) Open(ctx context.Context, rp *vfs.ResolvingPath, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
|
2020-04-01 02:15:55 +00:00
|
|
|
return nil, syserror.ENXIO
|
|
|
|
}
|
2020-04-03 21:07:42 +00:00
|
|
|
|
2020-04-27 23:00:39 +00:00
|
|
|
// NewDentry constructs and returns a sockfs dentry.
|
|
|
|
func NewDentry(creds *auth.Credentials, ino uint64) *vfs.Dentry {
|
2020-04-03 21:07:42 +00:00
|
|
|
// File mode matches net/socket.c:sock_alloc.
|
|
|
|
filemode := linux.FileMode(linux.S_IFSOCK | 0600)
|
|
|
|
i := &inode{}
|
2020-04-27 23:00:39 +00:00
|
|
|
i.Init(creds, ino, filemode)
|
2020-04-03 21:07:42 +00:00
|
|
|
|
|
|
|
d := &kernfs.Dentry{}
|
|
|
|
d.Init(i)
|
2020-04-27 23:00:39 +00:00
|
|
|
return d.VFSDentry()
|
2020-04-03 21:07:42 +00:00
|
|
|
}
|