Skip to content

Commit

Permalink
Add save/restore/resume hooks in runsc/boot/restore.go.
Browse files Browse the repository at this point in the history
Move save/resume methods to containerManager.

PiperOrigin-RevId: 642011529
  • Loading branch information
ayushr2 authored and gvisor-bot committed Jun 10, 2024
1 parent 04369e0 commit e147703
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 21 deletions.
12 changes: 0 additions & 12 deletions pkg/sentry/control/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,18 +389,6 @@ func (l *Lifecycle) reap(containerID string, tg *kernel.ThreadGroup) {
})
}

// Pause pauses all tasks, blocking until they are stopped.
func (l *Lifecycle) Pause(_, _ *struct{}) error {
l.Kernel.Pause()
return nil
}

// Resume resumes all tasks.
func (l *Lifecycle) Resume(_, _ *struct{}) error {
l.Kernel.Unpause()
return nil
}

// Shutdown sends signal to destroy the sentry/sandbox.
func (l *Lifecycle) Shutdown(_, _ *struct{}) error {
close(l.ShutdownCh)
Expand Down
1 change: 1 addition & 0 deletions runsc/boot/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ go_library(
"mount_hints.go",
"network.go",
"restore.go",
"restore_impl.go",
"seccheck.go",
"strace.go",
"vfs.go",
Expand Down
24 changes: 18 additions & 6 deletions runsc/boot/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ const (
// ContMgrRestoreSubcontainer restores a container from a statefile.
ContMgrRestoreSubcontainer = "containerManager.RestoreSubcontainer"

// ContMgrPause pauses all tasks, blocking until they are stopped.
ContMgrPause = "containerManager.Pause"

// ContMgrResume resumes all tasks.
ContMgrResume = "containerManager.Resume"

// ContMgrSignal sends a signal to a container.
ContMgrSignal = "containerManager.Signal"

Expand Down Expand Up @@ -130,12 +136,6 @@ const (
LoggingChange = "Logging.Change"
)

// Lifecycle related commands (see lifecycle.go for more details).
const (
LifecyclePause = "Lifecycle.Pause"
LifecycleResume = "Lifecycle.Resume"
)

// Usage related commands (see usage.go for more details).
const (
UsageCollect = "Usage.Collect"
Expand Down Expand Up @@ -644,6 +644,18 @@ func (cm *containerManager) RestoreSubcontainer(args *StartArgs, _ *struct{}) er
return nil
}

// Pause pauses all tasks, blocking until they are stopped.
func (cm *containerManager) Pause(_, _ *struct{}) error {
cm.l.k.Pause()
return nil
}

// Resume resumes all tasks.
func (cm *containerManager) Resume(_, _ *struct{}) error {
cm.l.k.Unpause()
return postResumeImpl(cm.l.k)
}

// Wait waits for the init process in the given container.
func (cm *containerManager) Wait(cid *string, waitStatus *uint32) error {
log.Debugf("containerManager.Wait, cid: %s", *cid)
Expand Down
19 changes: 18 additions & 1 deletion runsc/boot/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ func (r *restorer) restore(l *Loader) error {
// Release `l.mu` before calling into callbacks.
cu.Clean()

// r.restoreDone() signals and waits for the sandbox to start.
if err := r.restoreDone(); err != nil {
return err
}
Expand All @@ -304,6 +305,10 @@ func (r *restorer) restore(l *Loader) error {
r.pagesFile.Close()
}

if err := postRestoreImpl(l.k); err != nil {
return err
}

log.Infof("Restore successful")
return nil
}
Expand All @@ -319,10 +324,22 @@ func (l *Loader) save(o *control.SaveOpts) error {
}
o.Metadata["container_count"] = strconv.Itoa(l.containerCount())

if err := preSaveImpl(l.k, o); err != nil {
return err
}

state := control.State{
Kernel: l.k,
Watchdog: l.watchdog,
}
if err := state.Save(o, nil); err != nil {
return err
}

return state.Save(o, nil)
if o.Resume {
if err := postResumeImpl(l.k); err != nil {
return err
}
}
return nil
}
37 changes: 37 additions & 0 deletions runsc/boot/restore_impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2024 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.

//go:build !false
// +build !false

package boot

import (
"gvisor.dev/gvisor/pkg/sentry/control"
"gvisor.dev/gvisor/pkg/sentry/kernel"
)

func preSaveImpl(*kernel.Kernel, *control.SaveOpts) error {
return nil
}

// Precondition: The kernel should be running.
func postRestoreImpl(*kernel.Kernel) error {
return nil
}

// Precondition: The kernel should be running.
func postResumeImpl(*kernel.Kernel) error {
return nil
}
4 changes: 2 additions & 2 deletions runsc/sandbox/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,7 @@ func createSaveFiles(path string, direct bool, compression statefile.Compression
// Pause sends the pause call for a container in the sandbox.
func (s *Sandbox) Pause(cid string) error {
log.Debugf("Pause sandbox %q", s.ID)
if err := s.call(boot.LifecyclePause, nil, nil); err != nil {
if err := s.call(boot.ContMgrPause, nil, nil); err != nil {
return fmt.Errorf("pausing container %q: %w", cid, err)
}
return nil
Expand All @@ -1414,7 +1414,7 @@ func (s *Sandbox) Pause(cid string) error {
// Resume sends the resume call for a container in the sandbox.
func (s *Sandbox) Resume(cid string) error {
log.Debugf("Resume sandbox %q", s.ID)
if err := s.call(boot.LifecycleResume, nil, nil); err != nil {
if err := s.call(boot.ContMgrResume, nil, nil); err != nil {
return fmt.Errorf("resuming container %q: %w", cid, err)
}
return nil
Expand Down

0 comments on commit e147703

Please sign in to comment.