From: Yu Watanabe Date: Fri, 9 Mar 2018 10:34:50 +0000 (+0900) Subject: core/cgroup: accepts MemorySwapMax=0 (#8366) X-Git-Tag: v239~563 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=906bdbf5e79870f6997fc0925348f9412f3c5f3e;p=thirdparty%2Fsystemd.git core/cgroup: accepts MemorySwapMax=0 (#8366) Also, this moves two macros from dbus-util.h to dbus-cgroup.c, as they are only used in dbus-cgroup.c. Fixes #8363. --- diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index f480664613c..fb962ed4744 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -446,14 +446,129 @@ static int bus_cgroup_set_boolean( return 1; } -static BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight, CGROUP_MASK_CPU, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID,); -static BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_OK, CGROUP_CPU_SHARES_INVALID,); -static BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID,); -static BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEIGHT_IS_OK, CGROUP_BLKIO_WEIGHT_INVALID,); -static BUS_DEFINE_SET_CGROUP_WEIGHT(memory, CGROUP_MASK_MEMORY, , CGROUP_LIMIT_MAX, "infinity"); -static BUS_DEFINE_SET_CGROUP_WEIGHT(tasks_max, CGROUP_MASK_PIDS, , (uint64_t) -1, "infinity"); -static BUS_DEFINE_SET_CGROUP_SCALE(memory, CGROUP_MASK_MEMORY, physical_memory_scale); -static BUS_DEFINE_SET_CGROUP_SCALE(tasks_max, CGROUP_MASK_PIDS, system_tasks_max_scale); +#define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val) \ + static int bus_cgroup_set_##function( \ + Unit *u, \ + const char *name, \ + uint64_t *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + uint64_t v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, "t", &v); \ + if (r < 0) \ + return r; \ + \ + if (!check(v)) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Value specified in %s is out of range", name); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + *p = v; \ + unit_invalidate_cgroup(u, (mask)); \ + \ + if (v == (val)) \ + unit_write_settingf(u, flags, name, \ + "%s=", name); \ + else \ + unit_write_settingf(u, flags, name, \ + "%s=%" PRIu64, name, v); \ + } \ + \ + return 1; \ + } + +#define BUS_DEFINE_SET_CGROUP_LIMIT(function, mask, scale, minimum) \ + static int bus_cgroup_set_##function( \ + Unit *u, \ + const char *name, \ + uint64_t *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + uint64_t v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, "t", &v); \ + if (r < 0) \ + return r; \ + \ + if (v < minimum) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Value specified in %s is out of range", name); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + *p = v; \ + unit_invalidate_cgroup(u, (mask)); \ + \ + if (v == CGROUP_LIMIT_MAX) \ + unit_write_settingf(u, flags, name, \ + "%s=infinity", name); \ + else \ + unit_write_settingf(u, flags, name, \ + "%s=%" PRIu64, name, v); \ + } \ + \ + return 1; \ + } \ + static int bus_cgroup_set_##function##_scale( \ + Unit *u, \ + const char *name, \ + uint64_t *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + uint64_t v; \ + uint32_t raw; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, "u", &raw); \ + if (r < 0) \ + return r; \ + \ + v = scale(raw, UINT32_MAX); \ + if (v < minimum || v >= UINT64_MAX) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Value specified in %s is out of range", name); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + const char *e; \ + \ + *p = v; \ + unit_invalidate_cgroup(u, (mask)); \ + \ + /* Chop off suffix */ \ + assert_se(e = endswith(name, "Scale")); \ + name = strndupa(name, e - name); \ + \ + unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, \ + (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); \ + } \ + \ + return 1; \ + } + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" +BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight, CGROUP_MASK_CPU, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID); +BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_OK, CGROUP_CPU_SHARES_INVALID); +BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID); +BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEIGHT_IS_OK, CGROUP_BLKIO_WEIGHT_INVALID); +BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1); +BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0); +BUS_DEFINE_SET_CGROUP_LIMIT(tasks_max, CGROUP_MASK_PIDS, system_tasks_max_scale, 1); +#pragma GCC diagnostic pop int bus_cgroup_set_property( Unit *u, @@ -516,7 +631,7 @@ int bus_cgroup_set_property( return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error); if (streq(name, "MemorySwapMax")) - return bus_cgroup_set_memory(u, name, &c->memory_swap_max, message, flags, error); + return bus_cgroup_set_swap(u, name, &c->memory_swap_max, message, flags, error); if (streq(name, "MemoryMax")) return bus_cgroup_set_memory(u, name, &c->memory_max, message, flags, error); @@ -531,7 +646,7 @@ int bus_cgroup_set_property( return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error); if (streq(name, "MemorySwapMaxScale")) - return bus_cgroup_set_memory_scale(u, name, &c->memory_swap_max, message, flags, error); + return bus_cgroup_set_swap_scale(u, name, &c->memory_swap_max, message, flags, error); if (streq(name, "MemoryMaxScale")) return bus_cgroup_set_memory_scale(u, name, &c->memory_max, message, flags, error); diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h index ab8ba9dd28b..b65f7b3adc9 100644 --- a/src/core/dbus-util.h +++ b/src/core/dbus-util.h @@ -249,84 +249,6 @@ return 1; \ } -#define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val, str) \ - int bus_cgroup_set_##function( \ - Unit *u, \ - const char *name, \ - uint64_t *p, \ - sd_bus_message *message, \ - UnitWriteFlags flags, \ - sd_bus_error *error) { \ - \ - uint64_t v; \ - int r; \ - \ - assert(p); \ - \ - r = sd_bus_message_read(message, "t", &v); \ - if (r < 0) \ - return r; \ - \ - if (!check(v)) \ - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ - "Value specified in %s is out of range", name); \ - \ - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ - *p = v; \ - unit_invalidate_cgroup(u, (mask)); \ - \ - if (v == (val)) \ - unit_write_settingf(u, flags, name, \ - "%s=" str, name); \ - else \ - unit_write_settingf(u, flags, name, \ - "%s=%" PRIu64, name, v); \ - } \ - \ - return 1; \ - } - -#define BUS_DEFINE_SET_CGROUP_SCALE(function, mask, scale) \ - int bus_cgroup_set_##function##_scale( \ - Unit *u, \ - const char *name, \ - uint64_t *p, \ - sd_bus_message *message, \ - UnitWriteFlags flags, \ - sd_bus_error *error) { \ - \ - uint64_t v; \ - uint32_t raw; \ - int r; \ - \ - assert(p); \ - \ - r = sd_bus_message_read(message, "u", &raw); \ - if (r < 0) \ - return r; \ - \ - v = scale(raw, UINT32_MAX); \ - if (v <= 0 || v >= UINT64_MAX) \ - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ - "Value specified in %s is out of range", name); \ - \ - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ - const char *e; \ - \ - *p = v; \ - unit_invalidate_cgroup(u, (mask)); \ - \ - /* Chop off suffix */ \ - assert_se(e = endswith(name, "Scale")); \ - name = strndupa(name, e - name); \ - \ - unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, \ - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); \ - } \ - \ - return 1; \ - } - int bus_set_transient_mode_t(Unit *u, const char *name, mode_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_set_transient_unsigned(Unit *u, const char *name, unsigned *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_set_transient_user(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 1e3416c40b7..f2f9267b920 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -3345,7 +3345,8 @@ int config_parse_memory_limit( } else bytes = physical_memory_scale(r, 100U); - if (bytes <= 0 || bytes >= UINT64_MAX) { + if (bytes >= UINT64_MAX || + (bytes <= 0 && !streq(lvalue, "MemorySwapMax"))) { log_syntax(unit, LOG_ERR, filename, line, 0, "Memory limit '%s' out of range. Ignoring.", rvalue); return 0; }