mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Allow default control values to be set for cgroupfs.
PiperOrigin-RevId: 366891806
This commit is contained in:
committed by
gVisor bot
parent
2d9095c7a6
commit
88f198c2a9
@@ -94,6 +94,14 @@ var SupportedMountOptions = []string{"all", "cpu", "cpuacct", "cpuset", "memory"
|
||||
// +stateify savable
|
||||
type FilesystemType struct{}
|
||||
|
||||
// InternalData contains internal data passed in to the cgroupfs mount via
|
||||
// vfs.GetFilesystemOptions.InternalData.
|
||||
//
|
||||
// +stateify savable
|
||||
type InternalData struct {
|
||||
DefaultControlValues map[string]int64
|
||||
}
|
||||
|
||||
// filesystem implements vfs.FilesystemImpl.
|
||||
//
|
||||
// +stateify savable
|
||||
@@ -218,13 +226,19 @@ func (fsType FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
|
||||
fs.MaxCachedDentries = maxCachedDentries
|
||||
fs.VFSFilesystem().Init(vfsObj, &fsType, fs)
|
||||
|
||||
var defaults map[string]int64
|
||||
if opts.InternalData != nil {
|
||||
ctx.Debugf("cgroupfs.FilesystemType.GetFilesystem: default control values: %v", defaults)
|
||||
defaults = opts.InternalData.(*InternalData).DefaultControlValues
|
||||
}
|
||||
|
||||
for _, ty := range wantControllers {
|
||||
var c controller
|
||||
switch ty {
|
||||
case controllerMemory:
|
||||
c = newMemoryController(fs)
|
||||
c = newMemoryController(fs, defaults)
|
||||
case controllerCPU:
|
||||
c = newCPUController(fs)
|
||||
c = newCPUController(fs, defaults)
|
||||
case controllerCPUAcct:
|
||||
c = newCPUAcctController(fs)
|
||||
case controllerCPUSet:
|
||||
@@ -235,6 +249,12 @@ func (fsType FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
|
||||
fs.controllers = append(fs.controllers, c)
|
||||
}
|
||||
|
||||
if len(defaults) != 0 {
|
||||
// Internal data is always provided at sentry startup and unused values
|
||||
// indicate a problem with the sandbox config. Fail fast.
|
||||
panic(fmt.Sprintf("cgroupfs.FilesystemType.GetFilesystem: unknown internal mount data: %v", defaults))
|
||||
}
|
||||
|
||||
// Controllers usually appear in alphabetical order when displayed. Sort it
|
||||
// here now, so it never needs to be sorted elsewhere.
|
||||
sort.Slice(fs.controllers, func(i, j int) bool { return fs.controllers[i].Type() < fs.controllers[j].Type() })
|
||||
|
||||
@@ -28,22 +28,36 @@ type cpuController struct {
|
||||
controllerCommon
|
||||
|
||||
// CFS bandwidth control parameters, values in microseconds.
|
||||
cfsPeriod uint64
|
||||
cfsPeriod int64
|
||||
cfsQuota int64
|
||||
|
||||
// CPU shares, values should be (num core * 1024).
|
||||
shares uint64
|
||||
shares int64
|
||||
}
|
||||
|
||||
var _ controller = (*cpuController)(nil)
|
||||
|
||||
func newCPUController(fs *filesystem) *cpuController {
|
||||
func newCPUController(fs *filesystem, defaults map[string]int64) *cpuController {
|
||||
// Default values for controller parameters from Linux.
|
||||
c := &cpuController{
|
||||
cfsPeriod: 100000,
|
||||
cfsQuota: -1,
|
||||
shares: 1024,
|
||||
}
|
||||
|
||||
if val, ok := defaults["cpu.cfs_period_us"]; ok {
|
||||
c.cfsPeriod = val
|
||||
delete(defaults, "cpu.cfs_period_us")
|
||||
}
|
||||
if val, ok := defaults["cpu.cfs_quota_us"]; ok {
|
||||
c.cfsQuota = val
|
||||
delete(defaults, "cpu.cfs_quota_us")
|
||||
}
|
||||
if val, ok := defaults["cpu.shares"]; ok {
|
||||
c.shares = val
|
||||
delete(defaults, "cpu.shares")
|
||||
}
|
||||
|
||||
c.controllerCommon.init(controllerCPU, fs)
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ package cgroupfs
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
@@ -28,12 +30,23 @@ import (
|
||||
// +stateify savable
|
||||
type memoryController struct {
|
||||
controllerCommon
|
||||
|
||||
limitBytes int64
|
||||
}
|
||||
|
||||
var _ controller = (*memoryController)(nil)
|
||||
|
||||
func newMemoryController(fs *filesystem) *memoryController {
|
||||
c := &memoryController{}
|
||||
func newMemoryController(fs *filesystem, defaults map[string]int64) *memoryController {
|
||||
c := &memoryController{
|
||||
// Linux sets this to (PAGE_COUNTER_MAX * PAGE_SIZE) by default, which
|
||||
// is ~ 2**63 on a 64-bit system. So essentially, inifinity. The exact
|
||||
// value isn't very important.
|
||||
limitBytes: math.MaxInt64,
|
||||
}
|
||||
if val, ok := defaults["memory.limit_in_bytes"]; ok {
|
||||
c.limitBytes = val
|
||||
delete(defaults, "memory.limit_in_bytes")
|
||||
}
|
||||
c.controllerCommon.init(controllerMemory, fs)
|
||||
return c
|
||||
}
|
||||
@@ -41,6 +54,7 @@ func newMemoryController(fs *filesystem) *memoryController {
|
||||
// AddControlFiles implements controller.AddControlFiles.
|
||||
func (c *memoryController) AddControlFiles(ctx context.Context, creds *auth.Credentials, _ *cgroupInode, contents map[string]kernfs.Inode) {
|
||||
contents["memory.usage_in_bytes"] = c.fs.newControllerFile(ctx, creds, &memoryUsageInBytesData{})
|
||||
contents["memory.limit_in_bytes"] = c.fs.newStaticControllerFile(ctx, creds, linux.FileMode(0644), fmt.Sprintf("%d\n", c.limitBytes))
|
||||
}
|
||||
|
||||
// +stateify savable
|
||||
|
||||
Reference in New Issue
Block a user