mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Refactor container FS setup
No change in functionaly. Added containerMounter object to keep state while the mounts are processed. This will help upcoming changes to share mounts per-pod. PiperOrigin-RevId: 251350096
This commit is contained in:
committed by
Shentubot
parent
d28f71adcf
commit
f1aee6a7ad
@@ -237,7 +237,7 @@ func (cm *containerManager) Start(args *StartArgs, _ *struct{}) error {
|
||||
return fmt.Errorf("start arguments must contain stdin, stderr, and stdout followed by at least one file for the container root gofer")
|
||||
}
|
||||
|
||||
err := cm.l.startContainer(cm.l.k, args.Spec, args.Conf, args.CID, args.FilePayload.Files)
|
||||
err := cm.l.startContainer(args.Spec, args.Conf, args.CID, args.FilePayload.Files)
|
||||
if err != nil {
|
||||
log.Debugf("containerManager.Start failed %q: %+v: %v", args.CID, args, err)
|
||||
return err
|
||||
@@ -340,8 +340,8 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error {
|
||||
cm.l.k = k
|
||||
|
||||
// Set up the restore environment.
|
||||
fds := &fdDispenser{fds: cm.l.goferFDs}
|
||||
renv, err := createRestoreEnvironment(cm.l.spec, cm.l.conf, fds)
|
||||
mntr := newContainerMounter(cm.l.spec, "", cm.l.goferFDs, cm.l.k)
|
||||
renv, err := mntr.createRestoreEnvironment(cm.l.conf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating RestoreEnvironment: %v", err)
|
||||
}
|
||||
@@ -369,11 +369,11 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error {
|
||||
k.Timekeeper().SetClocks(time.NewCalibratedClocks())
|
||||
|
||||
// Since we have a new kernel we also must make a new watchdog.
|
||||
watchdog := watchdog.New(k, watchdog.DefaultTimeout, cm.l.conf.WatchdogAction)
|
||||
dog := watchdog.New(k, watchdog.DefaultTimeout, cm.l.conf.WatchdogAction)
|
||||
|
||||
// Change the loader fields to reflect the changes made when restoring.
|
||||
cm.l.k = k
|
||||
cm.l.watchdog = watchdog
|
||||
cm.l.watchdog = dog
|
||||
cm.l.rootProcArgs = kernel.CreateProcessArgs{}
|
||||
cm.l.restore = true
|
||||
|
||||
|
||||
+2
-1
@@ -28,11 +28,12 @@ import (
|
||||
// createFDMap creates an FD map that contains stdin, stdout, and stderr. If
|
||||
// console is true, then ioctl calls will be passed through to the host FD.
|
||||
// Upon success, createFDMap dups then closes stdioFDs.
|
||||
func createFDMap(ctx context.Context, k *kernel.Kernel, l *limits.LimitSet, console bool, stdioFDs []int) (*kernel.FDMap, error) {
|
||||
func createFDMap(ctx context.Context, l *limits.LimitSet, console bool, stdioFDs []int) (*kernel.FDMap, error) {
|
||||
if len(stdioFDs) != 3 {
|
||||
return nil, fmt.Errorf("stdioFDs should contain exactly 3 FDs (stdin, stdout, and stderr), but %d FDs received", len(stdioFDs))
|
||||
}
|
||||
|
||||
k := kernel.KernelFromContext(ctx)
|
||||
fdm := k.NewFDMap()
|
||||
defer fdm.DecRef()
|
||||
mounter := fs.FileOwnerFromContext(ctx)
|
||||
|
||||
+369
-358
File diff suppressed because it is too large
Load Diff
+31
-27
@@ -288,7 +288,7 @@ func New(args Args) (*Loader, error) {
|
||||
}
|
||||
|
||||
// Create a watchdog.
|
||||
watchdog := watchdog.New(k, watchdog.DefaultTimeout, args.Conf.WatchdogAction)
|
||||
dog := watchdog.New(k, watchdog.DefaultTimeout, args.Conf.WatchdogAction)
|
||||
|
||||
procArgs, err := newProcess(args.ID, args.Spec, creds, k)
|
||||
if err != nil {
|
||||
@@ -304,7 +304,7 @@ func New(args Args) (*Loader, error) {
|
||||
k: k,
|
||||
conf: args.Conf,
|
||||
console: args.Console,
|
||||
watchdog: watchdog,
|
||||
watchdog: dog,
|
||||
spec: args.Spec,
|
||||
goferFDs: args.GoferFDs,
|
||||
stdioFDs: args.StdioFDs,
|
||||
@@ -486,17 +486,21 @@ func (l *Loader) run() error {
|
||||
// If we are restoring, we do not want to create a process.
|
||||
// l.restore is set by the container manager when a restore call is made.
|
||||
if !l.restore {
|
||||
if err := setupContainerFS(
|
||||
&l.rootProcArgs,
|
||||
l.spec,
|
||||
l.conf,
|
||||
l.stdioFDs,
|
||||
l.goferFDs,
|
||||
l.console,
|
||||
l.rootProcArgs.Credentials,
|
||||
l.rootProcArgs.Limits,
|
||||
l.k,
|
||||
"" /* CID, which isn't needed for the root container */); err != nil {
|
||||
// Create the FD map, which will set stdin, stdout, and stderr. If console
|
||||
// is true, then ioctl calls will be passed through to the host fd.
|
||||
ctx := l.rootProcArgs.NewContext(l.k)
|
||||
fdm, err := createFDMap(ctx, l.rootProcArgs.Limits, l.console, l.stdioFDs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("importing fds: %v", err)
|
||||
}
|
||||
// CreateProcess takes a reference on FDMap if successful. We won't need
|
||||
// ours either way.
|
||||
l.rootProcArgs.FDMap = fdm
|
||||
|
||||
// cid for root container can be empty. Only subcontainers need it to set
|
||||
// the mount location.
|
||||
mntr := newContainerMounter(l.spec, "", l.goferFDs, l.k)
|
||||
if err := mntr.setupFS(ctx, l.conf, &l.rootProcArgs, l.rootProcArgs.Credentials); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -552,7 +556,7 @@ func (l *Loader) createContainer(cid string) error {
|
||||
// startContainer starts a child container. It returns the thread group ID of
|
||||
// the newly created process. Caller owns 'files' and may close them after
|
||||
// this method returns.
|
||||
func (l *Loader) startContainer(k *kernel.Kernel, spec *specs.Spec, conf *Config, cid string, files []*os.File) error {
|
||||
func (l *Loader) startContainer(spec *specs.Spec, conf *Config, cid string, files []*os.File) error {
|
||||
// Create capabilities.
|
||||
caps, err := specutils.Capabilities(conf.EnableRaw, spec.Process.Capabilities)
|
||||
if err != nil {
|
||||
@@ -596,6 +600,16 @@ func (l *Loader) startContainer(k *kernel.Kernel, spec *specs.Spec, conf *Config
|
||||
stdioFDs = append(stdioFDs, int(f.Fd()))
|
||||
}
|
||||
|
||||
// Create the FD map, which will set stdin, stdout, and stderr.
|
||||
ctx := procArgs.NewContext(l.k)
|
||||
fdm, err := createFDMap(ctx, procArgs.Limits, false, stdioFDs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("importing fds: %v", err)
|
||||
}
|
||||
// CreateProcess takes a reference on FDMap if successful. We won't need ours
|
||||
// either way.
|
||||
procArgs.FDMap = fdm
|
||||
|
||||
// Can't take ownership away from os.File. dup them to get a new FDs.
|
||||
var goferFDs []int
|
||||
for _, f := range files[3:] {
|
||||
@@ -606,22 +620,12 @@ func (l *Loader) startContainer(k *kernel.Kernel, spec *specs.Spec, conf *Config
|
||||
goferFDs = append(goferFDs, fd)
|
||||
}
|
||||
|
||||
if err := setupContainerFS(
|
||||
&procArgs,
|
||||
spec,
|
||||
conf,
|
||||
stdioFDs,
|
||||
goferFDs,
|
||||
false,
|
||||
creds,
|
||||
procArgs.Limits,
|
||||
k,
|
||||
cid); err != nil {
|
||||
mntr := newContainerMounter(spec, cid, goferFDs, l.k)
|
||||
if err := mntr.setupFS(ctx, conf, &procArgs, creds); err != nil {
|
||||
return fmt.Errorf("configuring container FS: %v", err)
|
||||
}
|
||||
|
||||
ctx := procArgs.NewContext(l.k)
|
||||
mns := k.RootMountNamespace()
|
||||
mns := l.k.RootMountNamespace()
|
||||
if err := setExecutablePath(ctx, mns, &procArgs); err != nil {
|
||||
return fmt.Errorf("setting executable path for %+v: %v", procArgs, err)
|
||||
}
|
||||
|
||||
@@ -397,14 +397,15 @@ func TestCreateMountNamespace(t *testing.T) {
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
// setupRootContainerFS needs to find root from the context after the
|
||||
// setupRootContainer needs to find root from the context after the
|
||||
// namespace is created.
|
||||
var mns *fs.MountNamespace
|
||||
setMountNS := func(m *fs.MountNamespace) {
|
||||
mns = m
|
||||
ctx.(*contexttest.TestContext).RegisterValue(fs.CtxRoot, mns.Root())
|
||||
}
|
||||
if err := setupRootContainerFS(ctx, ctx, &tc.spec, conf, []int{sandEnd}, setMountNS); err != nil {
|
||||
mntr := newContainerMounter(&tc.spec, "", []int{sandEnd}, nil)
|
||||
if err := mntr.setupRootContainer(ctx, ctx, conf, setMountNS); err != nil {
|
||||
t.Fatalf("createMountNamespace test case %q failed: %v", tc.name, err)
|
||||
}
|
||||
root := mns.Root()
|
||||
@@ -609,8 +610,8 @@ func TestRestoreEnvironment(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
conf := testConfig()
|
||||
fds := &fdDispenser{fds: tc.ioFDs}
|
||||
actualRenv, err := createRestoreEnvironment(tc.spec, conf, fds)
|
||||
mntr := newContainerMounter(tc.spec, "", tc.ioFDs, nil)
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user