summaryrefslogtreecommitdiff
path: root/src/core/dbus-unit.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-01-18 01:44:41 +0100
committerLennart Poettering <lennart@poettering.net>2013-01-18 01:44:41 +0100
commitd2a30975827b3447ca0fd5a2c06ec1ff15ce7f0f (patch)
tree65d593f4f9d129354ab081b6476ce46a596dd7a6 /src/core/dbus-unit.c
parentd54110d11d5ea3381cfdd129356b91669b547216 (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.c89
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;