dbus-cgroup: simplify bus_cgroup_set_property()

This commit is contained in:
Yu Watanabe 2018-01-03 02:30:16 +09:00
parent fffbc1dc7f
commit 681ae88e06
2 changed files with 174 additions and 272 deletions

View 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);
} 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;

View file

@ -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);