From 685d807958e952e8d34d1678cbd0cef545afe2d7 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 23 Apr 2019 12:56:51 +0200 Subject: [PATCH] Fix handling of unlimited (-1) ulimit values Addresses https://github.com/moby/moby/issues/39125 Signed-off-by: Sebastiaan van Stijn --- ulimit.go | 9 +++++++-- ulimit_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/ulimit.go b/ulimit.go index 5ac7fd8..fca0400 100644 --- a/ulimit.go +++ b/ulimit.go @@ -96,8 +96,13 @@ func ParseUlimit(val string) (*Ulimit, error) { return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1]) } - if soft > *hard { - return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard) + if *hard != -1 { + if soft == -1 { + return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: soft: -1 (unlimited), hard: %d", *hard) + } + if soft > *hard { + return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard) + } } return &Ulimit{Name: parts[0], Soft: soft, Hard: *hard}, nil diff --git a/ulimit_test.go b/ulimit_test.go index 902e023..0095855 100644 --- a/ulimit_test.go +++ b/ulimit_test.go @@ -2,6 +2,7 @@ package units import ( "fmt" + "math" "strconv" "testing" ) @@ -50,6 +51,52 @@ func TestParseUlimitHardLessThanSoft(t *testing.T) { if _, err := ParseUlimit("nofile=1024:1"); err == nil { t.Fatal("expected error on hard limit less than soft limit") } + if _, err := ParseUlimit("nofile=-1:1024"); err == nil { + t.Fatal("expected error on hard limit less than soft limit") + } +} + +func TestParseUlimitUnlimited(t *testing.T) { + tt := []struct { + in string + expected Ulimit + }{ + { + in: "nofile=-1", + expected: Ulimit{Name: "nofile", Soft: -1, Hard: -1}, + }, + { + in: "nofile=1024", + expected: Ulimit{Name: "nofile", Soft: 1024, Hard: 1024}, + }, + { + in: "nofile=1024:-1", + expected: Ulimit{Name: "nofile", Soft: 1024, Hard: -1}, + }, + { + in: "nofile=-1:-1", + expected: Ulimit{Name: "nofile", Soft: -1, Hard: -1}, + }, + } + + for _, tc := range tt { + t.Run(tc.in, func(t *testing.T) { + u, err := ParseUlimit(tc.in) + if err != nil { + t.Fatalf("unexpected error when setting unlimited hard limit: %v", err) + } + if u.Name != tc.expected.Name { + t.Fatalf("unexpected name. expected %s, got %s", tc.expected.Name, u.Name) + } + if u.Soft != tc.expected.Soft { + t.Fatalf("unexpected soft limit. expected %d, got %d", tc.expected.Soft, u.Soft) + } + if u.Hard != tc.expected.Hard { + t.Fatalf("unexpected hard limit. expected %d, got %d", tc.expected.Hard, u.Hard) + } + + }) + } } func TestParseUlimitInvalidValueType(t *testing.T) { @@ -99,6 +146,7 @@ func TestGetRlimit(t *testing.T) { {Ulimit{"rttime", 55, 102}, Rlimit{rlimitRttime, 55, 102}}, {Ulimit{"sigpending", 14, 20}, Rlimit{rlimitSigpending, 14, 20}}, {Ulimit{"stack", 1, 1}, Rlimit{rlimitStack, 1, 1}}, + {Ulimit{"stack", -1, -1}, Rlimit{rlimitStack, math.MaxUint64, math.MaxUint64}}, } for _, te := range tt {