chiark / gitweb /
systemctl: add new "get-cgroup-attr" to query current cgroup attribute value
[elogind.git] / src / systemctl / systemctl.c
index 003b70647efa9fc3e24c27949a5b9f4a540ade60..f3d661d2b53cd963dc8ec5fdff42ad439068a70e 100644 (file)
@@ -760,7 +760,6 @@ static int list_dependencies_get_dependencies(DBusConnection *bus, const char *n
 
         int r = 0;
         char **ret = NULL;
-        char **c;
 
         assert(bus);
         assert(name);
@@ -798,12 +797,7 @@ static int list_dependencies_get_dependencies(DBusConnection *bus, const char *n
         while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
                 const char *prop;
 
-                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
-                        log_error("Failed to parse reply.");
-                        r = -EIO;
-                        goto finish;
-                }
-
+                assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY);
                 dbus_message_iter_recurse(&sub, &sub2);
 
                 if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &prop, true) < 0) {
@@ -834,13 +828,13 @@ static int list_dependencies_get_dependencies(DBusConnection *bus, const char *n
 
                                         assert(dbus_message_iter_get_arg_type(&sub4) == DBUS_TYPE_STRING);
                                         dbus_message_iter_get_basic(&sub4, &s);
-                                        c = strv_append(ret, s);
-                                        if (c == NULL) {
-                                                r = log_oom();
+
+                                        r = strv_extend(&ret, s);
+                                        if (r < 0) {
+                                                log_oom();
                                                 goto finish;
                                         }
-                                        strv_free(ret);
-                                        ret = c;
+
                                         dbus_message_iter_next(&sub4);
                                 }
                         }
@@ -848,8 +842,9 @@ static int list_dependencies_get_dependencies(DBusConnection *bus, const char *n
         }
 finish:
         if (r < 0)
-                strv_freep(&ret);
-        *deps = ret;
+                strv_free(ret);
+        else
+                *deps = ret;
         return r;
 }
 
@@ -905,20 +900,24 @@ finish:
 }
 
 static int list_dependencies(DBusConnection *bus, char **args) {
-        int r = 0;
         _cleanup_free_ char *unit = NULL;
+        const char *u;
 
         assert(bus);
-        assert(args[1]);
 
-        unit = unit_name_mangle(args[1]);
-        if (!unit)
-                return log_oom();
+        if (args[1]) {
+                unit = unit_name_mangle(args[1]);
+                if (!unit)
+                        return log_oom();
+                u = unit;
+        } else
+                u = SPECIAL_DEFAULT_TARGET;
 
         pager_open_if_enabled();
-        printf("%s\n", unit);
-        r = list_dependencies_one(bus, unit, 0, NULL, 0);
-        return r;
+
+        puts(u);
+
+        return list_dependencies_one(bus, u, 0, NULL, 0);
 }
 
 static int dot_one_property(const char *name, const char *prop, DBusMessageIter *iter) {
@@ -2274,6 +2273,64 @@ static int set_cgroup_attr(DBusConnection *bus, char **args) {
         return 0;
 }
 
+static int get_cgroup_attr(DBusConnection *bus, char **args) {
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
+        DBusError error;
+        DBusMessageIter iter;
+        int r;
+        _cleanup_free_ char *n = NULL;
+        _cleanup_strv_free_ char **list = NULL;
+        char **a;
+
+        assert(bus);
+        assert(args);
+
+        dbus_error_init(&error);
+
+        n = unit_name_mangle(args[1]);
+        if (!n)
+                return log_oom();
+
+        m = dbus_message_new_method_call(
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "GetUnitControlGroupAttributes");
+        if (!m)
+                return log_oom();
+
+        dbus_message_iter_init_append(m, &iter);
+        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n))
+                return log_oom();
+
+        r = bus_append_strv_iter(&iter, args + 2);
+        if (r < 0)
+                return log_oom();
+
+        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+        if (!reply) {
+                log_error("Failed to issue method call: %s", bus_error_message(&error));
+                dbus_error_free(&error);
+                return -EIO;
+        }
+
+        dbus_message_iter_init(reply, &iter);
+        r = bus_parse_strv_iter(&iter, &list);
+        if (r < 0) {
+                log_error("Failed to parse value list.");
+                return r;
+        }
+
+        STRV_FOREACH(a, list) {
+                if (endswith(*a, "\n"))
+                        fputs(*a, stdout);
+                else
+                        puts(*a);
+        }
+
+        return 0;
+}
+
 typedef struct ExecStatusInfo {
         char *name;
 
@@ -4277,12 +4334,14 @@ static int systemctl_help(void) {
                "  help [NAME...|PID...]           Show manual for one or more units\n"
                "  reset-failed [NAME...]          Reset failed state for all, one, or more\n"
                "                                  units\n"
-               "  set-cgroup [NAME] [CGROUP...]   Add unit to a control group\n"
-               "  unset-cgroup [NAME] [CGROUP...] Remove unit from a control group\n"
+               "  get-cgroup-attr [NAME] [ATTR] ...\n"
+               "                                  Get control group attrubute\n"
                "  set-cgroup-attr [NAME] [ATTR] [VALUE] ...\n"
                "                                  Set control group attribute\n"
                "  unset-cgroup-attr [NAME] [ATTR...]\n"
                "                                  Unset control group attribute\n"
+               "  set-cgroup [NAME] [CGROUP...]   Add unit to a control group\n"
+               "  unset-cgroup [NAME] [CGROUP...] Remove unit from a control group\n"
                "  load [NAME...]                  Load one or more units\n"
                "  list-dependencies [NAME]        Recursively show units which are required\n"
                "                                  or wanted by this unit\n\n"
@@ -5262,6 +5321,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
                 { "isolate",               EQUAL, 2, start_unit        },
                 { "set-cgroup",            MORE,  2, set_cgroup        },
                 { "unset-cgroup",          MORE,  2, set_cgroup        },
+                { "get-cgroup-attr",       MORE,  2, get_cgroup_attr   },
                 { "set-cgroup-attr",       MORE,  2, set_cgroup_attr   },
                 { "unset-cgroup-attr",     MORE,  2, set_cgroup        },
                 { "kill",                  MORE,  2, kill_unit         },
@@ -5301,7 +5361,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
                 { "unmask",                MORE,  2, enable_unit       },
                 { "link",                  MORE,  2, enable_unit       },
                 { "switch-root",           MORE,  2, switch_root       },
-                { "list-dependencies",     EQUAL, 2, list_dependencies },
+                { "list-dependencies",     LESS,  2, list_dependencies },
         };
 
         int left;