From 087b953dc5d179f2515dac99c350e2bdbfa1cda7 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Mon, 14 Mar 2016 17:45:12 +1100 Subject: [PATCH 1/2] libcontainer: cgroups: deal with unlimited case for pids.max Make sure we don't error out collecting statistics for cases where pids.max == "max". In that case, we can use a limit of 0 which means "unlimited". In addition, change the name of the stats attribute (Max) to mirror the name of the resources attribute in the spec (Limit) so that it's consistent internally. Signed-off-by: Aleksa Sarai --- libcontainer/cgroups/fs/pids.go | 14 ++++++++++++-- libcontainer/cgroups/stats.go | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/libcontainer/cgroups/fs/pids.go b/libcontainer/cgroups/fs/pids.go index 8f187a59ea7..f1e37205518 100644 --- a/libcontainer/cgroups/fs/pids.go +++ b/libcontainer/cgroups/fs/pids.go @@ -4,6 +4,7 @@ package fs import ( "fmt" + "path/filepath" "strconv" "github.com/opencontainers/runc/libcontainer/cgroups" @@ -52,12 +53,21 @@ func (s *PidsGroup) GetStats(path string, stats *cgroups.Stats) error { return fmt.Errorf("failed to parse pids.current - %s", err) } - max, err := getCgroupParamUint(path, "pids.max") + maxString, err := getCgroupParamString(path, "pids.max") if err != nil { return fmt.Errorf("failed to parse pids.max - %s", err) } + // Default if pids.max == "max" is 0 -- which represents "no limit". + var max uint64 + if maxString != "max" { + max, err = parseUint(maxString, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse pids.max - unable to parse %q as a uint from Cgroup file %q", maxString, filepath.Join(path, "pids.max")) + } + } + stats.PidsStats.Current = current - stats.PidsStats.Max = max + stats.PidsStats.Limit = max return nil } diff --git a/libcontainer/cgroups/stats.go b/libcontainer/cgroups/stats.go index 7eba44148a4..1b280fc71c1 100644 --- a/libcontainer/cgroups/stats.go +++ b/libcontainer/cgroups/stats.go @@ -55,7 +55,7 @@ type PidsStats struct { // number of pids in the cgroup Current uint64 `json:"current,omitempty"` // active pids hard limit - Max uint64 `json:"max,omitempty"` + Limit uint64 `json:"limit,omitempty"` } type BlkioStatEntry struct { From a6d5179f601f1f5b8b2e98589df46ce8e6c7f5c9 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Mon, 14 Mar 2016 18:08:47 +1100 Subject: [PATCH 2/2] libcontainer: cgroups: add tests for pids.max == "max" Signed-off-by: Aleksa Sarai --- libcontainer/cgroups/fs/pids_test.go | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/libcontainer/cgroups/fs/pids_test.go b/libcontainer/cgroups/fs/pids_test.go index d4e3555f567..10671247ba3 100644 --- a/libcontainer/cgroups/fs/pids_test.go +++ b/libcontainer/cgroups/fs/pids_test.go @@ -81,7 +81,31 @@ func TestPidsStats(t *testing.T) { t.Fatalf("Expected %d, got %d for pids.current", 1337, stats.PidsStats.Current) } - if stats.PidsStats.Max != maxLimited { - t.Fatalf("Expected %d, got %d for pids.max", maxLimited, stats.PidsStats.Max) + if stats.PidsStats.Limit != maxLimited { + t.Fatalf("Expected %d, got %d for pids.max", maxLimited, stats.PidsStats.Limit) + } +} + +func TestPidsStatsUnlimited(t *testing.T) { + helper := NewCgroupTestUtil("pids", t) + defer helper.cleanup() + + helper.writeFileContents(map[string]string{ + "pids.current": strconv.Itoa(4096), + "pids.max": "max", + }) + + pids := &PidsGroup{} + stats := *cgroups.NewStats() + if err := pids.GetStats(helper.CgroupPath, &stats); err != nil { + t.Fatal(err) + } + + if stats.PidsStats.Current != 4096 { + t.Fatalf("Expected %d, got %d for pids.current", 4096, stats.PidsStats.Current) + } + + if stats.PidsStats.Limit != 0 { + t.Fatalf("Expected %d, got %d for pids.max", 0, stats.PidsStats.Limit) } }