diff --git a/init/README.md b/init/README.md index b0a73b946..b45da214a 100644 --- a/init/README.md +++ b/init/README.md @@ -506,6 +506,7 @@ Commands _resource_ is best specified using its text representation ('cpu', 'rtio', etc or 'RLIM_CPU', 'RLIM_RTIO', etc). It also may be specified as the int value that the resource enum corresponds to. + _cur_ and _max_ can be 'unlimited' or '-1' to indicate an infinite rlimit. `start ` > Start a service running if it is not already running. diff --git a/init/rlimit_parser.cpp b/init/rlimit_parser.cpp index fe1d6a724..1e0754ac0 100644 --- a/init/rlimit_parser.cpp +++ b/init/rlimit_parser.cpp @@ -65,12 +65,18 @@ Result> ParseRlimit(const std::vector& args) } rlimit limit; - if (!ParseUint(args[2], &limit.rlim_cur)) { + if (args[2] == "-1" || args[2] == "unlimited") { + limit.rlim_cur = RLIM_INFINITY; + } else if (!ParseUint(args[2], &limit.rlim_cur)) { return Error() << "Could not parse soft limit '" << args[2] << "'"; } - if (!ParseUint(args[3], &limit.rlim_max)) { + + if (args[3] == "-1" || args[3] == "unlimited") { + limit.rlim_max = RLIM_INFINITY; + } else if (!ParseUint(args[3], &limit.rlim_max)) { return Error() << "Could not parse hard limit '" << args[3] << "'"; } + return {resource, limit}; } diff --git a/init/rlimit_parser_test.cpp b/init/rlimit_parser_test.cpp index f3f9eb4e3..659ba8acb 100644 --- a/init/rlimit_parser_test.cpp +++ b/init/rlimit_parser_test.cpp @@ -49,58 +49,58 @@ void TestRlimitFailure(std::vector input, const std::string& expect TEST(rlimit, RlimitSuccess) { const std::vector, std::pair>> - inputs_and_results = { - {{"cpu", "10", "10"}, {0, {10, 10}}}, - {{"fsize", "10", "10"}, {1, {10, 10}}}, - {{"data", "10", "10"}, {2, {10, 10}}}, - {{"stack", "10", "10"}, {3, {10, 10}}}, - {{"core", "10", "10"}, {4, {10, 10}}}, - {{"rss", "10", "10"}, {5, {10, 10}}}, - {{"nproc", "10", "10"}, {6, {10, 10}}}, - {{"nofile", "10", "10"}, {7, {10, 10}}}, - {{"memlock", "10", "10"}, {8, {10, 10}}}, - {{"as", "10", "10"}, {9, {10, 10}}}, - {{"locks", "10", "10"}, {10, {10, 10}}}, - {{"sigpending", "10", "10"}, {11, {10, 10}}}, - {{"msgqueue", "10", "10"}, {12, {10, 10}}}, - {{"nice", "10", "10"}, {13, {10, 10}}}, - {{"rtprio", "10", "10"}, {14, {10, 10}}}, - {{"rttime", "10", "10"}, {15, {10, 10}}}, + inputs_and_results = { + {{"cpu", "10", "10"}, {0, {10, 10}}}, + {{"fsize", "10", "10"}, {1, {10, 10}}}, + {{"data", "10", "10"}, {2, {10, 10}}}, + {{"stack", "10", "10"}, {3, {10, 10}}}, + {{"core", "10", "10"}, {4, {10, 10}}}, + {{"rss", "10", "10"}, {5, {10, 10}}}, + {{"nproc", "10", "10"}, {6, {10, 10}}}, + {{"nofile", "10", "10"}, {7, {10, 10}}}, + {{"memlock", "10", "10"}, {8, {10, 10}}}, + {{"as", "10", "10"}, {9, {10, 10}}}, + {{"locks", "10", "10"}, {10, {10, 10}}}, + {{"sigpending", "10", "10"}, {11, {10, 10}}}, + {{"msgqueue", "10", "10"}, {12, {10, 10}}}, + {{"nice", "10", "10"}, {13, {10, 10}}}, + {{"rtprio", "10", "10"}, {14, {10, 10}}}, + {{"rttime", "10", "10"}, {15, {10, 10}}}, - {{"RLIM_CPU", "10", "10"}, {0, {10, 10}}}, - {{"RLIM_FSIZE", "10", "10"}, {1, {10, 10}}}, - {{"RLIM_DATA", "10", "10"}, {2, {10, 10}}}, - {{"RLIM_STACK", "10", "10"}, {3, {10, 10}}}, - {{"RLIM_CORE", "10", "10"}, {4, {10, 10}}}, - {{"RLIM_RSS", "10", "10"}, {5, {10, 10}}}, - {{"RLIM_NPROC", "10", "10"}, {6, {10, 10}}}, - {{"RLIM_NOFILE", "10", "10"}, {7, {10, 10}}}, - {{"RLIM_MEMLOCK", "10", "10"}, {8, {10, 10}}}, - {{"RLIM_AS", "10", "10"}, {9, {10, 10}}}, - {{"RLIM_LOCKS", "10", "10"}, {10, {10, 10}}}, - {{"RLIM_SIGPENDING", "10", "10"}, {11, {10, 10}}}, - {{"RLIM_MSGQUEUE", "10", "10"}, {12, {10, 10}}}, - {{"RLIM_NICE", "10", "10"}, {13, {10, 10}}}, - {{"RLIM_RTPRIO", "10", "10"}, {14, {10, 10}}}, - {{"RLIM_RTTIME", "10", "10"}, {15, {10, 10}}}, + {{"RLIM_CPU", "10", "10"}, {0, {10, 10}}}, + {{"RLIM_FSIZE", "10", "10"}, {1, {10, 10}}}, + {{"RLIM_DATA", "10", "10"}, {2, {10, 10}}}, + {{"RLIM_STACK", "10", "10"}, {3, {10, 10}}}, + {{"RLIM_CORE", "10", "10"}, {4, {10, 10}}}, + {{"RLIM_RSS", "10", "10"}, {5, {10, 10}}}, + {{"RLIM_NPROC", "10", "10"}, {6, {10, 10}}}, + {{"RLIM_NOFILE", "10", "10"}, {7, {10, 10}}}, + {{"RLIM_MEMLOCK", "10", "10"}, {8, {10, 10}}}, + {{"RLIM_AS", "10", "10"}, {9, {10, 10}}}, + {{"RLIM_LOCKS", "10", "10"}, {10, {10, 10}}}, + {{"RLIM_SIGPENDING", "10", "10"}, {11, {10, 10}}}, + {{"RLIM_MSGQUEUE", "10", "10"}, {12, {10, 10}}}, + {{"RLIM_NICE", "10", "10"}, {13, {10, 10}}}, + {{"RLIM_RTPRIO", "10", "10"}, {14, {10, 10}}}, + {{"RLIM_RTTIME", "10", "10"}, {15, {10, 10}}}, - {{"0", "10", "10"}, {0, {10, 10}}}, - {{"1", "10", "10"}, {1, {10, 10}}}, - {{"2", "10", "10"}, {2, {10, 10}}}, - {{"3", "10", "10"}, {3, {10, 10}}}, - {{"4", "10", "10"}, {4, {10, 10}}}, - {{"5", "10", "10"}, {5, {10, 10}}}, - {{"6", "10", "10"}, {6, {10, 10}}}, - {{"7", "10", "10"}, {7, {10, 10}}}, - {{"8", "10", "10"}, {8, {10, 10}}}, - {{"9", "10", "10"}, {9, {10, 10}}}, - {{"10", "10", "10"}, {10, {10, 10}}}, - {{"11", "10", "10"}, {11, {10, 10}}}, - {{"12", "10", "10"}, {12, {10, 10}}}, - {{"13", "10", "10"}, {13, {10, 10}}}, - {{"14", "10", "10"}, {14, {10, 10}}}, - {{"15", "10", "10"}, {15, {10, 10}}}, - }; + {{"0", "10", "10"}, {0, {10, 10}}}, + {{"1", "10", "10"}, {1, {10, 10}}}, + {{"2", "10", "10"}, {2, {10, 10}}}, + {{"3", "10", "10"}, {3, {10, 10}}}, + {{"4", "10", "10"}, {4, {10, 10}}}, + {{"5", "10", "10"}, {5, {10, 10}}}, + {{"6", "10", "10"}, {6, {10, 10}}}, + {{"7", "10", "10"}, {7, {10, 10}}}, + {{"8", "10", "10"}, {8, {10, 10}}}, + {{"9", "10", "10"}, {9, {10, 10}}}, + {{"10", "10", "10"}, {10, {10, 10}}}, + {{"11", "10", "10"}, {11, {10, 10}}}, + {{"12", "unlimited", "10"}, {12, {RLIM_INFINITY, 10}}}, + {{"13", "-1", "10"}, {13, {RLIM_INFINITY, 10}}}, + {{"14", "10", "unlimited"}, {14, {10, RLIM_INFINITY}}}, + {{"15", "10", "-1"}, {15, {10, RLIM_INFINITY}}}, + }; for (const auto& [input, expected_result] : inputs_and_results) { TestRlimitSuccess(input, expected_result); @@ -109,12 +109,16 @@ TEST(rlimit, RlimitSuccess) { TEST(rlimit, RlimitFailure) { const std::vector, std::string>> inputs_and_results = { - {{"-4", "10", "10"}, "Resource '-4' below the minimum resource value '0'"}, - {{"100", "10", "10"}, "Resource '100' over the maximum resource value '16'"}, - {{"bad_string", "10", "10"}, "Could not parse resource 'bad_string'"}, - {{"RLIM_", "10", "10"}, "Could not parse resource 'RLIM_'"}, - {{"cpu", "abc", "10"}, "Could not parse soft limit 'abc'"}, - {{"cpu", "10", "abc"}, "Could not parse hard limit 'abc'"}, + {{"-4", "10", "10"}, "Resource '-4' below the minimum resource value '0'"}, + {{"100", "10", "10"}, "Resource '100' over the maximum resource value '16'"}, + {{"bad_string", "10", "10"}, "Could not parse resource 'bad_string'"}, + {{"RLIM_", "10", "10"}, "Could not parse resource 'RLIM_'"}, + {{"cpu", "abc", "10"}, "Could not parse soft limit 'abc'"}, + {{"cpu", "10", "abc"}, "Could not parse hard limit 'abc'"}, + {{"cpu", "unlimit", "10"}, "Could not parse soft limit 'unlimit'"}, + {{"cpu", "10", "unlimit"}, "Could not parse hard limit 'unlimit'"}, + {{"cpu", "-2", "10"}, "Could not parse soft limit '-2'"}, + {{"cpu", "10", "-2"}, "Could not parse hard limit '-2'"}, }; for (const auto& [input, expected_result] : inputs_and_results) {