summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-06-25 09:25:18 +0200
committerGitHub <noreply@github.com>2020-06-25 09:25:18 +0200
commite60d3b13df2559d644e9ce44f5296b4cc3cc45f1 (patch)
treeb12d16841731df0da2f6dd76e08a68d59a6ed436
parentfd7c7fc8eefeaebee5c52d2bb436a8fffea3a3c9 (diff)
parentd184fb39b680afb23b778f9ea9fd19b894f86e80 (diff)
downloadsystemd-e60d3b13df2559d644e9ce44f5296b4cc3cc45f1.tar.gz
Merge pull request #16265 from Werkov/fix-16248
cgroup: Parse infinity properly for memory protections
-rw-r--r--src/core/load-fragment.c11
-rw-r--r--src/test/test-load-fragment.c60
2 files changed, 65 insertions, 6 deletions
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 4aaba1b31f..09065ccb36 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -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) {
diff --git a/src/test/test-load-fragment.c b/src/test/test-load-fragment.c
index 7de286436d..0293d1cd0f 100644
--- a/src/test/test-load-fragment.c
+++ b/src/test/test-load-fragment.c
@@ -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;
}