Make "systemd-analyze dot" output only lines matching a regular expression passed on the command line. Without the regular expression print everything. ---
A graph created with the full output of dot is completely incomprehensible on a regular system. It thus makes perfect sense IMHO to add filtering to systemd-analyze instead of trying to use sed/grep/awk/perl to filter the dependencies but preserving the first and last line with the braces. This, of course, is the first attempt so any comments are more than welcome. src/analyze/systemd-analyze.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c index 01bf55e..bddbeda 100644 --- a/src/analyze/systemd-analyze.c +++ b/src/analyze/systemd-analyze.c @@ -25,6 +25,9 @@ #include <getopt.h> #include <locale.h> #include <sys/utsname.h> +#include <sys/types.h> +#include <regex.h> +#include <string.h> #include "install.h" #include "log.h" @@ -578,7 +581,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, regex_t* regexp) { static const char * const colors[] = { "Requires", "[color=\"black\"]", @@ -591,6 +594,7 @@ static int graph_one_property(const char *name, const char *prop, DBusMessageIte "After", "[color=\"green\"]" }; + char buf[1024]; const char *c = NULL; unsigned i; @@ -624,14 +628,16 @@ 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); + snprintf(buf, sizeof(buf), "\t\"%s\"->\"%s\" %s;", name, s, c); + if (regexp == NULL || regexec(regexp, buf, 0, NULL, 0) == 0) + puts(buf); } } return 0; } -static int graph_one(DBusConnection *bus, const struct unit_info *u) { +static int graph_one(DBusConnection *bus, const struct unit_info *u, regex_t* regexp) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; const char *interface = "org.freedesktop.systemd1.Unit"; int r; @@ -675,7 +681,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, regexp); if (r < 0) return r; } @@ -683,10 +689,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* regexp_s) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; DBusMessageIter iter, sub; int r; + regex_t regexp; + int use_regexp = 0; r = bus_method_call_with_reply( bus, @@ -707,6 +715,16 @@ static int dot(DBusConnection *bus) { return -EIO; } + memset(®exp, 0, sizeof(regexp)); + if (regexp_s != NULL) { + r = regcomp(®exp, regexp_s, REG_NOSUB); + if (r != 0) { + log_error("Invalid regular expression."); + return -EINVAL; + } + use_regexp = 1; + } + printf("digraph systemd {\n"); for (dbus_message_iter_recurse(&iter, &sub); @@ -718,13 +736,16 @@ static int dot(DBusConnection *bus) { if (r < 0) return -EIO; - r = graph_one(bus, &u); + r = graph_one(bus, &u, use_regexp ? ®exp : NULL); if (r < 0) return r; } printf("}\n"); + if (use_regexp) + regfree(®exp); + log_info(" Color legend: black = Requires\n" " dark blue = Requisite\n" " dark grey = Wants\n" @@ -844,7 +865,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 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel