dbus: make more cgroup attributes runtime settable

This commit is contained in:
Lennart Poettering 2013-06-27 21:50:35 +02:00
parent 8e2af47840
commit b42defe3b8
5 changed files with 129 additions and 8 deletions

2
TODO
View File

@ -28,6 +28,8 @@ Fedora 19:
Features:
* when reloading configuration, apply new cgroup configuration
* implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory, fair scheduling?)
* handle jointly mounted controllers correctly

View File

@ -152,50 +152,120 @@ int bus_cgroup_set_property(
assert(i);
if (streq(name, "CPUAccounting")) {
dbus_bool_t b;
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN)
return -EINVAL;
if (mode != UNIT_CHECK) {
dbus_bool_t b;
dbus_message_iter_get_basic(i, &b);
c->cpu_accounting = b;
unit_write_drop_in(u, mode, "cpu-accounting", b ? "CPUAccounting=yes" : "CPUAccounting=no");
unit_write_drop_in_private_section(u, mode, "cpu-accounting", b ? "CPUAccounting=yes" : "CPUAccounting=no");
}
return 1;
} else if (streq(name, "CPUShares")) {
uint64_t u64;
unsigned long ul;
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64)
return -EINVAL;
dbus_message_iter_get_basic(i, &u64);
ul = (unsigned long) u64;
if (u64 <= 0 || u64 != (uint64_t) ul)
return -EINVAL;
if (mode != UNIT_CHECK) {
char buf[sizeof("CPUShares=") + DECIMAL_STR_MAX(ul)];
c->cpu_shares = ul;
sprintf(buf, "CPUShares=%lu", ul);
unit_write_drop_in_private_section(u, mode, "cpu-shares", buf);
}
return 1;
} else if (streq(name, "BlockIOAccounting")) {
dbus_bool_t b;
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN)
return -EINVAL;
if (mode != UNIT_CHECK) {
dbus_bool_t b;
dbus_message_iter_get_basic(i, &b);
c->blockio_accounting = b;
unit_write_drop_in(u, mode, "block-io-accounting", b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no");
unit_write_drop_in_private_section(u, mode, "block-io-accounting", b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no");
}
return 1;
} else if (streq(name, "BlockIOWeight")) {
uint64_t u64;
unsigned long ul;
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64)
return -EINVAL;
dbus_message_iter_get_basic(i, &u64);
ul = (unsigned long) u64;
if (u64 < 10 || u64 > 1000)
return -EINVAL;
if (mode != UNIT_CHECK) {
char buf[sizeof("BlockIOWeight=") + DECIMAL_STR_MAX(ul)];
c->cpu_shares = ul;
sprintf(buf, "BlockIOWeight=%lu", ul);
unit_write_drop_in_private_section(u, mode, "blockio-weight", buf);
}
return 1;
} else if (streq(name, "MemoryAccounting")) {
dbus_bool_t b;
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN)
return -EINVAL;
if (mode != UNIT_CHECK) {
dbus_bool_t b;
dbus_message_iter_get_basic(i, &b);
c->blockio_accounting = b;
unit_write_drop_in(u, mode, "memory-accounting", b ? "MemoryAccounting=yes" : "MemoryAccounting=no");
c->memory_accounting = b;
unit_write_drop_in_private_section(u, mode, "memory-accounting", b ? "MemoryAccounting=yes" : "MemoryAccounting=no");
}
return 1;
} else if (streq(name, "MemoryLimit") || streq(name, "MemorySoftLimit")) {
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64)
return -EINVAL;
if (mode != UNIT_CHECK) {
uint64_t limit;
char buf[sizeof("MemorySoftLimit=") + DECIMAL_STR_MAX(limit)];
dbus_message_iter_get_basic(i, &limit);
if (streq(name, "MemoryLimit")) {
c->memory_limit = limit;
sprintf(buf, "MemoryLimit=%" PRIu64, limit);
unit_write_drop_in_private_section(u, mode, "memory-limit", buf);
} else {
c->memory_soft_limit = limit;
sprintf(buf, "MemorySoftLimit=%" PRIu64, limit);
unit_write_drop_in_private_section(u, mode, "memory-soft-limit", buf);
}
}
return 1;
}
return 0;
}

View File

@ -2691,6 +2691,8 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co
int r;
assert(u);
assert(name);
assert(data);
if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
return 0;
@ -2703,6 +2705,23 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co
return write_string_file_atomic_label(q, data);
}
int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
_cleanup_free_ char *ndata = NULL;
assert(u);
assert(name);
assert(data);
if (!UNIT_VTABLE(u)->private_section)
return -EINVAL;
ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
if (!ndata)
return -ENOMEM;
return unit_write_drop_in(u, mode, name, ndata);
}
int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
_cleanup_free_ char *p = NULL, *q = NULL;
int r;

View File

@ -590,6 +590,7 @@ ExecContext *unit_get_exec_context(Unit *u) _pure_;
CGroupContext *unit_get_cgroup_context(Unit *u) _pure_;
int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data);
int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data);
int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name);
int unit_kill_context(Unit *u, KillContext *c, bool sigkill, pid_t main_pid, pid_t control_pid, bool main_pid_alien);

View File

@ -3632,6 +3632,35 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) {
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "b", &sub) ||
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &b))
return log_oom();
} else if (streq(field, "MemoryLimit") || streq(field, "MemorySoftLimit")) {
off_t bytes;
uint64_t u;
r = parse_bytes(eq, &bytes);
if (r < 0) {
log_error("Failed to parse bytes specification %s", assignment);
return -EINVAL;
}
u = bytes;
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "t", &sub) ||
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT64, &u))
return log_oom();
} else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
uint64_t u;
r = safe_atou64(eq, &u);
if (r < 0) {
log_error("Failed to parse %s value %s.", field, eq);
return -EINVAL;
}
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "t", &sub) ||
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT64, &u))
return log_oom();
} else {
log_error("Unknown assignment %s.", assignment);
return -EINVAL;