mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add a unique id per cgroup.
PiperOrigin-RevId: 540031470
This commit is contained in:
committed by
gVisor bot
parent
a0ed98b45d
commit
a589eb8a7c
@@ -25,6 +25,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"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"
|
||||
@@ -151,6 +152,9 @@ type controller interface {
|
||||
type cgroupInode struct {
|
||||
dir
|
||||
|
||||
// id is the id of this cgroup.
|
||||
id uint32
|
||||
|
||||
// controllers is the set of controllers for this cgroup. This is used to
|
||||
// store controller-specific state per cgroup. The set of controllers should
|
||||
// match the controllers for this hierarchy as tracked by the filesystem
|
||||
@@ -175,6 +179,16 @@ func (fs *filesystem) newCgroupInode(ctx context.Context, creds *auth.Credential
|
||||
}
|
||||
c.dir.cgi = c
|
||||
|
||||
k := kernel.KernelFromContext(ctx)
|
||||
r := k.CgroupRegistry()
|
||||
// Assign id for the cgroup.
|
||||
cid, err := r.NextCgroupID()
|
||||
if err != nil {
|
||||
log.Warningf("cgroupfs newCgroupInode: Failed to assign id to the cgroup: %v", err)
|
||||
}
|
||||
c.id = cid
|
||||
r.AddCgroup(c)
|
||||
|
||||
contents := make(map[string]kernfs.Inode)
|
||||
contents["cgroup.procs"] = fs.newControllerWritableFile(ctx, creds, &cgroupProcsData{c}, false)
|
||||
contents["tasks"] = fs.newControllerWritableFile(ctx, creds, &tasksData{c}, false)
|
||||
@@ -382,6 +396,11 @@ func (c *cgroupInode) WriteControl(ctx context.Context, name string, value strin
|
||||
return nil
|
||||
}
|
||||
|
||||
// ID implements kernel.CgroupImpl.ID.
|
||||
func (c *cgroupInode) ID() uint32 {
|
||||
return c.id
|
||||
}
|
||||
|
||||
func sortTIDs(tids []kernel.ThreadID) {
|
||||
sort.Slice(tids, func(i, j int) bool { return tids[i] < tids[j] })
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ import (
|
||||
// InvalidCgroupHierarchyID indicates an uninitialized hierarchy ID.
|
||||
const InvalidCgroupHierarchyID uint32 = 0
|
||||
|
||||
// InvalidCgroupID indicates an uninitialized cgroup ID.
|
||||
const InvalidCgroupID uint32 = 0
|
||||
|
||||
// CgroupControllerType is the name of a cgroup controller.
|
||||
type CgroupControllerType string
|
||||
|
||||
@@ -212,6 +215,9 @@ type CgroupImpl interface {
|
||||
// WriteControl allows a background context to write a cgroup's control
|
||||
// values.
|
||||
WriteControl(ctx context.Context, name string, val string) error
|
||||
|
||||
// ID returns the id of this cgroup.
|
||||
ID() uint32
|
||||
}
|
||||
|
||||
// hierarchy represents a cgroupfs filesystem instance, with a unique set of
|
||||
@@ -268,6 +274,11 @@ type CgroupRegistry struct {
|
||||
//
|
||||
lastHierarchyID atomicbitops.Uint32
|
||||
|
||||
// lastCgroupID is the id of the last allocated cgroup. Valid ids are
|
||||
// from 1 to math.MaxUint32.
|
||||
//
|
||||
lastCgroupID atomicbitops.Uint32
|
||||
|
||||
mu cgroupMutex `state:"nosave"`
|
||||
|
||||
// controllers is the set of currently known cgroup controllers on the
|
||||
@@ -287,6 +298,12 @@ type CgroupRegistry struct {
|
||||
//
|
||||
// +checklocks:mu
|
||||
hierarchiesByName map[string]hierarchy
|
||||
|
||||
// cgroups is the active set of cgroups. This contains all the cgroups
|
||||
// on the system.
|
||||
//
|
||||
// +checklocks:mu
|
||||
cgroups map[uint32]CgroupImpl
|
||||
}
|
||||
|
||||
func newCgroupRegistry() *CgroupRegistry {
|
||||
@@ -294,6 +311,7 @@ func newCgroupRegistry() *CgroupRegistry {
|
||||
controllers: make(map[CgroupControllerType]CgroupController),
|
||||
hierarchies: make(map[uint32]hierarchy),
|
||||
hierarchiesByName: make(map[string]hierarchy),
|
||||
cgroups: make(map[uint32]CgroupImpl),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,3 +530,29 @@ func (r *CgroupRegistry) GenerateProcCgroups(buf *bytes.Buffer) {
|
||||
fmt.Fprint(buf, e)
|
||||
}
|
||||
}
|
||||
|
||||
// NextCgroupID returns a newly allocated, unique cgroup ID.
|
||||
func (r *CgroupRegistry) NextCgroupID() (uint32, error) {
|
||||
if cid := r.lastCgroupID.Add(1); cid != 0 {
|
||||
return cid, nil
|
||||
}
|
||||
return InvalidCgroupID, fmt.Errorf("cgroup ID overflow")
|
||||
}
|
||||
|
||||
// AddCgroup adds the ID and cgroup in the map.
|
||||
func (r *CgroupRegistry) AddCgroup(cg CgroupImpl) {
|
||||
r.mu.Lock()
|
||||
r.cgroups[cg.ID()] = cg
|
||||
r.mu.Unlock()
|
||||
}
|
||||
|
||||
// GetCgroup returns the cgroup associated with the cgroup ID.
|
||||
func (r *CgroupRegistry) GetCgroup(cid uint32) (CgroupImpl, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
cg, ok := r.cgroups[cid]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cgroup with ID %d does not exist", cid)
|
||||
}
|
||||
return cg, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user