support pids cgroup

Signed-off-by: Yang Yang <yang8518296@163.com>
This commit is contained in:
yylt 2024-04-08 09:57:19 +08:00
parent af942d3564
commit 1719502ed2
8 changed files with 585 additions and 388 deletions

View File

@ -19,6 +19,8 @@ package adaptation
import (
"fmt"
"strings"
"github.com/containerd/nri/pkg/api"
)
type result struct {
@ -645,7 +647,16 @@ func (r *result) adjustResources(resources *LinuxResources, plugin string) error
container.RdtClass = String(v.GetValue())
reply.RdtClass = String(v.GetValue())
}
if v := resources.GetPids(); v != nil {
if err := r.owners.claimPidsLimit(id, plugin); err != nil {
return err
}
pidv := &api.LinuxPids{
Limit: v.GetLimit(),
}
container.Pids = pidv
reply.Pids = pidv
}
return nil
}
@ -820,6 +831,14 @@ func (r *result) updateResources(reply, u *ContainerUpdate, plugin string) error
}
resources.RdtClass = String(v.GetValue())
}
if v := resources.GetPids(); v != nil {
if err := r.owners.claimPidsLimit(id, plugin); err != nil {
return err
}
resources.Pids = &api.LinuxPids{
Limit: v.GetLimit(),
}
}
// update request/reply from copy on success
reply.Linux.Resources = resources.Copy()
@ -888,6 +907,7 @@ type owners struct {
cpuRealtimePeriod string
cpusetCpus string
cpusetMems string
pidsLimit string
hugepageLimits map[string]string
blockioClass string
rdtClass string
@ -981,6 +1001,10 @@ func (ro resultOwners) claimCpusetMems(id, plugin string) error {
return ro.ownersFor(id).claimCpusetMems(plugin)
}
func (ro resultOwners) claimPidsLimit(id, plugin string) error {
return ro.ownersFor(id).claimPidsLimit(plugin)
}
func (ro resultOwners) claimHugepageLimit(id, size, plugin string) error {
return ro.ownersFor(id).claimHugepageLimit(size, plugin)
}
@ -1169,6 +1193,14 @@ func (o *owners) claimCpusetMems(plugin string) error {
return nil
}
func (o *owners) claimPidsLimit(plugin string) error {
if other := o.pidsLimit; other != "" {
return conflict(plugin, other, "pids pinning")
}
o.pidsLimit = plugin
return nil
}
func (o *owners) claimHugepageLimit(size, plugin string) error {
if o.hugepageLimits == nil {
o.hugepageLimits = make(map[string]string)

View File

@ -219,6 +219,12 @@ func (a *ContainerAdjustment) SetLinuxCPUSetMems(value string) {
a.Linux.Resources.Cpu.Mems = value
}
// SetLinuxPidLimits records setting the pid max number for a container.
func (a *ContainerAdjustment) SetLinuxPidLimits(value int64) {
a.initLinuxResourcesPids()
a.Linux.Resources.Pids.Limit = value
}
// AddLinuxHugepageLimit records adding a hugepage limit for a container.
func (a *ContainerAdjustment) AddLinuxHugepageLimit(pageSize string, value uint64) {
a.initLinuxResources()
@ -302,6 +308,13 @@ func (a *ContainerAdjustment) initLinuxResourcesCPU() {
}
}
func (a *ContainerAdjustment) initLinuxResourcesPids() {
a.initLinuxResources()
if a.Linux.Resources.Pids == nil {
a.Linux.Resources.Pids = &LinuxPids{}
}
}
func (a *ContainerAdjustment) initLinuxResourcesUnified() {
a.initLinuxResources()
if a.Linux.Resources.Unified == nil {

File diff suppressed because it is too large Load Diff

View File

@ -328,6 +328,7 @@ message LinuxResources {
OptionalString rdt_class = 5;
map<string, string> unified = 6;
repeated LinuxDeviceCgroup devices = 7; // for NRI v1 emulation
LinuxPids pids = 8;
}
// Memory-related parts of (linux) resources.
@ -366,6 +367,11 @@ message POSIXRlimit {
uint64 soft = 3;
}
// Pids-related parts of (linux) resources.
message LinuxPids {
int64 limit = 1;
}
// Requested adjustments to a container being created.
message ContainerAdjustment {
map<string, string> annotations = 2;

View File

@ -65,6 +65,11 @@ func FromOCILinuxResources(o *rspec.LinuxResources, _ map[string]string) *LinuxR
Access: d.Access,
})
}
if p := o.Pids; p != nil {
l.Pids = &LinuxPids{
Limit: p.Limit,
}
}
return l
}
@ -148,7 +153,11 @@ func (r *LinuxResources) ToOCI() *rspec.LinuxResources {
Access: d.Access,
})
}
if r.Pids != nil {
o.Pids = &rspec.LinuxPids{
Limit: r.Pids.Limit,
}
}
return o
}
@ -226,6 +235,11 @@ func (r *LinuxResources) Copy() *LinuxResources {
o.Unified[k] = v
}
}
if r.Pids != nil {
o.Pids = &LinuxPids{
Limit: r.Pids.Limit,
}
}
o.BlockioClass = String(r.BlockioClass)
o.RdtClass = String(r.RdtClass)

