Merge pull request #11473 from Champ-Goblem:shim-add-cgroup-v2-metrics-support

PiperOrigin-RevId: 730560110
This commit is contained in:
gVisor bot
2025-02-25 14:52:09 -08:00
63 changed files with 301 additions and 136 deletions
+1 -1
View File
@@ -133,7 +133,7 @@ go_path(
# binaries have been factored into a cli package, which is
# a good practice in any case.
"//runsc/cli",
"//shim/cli",
"//shim/v1/cli",
"//webhook/pkg/cli",
"//tools/checklocks",
+2 -2
View File
@@ -84,8 +84,8 @@ global:
- "panic recovered: .*types/sizes.go:82: assertion failed"
exclude:
# Generated: exempt all.
- pkg/shim/runtimeoptions/runtimeoptions_cri.go
- pkg/shim/runtimeoptions/v14/runtimeoptions_cri.go
- pkg/shim/v1/runtimeoptions/runtimeoptions_cri.go
- pkg/shim/v1/runtimeoptions/v14/runtimeoptions_cri.go
analyzers:
asmdecl:
generated: # Enabled.
+1 -14
View File
@@ -18,8 +18,6 @@ import (
"errors"
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/state"
@@ -84,18 +82,7 @@ func (s *State) Save(o *SaveOpts, _ *struct{}) error {
Key: o.Key,
Metadata: o.Metadata,
MemoryFileSaveOpts: o.MemoryFileSaveOpts,
Callback: func(err error) {
if err == nil {
log.Infof("Save succeeded: exiting...")
s.Kernel.SetSaveSuccess(false /* autosave */)
} else {
log.Warningf("Save failed: %v", err)
s.Kernel.SetSaveError(err)
}
if !o.Resume {
s.Kernel.Kill(linux.WaitStatusExit(0))
}
},
Resume: o.Resume,
}
if o.HavePagesFile {
saveOpts.PagesMetadata, err = o.ReleaseFD(1)
+7
View File
@@ -31,6 +31,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
var _ vfs.FilesystemImplSaveRestoreExtension = (*filesystem)(nil)
// +stateify savable
type savedDentryRW struct {
read bool
@@ -134,6 +136,11 @@ func (d *dentry) beforeSave() {
}
}
// BeforeResume implements vfs.FilesystemImplSaveRestoreExtension.BeforeResume.
func (fs *filesystem) BeforeResume(ctx context.Context) {
fs.savedDentryRW = nil
}
// afterLoad is invoked by stateify.
func (fs *filesystem) afterLoad(ctx goContext.Context) {
fs.mf = pgalloc.MemoryFileFromContext(ctx)
+10 -1
View File
@@ -22,6 +22,7 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
@@ -68,6 +69,14 @@ var _ kernfs.Inode = (*tasksInode)(nil)
func (fs *filesystem) newTasksInode(ctx context.Context, k *kernel.Kernel, pidns *kernel.PIDNamespace, internalData *InternalData) *tasksInode {
root := auth.NewRootCredentials(pidns.UserNamespace())
// /proc is expected to have inode number
// include/linux/proc_ns.h:PROC_ROOT_INO == 1; ensure that this is the case
// by generating its inode number before any of its descendants.
rootIno := fs.NextIno()
if rootIno != 1 {
log.Traceback("proc root inode has number %d", rootIno)
}
contents := map[string]kernfs.Inode{
"cmdline": fs.newInode(ctx, root, 0444, &cmdLineData{}),
"cpuinfo": fs.newInode(ctx, root, 0444, newStaticFileSetStat(cpuInfoData(k))),
@@ -99,7 +108,7 @@ func (fs *filesystem) newTasksInode(ctx context.Context, k *kernel.Kernel, pidns
fs: fs,
fakeCgroupControllers: internalData.Cgroups,
}
inode.InodeAttrs.Init(ctx, root, linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), linux.ModeDirectory|0555)
inode.InodeAttrs.Init(ctx, root, linux.UNNAMED_MAJOR, fs.devMinor, rootIno, linux.ModeDirectory|0555)
inode.InitRefs()
inode.OrderedChildren.Init(kernfs.OrderedChildrenOptions{})
+5
View File
@@ -23,6 +23,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
var _ vfs.FilesystemImplSaveRestoreExtension = (*filesystem)(nil)
// saveMf is called by stateify.
func (fs *filesystem) saveMf() string {
if !fs.mf.IsSavable() {
@@ -75,6 +77,9 @@ func (fs *filesystem) PrepareSave(ctx context.Context) error {
return nil
}
// BeforeResume implements vfs.FilesystemImplSaveRestoreExtension.BeforeResume.
func (fs *filesystem) BeforeResume(ctx context.Context) {}
// CompleteRestore implements
// vfs.FilesystemImplSaveRestoreExtension.CompleteRestore.
func (fs *filesystem) CompleteRestore(ctx context.Context, opts vfs.CompleteRestoreOptions) error {
+13 -6
View File
@@ -26,23 +26,30 @@ import (
"gvisor.dev/gvisor/pkg/log"
)
// GetTransparentHugepageEnum returns the currently selected option for
// ReadTransparentHugepageEnum returns the currently selected option for
// whichever of
// /sys/kernel/mm/transparent_hugepage/{enabled,shmem_enabled,defrag} is
// specified by filename. (Only the basename is required, not the full path.)
func GetTransparentHugepageEnum(filename string) (string, error) {
func ReadTransparentHugepageEnum(filename string) (string, error) {
pathname := path.Join("/sys/kernel/mm/transparent_hugepage/", filename)
data, err := os.ReadFile(pathname)
if err != nil {
return "", err
}
return GetTransparentHugepageEnum(string(data))
}
// GetTransparentHugepageEnum returns the currently selected option given the
// contents of any of
// /sys/kernel/mm/transparent_hugepage/{enabled,shmem_enabled,defrag}.
func GetTransparentHugepageEnum(data string) (string, error) {
// In these files, the selected option is highlighted by square brackets.
m := regexp.MustCompile(`\[.*\]`).Find(data)
if m == nil {
return "", fmt.Errorf("failed to parse %s: %q", pathname, data)
m := regexp.MustCompile(`\[.*\]`).FindString(data)
if m == "" {
return "", fmt.Errorf("failed to find selected option in %q", data)
}
// Remove the square brackets.
return string(m[1 : len(m)-1]), nil
return m[1 : len(m)-1], nil
}
// NotifyCurrentMemcgPressureCallback requests that f is called whenever the
+5
View File
@@ -702,6 +702,11 @@ func (k *Kernel) SaveTo(ctx context.Context, w, pagesMetadata io.Writer, pagesFi
return nil
}
// BeforeResume is called before the kernel is resumed after save.
func (k *Kernel) BeforeResume(ctx context.Context) {
k.vfs.BeforeResume(ctx)
}
func (k *Kernel) saveMemoryFiles(ctx context.Context, w, pagesMetadata io.Writer, pagesFile *fd.FD, mfsToSave map[string]*pgalloc.MemoryFile, mfOpts pgalloc.SaveOpts) error {
// Save the memory files' state.
memoryStart := time.Now()
+23 -4
View File
@@ -20,6 +20,7 @@ import (
"fmt"
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fd"
@@ -68,15 +69,18 @@ type SaveOpts struct {
// MemoryFileSaveOpts is passed to calls to pgalloc.MemoryFile.SaveTo().
MemoryFileSaveOpts pgalloc.SaveOpts
// Callback is called prior to unpause, with any save error.
Callback func(err error)
// Resume indicates if the statefile is used for save-resume.
Resume bool
// Autosave indicates if the statefile is used for autosave.
Autosave bool
}
// Save saves the system state.
func (opts SaveOpts) Save(ctx context.Context, k *kernel.Kernel, w *watchdog.Watchdog) error {
t, _ := CPUTime()
log.Infof("Before save CPU usage: %s", t.String())
log.Infof("Sandbox save started, pausing all tasks.")
k.Pause()
k.ReceiveTaskStates()
@@ -127,7 +131,22 @@ func (opts SaveOpts) Save(ctx context.Context, k *kernel.Kernel, w *watchdog.Wat
}
}
}
opts.Callback(err)
t1, _ := CPUTime()
log.Infof("Save CPU usage: %s", (t1 - t).String())
if err == nil {
log.Infof("Save succeeded: exiting...")
k.SetSaveSuccess(opts.Autosave)
} else {
log.Warningf("Save failed: exiting... %v", err)
k.SetSaveError(err)
}
if opts.Resume {
k.BeforeResume(ctx)
} else {
// Kill the sandbox.
k.Kill(linux.WaitStatusExit(0))
}
return err
}
+15
View File
@@ -54,6 +54,10 @@ type FilesystemImplSaveRestoreExtension interface {
// PrepareSave prepares this filesystem for serialization.
PrepareSave(ctx context.Context) error
// BeforeResume is called before the kernel is resumed after save. It can be
// used to clean up any state that should be discarded after save.
BeforeResume(ctx context.Context)
// CompleteRestore completes restoration from checkpoint for this
// filesystem after deserialization.
CompleteRestore(ctx context.Context, opts CompleteRestoreOptions) error
@@ -73,6 +77,17 @@ func (vfs *VirtualFilesystem) PrepareSave(ctx context.Context) error {
return nil
}
// BeforeResume is called before the kernel is resumed after save and allows
// filesystems to clean up S/R state.
func (vfs *VirtualFilesystem) BeforeResume(ctx context.Context) {
for fs := range vfs.getFilesystems() {
if ext, ok := fs.impl.(FilesystemImplSaveRestoreExtension); ok {
ext.BeforeResume(ctx)
}
fs.DecRef(ctx)
}
}
// CompleteRestore completes restoration from checkpoint for all filesystems
// after deserialization.
func (vfs *VirtualFilesystem) CompleteRestore(ctx context.Context, opts *CompleteRestoreOptions) error {
+3 -3
View File
@@ -6,13 +6,13 @@ package(
)
go_library(
name = "shim",
name = "v1",
srcs = ["service.go"],
visibility = ["//shim:__subpackages__"],
deps = [
"//pkg/cleanup",
"//pkg/shim/extension",
"//pkg/shim/runsc",
"//pkg/shim/v1/extension",
"//pkg/shim/v1/runsc",
"//pkg/sync",
"@com_github_containerd_containerd//namespaces:go_default_library",
"@com_github_containerd_containerd//runtime/v2/shim:go_default_library",
@@ -25,9 +25,9 @@ go_library(
deps = [
"//pkg/atomicbitops",
"//pkg/cleanup",
"//pkg/shim/extension",
"//pkg/shim/runsccmd",
"//pkg/shim/utils",
"//pkg/shim/v1/extension",
"//pkg/shim/v1/runsccmd",
"//pkg/shim/v1/utils",
"@com_github_containerd_console//:go_default_library",
"@com_github_containerd_containerd//mount:go_default_library",
"@com_github_containerd_containerd//pkg/stdio:go_default_library",
@@ -22,7 +22,7 @@ import (
"github.com/containerd/console"
"github.com/containerd/errdefs"
runc "github.com/containerd/go-runc"
"gvisor.dev/gvisor/pkg/shim/extension"
"gvisor.dev/gvisor/pkg/shim/v1/extension"
)
type deletedState struct{}
@@ -33,8 +33,8 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/cleanup"
"gvisor.dev/gvisor/pkg/shim/extension"
"gvisor.dev/gvisor/pkg/shim/runsccmd"
"gvisor.dev/gvisor/pkg/shim/v1/extension"
"gvisor.dev/gvisor/pkg/shim/v1/runsccmd"
)
type execProcess struct {
@@ -20,7 +20,7 @@ import (
"fmt"
"github.com/containerd/console"
"gvisor.dev/gvisor/pkg/shim/extension"
"gvisor.dev/gvisor/pkg/shim/v1/extension"
)
type execState interface {
@@ -36,9 +36,9 @@ import (
runc "github.com/containerd/go-runc"
specs "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/shim/extension"
"gvisor.dev/gvisor/pkg/shim/runsccmd"
"gvisor.dev/gvisor/pkg/shim/utils"
"gvisor.dev/gvisor/pkg/shim/v1/extension"
"gvisor.dev/gvisor/pkg/shim/v1/runsccmd"
"gvisor.dev/gvisor/pkg/shim/v1/utils"
)
const statusStopped = "stopped"
@@ -23,7 +23,7 @@ import (
runc "github.com/containerd/go-runc"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/shim/extension"
"gvisor.dev/gvisor/pkg/shim/v1/extension"
)
type stateTransition int

Some files were not shown because too many files have changed in this diff Show More