Skip to content

Commit

Permalink
libcontainer/intelrdt: verify ClosID existence
Browse files Browse the repository at this point in the history
Check that the ClosID directory pre-exists if no L3 or MB schema has
been specified. Conform with the following line from runtime-spec
(config-linux):

  If closID is set, and neither of l3CacheSchema and memBwSchema are
  set, runtime MUST check if corresponding pre-configured directory
  closID is present in mounted resctrl. If such pre-configured directory
  closID exists, runtime MUST assign container to this closID and
  generate an error if directory does not exist.

Add a TODO note for verifying existing schemata against L3/MB
parameters.

Signed-off-by: Markus Lehtonen <[email protected]>
  • Loading branch information
marquiz committed May 4, 2021
1 parent e40d51c commit 685dc58
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
15 changes: 14 additions & 1 deletion libcontainer/intelrdt/intelrdt.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ var (
)

type intelRdtData struct {
root string
config *configs.Config
pid int
}
Expand Down Expand Up @@ -563,6 +562,14 @@ func (m *intelRdtManager) Apply(pid int) (err error) {
m.mu.Lock()
defer m.mu.Unlock()

if m.config.IntelRdt.ClosID != "" && m.config.IntelRdt.L3CacheSchema == "" && m.config.IntelRdt.MemBwSchema == "" {
// Check that the CLOS exists, i.e. it has been pre-configured to
// conform with the runtime spec
if _, err := os.Stat(path); err != nil {
return fmt.Errorf("clos dir not accessible (must be pre-created when l3CacheSchema and memBwSchema are empty): %w", err)
}
}

if err := os.MkdirAll(path, 0o755); err != nil {
return NewLastCmdError(err)
}
Expand Down Expand Up @@ -738,6 +745,12 @@ func (m *intelRdtManager) Set(container *configs.Config) error {
l3CacheSchema := container.IntelRdt.L3CacheSchema
memBwSchema := container.IntelRdt.MemBwSchema

// TODO: verify that l3CacheSchema and/or memBwSchema match the
// existing schemata if ClosID has been specified. This is a more
// involved than reading the file and doing plain string comparison as
// the value written in does not necessarily match what gets read out
// (leading zeros, cache id ordering etc).

// Write a single joint schema string to schemata file
if l3CacheSchema != "" && memBwSchema != "" {
if err := writeFile(path, "schemata", l3CacheSchema+"\n"+memBwSchema); err != nil {
Expand Down
32 changes: 32 additions & 0 deletions libcontainer/intelrdt/intelrdt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ package intelrdt

import (
"io"
"os"
"path/filepath"
"strings"
"testing"
)
Expand Down Expand Up @@ -113,6 +115,36 @@ func TestIntelRdtSetMemBwScSchema(t *testing.T) {
}
}

func TestApply(t *testing.T) {
helper := NewIntelRdtTestUtil(t)
defer helper.cleanup()

const closID = "test-clos"

helper.IntelRdtData.config.IntelRdt.ClosID = closID
intelrdt := NewManager(helper.IntelRdtData.config, "", helper.IntelRdtPath)
if err := intelrdt.Apply(1234); err == nil {
t.Fatal("unexpected success when applying pid")
}
if _, err := os.Stat(filepath.Join(helper.IntelRdtPath, closID)); err == nil {
t.Fatal("closid dir should not exist")
}

// Dir should be created if some schema has been specified
intelrdt.(*intelRdtManager).config.IntelRdt.L3CacheSchema = "L3:0=f"
if err := intelrdt.Apply(1235); err != nil {
t.Fatalf("Apply() failed: %v", err)
}

pids, err := getIntelRdtParamString(intelrdt.GetPath(), "tasks")
if err != nil {
t.Fatalf("failed to read tasks file: %v", err)
}
if pids != "1235" {
t.Fatalf("unexpected tasks file, expected '1235', got %q", pids)
}
}

const (
mountinfoValid = `18 40 0:18 / /sys rw,nosuid,nodev,noexec,relatime shared:6 - sysfs sysfs rw
19 40 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw
Expand Down
5 changes: 3 additions & 2 deletions libcontainer/intelrdt/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ func NewIntelRdtTestUtil(t *testing.T) *intelRdtTestUtil {
if err != nil {
t.Fatal(err)
}
d.root = tempDir
testIntelRdtPath := filepath.Join(d.root, "resctrl")
intelRdtRoot = tempDir
testIntelRdtPath := filepath.Join(tempDir, "resctrl")
if err != nil {
t.Fatal(err)
}
Expand All @@ -53,6 +53,7 @@ func NewIntelRdtTestUtil(t *testing.T) *intelRdtTestUtil {
}

func (c *intelRdtTestUtil) cleanup() {
intelRdtRoot = ""
os.RemoveAll(c.tempDir)
}

Expand Down

0 comments on commit 685dc58

Please sign in to comment.