View File

@ -112,6 +112,12 @@ func (u *ContainerUpdate) SetLinuxCPUSetMems(value string) {
u.Linux.Resources.Cpu.Mems = value
}
// SetLinuxPidLimits records setting the pid max number for a container.
func (u *ContainerUpdate) SetLinuxPidLimits(value int64) {
u.initLinuxResourcesPids()
u.Linux.Resources.Pids.Limit = value
}
// AddLinuxHugepageLimit records adding a hugepage limit for a container.
func (u *ContainerUpdate) AddLinuxHugepageLimit(pageSize string, value uint64) {
u.initLinuxResources()
@ -184,3 +190,10 @@ func (u *ContainerUpdate) initLinuxResourcesUnified() {
u.Linux.Resources.Unified = make(map[string]string)
}
}
func (u *ContainerUpdate) initLinuxResourcesPids() {
u.initLinuxResources()
if u.Linux.Resources.Pids == nil {
u.Linux.Resources.Pids = &LinuxPids{}
}
}

View File

@ -252,7 +252,9 @@ func (g *Generator) AdjustResources(r *nri.LinuxResources) error {
for k, v := range r.Unified {
g.AddLinuxResourcesUnified(k, v)
}
if v := r.GetPids(); v != nil {
g.SetLinuxResourcesPidsLimit(v.GetLimit())
}
if g.checkResources != nil {
if err := g.checkResources(g.Config.Linux.Resources); err != nil {
return fmt.Errorf("failed to adjust resources in OCI Spec: %w", err)

View File

@ -235,6 +235,30 @@ var _ = Describe("Adjustment", func() {
})
})
When("has pids limit", func() {
It("adjusts Spec correctly", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Pids: &api.LinuxPids{
Limit: 123,
},
},
},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec(withPidsLimit(123))))
})
})
When("has mounts", func() {
It("it sorts the Spec mount slice", func() {
var (
@ -397,6 +421,20 @@ func withCPUSetMems(v string) specOption {
}
}
func withPidsLimit(v int64) specOption {
return func(spec *rspec.Spec) {
if spec.Linux == nil {
spec.Linux = &rspec.Linux{}
}
if spec.Linux.Resources == nil {
spec.Linux.Resources = &rspec.LinuxResources{}
}
spec.Linux.Resources.Pids = &rspec.LinuxPids{
Limit: v,
}
}
}
func withMounts(mounts []rspec.Mount) specOption {
return func(spec *rspec.Spec) {
spec.Mounts = append(spec.Mounts, mounts...)
@ -431,6 +469,9 @@ func makeSpec(options ...specOption) *rspec.Spec {
Cpus: "0-111",
Mems: "0-4",
},
Pids: &rspec.LinuxPids{
Limit: 1,
},
},
},
}