diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go index 89deb96e..83aeb8f1 100644 --- a/libcontainer/factory_linux.go +++ b/libcontainer/factory_linux.go @@ -213,8 +213,7 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err newgidmapPath: l.NewgidmapPath, cgroupManager: l.NewCgroupsManager(config.Cgroups, nil), } - c.intelRdtManager = nil - if intelrdt.IsEnabled() && c.config.IntelRdt != nil { + if intelrdt.IsEnabled() { c.intelRdtManager = l.NewIntelRdtManager(config, id, "") } c.state = &stoppedState{c: c} @@ -256,8 +255,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) { if err := c.refreshState(); err != nil { return nil, err } - c.intelRdtManager = nil - if intelrdt.IsEnabled() && c.config.IntelRdt != nil { + if intelrdt.IsEnabled() { c.intelRdtManager = l.NewIntelRdtManager(&state.Config, id, state.IntelRdtPath) } return c, nil diff --git a/libcontainer/intelrdt/intelrdt.go b/libcontainer/intelrdt/intelrdt.go index 667625a1..ebb68f94 100644 --- a/libcontainer/intelrdt/intelrdt.go +++ b/libcontainer/intelrdt/intelrdt.go @@ -401,6 +401,10 @@ func GetIntelRdtPath(id string) (string, error) { // Applies Intel RDT configuration to the process with the specified pid func (m *IntelRdtManager) Apply(pid int) (err error) { + // If intelRdt is not specified in config, we do nothing + if m.Config.IntelRdt == nil { + return nil + } d, err := getIntelRdtData(m.Config, pid) if err != nil && !IsNotFound(err) { return err diff --git a/update.go b/update.go index 133be999..9bb6b610 100644 --- a/update.go +++ b/update.go @@ -9,6 +9,8 @@ import ( "strconv" "github.com/docker/go-units" + "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/intelrdt" "github.com/opencontainers/runtime-spec/specs-go" "github.com/urfave/cli" ) @@ -112,6 +114,10 @@ other options are ignored. Name: "pids-limit", Usage: "Maximum number of pids allowed in the container", }, + cli.StringFlag{ + Name: "l3-cache-schema", + Usage: "The string of Intel RDT/CAT L3 cache schema", + }, }, Action: func(context *cli.Context) error { if err := checkArgs(context, 1, exactArgs); err != nil { @@ -254,6 +260,34 @@ other options are ignored. config.Cgroups.Resources.MemorySwap = *r.Memory.Swap config.Cgroups.Resources.PidsLimit = r.Pids.Limit + // Update Intel RDT/CAT + if val := context.String("l3-cache-schema"); val != "" { + if !intelrdt.IsEnabled() { + return fmt.Errorf("Intel RDT: l3 cache schema is not enabled") + } + + // If intelRdt is not specified in original configuration, we just don't + // Apply() to create intelRdt group or attach tasks for this container. + // In update command, we could re-enable through IntelRdtManager.Apply() + // and then update intelrdt constraint. + if config.IntelRdt == nil { + state, err := container.State() + if err != nil { + return err + } + config.IntelRdt = &configs.IntelRdt{} + intelRdtManager := intelrdt.IntelRdtManager{ + Config: &config, + Id: container.ID(), + Path: state.IntelRdtPath, + } + if err := intelRdtManager.Apply(state.InitProcessPid); err != nil { + return err + } + } + config.IntelRdt.L3CacheSchema = val + } + return container.Set(config) }, }