@@ -12,6 +12,8 @@ import (
1212	"strings" 
1313	"sync" 
1414
15+ 	"github.com/sirupsen/logrus" 
16+ 
1517	"github.com/opencontainers/runc/libcontainer/configs" 
1618)
1719
@@ -167,10 +169,16 @@ type IntelRdtManager struct {
167169	Config  * configs.Config 
168170	Id      string 
169171	Path    string 
172+ 	Type    string 
170173}
171174
172175const  (
173- 	IntelRdtTasks  =  "tasks" 
176+ 	IntelRdtTasks          =  "tasks" 
177+ 	MonGroupDirectoryName  =  "mon_groups" 
178+ 	// Monitoring group. 
179+ 	MON  =  "MON" 
180+ 	// Control group. 
181+ 	CTRL_MON  =  "CTRL_MON" 
174182)
175183
176184var  (
@@ -548,26 +556,47 @@ func GetIntelRdtPath(id string) (string, error) {
548556	return  path , nil 
549557}
550558
559+ // Get the 'container_id" path in Intel RDT "monitoring group" filesystem. 
560+ func  GetMonGroupIntelRdtPath (id  string ) (string , error ) {
561+ 	rootPath , err  :=  getIntelRdtRoot ()
562+ 	if  err  !=  nil  {
563+ 		return  "" , err 
564+ 	}
565+ 
566+ 	path  :=  filepath .Join (rootPath , MonGroupDirectoryName , id )
567+ 	return  path , nil 
568+ }
569+ 
551570// Applies Intel RDT configuration to the process with the specified pid 
552571func  (m  * IntelRdtManager ) Apply (pid  int ) (err  error ) {
553- 	// If intelRdt is not specified in config, we do nothing 
554- 	if  m .Config .IntelRdt  ==  nil  {
572+ 	switch  m .Type  {
573+ 	case  CTRL_MON :
574+ 		// If intelRdt is not specified in config, we do nothing 
575+ 		if  m .Config .IntelRdt  ==  nil  {
576+ 			return  nil 
577+ 		}
578+ 		rdtData , err  :=  getIntelRdtData (m .Config , pid )
579+ 		if  err  !=  nil  &&  ! IsNotFound (err ) {
580+ 			return  err 
581+ 		}
582+ 
583+ 		m .mu .Lock ()
584+ 		defer  m .mu .Unlock ()
585+ 		path , err  :=  rdtData .join (m .Id )
586+ 		if  err  !=  nil  {
587+ 			return  err 
588+ 		}
589+ 
590+ 		m .Path  =  path 
555591		return  nil 
556- 	}
557- 	d , err  :=  getIntelRdtData (m .Config , pid )
558- 	if  err  !=  nil  &&  ! IsNotFound (err ) {
559- 		return  err 
560- 	}
561592
562- 	m .mu .Lock ()
563- 	defer  m .mu .Unlock ()
564- 	path , err  :=  d .join (m .Id )
565- 	if  err  !=  nil  {
566- 		return  err 
593+ 	case  MON :
594+ 		m .mu .Lock ()
595+ 		defer  m .mu .Unlock ()
596+ 		return  WriteIntelRdtTasks (m .Path , pid )
567597	}
568598
569- 	m .Path  =  path 
570- 	return  nil 
599+ 	return  fmt .Errorf ("couldn't recognize resctrl type: %v" , m .Type )
571600}
572601
573602// Destroys the Intel RDT 'container_id' group 
@@ -584,94 +613,124 @@ func (m *IntelRdtManager) Destroy() error {
584613// Returns Intel RDT path to save in a state file and to be able to 
585614// restore the object later 
586615func  (m  * IntelRdtManager ) GetPath () string  {
616+ 	var  err  error 
587617	if  m .Path  ==  ""  {
588- 		m .Path , _  =  GetIntelRdtPath (m .Id )
618+ 		switch  m .Type  {
619+ 		case  CTRL_MON :
620+ 			m .Path , err  =  GetIntelRdtPath (m .Id )
621+ 			if  err  !=  nil  {
622+ 				logrus .Errorf ("couldn't obtain Resctrl control group path for manager with id %v: %v" , m .Id , err )
623+ 			}
624+ 		case  MON :
625+ 			flattedContainerID  :=  strings .Replace (m .Id , "/" , "-" , - 1 )
626+ 			m .Path , err  =  GetMonGroupIntelRdtPath (flattedContainerID )
627+ 			if  err  !=  nil  {
628+ 				logrus .Errorf ("couldn't obtain Resctrl monitoring group path for manager with id %v: %v" , m .Id , err )
629+ 			}
630+ 		}
589631	}
590632	return  m .Path 
591633}
592634
593635// Returns statistics for Intel RDT 
594636func  (m  * IntelRdtManager ) GetStats () (* Stats , error ) {
595- 	// If intelRdt is not specified in config 
596- 	if  m .Config .IntelRdt  ==  nil  {
597- 		return  nil , nil 
598- 	}
599- 
600637	m .mu .Lock ()
601638	defer  m .mu .Unlock ()
602639	stats  :=  NewStats ()
603640
604- 	rootPath , err  :=  getIntelRdtRoot ()
605- 	if  err  !=  nil  {
606- 		return  nil , err 
607- 	}
608- 	// The read-only L3 cache and memory bandwidth schemata in root 
609- 	tmpRootStrings , err  :=  getIntelRdtParamString (rootPath , "schemata" )
610- 	if  err  !=  nil  {
611- 		return  nil , err 
612- 	}
613- 	schemaRootStrings  :=  strings .Split (tmpRootStrings , "\n " )
614- 
615- 	// The L3 cache and memory bandwidth schemata in 'container_id' group 
616- 	containerPath  :=  m .GetPath ()
617- 	tmpStrings , err  :=  getIntelRdtParamString (containerPath , "schemata" )
618- 	if  err  !=  nil  {
619- 		return  nil , err 
620- 	}
621- 	schemaStrings  :=  strings .Split (tmpStrings , "\n " )
641+ 	switch  m .Type  {
642+ 	case  CTRL_MON :
643+ 		containerPath  :=  m .GetPath ()
622644
623- 	if  IsCatEnabled () {
624- 		// The read-only L3 cache information 
625- 		l3CacheInfo , err  :=  getL3CacheInfo ()
645+ 		err  :=  getMonitoringStats (containerPath , stats )
626646		if  err  !=  nil  {
627647			return  nil , err 
628648		}
629- 		stats .L3CacheInfo  =  l3CacheInfo 
630649
631- 		// The read-only L3 cache schema  in root  
632- 		for   _ ,  schemaRoot   :=   range   schemaRootStrings  {
633- 			if  strings . Contains ( schemaRoot ,  "L3" )  {
634- 				stats . L3CacheSchemaRoot   =   strings . TrimSpace ( schemaRoot ) 
650+ 		// If intelRdt is not specified  in config  
651+ 		if   m . Config   !=   nil  {
652+ 			if  m . Config . IntelRdt   ==   nil  {
653+ 				return   nil ,  nil 
635654			}
636- 		}
637655
638- 		// The L3 cache schema in 'container_id' group 
639- 		for  _ , schema  :=  range  schemaStrings  {
640- 			if  strings .Contains (schema , "L3" ) {
641- 				stats .L3CacheSchema  =  strings .TrimSpace (schema )
656+ 			rootPath , err  :=  getIntelRdtRoot ()
657+ 			if  err  !=  nil  {
658+ 				return  nil , err 
642659			}
643- 		}
644- 	}
660+ 			// The read-only L3 cache and memory bandwidth schemata in root 
661+ 			tmpRootStrings , err  :=  getIntelRdtParamString (rootPath , "schemata" )
662+ 			if  err  !=  nil  {
663+ 				return  nil , err 
664+ 			}
665+ 			schemaRootStrings  :=  strings .Split (tmpRootStrings , "\n " )
645666
646- 	if  IsMbaEnabled () {
647- 		// The read-only memory bandwidth information 
648- 		memBwInfo , err  :=  getMemBwInfo ()
649- 		if  err  !=  nil  {
650- 			return  nil , err 
651- 		}
652- 		stats .MemBwInfo  =  memBwInfo 
667+ 			// The L3 cache and memory bandwidth schemata in 'container_id' group 
653668
654- 		// The read-only memory bandwidth information 
655- 		for  _ , schemaRoot  :=  range  schemaRootStrings  {
656- 			if  strings .Contains (schemaRoot , "MB" ) {
657- 				stats .MemBwSchemaRoot  =  strings .TrimSpace (schemaRoot )
669+ 			tmpStrings , err  :=  getIntelRdtParamString (containerPath , "schemata" )
670+ 			if  err  !=  nil  {
671+ 				return  nil , err 
658672			}
659- 		}
673+ 			schemaStrings  :=  strings .Split (tmpStrings , "\n " )
674+ 
675+ 			if  IsCatEnabled () {
676+ 				// The read-only L3 cache information 
677+ 				l3CacheInfo , err  :=  getL3CacheInfo ()
678+ 				if  err  !=  nil  {
679+ 					return  nil , err 
680+ 				}
681+ 				stats .L3CacheInfo  =  l3CacheInfo 
660682
661- 		// The memory bandwidth schema in 'container_id' group 
662- 		for  _ , schema  :=  range  schemaStrings  {
663- 			if  strings .Contains (schema , "MB" ) {
664- 				stats .MemBwSchema  =  strings .TrimSpace (schema )
683+ 				// The read-only L3 cache schema in root 
684+ 				for  _ , schemaRoot  :=  range  schemaRootStrings  {
685+ 					if  strings .Contains (schemaRoot , "L3" ) {
686+ 						stats .L3CacheSchemaRoot  =  strings .TrimSpace (schemaRoot )
687+ 					}
688+ 				}
689+ 
690+ 				// The L3 cache schema in 'container_id' group 
691+ 				for  _ , schema  :=  range  schemaStrings  {
692+ 					if  strings .Contains (schema , "L3" ) {
693+ 						stats .L3CacheSchema  =  strings .TrimSpace (schema )
694+ 					}
695+ 				}
696+ 			}
697+ 
698+ 			if  IsMbaEnabled () {
699+ 				// The read-only memory bandwidth information 
700+ 				memBwInfo , err  :=  getMemBwInfo ()
701+ 				if  err  !=  nil  {
702+ 					return  nil , err 
703+ 				}
704+ 				stats .MemBwInfo  =  memBwInfo 
705+ 
706+ 				// The read-only memory bandwidth information 
707+ 				for  _ , schemaRoot  :=  range  schemaRootStrings  {
708+ 					if  strings .Contains (schemaRoot , "MB" ) {
709+ 						stats .MemBwSchemaRoot  =  strings .TrimSpace (schemaRoot )
710+ 					}
711+ 				}
712+ 
713+ 				// The memory bandwidth schema in 'container_id' group 
714+ 				for  _ , schema  :=  range  schemaStrings  {
715+ 					if  strings .Contains (schema , "MB" ) {
716+ 						stats .MemBwSchema  =  strings .TrimSpace (schema )
717+ 					}
718+ 				}
665719			}
666720		}
667- 	}
668721
669- 	err   =   getMonitoringStats ( containerPath ,  stats ) 
670- 	 if   err   !=   nil  { 
671- 		 return   nil ,  err 
672- 	} 
722+ 		 return   stats ,  nil 
723+ 
724+ 	case   MON : 
725+ 		 path   :=   m . GetPath () 
673726
674- 	return  stats , nil 
727+ 		err  :=  getMonitoringStats (path , stats )
728+ 		if  err  !=  nil  {
729+ 			return  nil , err 
730+ 		}
731+ 		return  stats , nil 
732+ 	}
733+ 	return  nil , fmt .Errorf ("couldn't obtain stats from: %q resctrl manager of type: %q" , m .Id , m .Type )
675734}
676735
677736// Set Intel RDT "resource control" filesystem as configured. 
@@ -721,34 +780,45 @@ func (m *IntelRdtManager) Set(container *configs.Config) error {
721780	// For example, on a two-socket machine, the schema line could be 
722781	// "MB:0=5000;1=7000" which means 5000 MBps memory bandwidth limit on 
723782	// socket 0 and 7000 MBps memory bandwidth limit on socket 1. 
724- 	if  container .IntelRdt  !=  nil  {
725- 		path  :=  m .GetPath ()
726- 		l3CacheSchema  :=  container .IntelRdt .L3CacheSchema 
727- 		memBwSchema  :=  container .IntelRdt .MemBwSchema 
783+ 	switch  m .Type  {
784+ 	case  CTRL_MON :
785+ 		if  container .IntelRdt  !=  nil  {
786+ 			path  :=  m .GetPath ()
787+ 			l3CacheSchema  :=  container .IntelRdt .L3CacheSchema 
788+ 			memBwSchema  :=  container .IntelRdt .MemBwSchema 
789+ 
790+ 			// Write a single joint schema string to schemata file 
791+ 			if  l3CacheSchema  !=  ""  &&  memBwSchema  !=  ""  {
792+ 				if  err  :=  writeFile (path , "schemata" , l3CacheSchema + "\n " + memBwSchema ); err  !=  nil  {
793+ 					return  NewLastCmdError (err )
794+ 				}
795+ 			}
728796
729- 		// Write a single joint schema string to schemata file 
730- 		if  l3CacheSchema  !=  ""  &&  memBwSchema  !=  ""  {
731- 			if  err  :=  writeFile (path , "schemata" , l3CacheSchema + "\n " + memBwSchema ); err  !=  nil  {
732- 				return  NewLastCmdError (err )
797+ 			// Write only L3 cache schema string to schemata file 
798+ 			if  l3CacheSchema  !=  ""  &&  memBwSchema  ==  ""  {
799+ 				if  err  :=  writeFile (path , "schemata" , l3CacheSchema ); err  !=  nil  {
800+ 					return  NewLastCmdError (err )
801+ 				}
733802			}
734- 		}
735803
736- 		// Write only L3 cache schema string to schemata file 
737- 		if  l3CacheSchema  !=  ""  &&  memBwSchema  ==  ""  {
738- 			if  err  :=  writeFile (path , "schemata" , l3CacheSchema ); err  !=  nil  {
739- 				return  NewLastCmdError (err )
804+ 			// Write only memory bandwidth schema string to schemata file 
805+ 			if  l3CacheSchema  ==  ""  &&  memBwSchema  !=  ""  {
806+ 				if  err  :=  writeFile (path , "schemata" , memBwSchema ); err  !=  nil  {
807+ 					return  NewLastCmdError (err )
808+ 				}
740809			}
741810		}
742811
743- 		// Write only memory bandwidth schema string to schemata file 
744- 		if  l3CacheSchema  ==  ""  &&  memBwSchema  !=  ""  {
745- 			if  err  :=  writeFile (path , "schemata" , memBwSchema ); err  !=  nil  {
746- 				return  NewLastCmdError (err )
747- 			}
812+ 	case  MON :
813+ 		if  _ , err  :=  os .Stat (m .GetPath ()); err  ==  nil  {
814+ 			return  nil 
815+ 		}
816+ 		if  err  :=  os .Mkdir (m .GetPath (), 0755 ); err  !=  nil  {
817+ 			return  err 
748818		}
749819	}
750820
751- 	return  nil 
821+ 	return  fmt . Errorf ( "couldn't set configuration for: %q resctrl manager of type: %q" ,  m . Id ,  m . Type ) 
752822}
753823
754824func  (raw  * intelRdtData ) join (id  string ) (string , error ) {
0 commit comments