diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-01-18 01:44:41 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-01-18 01:44:41 +0100 |
commit | d2a30975827b3447ca0fd5a2c06ec1ff15ce7f0f (patch) | |
tree | 65d593f4f9d129354ab081b6476ce46a596dd7a6 /src/core/dbus-unit.c | |
parent | d54110d11d5ea3381cfdd129356b91669b547216 (diff) |
systemctl: add new "get-cgroup-attr" to query current cgroup attribute value
Also adds a pair of bus calls for this to the daemon.
Diffstat (limited to 'src/core/dbus-unit.c')
-rw-r--r-- | src/core/dbus-unit.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index c7bf043764..d2f8ebf760 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -502,6 +502,27 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn reply = dbus_message_new_method_return(message); if (!reply) goto oom; + } else if (streq_ptr(dbus_message_get_member(message), "GetControlGroupAttributes")) { + DBusMessageIter iter; + _cleanup_strv_free_ char **list = NULL; + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status"); + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + r = bus_unit_cgroup_attribute_get(u, &iter, &list); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + if (bus_append_strv_iter(&iter, list) < 0) + goto oom; + } else if (streq_ptr(dbus_message_get_member(message), "SetControlGroupAttributes")) { DBusMessageIter iter; @@ -965,6 +986,74 @@ int bus_unit_cgroup_unset(Unit *u, DBusMessageIter *iter) { return 0; } +int bus_unit_cgroup_attribute_get(Unit *u, DBusMessageIter *iter, char ***_result) { + _cleanup_strv_free_ char **l = NULL, **result = NULL; + char **name; + int r; + + assert(u); + assert(iter); + assert(_result); + + if (!unit_get_exec_context(u)) + return -EINVAL; + + r = bus_parse_strv_iter(iter, &l); + if (r < 0) + return r; + + STRV_FOREACH(name, l) { + _cleanup_free_ char *controller = NULL; + const char *dot; + CGroupAttribute *a; + CGroupBonding *b; + + dot = strchr(*name, '.'); + if (dot) { + controller = strndup(*name, dot - *name); + if (!controller) + return -ENOMEM; + } + + /* First attempt, read the value from the kernel */ + b = cgroup_bonding_find_list(u->cgroup_bondings, controller); + if (b) { + _cleanup_free_ char *p = NULL, *v = NULL; + + r = cg_get_path(b->controller, b->path, *name, &p); + if (r < 0) + return r; + + r = read_full_file(p, &v, NULL); + if (r >= 0) { + r = strv_extend(&result, v); + if (r < 0) + return r; + + continue; + } else if (r != -ENOENT) + return r; + } + + /* If that didn't work, read our cached value */ + a = cgroup_attribute_find_list(u->cgroup_attributes, NULL, *name); + if (a) { + r = strv_extend(&result, a->value); + if (r < 0) + return r; + + continue; + } + + return -ENOENT; + } + + *_result = result; + result = NULL; + + return 0; +} + int bus_unit_cgroup_attribute_set(Unit *u, DBusMessageIter *iter) { DBusMessageIter sub, sub2; int r; |