]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dbus-cgroup: simplify bus_cgroup_set_property() 7759/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 2 Jan 2018 17:30:16 +0000 (02:30 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 2 Jan 2018 17:33:16 +0000 (02:33 +0900)
src/core/dbus-cgroup.c
src/core/dbus-util.h

index 41a614397d81b27f3d6238b24583d21236ed0496..cd57cefabc1896aaf175d5fbd2e7bf03677daf22 100644 (file)
@@ -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);
+
+        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);
 
-        } else if (streq(name, "CPUQuotaPerSecUSec")) {
+        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;
 
index bef8bc35e19845b45fddaf11e588547ef7e18d91..8260298577adcaa1e0da9a00cf7f2c9ff494b423 100644 (file)
         }                                                               \
         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);