[systemd-devel] [PATCH v2] systemd-analyze: filter dot output

Łukasz Stelmach stlman at poczta.fm
Tue Mar 26 12:44:26 PDT 2013


Make "systemd-analyze dot" output only lines with units matching
given glob(7) patterns. With one pattern either unit may match
the pattern. With two patterns units need to match the patterns
respectively. Without any patterns all relationships are printed.
---

This filtering isn't as powerfull as regular expressions but it does
its job well.

 man/systemd-analyze.xml       |  8 +++++++-
 src/analyze/systemd-analyze.c | 26 +++++++++++++++++++-------
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index 533bc42..bf22544 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -58,7 +58,7 @@
                         <command>systemd-analyze <arg choice="opt" rep="repeat">OPTIONS</arg> plot <arg choice="opt">> file.svg</arg></command>
                 </cmdsynopsis>
                 <cmdsynopsis>
-                        <command>systemd-analyze <arg choice="opt" rep="repeat">OPTIONS</arg> dot </command>
+                        <command>systemd-analyze <arg choice="opt" rep="repeat">OPTIONS</arg> dot <arg choice="opt">pattern <arg choice="opt">pattern</arg></arg> </command>
                 </cmdsynopsis>
         </refsynopsisdiv>
 
@@ -104,6 +104,12 @@
                 is passed the generated graph will show both ordering
                 and requirement dependencies.</para>
 
+                <para>Optional patterns may be given to limit the
+                output. With one pattern all lines for which at least
+                one of the unit names matches the pattern shall be
+                printed. With two patterns, the lines for which the
+                units match patterns respectively.</para>
+
                 <para>If no command is passed <command>systemd-analyze
                 time</command> is implied.</para>
 
diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c
index 01bf55e..62d14e5 100644
--- a/src/analyze/systemd-analyze.c
+++ b/src/analyze/systemd-analyze.c
@@ -25,6 +25,7 @@
 #include <getopt.h>
 #include <locale.h>
 #include <sys/utsname.h>
+#include <fnmatch.h>
 
 #include "install.h"
 #include "log.h"
@@ -578,7 +579,7 @@ static int analyze_time(DBusConnection *bus) {
         return 0;
 }
 
-static int graph_one_property(const char *name, const char *prop, DBusMessageIter *iter) {
+static int graph_one_property(const char *name, const char *prop, DBusMessageIter *iter, const char* nameg, const char* sg) {
 
         static const char * const colors[] = {
                 "Requires",              "[color=\"black\"]",
@@ -624,14 +625,17 @@ static int graph_one_property(const char *name, const char *prop, DBusMessageIte
 
                         assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
                         dbus_message_iter_get_basic(&sub, &s);
-                        printf("\t\"%s\"->\"%s\" %s;\n", name, s, c);
+                        if ((nameg == NULL && sg == NULL) ||
+                            (nameg != NULL && sg == NULL && (fnmatch(nameg, name, 0) == 0 || fnmatch(nameg, s, 0) == 0)) ||
+                            (nameg != NULL && sg != NULL && (fnmatch(nameg, name, 0) == 0 && fnmatch(sg, s, 0) == 0)))
+                                printf("\t\"%s\"->\"%s\" %s;\n", name, s, c);
                 }
         }
 
         return 0;
 }
 
-static int graph_one(DBusConnection *bus, const struct unit_info *u) {
+static int graph_one(DBusConnection *bus, const struct unit_info *u, const char *nameg, const char *sg) {
         _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
         const char *interface = "org.freedesktop.systemd1.Unit";
         int r;
@@ -675,7 +679,7 @@ static int graph_one(DBusConnection *bus, const struct unit_info *u) {
                 }
 
                 dbus_message_iter_recurse(&sub2, &sub3);
-                r = graph_one_property(u->id, prop, &sub3);
+                r = graph_one_property(u->id, prop, &sub3, nameg, sg);
                 if (r < 0)
                         return r;
         }
@@ -683,10 +687,12 @@ static int graph_one(DBusConnection *bus, const struct unit_info *u) {
         return 0;
 }
 
-static int dot(DBusConnection *bus) {
+static int dot(DBusConnection *bus, char* av[], int oi) {
         _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
         DBusMessageIter iter, sub;
         int r;
+        const char *nameg = NULL;
+        const char *sg = NULL;
 
         r = bus_method_call_with_reply(
                         bus,
@@ -707,6 +713,12 @@ static int dot(DBusConnection *bus) {
                 return -EIO;
         }
 
+        if (av[oi] != NULL)
+                nameg = av[oi++];
+
+        if (av[oi] != NULL)
+                sg = av[oi++];
+
         printf("digraph systemd {\n");
 
         for (dbus_message_iter_recurse(&iter, &sub);
@@ -718,7 +730,7 @@ static int dot(DBusConnection *bus) {
                 if (r < 0)
                         return -EIO;
 
-                r = graph_one(bus, &u);
+                r = graph_one(bus, &u, nameg, sg);
                 if (r < 0)
                         return r;
         }
@@ -844,7 +856,7 @@ int main(int argc, char *argv[]) {
         else if (streq(argv[optind], "plot"))
                 r = analyze_plot(bus);
         else if (streq(argv[optind], "dot"))
-                r = dot(bus);
+                r = dot(bus, argv, optind+1);
         else
                 log_error("Unknown operation '%s'.", argv[optind]);
 
-- 
1.8.1.5



More information about the systemd-devel mailing list