Skip to content

Commit 6a371ac

Browse files
committed
device-injector: add scheduling policy adjustment.
Signed-off-by: Krisztian Litkey <[email protected]>
1 parent e06369e commit 6a371ac

1 file changed

Lines changed: 99 additions & 0 deletions

File tree

plugins/device-injector/device-injector.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ const (
5151
netDeviceKey = "network-devices.noderesource.dev"
5252
// Deprecated: Prefix of the key used for network device injection.
5353
oldNetDeviceKey = "network-devices.nri.io"
54+
// Prefix of the key used for scheduler attribute adjustment.
55+
schedulerKey = "scheduling-policy.noderesource.dev"
56+
// Deprecated: Prefix of the key used for scheduler attribute adjustment.
57+
oldSchedulerKey = "scheduling-policy.nri.io"
5458
)
5559

5660
var (
@@ -89,6 +93,17 @@ type netDevice struct {
8993
Name string `json:"name"`
9094
}
9195

96+
// scheduler attribute adjustment
97+
type scheduler struct {
98+
Policy string `json:"policy"`
99+
Nice int32 `json:"nice"`
100+
Priority int32 `json:"priority"`
101+
Flags []string `json:"flags"`
102+
Runtime uint64 `json:"runtime"`
103+
Deadline uint64 `json:"deadline"`
104+
Period uint64 `json:"period"`
105+
}
106+
92107
// our injector plugin
93108
type plugin struct {
94109
stub stub.Stub
@@ -117,6 +132,9 @@ func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, ctr *ap
117132
if err := setIOPriority(pod, ctr, adjust); err != nil {
118133
return nil, nil, err
119134
}
135+
if err := adjustScheduler(pod, ctr, adjust); err != nil {
136+
return nil, nil, err
137+
}
120138

121139
if err := injectNetDevices(pod, ctr, adjust); err != nil {
122140
return nil, nil, err
@@ -275,6 +293,29 @@ func setIOPriority(pod *api.PodSandbox, ctr *api.Container, a *api.ContainerAdju
275293
return nil
276294
}
277295

296+
func adjustScheduler(pod *api.PodSandbox, ctr *api.Container, a *api.ContainerAdjustment) error {
297+
sch, err := parseScheduler(ctr.Name, pod.Annotations)
298+
if err != nil {
299+
return err
300+
}
301+
302+
if sch == nil {
303+
log.Debugf("%s: no scheduling attributes annotated...", containerName(pod, ctr))
304+
return nil
305+
}
306+
307+
if verbose {
308+
dump(containerName(pod, ctr), "annotated scheduling attributes", sch)
309+
}
310+
311+
a.SetLinuxScheduler(sch.ToNRI())
312+
if !verbose {
313+
log.Infof("%s: adjusted scheduling attributes to %s...", containerName(pod, ctr), sch)
314+
}
315+
316+
return nil
317+
}
318+
278319
func parseIOPriority(ctr string, annotations map[string]string) (*ioPrio, error) {
279320
var (
280321
priority = &ioPrio{}
@@ -337,6 +378,23 @@ func parseNetDevices(ctr string, annotations map[string]string) ([]*netDevice, e
337378
return devices, nil
338379
}
339380

381+
func parseScheduler(ctr string, annotations map[string]string) (*scheduler, error) {
382+
var (
383+
sch = &scheduler{}
384+
)
385+
386+
annotation := getAnnotation(annotations, schedulerKey, oldSchedulerKey, ctr)
387+
if annotation == nil {
388+
return nil, nil
389+
}
390+
391+
if err := yaml.Unmarshal(annotation, sch); err != nil {
392+
return nil, fmt.Errorf("invalid scheduler annotation %q: %w", string(annotation), err)
393+
}
394+
395+
return sch, nil
396+
}
397+
340398
func getAnnotation(annotations map[string]string, mainKey, oldKey, ctr string) []byte {
341399
for _, key := range []string{
342400
mainKey + "/container." + ctr,
@@ -420,6 +478,47 @@ func (p *ioPrio) String() string {
420478
return fmt.Sprintf("<I/O priority class %s:%d>", p.Class, p.Priority)
421479
}
422480

481+
// Convert scheduling attributes to the NRI API representation.
482+
func (sch *scheduler) ToNRI() *api.LinuxScheduler {
483+
apiSch := &api.LinuxScheduler{
484+
Policy: api.LinuxSchedulerPolicy(api.LinuxSchedulerPolicy_value[sch.Policy]),
485+
Nice: sch.Nice,
486+
Priority: sch.Priority,
487+
Runtime: sch.Runtime,
488+
Deadline: sch.Deadline,
489+
Period: sch.Period,
490+
}
491+
492+
for _, f := range sch.Flags {
493+
apiSch.Flags = append(apiSch.Flags, api.LinuxSchedulerFlag(api.LinuxSchedulerFlag_value[f]))
494+
}
495+
496+
return apiSch
497+
}
498+
499+
func (sc *scheduler) String() string {
500+
if sc == nil {
501+
return "<no scheduling attributes>"
502+
}
503+
504+
s := fmt.Sprintf("<scheduler policy=%s", sc.Policy)
505+
if sc.Nice != 0 {
506+
s += fmt.Sprintf(", nice=%d", sc.Nice)
507+
}
508+
if sc.Priority != 0 {
509+
s += fmt.Sprintf(", priority=%d", sc.Priority)
510+
}
511+
if sc.Runtime != 0 {
512+
s += fmt.Sprintf(", runtime=%d, deadline=%d, period=%d", sc.Runtime, sc.Deadline, sc.Period)
513+
}
514+
if len(sc.Flags) > 0 {
515+
s += fmt.Sprintf(", flags=%v", sc.Flags)
516+
}
517+
s += ">"
518+
519+
return s
520+
}
521+
423522
// Construct a container name for log messages.
424523
func containerName(pod *api.PodSandbox, container *api.Container) string {
425524
if pod != nil {

0 commit comments

Comments
 (0)