From 681ae88e06f2acbfb3b7adf681a681c32c1d5843 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 3 Jan 2018 02:30:16 +0900 Subject: [PATCH] dbus-cgroup: simplify bus_cgroup_set_property() --- src/core/dbus-cgroup.c | 366 +++++++++++------------------------------ src/core/dbus-util.h | 80 +++++++++ 2 files changed, 174 insertions(+), 272 deletions(-) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 41a614397d..cd57cefabc 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -28,6 +28,7 @@ #include "cgroup-util.h" #include "cgroup.h" #include "dbus-cgroup.h" +#include "dbus-util.h" #include "fd-util.h" #include "fileio.h" #include "path-util.h" @@ -413,6 +414,41 @@ static int bus_cgroup_set_transient_property( return 0; } +static int bus_cgroup_set_boolean( + Unit *u, + const char *name, + bool *p, + CGroupMask mask, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + int b, r; + + assert(p); + + r = sd_bus_message_read(message, "b", &b); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + *p = b; + unit_invalidate_cgroup(u, mask); + unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b)); + } + + 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); + int bus_cgroup_set_property( Unit *u, CGroupContext *c, @@ -431,74 +467,82 @@ int bus_cgroup_set_property( flags |= UNIT_PRIVATE; - if (streq(name, "CPUAccounting")) { - int b; + if (streq(name, "CPUAccounting")) + return bus_cgroup_set_boolean(u, name, &c->cpu_accounting, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU, message, flags, error); - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; + if (streq(name, "CPUWeight")) + return bus_cgroup_set_cpu_weight(u, name, &c->cpu_weight, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->cpu_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU); - unit_write_settingf(u, flags, name, "CPUAccounting=%s", yes_no(b)); - } + if (streq(name, "StartupCPUWeight")) + return bus_cgroup_set_cpu_weight(u, name, &c->startup_cpu_weight, message, flags, error); - return 1; + if (streq(name, "CPUShares")) + return bus_cgroup_set_cpu_shares(u, name, &c->cpu_shares, message, flags, error); - } else if (STR_IN_SET(name, "CPUWeight", "StartupCPUWeight")) { - uint64_t weight; + if (streq(name, "StartupCPUShares")) + return bus_cgroup_set_cpu_shares(u, name, &c->startup_cpu_shares, message, flags, error); - r = sd_bus_message_read(message, "t", &weight); - if (r < 0) - return r; + if (streq(name, "IOAccounting")) + return bus_cgroup_set_boolean(u, name, &c->io_accounting, CGROUP_MASK_IO, message, flags, error); - if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= value out of range", name); + if (streq(name, "IOWeight")) + return bus_cgroup_set_io_weight(u, name, &c->io_weight, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (streq(name, "CPUWeight")) - c->cpu_weight = weight; - else /* "StartupCPUWeight" */ - c->startup_cpu_weight = weight; + if (streq(name, "StartupIOWeight")) + return bus_cgroup_set_io_weight(u, name, &c->startup_io_weight, message, flags, error); - unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + if (streq(name, "BlockIOAccounting")) + return bus_cgroup_set_boolean(u, name, &c->blockio_accounting, CGROUP_MASK_BLKIO, message, flags, error); - if (weight == CGROUP_WEIGHT_INVALID) - unit_write_settingf(u, flags, name, "%s=", name); - else - unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, weight); - } + if (streq(name, "BlockIOWeight")) + return bus_cgroup_set_blockio_weight(u, name, &c->blockio_weight, message, flags, error); - return 1; + if (streq(name, "StartupBlockIOWeight")) + return bus_cgroup_set_blockio_weight(u, name, &c->startup_blockio_weight, message, flags, error); - } else if (STR_IN_SET(name, "CPUShares", "StartupCPUShares")) { - uint64_t shares; + if (streq(name, "MemoryAccounting")) + return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error); - r = sd_bus_message_read(message, "t", &shares); - if (r < 0) - return r; + if (streq(name, "MemoryLow")) + return bus_cgroup_set_memory(u, name, &c->memory_low, message, flags, error); - if (!CGROUP_CPU_SHARES_IS_OK(shares)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= value out of range", name); + if (streq(name, "MemoryHigh")) + return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (streq(name, "CPUShares")) - c->cpu_shares = shares; - else /* "StartupCPUShares" */ - c->startup_cpu_shares = shares; + if (streq(name, "MemorySwapMax")) + return bus_cgroup_set_memory(u, name, &c->memory_swap_max, message, flags, error); - unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + if (streq(name, "MemoryMax")) + return bus_cgroup_set_memory(u, name, &c->memory_max, message, flags, error); - if (shares == CGROUP_CPU_SHARES_INVALID) - unit_write_settingf(u, flags, name, "%s=", name); - else - unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, shares); - } + if (streq(name, "MemoryLimit")) + return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error); - return 1; + if (streq(name, "MemoryLowScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_low, message, flags, error); - } else if (streq(name, "CPUQuotaPerSecUSec")) { + if (streq(name, "MemoryHighScale")) + 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); + + if (streq(name, "MemoryMaxScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_max, message, flags, error); + + if (streq(name, "MemoryLimitScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_limit, message, flags, error); + + if (streq(name, "TasksAccountingScale")) + return bus_cgroup_set_boolean(u, name, &c->tasks_accounting, CGROUP_MASK_PIDS, message, flags, error); + + if (streq(name, "TasksMax")) + return bus_cgroup_set_tasks_max(u, name, &c->tasks_max, message, flags, error); + + if (streq(name, "TasksMaxScale")) + return bus_cgroup_set_tasks_max_scale(u, name, &c->tasks_max, message, flags, error); + + if (streq(name, "CPUQuotaPerSecUSec")) { uint64_t u64; r = sd_bus_message_read(message, "t", &u64); @@ -524,47 +568,6 @@ int bus_cgroup_set_property( return 1; - } else if (streq(name, "IOAccounting")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->io_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_IO); - unit_write_settingf(u, flags, name, "IOAccounting=%s", yes_no(b)); - } - - return 1; - - } else if (STR_IN_SET(name, "IOWeight", "StartupIOWeight")) { - uint64_t weight; - - r = sd_bus_message_read(message, "t", &weight); - if (r < 0) - return r; - - if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= value out of range", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (streq(name, "IOWeight")) - c->io_weight = weight; - else /* "StartupIOWeight" */ - c->startup_io_weight = weight; - - unit_invalidate_cgroup(u, CGROUP_MASK_IO); - - if (weight == CGROUP_WEIGHT_INVALID) - unit_write_settingf(u, flags, name, "%s=", name); - else - unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, weight); - } - - return 1; - } else if ((iol_type = cgroup_io_limit_type_from_string(name)) >= 0) { const char *path; unsigned n = 0; @@ -735,47 +738,6 @@ int bus_cgroup_set_property( return 1; - } else if (streq(name, "BlockIOAccounting")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->blockio_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); - unit_write_settingf(u, flags, name, "BlockIOAccounting=%s", yes_no(b)); - } - - return 1; - - } else if (STR_IN_SET(name, "BlockIOWeight", "StartupBlockIOWeight")) { - uint64_t weight; - - r = sd_bus_message_read(message, "t", &weight); - if (r < 0) - return r; - - if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= value out of range", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (streq(name, "BlockIOWeight")) - c->blockio_weight = weight; - else /* "StartupBlockIOWeight" */ - c->startup_blockio_weight = weight; - - unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); - - if (weight == CGROUP_BLKIO_WEIGHT_INVALID) - unit_write_settingf(u, flags, name, "%s=", name); - else - unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, weight); - } - - return 1; - } else if (STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) { const char *path; bool read = true; @@ -963,89 +925,6 @@ int bus_cgroup_set_property( return 1; - } else if (streq(name, "MemoryAccounting")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->memory_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_settingf(u, flags, name, "MemoryAccounting=%s", yes_no(b)); - } - - return 1; - - } else if (STR_IN_SET(name, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit")) { - uint64_t v; - - r = sd_bus_message_read(message, "t", &v); - if (r < 0) - return r; - if (v <= 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (streq(name, "MemoryLow")) - c->memory_low = v; - else if (streq(name, "MemoryHigh")) - c->memory_high = v; - else if (streq(name, "MemorySwapMax")) - c->memory_swap_max = v; - else if (streq(name, "MemoryMax")) - c->memory_max = v; - else /* "MemoryLimit" */ - c->memory_limit = v; - - unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - - 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; - - } else if (STR_IN_SET(name, "MemoryLowScale", "MemoryHighScale", "MemoryMaxScale", "MemorySwapMaxScale", "MemoryLimitScale")) { - uint32_t raw; - uint64_t v; - - r = sd_bus_message_read(message, "u", &raw); - if (r < 0) - return r; - - v = physical_memory_scale(raw, UINT32_MAX); - if (v <= 0 || v == UINT64_MAX) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - const char *e; - - /* Chop off suffix */ - assert_se(e = endswith(name, "Scale")); - name = strndupa(name, e - name); - - if (streq(name, "MemoryLow")) - c->memory_low = v; - else if (streq(name, "MemoryHigh")) - c->memory_high = v; - else if (streq(name, "MemorySwapMax")) - c->memory_swap_max = v; - else if (streq(name, "MemoryMax")) - c->memory_max = v; - else /* "MemoryLimit" */ - c->memory_limit = v; - - unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); - } - - return 1; - } else if (streq(name, "DevicePolicy")) { const char *policy; CGroupDevicePolicy p; @@ -1156,63 +1035,6 @@ int bus_cgroup_set_property( return 1; - } else if (streq(name, "TasksAccounting")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->tasks_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - unit_write_settingf(u, flags, name, "TasksAccounting=%s", yes_no(b)); - } - - return 1; - - } else if (streq(name, "TasksMax")) { - uint64_t limit; - - r = sd_bus_message_read(message, "t", &limit); - if (r < 0) - return r; - if (limit <= 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->tasks_max = limit; - unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - - if (limit == (uint64_t) -1) - unit_write_setting(u, flags, name, "TasksMax=infinity"); - else - unit_write_settingf(u, flags, name, "TasksMax=%" PRIu64, limit); - } - - return 1; - - } else if (streq(name, "TasksMaxScale")) { - uint64_t limit; - uint32_t raw; - - r = sd_bus_message_read(message, "u", &raw); - if (r < 0) - return r; - - limit = system_tasks_max_scale(raw, UINT32_MAX); - if (limit <= 0 || limit >= UINT64_MAX) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->tasks_max = limit; - unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - unit_write_settingf(u, flags, name, "TasksMax=%" PRIu32 "%%", - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); - } - - return 1; - } else if (streq(name, "IPAccounting")) { int b; diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h index bef8bc35e1..8260298577 100644 --- a/src/core/dbus-util.h +++ b/src/core/dbus-util.h @@ -256,6 +256,86 @@ } \ struct __useless_struct_to_allow_trailing_semicolon__ +#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; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#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; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + 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);