9fc0f6
From 2b7fc0e2a0a680fe61041e569eda50f06c3f8768 Mon Sep 17 00:00:00 2001
9fc0f6
From: Lukas Nykryn <lnykryn@redhat.com>
9fc0f6
Date: Mon, 28 Jul 2014 18:18:58 +0200
9fc0f6
Subject: [PATCH] cgls: fix running with -M option
9fc0f6
9fc0f6
systemd-machined doesn't store cgroup path in a state file anymore.
9fc0f6
Let's figure it out from the scope.
9fc0f6
9fc0f6
Resolves: #1085455
9fc0f6
---
9fc0f6
 Makefile.am     |  8 +++++-
9fc0f6
 src/cgls/cgls.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
9fc0f6
 2 files changed, 91 insertions(+), 2 deletions(-)
9fc0f6
9fc0f6
diff --git a/Makefile.am b/Makefile.am
9fc0f6
index fa2fba6..a9fb792 100644
9fc0f6
--- a/Makefile.am
9fc0f6
+++ b/Makefile.am
9fc0f6
@@ -1830,8 +1830,14 @@ systemd_reply_password_LDADD = \
9fc0f6
 systemd_cgls_SOURCES = \
9fc0f6
 	src/cgls/cgls.c
9fc0f6
 
9fc0f6
+systemd_cgls_CFLAGS = \
9fc0f6
+	$(AM_CFLAGS) \
9fc0f6
+	$(DBUS_CFLAGS)
9fc0f6
+
9fc0f6
 systemd_cgls_LDADD = \
9fc0f6
-	libsystemd-shared.la
9fc0f6
+	libsystemd-shared.la \
9fc0f6
+	libsystemd-dbus.la \
9fc0f6
+	libudev.la
9fc0f6
 
9fc0f6
 # ------------------------------------------------------------------------------
9fc0f6
 systemd_cgtop_SOURCES = \
9fc0f6
diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c
9fc0f6
index c689b5c..f678657 100644
9fc0f6
--- a/src/cgls/cgls.c
9fc0f6
+++ b/src/cgls/cgls.c
9fc0f6
@@ -19,6 +19,7 @@
9fc0f6
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
9fc0f6
 ***/
9fc0f6
 
9fc0f6
+#include <dbus/dbus.h>
9fc0f6
 #include <limits.h>
9fc0f6
 #include <stdio.h>
9fc0f6
 #include <unistd.h>
9fc0f6
@@ -35,6 +36,8 @@
9fc0f6
 #include "build.h"
9fc0f6
 #include "output-mode.h"
9fc0f6
 #include "fileio.h"
9fc0f6
+#include "dbus-common.h"
9fc0f6
+#include "unit-name.h"
9fc0f6
 
9fc0f6
 static bool arg_no_pager = false;
9fc0f6
 static bool arg_kernel_threads = false;
9fc0f6
@@ -127,6 +130,10 @@ int main(int argc, char *argv[]) {
9fc0f6
         int r = 0, retval = EXIT_FAILURE;
9fc0f6
         int output_flags;
9fc0f6
         char _cleanup_free_ *root = NULL;
9fc0f6
+        DBusConnection *bus = NULL;
9fc0f6
+        DBusError error;
9fc0f6
+
9fc0f6
+        dbus_error_init(&error);
9fc0f6
 
9fc0f6
         log_parse_environment();
9fc0f6
         log_open();
9fc0f6
@@ -147,6 +154,14 @@ int main(int argc, char *argv[]) {
9fc0f6
                 }
9fc0f6
         }
9fc0f6
 
9fc0f6
+        bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
9fc0f6
+
9fc0f6
+        if (!bus) {
9fc0f6
+                printf("Failed to get D-Bus connection: %s", error.message);
9fc0f6
+                retval = EXIT_FAILURE;
9fc0f6
+                goto finish;
9fc0f6
+        }
9fc0f6
+
9fc0f6
         output_flags =
9fc0f6
                 arg_all * OUTPUT_SHOW_ALL |
9fc0f6
                 (arg_full > 0) * OUTPUT_FULL_WIDTH;
