Skip to content

Commit 6c307f8

Browse files
committed
libcontainer: intelrdt: add user-friendly diagnostics for Intel RDT operation errors
Linux kernel v4.15 introduces better diagnostics for Intel RDT operation errors. If any error returns when making new directories or writing to any of the control file in resctrl filesystem, reading file /sys/fs/resctrl/info/last_cmd_status could provide more information that can be conveyed in the error returns from file operations. Some examples: echo "L3:0=f3;1=ff" > /sys/fs/resctrl/container_id/schemata -bash: echo: write error: Invalid argument cat /sys/fs/resctrl/info/last_cmd_status mask f3 has non-consecutive 1-bits echo "MB:0=0;1=110" > /sys/fs/resctrl/container_id/schemata -bash: echo: write error: Invalid argument cat /sys/fs/resctrl/info/last_cmd_status MB value 0 out of range [10,100] cd /sys/fs/resctrl mkdir 1 2 3 4 5 6 7 8 mkdir: cannot create directory '8': No space left on device cat /sys/fs/resctrl/info/last_cmd_status out of CLOSIDs See 'last_cmd_status' for more details in kernel documentation: https://www.kernel.org/doc/Documentation/x86/intel_rdt_ui.txt In runc, we could append the diagnostics information to the error message of Intel RDT operation errors to provide more user-friendly information. Signed-off-by: Xiaochen Shen <[email protected]>
1 parent c2ab1e6 commit 6c307f8

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

libcontainer/intelrdt/intelrdt.go

+41-5
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,22 @@ func getMemBwInfo() (*MemBwInfo, error) {
439439
return memBwInfo, nil
440440
}
441441

442+
// Get diagnostics for last filesystem operation error from file info/last_cmd_status
443+
func getLastCmdStatus() (string, error) {
444+
rootPath, err := getIntelRdtRoot()
445+
if err != nil {
446+
return "", err
447+
}
448+
449+
path := filepath.Join(rootPath, "info")
450+
lastCmdStatus, err := getIntelRdtParamString(path, "last_cmd_status")
451+
if err != nil {
452+
return "", err
453+
}
454+
455+
return lastCmdStatus, nil
456+
}
457+
442458
// WriteIntelRdtTasks writes the specified pid into the "tasks" file
443459
func WriteIntelRdtTasks(dir string, pid int) error {
444460
if dir == "" {
@@ -637,21 +653,21 @@ func (m *IntelRdtManager) Set(container *configs.Config) error {
637653
// Write a single joint schema string to schemata file
638654
if l3CacheSchema != "" && memBwSchema != "" {
639655
if err := writeFile(path, "schemata", l3CacheSchema+"\n"+memBwSchema); err != nil {
640-
return err
656+
return NewLastCmdError(err)
641657
}
642658
}
643659

644660
// Write only L3 cache schema string to schemata file
645661
if l3CacheSchema != "" && memBwSchema == "" {
646662
if err := writeFile(path, "schemata", l3CacheSchema); err != nil {
647-
return err
663+
return NewLastCmdError(err)
648664
}
649665
}
650666

651667
// Write only memory bandwidth schema string to schemata file
652668
if l3CacheSchema == "" && memBwSchema != "" {
653669
if err := writeFile(path, "schemata", memBwSchema); err != nil {
654-
return err
670+
return NewLastCmdError(err)
655671
}
656672
}
657673
}
@@ -662,11 +678,11 @@ func (m *IntelRdtManager) Set(container *configs.Config) error {
662678
func (raw *intelRdtData) join(id string) (string, error) {
663679
path := filepath.Join(raw.root, id)
664680
if err := os.MkdirAll(path, 0755); err != nil {
665-
return "", err
681+
return "", NewLastCmdError(err)
666682
}
667683

668684
if err := WriteIntelRdtTasks(path, raw.pid); err != nil {
669-
return "", err
685+
return "", NewLastCmdError(err)
670686
}
671687
return path, nil
672688
}
@@ -692,3 +708,23 @@ func IsNotFound(err error) bool {
692708
_, ok := err.(*NotFoundError)
693709
return ok
694710
}
711+
712+
type LastCmdError struct {
713+
LastCmdStatus string
714+
Err error
715+
}
716+
717+
func (e *LastCmdError) Error() string {
718+
return fmt.Sprintf(e.Err.Error() + ", last_cmd_status: " + e.LastCmdStatus)
719+
}
720+
721+
func NewLastCmdError(err error) error {
722+
lastCmdStatus, err1 := getLastCmdStatus()
723+
if err1 == nil {
724+
return &LastCmdError{
725+
LastCmdStatus: lastCmdStatus,
726+
Err: err,
727+
}
728+
}
729+
return err
730+
}

0 commit comments

Comments
 (0)