mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
cgroupfs: Stub control files to allow subcontainer creation with gcontain.
PiperOrigin-RevId: 435569386
This commit is contained in:
committed by
gVisor bot
parent
cf0bdacdd5
commit
24cef0a622
@@ -57,10 +57,12 @@
|
||||
package cgroupfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
@@ -71,6 +73,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -546,6 +549,11 @@ type controllerFile struct {
|
||||
kernfs.DynamicBytesFile
|
||||
}
|
||||
|
||||
// SetStat implements kernfs.Inode.SetStat.
|
||||
func (f *controllerFile) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *auth.Credentials, opts vfs.SetStatOptions) error {
|
||||
return f.InodeAttrs.SetStat(ctx, fs, creds, opts)
|
||||
}
|
||||
|
||||
func (fs *filesystem) newControllerFile(ctx context.Context, creds *auth.Credentials, data vfs.DynamicBytesSource) kernfs.Inode {
|
||||
f := &controllerFile{}
|
||||
f.Init(ctx, creds, linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), data, readonlyFileMode)
|
||||
@@ -568,6 +576,11 @@ type staticControllerFile struct {
|
||||
vfs.StaticData
|
||||
}
|
||||
|
||||
// SetStat implements kernfs.Inode.SetStat.
|
||||
func (f *staticControllerFile) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *auth.Credentials, opts vfs.SetStatOptions) error {
|
||||
return f.InodeAttrs.SetStat(ctx, fs, creds, opts)
|
||||
}
|
||||
|
||||
// Note: We let the caller provide the mode so that static files may be used to
|
||||
// fake both readable and writable control files. However, static files are
|
||||
// effectively readonly, as attempting to write to them will return EIO
|
||||
@@ -577,3 +590,40 @@ func (fs *filesystem) newStaticControllerFile(ctx context.Context, creds *auth.C
|
||||
f.Init(ctx, creds, linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), f, mode)
|
||||
return f
|
||||
}
|
||||
|
||||
// stubControllerFile is a writable control file that remembers the control
|
||||
// value written to it.
|
||||
//
|
||||
// +stateify savable
|
||||
type stubControllerFile struct {
|
||||
controllerFile
|
||||
|
||||
// data is accessed through atomic ops.
|
||||
data *int64
|
||||
}
|
||||
|
||||
// Generate implements vfs.DynamicBytesSource.Generate.
|
||||
func (f *stubControllerFile) Generate(ctx context.Context, buf *bytes.Buffer) error {
|
||||
fmt.Fprintf(buf, "%d\n", atomic.LoadInt64(f.data))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write implements vfs.WritableDynamicBytesSource.Write.
|
||||
func (f *stubControllerFile) Write(ctx context.Context, _ *vfs.FileDescription, src usermem.IOSequence, offset int64) (int64, error) {
|
||||
val, n, err := parseInt64FromString(ctx, src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
atomic.StoreInt64(f.data, val)
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// newStubControllerFile creates a new stub controller file tbat loads and
|
||||
// stores a control value from data.
|
||||
func (fs *filesystem) newStubControllerFile(ctx context.Context, creds *auth.Credentials, data *int64) kernfs.Inode {
|
||||
f := &stubControllerFile{
|
||||
data: data,
|
||||
}
|
||||
f.Init(ctx, creds, linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), f, writableFileMode)
|
||||
return f
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
package cgroupfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
@@ -76,7 +73,7 @@ func (c *cpuController) Clone() controller {
|
||||
|
||||
// AddControlFiles implements controller.AddControlFiles.
|
||||
func (c *cpuController) AddControlFiles(ctx context.Context, creds *auth.Credentials, _ *cgroupInode, contents map[string]kernfs.Inode) {
|
||||
contents["cpu.cfs_period_us"] = c.fs.newStaticControllerFile(ctx, creds, linux.FileMode(0644), fmt.Sprintf("%d\n", c.cfsPeriod))
|
||||
contents["cpu.cfs_quota_us"] = c.fs.newStaticControllerFile(ctx, creds, linux.FileMode(0644), fmt.Sprintf("%d\n", c.cfsQuota))
|
||||
contents["cpu.shares"] = c.fs.newStaticControllerFile(ctx, creds, linux.FileMode(0644), fmt.Sprintf("%d\n", c.shares))
|
||||
contents["cpu.cfs_period_us"] = c.fs.newStubControllerFile(ctx, creds, &c.cfsPeriod)
|
||||
contents["cpu.cfs_quota_us"] = c.fs.newStubControllerFile(ctx, creds, &c.cfsQuota)
|
||||
contents["cpu.shares"] = c.fs.newStubControllerFile(ctx, creds, &c.shares)
|
||||
}
|
||||
|
||||
@@ -15,14 +15,9 @@
|
||||
package cgroupfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
// +stateify savable
|
||||
@@ -51,26 +46,5 @@ func (c *jobController) Clone() controller {
|
||||
}
|
||||
|
||||
func (c *jobController) AddControlFiles(ctx context.Context, creds *auth.Credentials, _ *cgroupInode, contents map[string]kernfs.Inode) {
|
||||
contents["job.id"] = c.fs.newControllerWritableFile(ctx, creds, &jobIDData{c: c})
|
||||
}
|
||||
|
||||
// +stateify savable
|
||||
type jobIDData struct {
|
||||
c *jobController
|
||||
}
|
||||
|
||||
// Generate implements vfs.DynamicBytesSource.Generate.
|
||||
func (d *jobIDData) Generate(ctx context.Context, buf *bytes.Buffer) error {
|
||||
fmt.Fprintf(buf, "%d\n", d.c.id)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write implements vfs.WritableDynamicBytesSource.Write.
|
||||
func (d *jobIDData) Write(ctx context.Context, _ *vfs.FileDescription, src usermem.IOSequence, offset int64) (int64, error) {
|
||||
val, n, err := parseInt64FromString(ctx, src)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
d.c.id = val
|
||||
return n, nil
|
||||
contents["job.id"] = c.fs.newStubControllerFile(ctx, creds, &c.id)
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ type memoryController struct {
|
||||
limitBytes int64
|
||||
softLimitBytes int64
|
||||
moveChargeAtImmigrate int64
|
||||
pressureLevel int64
|
||||
}
|
||||
|
||||
var _ controller = (*memoryController)(nil)
|
||||
@@ -78,9 +79,10 @@ func (c *memoryController) Clone() controller {
|
||||
// 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))
|
||||
contents["memory.soft_limit_in_bytes"] = c.fs.newStaticControllerFile(ctx, creds, linux.FileMode(0644), fmt.Sprintf("%d\n", c.softLimitBytes))
|
||||
contents["memory.move_charge_at_immigrate"] = c.fs.newStaticControllerFile(ctx, creds, linux.FileMode(0644), fmt.Sprintf("%d\n", c.moveChargeAtImmigrate))
|
||||
contents["memory.limit_in_bytes"] = c.fs.newStubControllerFile(ctx, creds, &c.limitBytes)
|
||||
contents["memory.soft_limit_in_bytes"] = c.fs.newStubControllerFile(ctx, creds, &c.softLimitBytes)
|
||||
contents["memory.move_charge_at_immigrate"] = c.fs.newStubControllerFile(ctx, creds, &c.moveChargeAtImmigrate)
|
||||
contents["memory.pressure_level"] = c.fs.newStaticControllerFile(ctx, creds, linux.FileMode(0644), fmt.Sprintf("%d\n", c.pressureLevel))
|
||||
}
|
||||
|
||||
// +stateify savable
|
||||
|
||||
Reference in New Issue
Block a user