libct/cg/fscommon: introduce and use ParseError

1. Introduce ParseError type as a way to unify error messages related to
   file parsing. Use it from GetCgroup* functions.

2. Do not discard the error from strconv.Parse{Int,Uint} -- it contains
   the value being parsed, and the details about the error.

2. As the error above already contains the value, drop it from format.

[v2: use path.Join in Error]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin
2021-06-08 12:45:03 -07:00
parent adcd3b4451
commit f813174d5e
+21 -3
View File
@@ -5,6 +5,7 @@ package fscommon
import (
"fmt"
"math"
"path"
"strconv"
"strings"
@@ -20,6 +21,19 @@ var (
WriteFile = cgroups.WriteFile
)
// ParseError records a parse error details, including the file path.
type ParseError struct {
Path string
File string
Err error
}
func (e *ParseError) Error() string {
return "unable to parse " + path.Join(e.Path, e.File) + ": " + e.Err.Error()
}
func (e *ParseError) Unwrap() error { return e.Err }
// ParseUint converts a string to an uint64 integer.
// Negative values are returned at zero as, due to kernel bugs,
// some of the memory cgroup stats can be negative.
@@ -72,7 +86,11 @@ func GetValueByKey(path, file, key string) (uint64, error) {
for _, line := range lines {
arr := strings.Split(line, " ")
if len(arr) == 2 && arr[0] == key {
return ParseUint(arr[1], 10, 64)
val, err := ParseUint(arr[1], 10, 64)
if err != nil {
err = &ParseError{Path: path, File: file, Err: err}
}
return val, err
}
}
@@ -93,7 +111,7 @@ func GetCgroupParamUint(path, file string) (uint64, error) {
res, err := ParseUint(contents, 10, 64)
if err != nil {
return res, fmt.Errorf("unable to parse file %q", path+"/"+file)
return res, &ParseError{Path: path, File: file, Err: err}
}
return res, nil
}
@@ -112,7 +130,7 @@ func GetCgroupParamInt(path, file string) (int64, error) {
res, err := strconv.ParseInt(contents, 10, 64)
if err != nil {
return res, fmt.Errorf("unable to parse %q as a int from Cgroup file %q", contents, path+"/"+file)
return res, &ParseError{Path: path, File: file, Err: err}
}
return res, nil
}