Merge pull request #16265 from Werkov/fix-16248

cgroup: Parse infinity properly for memory protections
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-06-25 09:25:18 +02:00 committed by GitHub
commit e60d3b13df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 6 deletions

View File

@ -3427,13 +3427,12 @@ int config_parse_memory_limit(
uint64_t bytes = CGROUP_LIMIT_MAX;
int r;
if (STR_IN_SET(lvalue, "DefaultMemoryLow",
"DefaultMemoryMin",
"MemoryLow",
"MemoryMin"))
if (isempty(rvalue) && STR_IN_SET(lvalue, "DefaultMemoryLow",
"DefaultMemoryMin",
"MemoryLow",
"MemoryMin"))
bytes = CGROUP_LIMIT_MIN;
if (!isempty(rvalue) && !streq(rvalue, "infinity")) {
else if (!isempty(rvalue) && !streq(rvalue, "infinity")) {
r = parse_permille(rvalue);
if (r < 0) {

View File

@ -27,6 +27,9 @@
#include "tmpfile-util.h"
#include "user-util.h"
/* Nontrivial value serves as a placeholder to check that parsing function (didn't) change it */
#define CGROUP_LIMIT_DUMMY 3
static int test_unit_file_get_set(void) {
int r;
Hashmap *h;
@ -773,6 +776,62 @@ static void test_unit_dump_config_items(void) {
unit_dump_config_items(stdout);
}
static void test_config_parse_memory_limit(void) {
/* int config_parse_memory_limit(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) */
CGroupContext c;
struct limit_test {
const char *limit;
const char *value;
uint64_t *result;
uint64_t expected;
} limit_tests[]= {
{ "MemoryMin", "", &c.memory_min, CGROUP_LIMIT_MIN },
{ "MemoryMin", "0", &c.memory_min, CGROUP_LIMIT_MIN },
{ "MemoryMin", "10", &c.memory_min, 10 },
{ "MemoryMin", "infinity", &c.memory_min, CGROUP_LIMIT_MAX },
{ "MemoryLow", "", &c.memory_low, CGROUP_LIMIT_MIN },
{ "MemoryLow", "0", &c.memory_low, CGROUP_LIMIT_MIN },
{ "MemoryLow", "10", &c.memory_low, 10 },
{ "MemoryLow", "infinity", &c.memory_low, CGROUP_LIMIT_MAX },
{ "MemoryHigh", "", &c.memory_high, CGROUP_LIMIT_MAX },
{ "MemoryHigh", "0", &c.memory_high, CGROUP_LIMIT_DUMMY },
{ "MemoryHigh", "10", &c.memory_high, 10 },
{ "MemoryHigh", "infinity", &c.memory_high, CGROUP_LIMIT_MAX },
{ "MemoryMax", "", &c.memory_max, CGROUP_LIMIT_MAX },
{ "MemoryMax", "0", &c.memory_max, CGROUP_LIMIT_DUMMY },
{ "MemoryMax", "10", &c.memory_max, 10 },
{ "MemoryMax", "infinity", &c.memory_max, CGROUP_LIMIT_MAX },
};
size_t i;
int r;
for (i = 0; i < ELEMENTSOF(limit_tests); i++) {
c.memory_min = CGROUP_LIMIT_DUMMY;
c.memory_low = CGROUP_LIMIT_DUMMY;
c.memory_high = CGROUP_LIMIT_DUMMY;
c.memory_max = CGROUP_LIMIT_DUMMY;
r = config_parse_memory_limit(NULL, "fake", 1, "section", 1,
limit_tests[i].limit, 1,
limit_tests[i].value, &c, NULL);
log_info("%s=%s\t%"PRIu64"==%"PRIu64"\n",
limit_tests[i].limit, limit_tests[i].value,
*limit_tests[i].result, limit_tests[i].expected);
assert_se(r >= 0);
assert_se(*limit_tests[i].result == limit_tests[i].expected);
}
}
int main(int argc, char *argv[]) {
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
int r;
@ -793,6 +852,7 @@ int main(int argc, char *argv[]) {
test_config_parse_pass_environ();
TEST_REQ_RUNNING_SYSTEMD(test_install_printf());
test_unit_dump_config_items();
test_config_parse_memory_limit();
return r;
}