mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Start deletion of VFS1 from runsc config
Updates #1624 PiperOrigin-RevId: 450708193
This commit is contained in:
committed by
gVisor bot
parent
a6fbca2eec
commit
adff8e5863
@@ -54,10 +54,8 @@ go_library(
|
||||
"//pkg/sentry/fdimport",
|
||||
"//pkg/sentry/fs",
|
||||
"//pkg/sentry/fs/dev",
|
||||
"//pkg/sentry/fs/gofer",
|
||||
"//pkg/sentry/fs/host",
|
||||
"//pkg/sentry/fs/proc",
|
||||
"//pkg/sentry/fs/ramfs",
|
||||
"//pkg/sentry/fs/sys",
|
||||
"//pkg/sentry/fs/tmpfs",
|
||||
"//pkg/sentry/fs/tty",
|
||||
@@ -143,12 +141,9 @@ go_test(
|
||||
library = ":boot",
|
||||
deps = [
|
||||
"//pkg/control/server",
|
||||
"//pkg/fd",
|
||||
"//pkg/fspath",
|
||||
"//pkg/log",
|
||||
"//pkg/p9",
|
||||
"//pkg/sentry/contexttest",
|
||||
"//pkg/sentry/fs",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/sync",
|
||||
"//pkg/unet",
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/sentry/control"
|
||||
controlpb "gvisor.dev/gvisor/pkg/sentry/control/control_go_proto"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/seccheck"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/netstack"
|
||||
@@ -446,18 +445,10 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error {
|
||||
|
||||
// Set up the restore environment.
|
||||
ctx := k.SupervisorContext()
|
||||
mntr := newContainerMounter(&cm.l.root, cm.l.k, cm.l.mountHints, kernel.VFS2Enabled, cm.l.productName)
|
||||
if kernel.VFS2Enabled {
|
||||
ctx, err = mntr.configureRestore(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("configuring filesystem restore: %v", err)
|
||||
}
|
||||
} else {
|
||||
renv, err := mntr.createRestoreEnvironment(cm.l.root.conf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating RestoreEnvironment: %v", err)
|
||||
}
|
||||
fs.SetRestoreEnvironment(*renv)
|
||||
mntr := newContainerMounter(&cm.l.root, cm.l.k, cm.l.mountHints, cm.l.productName)
|
||||
ctx, err = mntr.configureRestore(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("configuring filesystem restore: %v", err)
|
||||
}
|
||||
|
||||
// Prepare to load from the state file.
|
||||
|
||||
+5
-596
File diff suppressed because it is too large
Load Diff
@@ -243,7 +243,7 @@ func TestGetMountAccessType(t *testing.T) {
|
||||
t.Fatalf("newPodMountHints failed: %v", err)
|
||||
}
|
||||
mounter := containerMounter{hints: podHints}
|
||||
conf := &config.Config{VFS2: true, FileAccessMounts: config.FileAccessShared}
|
||||
conf := &config.Config{FileAccessMounts: config.FileAccessShared}
|
||||
if got := mounter.getMountAccessType(conf, &specs.Mount{Source: source}); got != tst.want {
|
||||
t.Errorf("getMountAccessType(), want: %v, got: %v", tst.want, got)
|
||||
}
|
||||
|
||||
+25
-70
@@ -253,13 +253,10 @@ func New(args Args) (*Loader, error) {
|
||||
return nil, fmt.Errorf("setting up memory usage: %w", err)
|
||||
}
|
||||
|
||||
// Is this a VFSv2 kernel?
|
||||
if args.Conf.VFS2 {
|
||||
kernel.VFS2Enabled = true
|
||||
kernel.FUSEEnabled = args.Conf.FUSE
|
||||
kernel.LISAFSEnabled = args.Conf.Lisafs
|
||||
vfs2.Override()
|
||||
}
|
||||
kernel.VFS2Enabled = true
|
||||
kernel.FUSEEnabled = args.Conf.FUSE
|
||||
kernel.LISAFSEnabled = args.Conf.Lisafs
|
||||
vfs2.Override()
|
||||
|
||||
// Make host FDs stable between invocations. Host FDs must map to the exact
|
||||
// same number when the sandbox is restored. Otherwise the wrong FD will be
|
||||
@@ -377,14 +374,8 @@ func New(args Args) (*Loader, error) {
|
||||
return nil, fmt.Errorf("initializing kernel: %w", err)
|
||||
}
|
||||
|
||||
if kernel.VFS2Enabled {
|
||||
if err := registerFilesystems(k); err != nil {
|
||||
return nil, fmt.Errorf("registering filesystems: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := adjustDirentCache(k); err != nil {
|
||||
return nil, err
|
||||
if err := registerFilesystems(k); err != nil {
|
||||
return nil, fmt.Errorf("registering filesystems: %w", err)
|
||||
}
|
||||
|
||||
// Turn on packet logging if enabled.
|
||||
@@ -419,15 +410,13 @@ func New(args Args) (*Loader, error) {
|
||||
info.conf = args.Conf
|
||||
info.spec = args.Spec
|
||||
|
||||
if kernel.VFS2Enabled {
|
||||
// Set up host mount that will be used for imported fds.
|
||||
hostFilesystem, err := hostvfs2.NewFilesystem(k.VFS())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create hostfs filesystem: %w", err)
|
||||
}
|
||||
defer hostFilesystem.DecRef(k.SupervisorContext())
|
||||
k.SetHostMount(k.VFS().NewDisconnectedMount(hostFilesystem, nil, &vfs.MountOptions{}))
|
||||
// Set up host mount that will be used for imported fds.
|
||||
hostFilesystem, err := hostvfs2.NewFilesystem(k.VFS())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create hostfs filesystem: %w", err)
|
||||
}
|
||||
defer hostFilesystem.DecRef(k.SupervisorContext())
|
||||
k.SetHostMount(k.VFS().NewDisconnectedMount(hostFilesystem, nil, &vfs.MountOptions{}))
|
||||
|
||||
if args.PodInitConfigFD >= 0 {
|
||||
if err := setupSeccheck(args.PodInitConfigFD, args.SinkFDs); err != nil {
|
||||
@@ -837,30 +826,22 @@ func (l *Loader) createContainerProcess(root bool, cid string, info *containerIn
|
||||
}
|
||||
l.startGoferMonitor(cid, int32(info.goferFDs[0].FD()))
|
||||
|
||||
mntr := newContainerMounter(info, l.k, l.mountHints, kernel.VFS2Enabled, l.productName)
|
||||
mntr := newContainerMounter(info, l.k, l.mountHints, l.productName)
|
||||
if root {
|
||||
if err := mntr.processHints(info.conf, info.procArgs.Credentials); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
if err := setupContainerFS(ctx, info.conf, mntr, &info.procArgs); err != nil {
|
||||
if err := setupContainerVFS(ctx, info.conf, mntr, &info.procArgs); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
// Add the HOME environment variable if it is not already set.
|
||||
var envv []string
|
||||
if kernel.VFS2Enabled {
|
||||
envv, err = user.MaybeAddExecUserHomeVFS2(ctx, info.procArgs.MountNamespaceVFS2,
|
||||
info.procArgs.Credentials.RealKUID, info.procArgs.Envv)
|
||||
|
||||
} else {
|
||||
envv, err = user.MaybeAddExecUserHome(ctx, info.procArgs.MountNamespace,
|
||||
info.procArgs.Credentials.RealKUID, info.procArgs.Envv)
|
||||
}
|
||||
info.procArgs.Envv, err = user.MaybeAddExecUserHomeVFS2(ctx, info.procArgs.MountNamespaceVFS2,
|
||||
info.procArgs.Credentials.RealKUID, info.procArgs.Envv)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
info.procArgs.Envv = envv
|
||||
|
||||
// Create and start the new process.
|
||||
tg, _, err := l.k.CreateProcess(info.procArgs)
|
||||
@@ -1012,22 +993,10 @@ func (l *Loader) executeAsync(args *control.ExecArgs) (kernel.ThreadID, error) {
|
||||
|
||||
// Get the container MountNamespace from the Task. Try to acquire ref may fail
|
||||
// in case it raced with task exit.
|
||||
if kernel.VFS2Enabled {
|
||||
// task.MountNamespaceVFS2() does not take a ref, so we must do so ourselves.
|
||||
args.MountNamespaceVFS2 = tg.Leader().MountNamespaceVFS2()
|
||||
if args.MountNamespaceVFS2 == nil || !args.MountNamespaceVFS2.TryIncRef() {
|
||||
return 0, fmt.Errorf("container %q has stopped", args.ContainerID)
|
||||
}
|
||||
} else {
|
||||
var reffed bool
|
||||
tg.Leader().WithMuLocked(func(t *kernel.Task) {
|
||||
// task.MountNamespace() does not take a ref, so we must do so ourselves.
|
||||
args.MountNamespace = t.MountNamespace()
|
||||
reffed = args.MountNamespace.TryIncRef()
|
||||
})
|
||||
if !reffed {
|
||||
return 0, fmt.Errorf("container %q has stopped", args.ContainerID)
|
||||
}
|
||||
// task.MountNamespaceVFS2() does not take a ref, so we must do so ourselves.
|
||||
args.MountNamespaceVFS2 = tg.Leader().MountNamespaceVFS2()
|
||||
if args.MountNamespaceVFS2 == nil || !args.MountNamespaceVFS2.TryIncRef() {
|
||||
return 0, fmt.Errorf("container %q has stopped", args.ContainerID)
|
||||
}
|
||||
|
||||
args.Envv, err = specutils.ResolveEnvs(args.Envv)
|
||||
@@ -1036,25 +1005,11 @@ func (l *Loader) executeAsync(args *control.ExecArgs) (kernel.ThreadID, error) {
|
||||
}
|
||||
|
||||
// Add the HOME environment variable if it is not already set.
|
||||
if kernel.VFS2Enabled {
|
||||
root := args.MountNamespaceVFS2.Root()
|
||||
ctx := vfs.WithRoot(l.k.SupervisorContext(), root)
|
||||
defer args.MountNamespaceVFS2.DecRef(ctx)
|
||||
envv, err := user.MaybeAddExecUserHomeVFS2(ctx, args.MountNamespaceVFS2, args.KUID, args.Envv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
args.Envv = envv
|
||||
} else {
|
||||
root := args.MountNamespace.Root()
|
||||
ctx := fs.WithRoot(l.k.SupervisorContext(), root)
|
||||
defer args.MountNamespace.DecRef(ctx)
|
||||
defer root.DecRef(ctx)
|
||||
envv, err := user.MaybeAddExecUserHome(ctx, args.MountNamespace, args.KUID, args.Envv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
args.Envv = envv
|
||||
ctx := vfs.WithRoot(l.k.SupervisorContext(), args.MountNamespaceVFS2.Root())
|
||||
defer args.MountNamespaceVFS2.DecRef(ctx)
|
||||
args.Envv, err = user.MaybeAddExecUserHomeVFS2(ctx, args.MountNamespaceVFS2, args.KUID, args.Envv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
args.PIDNamespace = tg.PIDNamespace()
|
||||
|
||||
|
||||
+5
-288
@@ -18,19 +18,15 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/control/server"
|
||||
"gvisor.dev/gvisor/pkg/fd"
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/p9"
|
||||
"gvisor.dev/gvisor/pkg/sentry/contexttest"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/unet"
|
||||
@@ -110,14 +106,12 @@ func startGofer(root string) (int, func(), error) {
|
||||
return sandboxEnd, cleanup, nil
|
||||
}
|
||||
|
||||
func createLoader(vfsEnabled bool, spec *specs.Spec) (*Loader, func(), error) {
|
||||
func createLoader(spec *specs.Spec) (*Loader, func(), error) {
|
||||
fd, err := server.CreateSocket(ControlSocketAddr(fmt.Sprintf("%010d", rand.Int())[:10]))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
conf := testConfig()
|
||||
conf.VFS2 = vfsEnabled
|
||||
|
||||
sandEnd, cleanup, err := startGofer(spec.Root.Path)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -152,16 +146,7 @@ func createLoader(vfsEnabled bool, spec *specs.Spec) (*Loader, func(), error) {
|
||||
|
||||
// TestRun runs a simple application in a sandbox and checks that it succeeds.
|
||||
func TestRun(t *testing.T) {
|
||||
doRun(t, false)
|
||||
}
|
||||
|
||||
// TestRunVFS2 runs TestRun in VFSv2.
|
||||
func TestRunVFS2(t *testing.T) {
|
||||
doRun(t, true)
|
||||
}
|
||||
|
||||
func doRun(t *testing.T, vfsEnabled bool) {
|
||||
l, cleanup, err := createLoader(vfsEnabled, testSpec())
|
||||
l, cleanup, err := createLoader(testSpec())
|
||||
if err != nil {
|
||||
t.Fatalf("error creating loader: %v", err)
|
||||
}
|
||||
@@ -199,16 +184,7 @@ func doRun(t *testing.T, vfsEnabled bool) {
|
||||
// TestStartSignal tests that the controller Start message will cause
|
||||
// WaitForStartSignal to return.
|
||||
func TestStartSignal(t *testing.T) {
|
||||
doStartSignal(t, false)
|
||||
}
|
||||
|
||||
// TestStartSignalVFS2 does TestStartSignal with VFS2.
|
||||
func TestStartSignalVFS2(t *testing.T) {
|
||||
doStartSignal(t, true)
|
||||
}
|
||||
|
||||
func doStartSignal(t *testing.T, vfsEnabled bool) {
|
||||
l, cleanup, err := createLoader(vfsEnabled, testSpec())
|
||||
l, cleanup, err := createLoader(testSpec())
|
||||
if err != nil {
|
||||
t.Fatalf("error creating loader: %v", err)
|
||||
}
|
||||
@@ -253,7 +229,6 @@ func doStartSignal(t *testing.T, vfsEnabled bool) {
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
t.Errorf("WaitForStartSignal did not complete but it should have")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type CreateMountTestcase struct {
|
||||
@@ -431,49 +406,6 @@ func createMountTestcases() []*CreateMountTestcase {
|
||||
|
||||
// Test that MountNamespace can be created with various specs.
|
||||
func TestCreateMountNamespace(t *testing.T) {
|
||||
for _, tc := range createMountTestcases() {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
conf := testConfig()
|
||||
ctx := contexttest.Context(t)
|
||||
|
||||
sandEnd, cleanup, err := startGofer(tc.spec.Root.Path)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create gofer: %v", err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
info := containerInfo{
|
||||
conf: conf,
|
||||
spec: &tc.spec,
|
||||
goferFDs: []*fd.FD{fd.New(sandEnd)},
|
||||
}
|
||||
|
||||
mntr := newContainerMounter(&info, nil, &podMountHints{}, false /* vfs2Enabled */, "")
|
||||
mns, err := mntr.createMountNamespace(ctx, conf)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create mount namespace: %v", err)
|
||||
}
|
||||
ctx = fs.WithRoot(ctx, mns.Root())
|
||||
if err := mntr.mountSubmounts(ctx, conf, mns); err != nil {
|
||||
t.Fatalf("failed to create mount namespace: %v", err)
|
||||
}
|
||||
|
||||
root := mns.Root()
|
||||
defer root.DecRef(ctx)
|
||||
for _, p := range tc.expectedPaths {
|
||||
maxTraversals := uint(0)
|
||||
if d, err := mns.FindInode(ctx, root, root, p, &maxTraversals); err != nil {
|
||||
t.Errorf("expected path %v to exist with spec %v, but got error %v", p, tc.spec, err)
|
||||
} else {
|
||||
d.DecRef(ctx)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Test that MountNamespace can be created with various specs.
|
||||
func TestCreateMountNamespaceVFS2(t *testing.T) {
|
||||
for _, tc := range createMountTestcases() {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
spec := testSpec()
|
||||
@@ -481,14 +413,14 @@ func TestCreateMountNamespaceVFS2(t *testing.T) {
|
||||
spec.Root = tc.spec.Root
|
||||
|
||||
t.Logf("Using root: %q", spec.Root.Path)
|
||||
l, loaderCleanup, err := createLoader(true /* VFS2 Enabled */, spec)
|
||||
l, loaderCleanup, err := createLoader(spec)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create loader: %v", err)
|
||||
}
|
||||
defer l.Destroy()
|
||||
defer loaderCleanup()
|
||||
|
||||
mntr := newContainerMounter(&l.root, l.k, l.mountHints, true /* vfs2Enabled */, "")
|
||||
mntr := newContainerMounter(&l.root, l.k, l.mountHints, "")
|
||||
if err := mntr.processHints(l.root.conf, l.root.procArgs.Credentials); err != nil {
|
||||
t.Fatalf("failed process hints: %v", err)
|
||||
}
|
||||
@@ -518,218 +450,3 @@ func TestCreateMountNamespaceVFS2(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestRestoreEnvironment tests that the correct mounts are collected from the spec and config
|
||||
// in order to build the environment for restoring.
|
||||
func TestRestoreEnvironment(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
spec *specs.Spec
|
||||
ioFDs []int
|
||||
errorExpected bool
|
||||
expectedRenv fs.RestoreEnvironment
|
||||
}{
|
||||
{
|
||||
name: "basic spec test",
|
||||
spec: &specs.Spec{
|
||||
Root: &specs.Root{
|
||||
Path: os.TempDir(),
|
||||
Readonly: true,
|
||||
},
|
||||
Mounts: []specs.Mount{
|
||||
{
|
||||
Destination: "/some/very/very/deep/path",
|
||||
Type: "tmpfs",
|
||||
},
|
||||
{
|
||||
Destination: "/proc",
|
||||
Type: "tmpfs",
|
||||
},
|
||||
},
|
||||
},
|
||||
ioFDs: []int{0},
|
||||
errorExpected: false,
|
||||
expectedRenv: fs.RestoreEnvironment{
|
||||
MountSources: map[string][]fs.MountArgs{
|
||||
"9p": {
|
||||
{
|
||||
Dev: "9pfs-/",
|
||||
Flags: fs.MountSourceFlags{ReadOnly: true},
|
||||
DataString: "trans=fd,rfdno=0,wfdno=0",
|
||||
},
|
||||
},
|
||||
"tmpfs": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"devtmpfs": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"devpts": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"sysfs": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bind type test",
|
||||
spec: &specs.Spec{
|
||||
Root: &specs.Root{
|
||||
Path: os.TempDir(),
|
||||
Readonly: true,
|
||||
},
|
||||
Mounts: []specs.Mount{
|
||||
{
|
||||
Destination: "/dev/fd-foo",
|
||||
Type: "bind",
|
||||
},
|
||||
},
|
||||
},
|
||||
ioFDs: []int{0, 1},
|
||||
errorExpected: false,
|
||||
expectedRenv: fs.RestoreEnvironment{
|
||||
MountSources: map[string][]fs.MountArgs{
|
||||
"9p": {
|
||||
{
|
||||
Dev: "9pfs-/",
|
||||
Flags: fs.MountSourceFlags{ReadOnly: true},
|
||||
DataString: "trans=fd,rfdno=0,wfdno=0",
|
||||
},
|
||||
{
|
||||
Dev: "9pfs-/dev/fd-foo",
|
||||
DataString: "trans=fd,rfdno=1,wfdno=1,cache=remote_revalidating",
|
||||
},
|
||||
},
|
||||
"tmpfs": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"devtmpfs": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"devpts": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"proc": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"sysfs": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "options test",
|
||||
spec: &specs.Spec{
|
||||
Root: &specs.Root{
|
||||
Path: os.TempDir(),
|
||||
Readonly: true,
|
||||
},
|
||||
Mounts: []specs.Mount{
|
||||
{
|
||||
Destination: "/dev/fd-foo",
|
||||
Type: "tmpfs",
|
||||
Options: []string{"uid=1022", "noatime"},
|
||||
},
|
||||
},
|
||||
},
|
||||
ioFDs: []int{0},
|
||||
errorExpected: false,
|
||||
expectedRenv: fs.RestoreEnvironment{
|
||||
MountSources: map[string][]fs.MountArgs{
|
||||
"9p": {
|
||||
{
|
||||
Dev: "9pfs-/",
|
||||
Flags: fs.MountSourceFlags{ReadOnly: true},
|
||||
DataString: "trans=fd,rfdno=0,wfdno=0",
|
||||
},
|
||||
},
|
||||
"tmpfs": {
|
||||
{
|
||||
Dev: "none",
|
||||
Flags: fs.MountSourceFlags{NoAtime: true},
|
||||
DataString: "uid=1022",
|
||||
},
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"devtmpfs": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"devpts": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"proc": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
"sysfs": {
|
||||
{
|
||||
Dev: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
conf := testConfig()
|
||||
conf.VFS2 = true
|
||||
var ioFDs []*fd.FD
|
||||
for _, ioFD := range tc.ioFDs {
|
||||
ioFDs = append(ioFDs, fd.New(ioFD))
|
||||
}
|
||||
info := containerInfo{
|
||||
conf: conf,
|
||||
spec: tc.spec,
|
||||
goferFDs: ioFDs,
|
||||
}
|
||||
mntr := newContainerMounter(&info, nil, &podMountHints{}, conf.VFS2, "")
|
||||
actualRenv, err := mntr.createRestoreEnvironment(conf)
|
||||
if !tc.errorExpected && err != nil {
|
||||
t.Fatalf("could not create restore environment for test:%s", tc.name)
|
||||
} else if tc.errorExpected {
|
||||
if err == nil {
|
||||
t.Errorf("expected an error, but no error occurred.")
|
||||
}
|
||||
} else {
|
||||
if !reflect.DeepEqual(*actualRenv, tc.expectedRenv) {
|
||||
t.Errorf("restore environments did not match for test:%s\ngot:%+v\nwant:%+v\n", tc.name, *actualRenv, tc.expectedRenv)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -151,7 +151,7 @@ func registerFilesystems(k *kernel.Kernel) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupContainerVFS2(ctx context.Context, conf *config.Config, mntr *containerMounter, procArgs *kernel.CreateProcessArgs) error {
|
||||
func setupContainerVFS(ctx context.Context, conf *config.Config, mntr *containerMounter, procArgs *kernel.CreateProcessArgs) error {
|
||||
mns, err := mntr.mountAll(conf, procArgs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to setupFS: %w", err)
|
||||
@@ -213,7 +213,7 @@ func (c *containerMounter) mountAll(conf *config.Config, procArgs *kernel.Create
|
||||
// createMountNamespaceVFS2 creates the container's root mount and namespace.
|
||||
func (c *containerMounter) createMountNamespaceVFS2(ctx context.Context, conf *config.Config, creds *auth.Credentials) (*vfs.MountNamespace, error) {
|
||||
fd := c.fds.remove()
|
||||
data := goferMountData(fd, conf.FileAccess, true /* vfs2 */, conf.Lisafs)
|
||||
data := goferMountData(fd, conf.FileAccess, conf.Lisafs)
|
||||
|
||||
// We can't check for overlayfs here because sandbox is chroot'ed and gofer
|
||||
// can only send mount options for specs.Mounts (specs.Root is missing
|
||||
@@ -525,7 +525,7 @@ func (c *containerMounter) getMountNameAndOptionsVFS2(conf *config.Config, m *mo
|
||||
// but unlikely to be correct in this context.
|
||||
return "", nil, false, fmt.Errorf("9P mount requires a connection FD")
|
||||
}
|
||||
data = goferMountData(m.fd, c.getMountAccessType(conf, m.mount), true /* vfs2 */, conf.Lisafs)
|
||||
data = goferMountData(m.fd, c.getMountAccessType(conf, m.mount), conf.Lisafs)
|
||||
internalData = gofer.InternalFilesystemOptions{
|
||||
UniqueID: m.mount.Destination,
|
||||
}
|
||||
@@ -718,10 +718,10 @@ func (c *containerMounter) mountTmpVFS2(ctx context.Context, conf *config.Config
|
||||
}
|
||||
}
|
||||
|
||||
// processHintsVFS2 processes annotations that container hints about how volumes
|
||||
// processHints processes annotations that container hints about how volumes
|
||||
// should be mounted (e.g. a volume shared between containers). It must be
|
||||
// called for the root container only.
|
||||
func (c *containerMounter) processHintsVFS2(conf *config.Config, creds *auth.Credentials) error {
|
||||
func (c *containerMounter) processHints(conf *config.Config, creds *auth.Credentials) error {
|
||||
ctx := c.k.SupervisorContext()
|
||||
for _, hint := range c.hints.mounts {
|
||||
// TODO(b/142076984): Only support tmpfs for now. Bind mounts require a
|
||||
|
||||
+4
-4
@@ -218,7 +218,7 @@ func (g *Gofer) serveLisafs(spec *specs.Spec, conf *config.Config, root string)
|
||||
|
||||
mountIdx := 1 // first one is the root
|
||||
for _, m := range spec.Mounts {
|
||||
if !specutils.IsGoferMount(m, conf.VFS2) {
|
||||
if !specutils.IsGoferMount(m) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ func (g *Gofer) serve9P(spec *specs.Spec, conf *config.Config, root string) subc
|
||||
|
||||
mountIdx := 1 // first one is the root
|
||||
for _, m := range spec.Mounts {
|
||||
if specutils.IsGoferMount(m, conf.VFS2) {
|
||||
if specutils.IsGoferMount(m) {
|
||||
cfg := fsgofer.Config{
|
||||
ROMount: isReadonlyMount(m.Options) || conf.Overlay,
|
||||
HostUDS: conf.FSGoferHostUDS,
|
||||
@@ -445,7 +445,7 @@ func setupRootFS(spec *specs.Spec, conf *config.Config) error {
|
||||
// creates directories as needed.
|
||||
func setupMounts(conf *config.Config, mounts []specs.Mount, root, procPath string) error {
|
||||
for _, m := range mounts {
|
||||
if !specutils.IsGoferMount(m, conf.VFS2) {
|
||||
if !specutils.IsGoferMount(m) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -485,7 +485,7 @@ func setupMounts(conf *config.Config, mounts []specs.Mount, root, procPath strin
|
||||
func resolveMounts(conf *config.Config, mounts []specs.Mount, root string) ([]specs.Mount, error) {
|
||||
cleanMounts := make([]specs.Mount, 0, len(mounts))
|
||||
for _, m := range mounts {
|
||||
if !specutils.IsGoferMount(m, conf.VFS2) {
|
||||
if !specutils.IsGoferMount(m) {
|
||||
cleanMounts = append(cleanMounts, m)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -204,9 +204,6 @@ type Config struct {
|
||||
// E.g. 0.2 CPU quota will result in 1, and 1.9 in 2.
|
||||
CPUNumFromQuota bool `flag:"cpu-num-from-quota"`
|
||||
|
||||
// DEPRECATED: VFS2 is always enabled and cannot be disabled.
|
||||
VFS2 bool
|
||||
|
||||
// Enable lisafs.
|
||||
Lisafs bool `flag:"lisafs"`
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ func checkOciSeccomp(name string, value string) error {
|
||||
|
||||
// NewFromFlags creates a new Config with values coming from command line flags.
|
||||
func NewFromFlags(flagSet *flag.FlagSet) (*Config, error) {
|
||||
conf := &Config{VFS2: true}
|
||||
conf := &Config{}
|
||||
|
||||
obj := reflect.ValueOf(conf).Elem()
|
||||
st := obj.Type()
|
||||
|
||||
@@ -938,7 +938,7 @@ func (c *Container) createGoferProcess(spec *specs.Spec, conf *config.Config, bu
|
||||
// Add root mount and then add any other additional mounts.
|
||||
mountCount := 1
|
||||
for _, m := range spec.Mounts {
|
||||
if specutils.IsGoferMount(m, conf.VFS2) {
|
||||
if specutils.IsGoferMount(m) {
|
||||
mountCount++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,9 +335,9 @@ func capsFromNames(names []string, skipSet map[linux.Capability]struct{}) (auth.
|
||||
|
||||
// IsGoferMount returns true if the given mount can be mounted as an external
|
||||
// gofer.
|
||||
func IsGoferMount(m specs.Mount, vfs2Enabled bool) bool {
|
||||
func IsGoferMount(m specs.Mount) bool {
|
||||
MaybeConvertToBindMount(&m)
|
||||
return m.Type == "bind" && m.Source != "" && IsSupportedDevMount(m, vfs2Enabled)
|
||||
return m.Type == "bind" && m.Source != ""
|
||||
}
|
||||
|
||||
// MaybeConvertToBindMount converts mount type to "bind" in case any of the
|
||||
@@ -357,29 +357,6 @@ func MaybeConvertToBindMount(m *specs.Mount) {
|
||||
}
|
||||
}
|
||||
|
||||
// IsSupportedDevMount returns true if m.Destination does not specify a
|
||||
// path that is hardcoded by VFS1's implementation of /dev.
|
||||
func IsSupportedDevMount(m specs.Mount, vfs2Enabled bool) bool {
|
||||
// VFS2 has no hardcoded files under /dev, so everything is allowed.
|
||||
if vfs2Enabled {
|
||||
return true
|
||||
}
|
||||
|
||||
// See pkg/sentry/fs/dev/dev.go.
|
||||
var existingDevices = []string{
|
||||
"/dev/fd", "/dev/stdin", "/dev/stdout", "/dev/stderr",
|
||||
"/dev/null", "/dev/zero", "/dev/full", "/dev/random",
|
||||
"/dev/urandom", "/dev/shm", "/dev/ptmx",
|
||||
}
|
||||
dst := filepath.Clean(m.Destination)
|
||||
for _, dev := range existingDevices {
|
||||
if dst == dev || strings.HasPrefix(dst, dev+"/") {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// WaitForReady waits for a process to become ready. The process is ready when
|
||||
// the 'ready' function returns true. It continues to wait if 'ready' returns
|
||||
// false. It returns error on timeout, if the process stops or if 'ready' fails.
|
||||
|
||||
Reference in New Issue
Block a user