You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
5.2 KiB
123 lines
5.2 KiB
From 8946c35e525c2a14b12ed425f11af152e37d8583 Mon Sep 17 00:00:00 2001 |
|
From: Michal Sekletar <msekleta@redhat.com> |
|
Date: Fri, 10 Apr 2015 15:56:52 +0200 |
|
Subject: [PATCH] bus-util: be more verbose if dbus job fails |
|
|
|
Users might have hard time figuring out why exactly their systemctl request |
|
failed. If dbus job fails try to figure out more details about failure by |
|
examining Result property of the service. |
|
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=1016680 |
|
|
|
Cherry-picked from: d5cad22109749faffb7563e4b2a3a728486d47b5 |
|
Resolves: #1016680 |
|
--- |
|
src/libsystemd/sd-bus/bus-util.c | 79 +++++++++++++++++++++++++++++--- |
|
1 file changed, 72 insertions(+), 7 deletions(-) |
|
|
|
diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c |
|
index b0a5a7592a..2e6d889620 100644 |
|
--- a/src/libsystemd/sd-bus/bus-util.c |
|
+++ b/src/libsystemd/sd-bus/bus-util.c |
|
@@ -30,6 +30,7 @@ |
|
#include "path-util.h" |
|
#include "missing.h" |
|
#include "set.h" |
|
+#include "unit-name.h" |
|
|
|
#include "sd-bus.h" |
|
#include "bus-error.h" |
|
@@ -1690,6 +1691,68 @@ static int bus_process_wait(sd_bus *bus) { |
|
} |
|
} |
|
|
|
+static int bus_job_get_service_result(BusWaitForJobs *d, char **result) { |
|
+ _cleanup_free_ char *dbus_path = NULL; |
|
+ |
|
+ assert(d); |
|
+ assert(d->name); |
|
+ assert(result); |
|
+ |
|
+ dbus_path = unit_dbus_path_from_name(d->name); |
|
+ if (!dbus_path) |
|
+ return -ENOMEM; |
|
+ |
|
+ return sd_bus_get_property_string(d->bus, |
|
+ "org.freedesktop.systemd1", |
|
+ dbus_path, |
|
+ "org.freedesktop.systemd1.Service", |
|
+ "Result", |
|
+ NULL, |
|
+ result); |
|
+} |
|
+ |
|
+static const struct { |
|
+ const char *result, *explanation; |
|
+} explanations [] = { |
|
+ { "resources", "configured resource limit was exceeded" }, |
|
+ { "timeout", "timeout was exceeded" }, |
|
+ { "exit-code", "control process exited with error code" }, |
|
+ { "signal", "fatal signal was delivered to the control process" }, |
|
+ { "core-dump", "fatal signal was delivered to the control process. Core dumped" }, |
|
+ { "watchdog", "service failed to send watchdog ping" }, |
|
+ { "start-limit", "start of the service was attempted too often too quickly" } |
|
+}; |
|
+ |
|
+static void log_job_error_with_service_result(const char* service, const char *result) { |
|
+ unsigned i; |
|
+ _cleanup_free_ char *service_shell_quoted = NULL; |
|
+ |
|
+ assert(service); |
|
+ assert(result); |
|
+ |
|
+ service_shell_quoted = shell_maybe_quote(service); |
|
+ |
|
+ for (i = 0; i < ELEMENTSOF(explanations); ++i) |
|
+ if (streq(result, explanations[i].result)) |
|
+ break; |
|
+ |
|
+ if (i < ELEMENTSOF(explanations)) |
|
+ log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n", |
|
+ service, |
|
+ explanations[i].explanation, |
|
+ strna(service_shell_quoted)); |
|
+ else |
|
+ log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n", |
|
+ service, |
|
+ strna(service_shell_quoted)); |
|
+ |
|
+ /* For some results maybe additional explanation is required */ |
|
+ if (streq_ptr(result, "start-limit")) |
|
+ log_info("To force a start please invoke \"systemctl reset-failed %s\" followed by \"systemctl start %s\" again.", |
|
+ strna(service_shell_quoted), |
|
+ strna(service_shell_quoted)); |
|
+} |
|
+ |
|
static int check_wait_response(BusWaitForJobs *d, bool quiet) { |
|
int r = 0; |
|
|
|
@@ -1709,15 +1772,17 @@ static int check_wait_response(BusWaitForJobs *d, bool quiet) { |
|
else if (streq(d->result, "unsupported")) |
|
log_error("Operation on or unit type of %s not supported on this system.", strna(d->name)); |
|
else if (!streq(d->result, "done") && !streq(d->result, "skipped")) { |
|
- _cleanup_free_ char *quoted = NULL; |
|
+ if (d->name) { |
|
+ int q; |
|
+ _cleanup_free_ char *result = NULL; |
|
|
|
- if (d->name) |
|
- quoted = shell_maybe_quote(d->name); |
|
+ q = bus_job_get_service_result(d, &result); |
|
+ if (q < 0) |
|
+ log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name); |
|
|
|
- if (quoted) |
|
- log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xe' for details.", d->name, quoted); |
|
- else |
|
- log_error("Job failed. See 'journalctl -xe' for details."); |
|
+ log_job_error_with_service_result(d->name, result); |
|
+ } else |
|
+ log_error("Job failed. See \"journalctl -xe\" for details."); |
|
} |
|
} |
|
|
|
|