diff --git a/libcontainer/cgroups/utils.go b/libcontainer/cgroups/utils.go index 9717acc7291..ec79ae76723 100644 --- a/libcontainer/cgroups/utils.go +++ b/libcontainer/cgroups/utils.go @@ -22,6 +22,13 @@ const ( CgroupProcesses = "cgroup.procs" ) +// HugePageSizeUnitList is a list of the units used by the linux kernel when +// naming the HugePage control files. +// https://www.kernel.org/doc/Documentation/cgroup-v1/hugetlb.txt +// TODO Since the kernel only use KB, MB and GB; TB and PB should be removed, +// depends on https://github.com/docker/go-units/commit/a09cd47f892041a4fac473133d181f5aea6fa393 +var HugePageSizeUnitList = []string{"B", "KB", "MB", "GB", "TB", "PB"} + // https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt func FindCgroupMountpoint(cgroupPath, subsystem string) (string, error) { mnt, _, err := FindCgroupMountpointAndRoot(cgroupPath, subsystem) @@ -409,19 +416,26 @@ func RemovePaths(paths map[string]string) (err error) { } func GetHugePageSize() ([]string, error) { - var pageSizes []string - sizeList := []string{"B", "kB", "MB", "GB", "TB", "PB"} files, err := ioutil.ReadDir("/sys/kernel/mm/hugepages") if err != nil { - return pageSizes, err + return []string{}, err } + var fileNames []string for _, st := range files { - nameArray := strings.Split(st.Name(), "-") + fileNames = append(fileNames, st.Name()) + } + return getHugePageSizeFromFilenames(fileNames) +} + +func getHugePageSizeFromFilenames(fileNames []string) ([]string, error) { + var pageSizes []string + for _, fileName := range fileNames { + nameArray := strings.Split(fileName, "-") pageSize, err := units.RAMInBytes(nameArray[1]) if err != nil { return []string{}, err } - sizeString := units.CustomSize("%g%s", float64(pageSize), 1024.0, sizeList) + sizeString := units.CustomSize("%g%s", float64(pageSize), 1024.0, HugePageSizeUnitList) pageSizes = append(pageSizes, sizeString) } diff --git a/libcontainer/cgroups/utils_test.go b/libcontainer/cgroups/utils_test.go index fcca9d73a59..3214b9de0da 100644 --- a/libcontainer/cgroups/utils_test.go +++ b/libcontainer/cgroups/utils_test.go @@ -4,6 +4,7 @@ package cgroups import ( "bytes" + "errors" "fmt" "reflect" "strings" @@ -421,3 +422,38 @@ func TestFindCgroupMountpointAndRoot(t *testing.T) { } } } + +func TestGetHugePageSizeImpl(t *testing.T) { + + testCases := []struct { + inputFiles []string + outputPageSizes []string + err error + }{ + { + inputFiles: []string{"hugepages-1048576kB", "hugepages-2048kB", "hugepages-32768kB", "hugepages-64kB"}, + outputPageSizes: []string{"1GB", "2MB", "32MB", "64KB"}, + err: nil, + }, + { + inputFiles: []string{}, + outputPageSizes: []string{}, + err: nil, + }, + { + inputFiles: []string{"hugepages-a"}, + outputPageSizes: []string{}, + err: errors.New("invalid size: 'a'"), + }, + } + + for _, c := range testCases { + pageSizes, err := getHugePageSizeFromFilenames(c.inputFiles) + if len(pageSizes) != 0 && len(c.outputPageSizes) != 0 && !reflect.DeepEqual(pageSizes, c.outputPageSizes) { + t.Errorf("expected %s, got %s", c.outputPageSizes, pageSizes) + } + if err != nil && err.Error() != c.err.Error() { + t.Errorf("expected error %s, got %s", c.err, err) + } + } +}