@@ -146,10 +146,11 @@ import (
146
146
*/
147
147
148
148
type 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
153
154
}
154
155
155
156
// 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 {
170
171
// is actually available. Used by unit tests that mock intelrdt paths.
171
172
func newManager (config * configs.Config , id string , path string ) * Manager {
172
173
return & Manager {
173
- config : config ,
174
- id : id ,
175
- path : path ,
174
+ config : config ,
175
+ id : id ,
176
+ path : path ,
177
+ directoryCreated : false ,
176
178
}
177
179
}
178
180
@@ -466,6 +468,14 @@ func (m *Manager) Apply(pid int) (err error) {
466
468
}
467
469
}
468
470
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
+
469
479
if err := os .MkdirAll (path , 0o755 ); err != nil {
470
480
return newLastCmdError (err )
471
481
}
@@ -482,8 +492,9 @@ func (m *Manager) Apply(pid int) (err error) {
482
492
func (m * Manager ) Destroy () error {
483
493
// Don't remove resctrl group if closid has been explicitly specified. The
484
494
// 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 {
487
498
m .mu .Lock ()
488
499
defer m .mu .Unlock ()
489
500
if err := os .RemoveAll (m .GetPath ()); err != nil {
@@ -589,6 +600,28 @@ func (m *Manager) GetStats() (*Stats, error) {
589
600
return stats , nil
590
601
}
591
602
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
+
592
625
// Set Intel RDT "resource control" filesystem as configured.
593
626
func (m * Manager ) Set (container * configs.Config ) error {
594
627
// About L3 cache schema:
@@ -649,7 +682,8 @@ func (m *Manager) Set(container *configs.Config) error {
649
682
650
683
// Write a single joint schema string to schemata file
651
684
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 {
653
687
return err
654
688
}
655
689
}
0 commit comments