]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/dbus-cgroup.c
cgroup: fix handling of TasksAccounting= property
[thirdparty/systemd.git] / src / core / dbus-cgroup.c
index 755b66ef8f5ef8965de0539b920074460a340b6b..f8d90d4b3a922c064456c7ac6ecc3db345491a00 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, "TasksAccounting"))
+                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;
@@ -691,7 +694,7 @@ int bus_cgroup_set_property(
                                                 free(a);
                                                 return -ENOMEM;
                                         }
-                                        LIST_PREPEND(device_weights,c->io_device_weights, a);
+                                        LIST_PREPEND(device_weights, c->io_device_weights, a);
                                 }
 
                                 a->weight = weight;
@@ -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;
@@ -918,7 +880,7 @@ int bus_cgroup_set_property(
                                                 free(a);
                                                 return -ENOMEM;
                                         }
-                                        LIST_PREPEND(device_weights,c->blockio_device_weights, a);
+                                        LIST_PREPEND(device_weights, c->blockio_device_weights, a);
                                 }
 
                                 a->weight = weight;
@@ -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;