diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index c8d0b4743b..9f313d76f1 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -93,20 +93,21 @@
been started at what time, highlighting the time they
spent on initialization.
- systemd-analyze dot
- Generate textual dependency graph description in dot
- format for further processing with the GraphViz
+ systemd-analyze dot Generate
+ textual dependency graph description in dot format for
+ further processing with the GraphViz
dot1
tool. Use a command line like systemd-analyze
- dot | dot -Tsvg > systemd.svg to generate
- a graphical dependency tree. Unless
+ dot | dot -Tsvg > systemd.svg to generate a
+ graphical dependency tree. Unless
or
is passed the generated graph will show both ordering
- and requirement dependencies.
-
- Optional patterns may be given at the end. The
- relationship is printed if any of these matches either
- lefthand or righthand node.
+ and requirement dependencies. Optional pattern
+ globbing style specifications
+ (e.g. *.target) may be given at
+ the end. A unit dependency is included in the graph if
+ any of these patterns match either the origin or
+ destination node.If no command is passed systemd-analyze
time is implied.
@@ -191,6 +192,23 @@
code otherwise.
+
+ Examples
+
+ This plots all dependencies of any unit whose
+ name starts with "avahi-daemon.":
+
+ $ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg
+$ eog avahi.svg
+
+ This plots the dependencies between all known target units:
+
+ systemd-analyze dot --to-pattern='*.target' --from-patter='*.target' | dot -Tsvg > targets.svg
+$ eog targets.svg
+
+
+
+
See Also
diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c
index ec579282e7..e648a4449f 100644
--- a/src/analyze/systemd-analyze.c
+++ b/src/analyze/systemd-analyze.c
@@ -626,40 +626,48 @@ static int graph_one_property(const char *name, const char *prop, DBusMessageIte
dbus_message_iter_next(&sub)) {
const char *s;
char **p;
- bool match_found = true;
+ bool match_found;
assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
dbus_message_iter_get_basic(&sub, &s);
- STRV_FOREACH(p, arg_dot_from_patterns) {
+ if (!strv_isempty(arg_dot_from_patterns)) {
match_found = false;
- if (fnmatch(*p, name, 0) == 0) {
- match_found = true;
- break;
- }
- }
- if (!match_found)
- continue;
- STRV_FOREACH(p, arg_dot_to_patterns) {
- match_found = false;
- if (fnmatch(*p, s, 0) == 0) {
- match_found = true;
- break;
- }
- }
- if (!match_found)
- continue;
+ STRV_FOREACH(p, arg_dot_from_patterns)
+ if (fnmatch(*p, name, 0) == 0) {
+ match_found = true;
+ break;
+ }
- STRV_FOREACH(p, patterns) {
- match_found = false;
- if (fnmatch(*p, name, 0) == 0 || fnmatch(*p, s, 0) == 0) {
- match_found = true;
- break;
- }
+ if (!match_found)
+ continue;
+ }
+
+ if (!strv_isempty(arg_dot_to_patterns)) {
+ match_found = false;
+
+ STRV_FOREACH(p, arg_dot_to_patterns)
+ if (fnmatch(*p, s, 0) == 0) {
+ match_found = true;
+ break;
+ }
+
+ if (!match_found)
+ continue;
+ }
+
+ if (!strv_isempty(patterns)) {
+ match_found = false;
+
+ STRV_FOREACH(p, patterns)
+ if (fnmatch(*p, name, 0) == 0 || fnmatch(*p, s, 0) == 0) {
+ match_found = true;
+ break;
+ }
+ if (!match_found)
+ continue;
}
- if (!match_found)
- continue;
printf("\t\"%s\"->\"%s\" %s;\n", name, s, c);
}