From fc3f4803d08fdbef614708589c2de236fc5c79b9 Mon Sep 17 00:00:00 2001 From: Allen Sun Date: Thu, 22 Feb 2018 14:00:35 +0800 Subject: [PATCH] feature: support IntelRdtL3Cbm in pouch container Signed-off-by: Allen Sun --- cli/container.go | 12 ++++++++++++ cli/container_test.go | 20 ++++++++++++++++++++ cli/create.go | 1 + cli/run.go | 1 + daemon/mgr/spec.go | 3 +++ daemon/mgr/spec_linux.go | 13 +++++++++++++ test/cli_create_test.go | 17 +++++++++++++++++ 7 files changed, 67 insertions(+) diff --git a/cli/container.go b/cli/container.go index 7542b9d371..828f467403 100644 --- a/cli/container.go +++ b/cli/container.go @@ -48,6 +48,7 @@ type container struct { blkioDeviceWriteBps ThrottleBpsDevice blkioDeviceReadIOps ThrottleIOpsDevice blkioDeviceWriteIOps ThrottleIOpsDevice + IntelRdtL3Cbm string } func (c *container) config() (*types.ContainerCreateConfig, error) { @@ -70,6 +71,11 @@ func (c *container) config() (*types.ContainerCreateConfig, error) { return nil, err } + intelRdtL3Cbm, err := parseIntelRdt(c.IntelRdtL3Cbm) + if err != nil { + return nil, err + } + deviceMappings, err := parseDeviceMappings(c.devices) if err != nil { return nil, err @@ -143,6 +149,7 @@ func (c *container) config() (*types.ContainerCreateConfig, error) { BlkioDeviceReadIOps: c.blkioDeviceReadIOps.value(), BlkioDeviceWriteBps: c.blkioDeviceWriteBps.value(), BlkioDeviceWriteIOps: c.blkioDeviceWriteIOps.value(), + IntelRdtL3Cbm: intelRdtL3Cbm, }, EnableLxcfs: c.enableLxcfs, Privileged: c.privileged, @@ -260,6 +267,11 @@ func validateMemorySwappiness(memorySwappiness int64) error { return nil } +func parseIntelRdt(intelRdtL3Cbm string) (string, error) { + // FIXME: add Intel RDT L3 Cbm validation + return intelRdtL3Cbm, nil +} + func parseRestartPolicy(restartPolicy string) (*types.RestartPolicy, error) { policy := &types.RestartPolicy{} diff --git a/cli/container_test.go b/cli/container_test.go index da0315d3c6..2fecc3ded6 100644 --- a/cli/container_test.go +++ b/cli/container_test.go @@ -436,3 +436,23 @@ func Test_parseNetwork(t *testing.T) { assert.Equal(t, testCase.expect.network.mode, mode) } } + +func Test_parseIntelRdt(t *testing.T) { + type args struct { + intelRdtL3Cbm string + } + tests := []struct { + name string + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := parseIntelRdt(tt.args.intelRdtL3Cbm); (err != nil) != tt.wantErr { + t.Errorf("parseIntelRdt() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/cli/create.go b/cli/create.go index 1f426d5f35..98387fb268 100644 --- a/cli/create.go +++ b/cli/create.go @@ -74,6 +74,7 @@ func (cc *CreateCommand) addFlags() { flagSet.Var(&cc.blkioDeviceReadIOps, "device-read-iops", "Limit read rate (IO per second) from a device") flagSet.Var(&cc.blkioDeviceWriteBps, "device-write-bps", "Limit write rate (bytes per second) from a device") flagSet.Var(&cc.blkioDeviceWriteIOps, "device-write-iops", "Limit write rate (IO per second) from a device") + flagSet.StringVar(&cc.IntelRdtL3Cbm, "intel-rdt-l3-cbm", "", "Limit container resource for Intel RDT/CAT which introduced in Linux 4.10 kernel") } // runCreate is the entry of create command. diff --git a/cli/run.go b/cli/run.go index f104893383..dab1db0ec9 100644 --- a/cli/run.go +++ b/cli/run.go @@ -82,6 +82,7 @@ func (rc *RunCommand) addFlags() { flagSet.Var(&rc.blkioDeviceReadIOps, "device-read-iops", "Limit read rate (IO per second) from a device") flagSet.Var(&rc.blkioDeviceWriteBps, "device-write-bps", "Limit write rate (bytes per second) from a device") flagSet.Var(&rc.blkioDeviceWriteIOps, "device-write-iops", "Limit write rate (IO per second) from a device") + flagSet.StringVar(&rc.IntelRdtL3Cbm, "intel-rdt-l3-cbm", "", "Limit container resource for Intel RDT/CAT which introduced in Linux 4.10 kernel") } // runRun is the entry of run command. diff --git a/daemon/mgr/spec.go b/daemon/mgr/spec.go index 0d99be03bd..2693fa05de 100644 --- a/daemon/mgr/spec.go +++ b/daemon/mgr/spec.go @@ -58,6 +58,9 @@ var setupFunc = []SetupFunc{ // blkio spec setupBlkio, + + // IntelRdtL3Cbm + setupIntelRdt, } // Register is used to registe spec setup function. diff --git a/daemon/mgr/spec_linux.go b/daemon/mgr/spec_linux.go index 7ae5a377ab..d81d5a17c4 100644 --- a/daemon/mgr/spec_linux.go +++ b/daemon/mgr/spec_linux.go @@ -117,3 +117,16 @@ func setupCapabilities(ctx context.Context, meta *ContainerMeta, spec *SpecWrapp return nil } + +func setupIntelRdt(ctx context.Context, meta *ContainerMeta, spec *SpecWrapper) error { + s := spec.s + if s.Linux.IntelRdt == nil { + s.Linux.IntelRdt = &specs.LinuxIntelRdt{} + } + + s.Linux.IntelRdt = &specs.LinuxIntelRdt{ + L3CacheSchema: meta.HostConfig.IntelRdtL3Cbm, + } + + return nil +} diff --git a/test/cli_create_test.go b/test/cli_create_test.go index f795cfd322..664e78e81e 100644 --- a/test/cli_create_test.go +++ b/test/cli_create_test.go @@ -329,3 +329,20 @@ func (suite *PouchCreateSuite) TestCreateWithUser(c *check.C) { } c.Assert(result.Config.User, check.Equals, user) } + +// TestCreateWithIntelRdt tests creating container with Intel Rdt. +func (suite *PouchCreateSuite) TestCreateWithIntelRdt(c *check.C) { + name := "TestCreateWithIntelRdt" + intelRdt := "L3:=" + + res := command.PouchRun("create", "--name", name, "--intel-rdt-l3-cbm", intelRdt, busyboxImage) + res.Assert(c, icmd.Success) + + output := command.PouchRun("inspect", name).Stdout() + + result := &types.ContainerJSON{} + if err := json.Unmarshal([]byte(output), result); err != nil { + c.Errorf("failed to decode inspect output: %v", err) + } + c.Assert(result.HostConfig.IntelRdtL3Cbm, check.Equals, intelRdt) +}