@@ -146,10 +146,11 @@ import (
146146 */
147147
148148type Manager struct {
149- mu sync.Mutex
150- config * configs.Config
151- id string
152- path string
149+ mu sync.Mutex
150+ config * configs.Config
151+ id string
152+ path string
153+ directoryCreated bool
153154}
154155
155156// NewManager returns a new instance of Manager, or nil if the Intel RDT
@@ -170,9 +171,10 @@ func NewManager(config *configs.Config, id string, path string) *Manager {
170171// is actually available. Used by unit tests that mock intelrdt paths.
171172func newManager (config * configs.Config , id string , path string ) * Manager {
172173 return & Manager {
173- config : config ,
174- id : id ,
175- path : path ,
174+ config : config ,
175+ id : id ,
176+ path : path ,
177+ directoryCreated : false ,
176178 }
177179}
178180
@@ -466,6 +468,14 @@ func (m *Manager) Apply(pid int) (err error) {
466468 }
467469 }
468470
471+ // If the directory doesn't exist we need to create it -> it means we also need
472+ // to clean it up afterwards. Make a note to the manager.
473+ if _ , err := os .Stat (path ); err != nil {
474+ if os .IsNotExist (err ) {
475+ m .directoryCreated = true
476+ }
477+ }
478+
469479 if err := os .MkdirAll (path , 0o755 ); err != nil {
470480 return newLastCmdError (err )
471481 }
@@ -482,8 +492,9 @@ func (m *Manager) Apply(pid int) (err error) {
482492func (m * Manager ) Destroy () error {
483493 // Don't remove resctrl group if closid has been explicitly specified. The
484494 // group is likely externally managed, i.e. by some other entity than us.
485- // There are probably other containers/tasks sharing the same group.
486- if m .config .IntelRdt != nil && m .config .IntelRdt .ClosID == "" {
495+ // There are probably other containers/tasks sharing the same group. Also
496+ // only remove the directory if it was created by us.
497+ if m .config .IntelRdt != nil && m .config .IntelRdt .ClosID == "" && m .directoryCreated {
487498 m .mu .Lock ()
488499 defer m .mu .Unlock ()
489500 if err := os .RemoveAll (m .GetPath ()); err != nil {
@@ -589,6 +600,28 @@ func (m *Manager) GetStats() (*Stats, error) {
589600 return stats , nil
590601}
591602
603+ func combineSchemas (l3CacheSchema , memBwSchema string ) string {
604+ // If both l3CacheSchema and memBwSchema are set and
605+ // l3CacheSchema contains a line beginning with "MB:", the
606+ // value written to schemata file MUST be the non-"MB:"
607+ // line(s) from l3CacheSchema and the line from memBWSchema.
608+
609+ validLines := make ([]string , 0 )
610+
611+ // Split the l3CacheSchema to lines.
612+ lines := strings .Split (l3CacheSchema , "\n " )
613+
614+ // Remove the "MB:" lines.
615+ for _ , line := range lines {
616+ if strings .HasPrefix (line , "MB:" ) {
617+ continue
618+ }
619+ validLines = append (validLines , line )
620+ }
621+
622+ return strings .Join (validLines , "\n " ) + "\n " + memBwSchema
623+ }
624+
592625// Set Intel RDT "resource control" filesystem as configured.
593626func (m * Manager ) Set (container * configs.Config ) error {
594627 // About L3 cache schema:
@@ -649,7 +682,8 @@ func (m *Manager) Set(container *configs.Config) error {
649682
650683 // Write a single joint schema string to schemata file
651684 if l3CacheSchema != "" && memBwSchema != "" {
652- if err := writeFile (path , "schemata" , l3CacheSchema + "\n " + memBwSchema ); err != nil {
685+ schemata := combineSchemas (l3CacheSchema , memBwSchema )
686+ if err := writeFile (path , "schemata" , schemata ); err != nil {
653687 return err
654688 }
655689 }
0 commit comments