#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"
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,
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);
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;
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;
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;
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;
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;
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;