mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
committed by
gVisor bot
parent
e4058c0355
commit
18cb3d24cb
+32
-30
@@ -37,6 +37,12 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs/gofer"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/devpts"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/devtmpfs"
|
||||
gofervfs2 "gvisor.dev/gvisor/pkg/sentry/fsimpl/gofer"
|
||||
procvfs2 "gvisor.dev/gvisor/pkg/sentry/fsimpl/proc"
|
||||
sysvfs2 "gvisor.dev/gvisor/pkg/sentry/fsimpl/sys"
|
||||
tmpfsvfs2 "gvisor.dev/gvisor/pkg/sentry/fsimpl/tmpfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
@@ -44,23 +50,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// Filesystem name for 9p gofer mounts.
|
||||
rootFsName = "9p"
|
||||
|
||||
// Device name for root mount.
|
||||
rootDevice = "9pfs-/"
|
||||
|
||||
// MountPrefix is the annotation prefix for mount hints.
|
||||
MountPrefix = "dev.gvisor.spec.mount."
|
||||
|
||||
// Filesystems that runsc supports.
|
||||
bind = "bind"
|
||||
devpts = "devpts"
|
||||
devtmpfs = "devtmpfs"
|
||||
proc = "proc"
|
||||
sysfs = "sysfs"
|
||||
tmpfs = "tmpfs"
|
||||
nonefs = "none"
|
||||
// Supported filesystems that map to different internal filesystem.
|
||||
bind = "bind"
|
||||
nonefs = "none"
|
||||
)
|
||||
|
||||
// tmpfs has some extra supported options that we must pass through.
|
||||
@@ -108,12 +106,12 @@ func compileMounts(spec *specs.Spec) []specs.Mount {
|
||||
|
||||
// Always mount /dev.
|
||||
mounts = append(mounts, specs.Mount{
|
||||
Type: devtmpfs,
|
||||
Type: devtmpfs.Name,
|
||||
Destination: "/dev",
|
||||
})
|
||||
|
||||
mounts = append(mounts, specs.Mount{
|
||||
Type: devpts,
|
||||
Type: devpts.Name,
|
||||
Destination: "/dev/pts",
|
||||
})
|
||||
|
||||
@@ -137,13 +135,13 @@ func compileMounts(spec *specs.Spec) []specs.Mount {
|
||||
var mandatoryMounts []specs.Mount
|
||||
if !procMounted {
|
||||
mandatoryMounts = append(mandatoryMounts, specs.Mount{
|
||||
Type: proc,
|
||||
Type: procvfs2.Name,
|
||||
Destination: "/proc",
|
||||
})
|
||||
}
|
||||
if !sysMounted {
|
||||
mandatoryMounts = append(mandatoryMounts, specs.Mount{
|
||||
Type: sysfs,
|
||||
Type: sysvfs2.Name,
|
||||
Destination: "/sys",
|
||||
})
|
||||
}
|
||||
@@ -156,12 +154,16 @@ func compileMounts(spec *specs.Spec) []specs.Mount {
|
||||
}
|
||||
|
||||
// p9MountOptions creates a slice of options for a p9 mount.
|
||||
func p9MountOptions(fd int, fa FileAccessType) []string {
|
||||
func p9MountOptions(fd int, fa FileAccessType, vfs2 bool) []string {
|
||||
opts := []string{
|
||||
"trans=fd",
|
||||
"rfdno=" + strconv.Itoa(fd),
|
||||
"wfdno=" + strconv.Itoa(fd),
|
||||
"privateunixsocket=true",
|
||||
}
|
||||
if !vfs2 {
|
||||
// privateunixsocket is always enabled in VFS2. VFS1 requires explicit
|
||||
// enablement.
|
||||
opts = append(opts, "privateunixsocket=true")
|
||||
}
|
||||
if fa == FileAccessShared {
|
||||
opts = append(opts, "cache=remote_revalidating")
|
||||
@@ -234,7 +236,7 @@ func isSupportedMountFlag(fstype, opt string) bool {
|
||||
case "rw", "ro", "noatime", "noexec":
|
||||
return true
|
||||
}
|
||||
if fstype == tmpfs {
|
||||
if fstype == tmpfsvfs2.Name {
|
||||
ok, err := parseMountOption(opt, tmpfsAllowedOptions...)
|
||||
return ok && err == nil
|
||||
}
|
||||
@@ -444,7 +446,7 @@ func (m *mountHint) setOptions(val string) error {
|
||||
}
|
||||
|
||||
func (m *mountHint) isSupported() bool {
|
||||
return m.mount.Type == tmpfs && m.share == pod
|
||||
return m.mount.Type == tmpfsvfs2.Name && m.share == pod
|
||||
}
|
||||
|
||||
// checkCompatible verifies that shared mount is compatible with master.
|
||||
@@ -586,7 +588,7 @@ func (c *containerMounter) processHints(conf *Config) error {
|
||||
for _, hint := range c.hints.mounts {
|
||||
// TODO(b/142076984): Only support tmpfs for now. Bind mounts require a
|
||||
// common gofer to mount all shared volumes.
|
||||
if hint.mount.Type != tmpfs {
|
||||
if hint.mount.Type != tmpfsvfs2.Name {
|
||||
continue
|
||||
}
|
||||
log.Infof("Mounting master of shared mount %q from %q type %q", hint.name, hint.mount.Source, hint.mount.Type)
|
||||
@@ -723,7 +725,7 @@ func (c *containerMounter) createRootMount(ctx context.Context, conf *Config) (*
|
||||
fd := c.fds.remove()
|
||||
log.Infof("Mounting root over 9P, ioFD: %d", fd)
|
||||
p9FS := mustFindFilesystem("9p")
|
||||
opts := p9MountOptions(fd, conf.FileAccess)
|
||||
opts := p9MountOptions(fd, conf.FileAccess, false /* vfs2 */)
|
||||
|
||||
if conf.OverlayfsStaleRead {
|
||||
// We can't check for overlayfs here because sandbox is chroot'ed and gofer
|
||||
@@ -779,11 +781,11 @@ func (c *containerMounter) getMountNameAndOptions(conf *Config, m specs.Mount) (
|
||||
}
|
||||
|
||||
switch m.Type {
|
||||
case devpts, devtmpfs, proc, sysfs:
|
||||
case devpts.Name, devtmpfs.Name, procvfs2.Name, sysvfs2.Name:
|
||||
fsName = m.Type
|
||||
case nonefs:
|
||||
fsName = sysfs
|
||||
case tmpfs:
|
||||
fsName = sysvfs2.Name
|
||||
case tmpfsvfs2.Name:
|
||||
fsName = m.Type
|
||||
|
||||
var err error
|
||||
@@ -794,8 +796,8 @@ func (c *containerMounter) getMountNameAndOptions(conf *Config, m specs.Mount) (
|
||||
|
||||
case bind:
|
||||
fd := c.fds.remove()
|
||||
fsName = "9p"
|
||||
opts = p9MountOptions(fd, c.getMountAccessType(m))
|
||||
fsName = gofervfs2.Name
|
||||
opts = p9MountOptions(fd, c.getMountAccessType(m), conf.VFS2)
|
||||
// If configured, add overlay to all writable mounts.
|
||||
useOverlay = conf.Overlay && !mountFlags(m.Options).ReadOnly
|
||||
|
||||
@@ -948,7 +950,7 @@ func (c *containerMounter) createRestoreEnvironment(conf *Config) (*fs.RestoreEn
|
||||
|
||||
// Add root mount.
|
||||
fd := c.fds.remove()
|
||||
opts := p9MountOptions(fd, conf.FileAccess)
|
||||
opts := p9MountOptions(fd, conf.FileAccess, false /* vfs2 */)
|
||||
|
||||
mf := fs.MountSourceFlags{}
|
||||
if c.root.Readonly || conf.Overlay {
|
||||
@@ -960,7 +962,7 @@ func (c *containerMounter) createRestoreEnvironment(conf *Config) (*fs.RestoreEn
|
||||
Flags: mf,
|
||||
DataString: strings.Join(opts, ","),
|
||||
}
|
||||
renv.MountSources[rootFsName] = append(renv.MountSources[rootFsName], rootMount)
|
||||
renv.MountSources[gofervfs2.Name] = append(renv.MountSources[gofervfs2.Name], rootMount)
|
||||
|
||||
// Add submounts.
|
||||
var tmpMounted bool
|
||||
@@ -976,7 +978,7 @@ func (c *containerMounter) createRestoreEnvironment(conf *Config) (*fs.RestoreEn
|
||||
// TODO(b/67958150): handle '/tmp' properly (see mountTmp()).
|
||||
if !tmpMounted {
|
||||
tmpMount := specs.Mount{
|
||||
Type: tmpfs,
|
||||
Type: tmpfsvfs2.Name,
|
||||
Destination: "/tmp",
|
||||
}
|
||||
if err := c.addRestoreMount(conf, renv, tmpMount); err != nil {
|
||||
@@ -1032,7 +1034,7 @@ func (c *containerMounter) mountTmp(ctx context.Context, conf *Config, mns *fs.M
|
||||
// No '/tmp' found (or fallthrough from above). Safe to mount internal
|
||||
// tmpfs.
|
||||
tmpMount := specs.Mount{
|
||||
Type: tmpfs,
|
||||
Type: tmpfsvfs2.Name,
|
||||
Destination: "/tmp",
|
||||
// Sticky bit is added to prevent accidental deletion of files from
|
||||
// another user. This is normally done for /tmp.
|
||||
|
||||
+18
-69
@@ -18,7 +18,6 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
@@ -26,12 +25,12 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/sentry/devices/memdev"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs"
|
||||
devpts2 "gvisor.dev/gvisor/pkg/sentry/fsimpl/devpts"
|
||||
devtmpfsimpl "gvisor.dev/gvisor/pkg/sentry/fsimpl/devtmpfs"
|
||||
goferimpl "gvisor.dev/gvisor/pkg/sentry/fsimpl/gofer"
|
||||
procimpl "gvisor.dev/gvisor/pkg/sentry/fsimpl/proc"
|
||||
sysimpl "gvisor.dev/gvisor/pkg/sentry/fsimpl/sys"
|
||||
tmpfsimpl "gvisor.dev/gvisor/pkg/sentry/fsimpl/tmpfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/devpts"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/devtmpfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/gofer"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/proc"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/sys"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/tmpfs"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
@@ -42,28 +41,28 @@ import (
|
||||
)
|
||||
|
||||
func registerFilesystems(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials) error {
|
||||
vfsObj.MustRegisterFilesystemType(devpts2.Name, &devpts2.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
vfsObj.MustRegisterFilesystemType(devpts.Name, &devpts.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
AllowUserList: true,
|
||||
// TODO(b/29356795): Users may mount this once the terminals are in a
|
||||
// usable state.
|
||||
AllowUserMount: false,
|
||||
})
|
||||
vfsObj.MustRegisterFilesystemType(devtmpfsimpl.Name, &devtmpfsimpl.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
vfsObj.MustRegisterFilesystemType(devtmpfs.Name, &devtmpfs.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
AllowUserMount: true,
|
||||
AllowUserList: true,
|
||||
})
|
||||
vfsObj.MustRegisterFilesystemType(goferimpl.Name, &goferimpl.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
vfsObj.MustRegisterFilesystemType(gofer.Name, &gofer.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
AllowUserList: true,
|
||||
})
|
||||
vfsObj.MustRegisterFilesystemType(procimpl.Name, &procimpl.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
vfsObj.MustRegisterFilesystemType(proc.Name, &proc.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
AllowUserMount: true,
|
||||
AllowUserList: true,
|
||||
})
|
||||
vfsObj.MustRegisterFilesystemType(sysimpl.Name, &sysimpl.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
vfsObj.MustRegisterFilesystemType(sys.Name, &sys.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
AllowUserMount: true,
|
||||
AllowUserList: true,
|
||||
})
|
||||
vfsObj.MustRegisterFilesystemType(tmpfsimpl.Name, &tmpfsimpl.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
vfsObj.MustRegisterFilesystemType(tmpfs.Name, &tmpfs.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
|
||||
AllowUserMount: true,
|
||||
AllowUserList: true,
|
||||
})
|
||||
@@ -72,7 +71,7 @@ func registerFilesystems(ctx context.Context, vfsObj *vfs.VirtualFilesystem, cre
|
||||
if err := memdev.Register(vfsObj); err != nil {
|
||||
return fmt.Errorf("registering memdev: %w", err)
|
||||
}
|
||||
a, err := devtmpfsimpl.NewAccessor(ctx, vfsObj, creds, devtmpfsimpl.Name)
|
||||
a, err := devtmpfs.NewAccessor(ctx, vfsObj, creds, devtmpfs.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating devtmpfs accessor: %w", err)
|
||||
}
|
||||
@@ -193,10 +192,10 @@ func (c *containerMounter) setupVFS2(ctx context.Context, conf *Config, procArgs
|
||||
|
||||
func (c *containerMounter) createMountNamespaceVFS2(ctx context.Context, conf *Config, creds *auth.Credentials) (*vfs.MountNamespace, error) {
|
||||
fd := c.fds.remove()
|
||||
opts := strings.Join(p9MountOptionsVFS2(fd, conf.FileAccess), ",")
|
||||
opts := strings.Join(p9MountOptions(fd, conf.FileAccess, true /* vfs2 */), ",")
|
||||
|
||||
log.Infof("Mounting root over 9P, ioFD: %d", fd)
|
||||
mns, err := c.k.VFS().NewMountNamespace(ctx, creds, "", rootFsName, &vfs.GetFilesystemOptions{Data: opts})
|
||||
mns, err := c.k.VFS().NewMountNamespace(ctx, creds, "", gofer.Name, &vfs.GetFilesystemOptions{Data: opts})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setting up mount namespace: %w", err)
|
||||
}
|
||||
@@ -223,7 +222,8 @@ func (c *containerMounter) prepareMountsVFS2() {
|
||||
sort.Slice(c.mounts, func(i, j int) bool { return len(c.mounts[i].Destination) < len(c.mounts[j].Destination) })
|
||||
}
|
||||
|
||||
// TODO(gvisor.dev/issue/1487): Implement submount options similar to the VFS1 version.
|
||||
// TODO(gvisor.dev/issue/1487): Implement submount options similar to the VFS1
|
||||
// version.
|
||||
func (c *containerMounter) mountSubmountVFS2(ctx context.Context, conf *Config, mns *vfs.MountNamespace, creds *auth.Credentials, submount *specs.Mount) error {
|
||||
root := mns.Root()
|
||||
defer root.DecRef()
|
||||
@@ -233,7 +233,7 @@ func (c *containerMounter) mountSubmountVFS2(ctx context.Context, conf *Config,
|
||||
Path: fspath.Parse(submount.Destination),
|
||||
}
|
||||
|
||||
fsName, options, useOverlay, err := c.getMountNameAndOptionsVFS2(conf, *submount)
|
||||
fsName, options, useOverlay, err := c.getMountNameAndOptions(conf, *submount)
|
||||
if err != nil {
|
||||
return fmt.Errorf("mountOptions failed: %w", err)
|
||||
}
|
||||
@@ -263,57 +263,6 @@ func (c *containerMounter) mountSubmountVFS2(ctx context.Context, conf *Config,
|
||||
return nil
|
||||
}
|
||||
|
||||
// getMountNameAndOptionsVFS2 retrieves the fsName, opts, and useOverlay values
|
||||
// used for mounts.
|
||||
func (c *containerMounter) getMountNameAndOptionsVFS2(conf *Config, m specs.Mount) (string, []string, bool, error) {
|
||||
var (
|
||||
fsName string
|
||||
opts []string
|
||||
useOverlay bool
|
||||
)
|
||||
|
||||
switch m.Type {
|
||||
case devpts, devtmpfs, proc, sysfs:
|
||||
fsName = m.Type
|
||||
case nonefs:
|
||||
fsName = sysfs
|
||||
case tmpfs:
|
||||
fsName = m.Type
|
||||
|
||||
var err error
|
||||
opts, err = parseAndFilterOptions(m.Options, tmpfsAllowedOptions...)
|
||||
if err != nil {
|
||||
return "", nil, false, err
|
||||
}
|
||||
|
||||
case bind:
|
||||
fd := c.fds.remove()
|
||||
fsName = "9p"
|
||||
opts = p9MountOptionsVFS2(fd, c.getMountAccessType(m))
|
||||
// If configured, add overlay to all writable mounts.
|
||||
useOverlay = conf.Overlay && !mountFlags(m.Options).ReadOnly
|
||||
|
||||
default:
|
||||
log.Warningf("ignoring unknown filesystem type %q", m.Type)
|
||||
}
|
||||
return fsName, opts, useOverlay, nil
|
||||
}
|
||||
|
||||
// p9MountOptions creates a slice of options for a p9 mount.
|
||||
// TODO(gvisor.dev/issue/1624): Remove this version once privateunixsocket is
|
||||
// deleted, along with the rest of VFS1.
|
||||
func p9MountOptionsVFS2(fd int, fa FileAccessType) []string {
|
||||
opts := []string{
|
||||
"trans=fd",
|
||||
"rfdno=" + strconv.Itoa(fd),
|
||||
"wfdno=" + strconv.Itoa(fd),
|
||||
}
|
||||
if fa == FileAccessShared {
|
||||
opts = append(opts, "cache=remote_revalidating")
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func (c *containerMounter) makeSyntheticMount(ctx context.Context, currentPath string, root vfs.VirtualDentry, creds *auth.Credentials) error {
|
||||
target := &vfs.PathOperation{
|
||||
Root: root,
|
||||
|
||||
Reference in New Issue
Block a user