9fc0f6
@@ -189,8 +204,67 @@ int main(int argc, char *argv[]) {
9fc0f6
                 } else {
9fc0f6
                         if (arg_machine) {
9fc0f6
                                 char *m;
9fc0f6
+                                const char *cgroup;
9fc0f6
+                                const char *property = "ControlGroup";
9fc0f6
+                                const char *interface = "org.freedesktop.systemd1.Scope";
9fc0f6
+                                _cleanup_free_ char *scope = NULL;
9fc0f6
+                                _cleanup_free_ char *path = NULL;
9fc0f6
+                                _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
9fc0f6
+                                DBusMessageIter iter, sub;
9fc0f6
+
9fc0f6
                                 m = strappenda("/run/systemd/machines/", arg_machine);
9fc0f6
-                                r = parse_env_file(m, NEWLINE, "CGROUP", &root, NULL);
9fc0f6
+                                r = parse_env_file(m, NEWLINE, "SCOPE", &scope, NULL);
9fc0f6
+
9fc0f6
+                                if (r < 0) {
9fc0f6
+                                        log_error("Failed to get machine path: %s", strerror(-r));
9fc0f6
+                                        goto finish;
9fc0f6
+                                }
9fc0f6
+
9fc0f6
+                                path = unit_dbus_path_from_name(scope);
9fc0f6
+                                if (!path) {
9fc0f6
+                                        r = log_oom();
9fc0f6
+                                        goto finish;
9fc0f6
+                                }
9fc0f6
+
9fc0f6
+                                r = bus_method_call_with_reply(
9fc0f6
+                                                bus,
9fc0f6
+                                                "org.freedesktop.systemd1",
9fc0f6
+                                                path,
9fc0f6
+                                                "org.freedesktop.DBus.Properties",
9fc0f6
+                                                "Get",
9fc0f6
+                                                &reply,
9fc0f6
+                                                &error,
9fc0f6
+                                                DBUS_TYPE_STRING, &interface,
9fc0f6
+                                                DBUS_TYPE_STRING, &property,
9fc0f6
+                                                DBUS_TYPE_INVALID);
9fc0f6
+                                if (r < 0) {
9fc0f6
+                                        log_error("Failed to query ControlGroup: %s", bus_error(&error, r));
9fc0f6
+                                        dbus_error_free(&error);
9fc0f6
+                                        goto finish;
9fc0f6
+                                }
9fc0f6
+
9fc0f6
+                                if (!dbus_message_iter_init(reply, &iter) ||
9fc0f6
+                                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
9fc0f6
+                                        log_error("Failed to parse reply.");
9fc0f6
+                                        r = -EINVAL;
9fc0f6
+                                        goto finish;
9fc0f6
+                                }
9fc0f6
+
9fc0f6
+                                dbus_message_iter_recurse(&iter, &sub);
9fc0f6
+                                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
9fc0f6
+                                        log_error("Failed to parse reply.");
9fc0f6
+                                        r = -EINVAL;
9fc0f6
+                                        goto finish;
9fc0f6
+                                }
9fc0f6
+
9fc0f6
+                                dbus_message_iter_get_basic(&sub, &cgroup);
9fc0f6
+
9fc0f6
+                                root = strdup(cgroup);
9fc0f6
+                                if (!root) {
9fc0f6
+                                        r = log_oom();
9fc0f6
+                                        goto finish;
9fc0f6
+                                }
9fc0f6
+
9fc0f6
                         } else
9fc0f6
                                 r = cg_get_root_path(&root);
9fc0f6
                         if (r < 0) {
9fc0f6
@@ -211,6 +285,15 @@ int main(int argc, char *argv[]) {
9fc0f6
                 retval = EXIT_SUCCESS;
9fc0f6
 
9fc0f6
 finish:
9fc0f6
+
9fc0f6
+        if (bus) {
9fc0f6
+                dbus_connection_flush(bus);
9fc0f6
+                dbus_connection_close(bus);
9fc0f6
+                dbus_connection_unref(bus);
9fc0f6
+        }
9fc0f6
+
9fc0f6
+        dbus_error_free(&error);
9fc0f6
+        dbus_shutdown();
9fc0f6
         pager_close();
9fc0f6
 
9fc0f6
         return retval;