diff options
author | Lennart Poettering <lennart@poettering.net> | 2024-06-20 16:22:32 +0200 |
---|---|---|
committer | Mike Yuan <me@yhndnzj.com> | 2024-06-20 19:03:44 +0200 |
commit | 8ea918697af13b956f3c9f4605e0a7410343fc27 (patch) | |
tree | 92a0dcf9f6b6c4d03f325f251f52cd752211e97b | |
parent | systemctl-show: show Status{Bus,Varlink}Error in status (diff) | |
download | systemd-8ea918697af13b956f3c9f4605e0a7410343fc27.tar.xz systemd-8ea918697af13b956f3c9f4605e0a7410343fc27.zip |
busctl: send BUSERROR= to caller via sd_notify() protocol
varlinkctl has this nice feature that it sends the varlink error it gets
via sd_notify() to the caller. With previous commits this information
is collected and exposed in "systemctl status".
Let's make sure we can provide the same in busctl: also propagate errors
the same way.
With this we can comprehensively close #6073
-rw-r--r-- | src/busctl/busctl.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 5061afe6c9..4a5fac7606 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -159,6 +159,14 @@ static int acquire_bus(bool set_monitor, sd_bus **ret) { return 0; } +static void notify_bus_error(const sd_bus_error *error) { + + if (!sd_bus_error_is_set(error)) + return; + + (void) sd_notifyf(/* unset_environment= */ false, "BUSERROR=%s", error->name); +} + static int list_bus_names(int argc, char **argv, void *userdata) { _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -459,6 +467,7 @@ static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *p "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL); if (r < 0) { + notify_bus_error(&error); printf("%sFailed to introspect object %s of service %s: %s%s\n", ansi_highlight_red(), path, service, bus_error_message(&error, r), @@ -996,9 +1005,11 @@ static int introspect(int argc, char **argv, void *userdata) { r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply_xml, NULL); - if (r < 0) + if (r < 0) { + notify_bus_error(&error); return log_error_errno(r, "Failed to introspect object %s of service %s: %s", argv[2], argv[1], bus_error_message(&error, r)); + } r = sd_bus_message_read(reply_xml, "s", &xml); if (r < 0) @@ -1032,9 +1043,11 @@ static int introspect(int argc, char **argv, void *userdata) { r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", m->interface); - if (r < 0) + if (r < 0) { + notify_bus_error(&error); return log_error_errno(r, "Failed to get all properties on interface %s: %s", m->interface, bus_error_message(&error, r)); + } r = sd_bus_message_enter_container(reply, 'a', "{sv}"); if (r < 0) @@ -1305,9 +1318,11 @@ static int monitor(int argc, char **argv, int (*dump)(sd_bus_message *m, FILE *f return bus_log_create_error(r); r = sd_bus_call(bus, message, arg_timeout, &error, NULL); - if (r < 0) + if (r < 0) { + notify_bus_error(&error); return log_error_errno(r, "Call to org.freedesktop.DBus.Monitoring.BecomeMonitor failed: %s", bus_error_message(&error, r)); + } r = sd_bus_get_unique_name(bus, &unique_name); if (r < 0) @@ -2076,8 +2091,10 @@ static int call(int argc, char **argv, void *userdata) { } r = sd_bus_call(bus, m, arg_timeout, &error, &reply); - if (r < 0) + if (r < 0) { + notify_bus_error(&error); return log_error_errno(r, "Call failed: %s", bus_error_message(&error, r)); + } r = sd_bus_message_is_empty(reply); if (r < 0) @@ -2180,10 +2197,12 @@ static int get_property(int argc, char **argv, void *userdata) { r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "Get", &error, &reply, "ss", argv[3], *i); - if (r < 0) + if (r < 0) { + notify_bus_error(&error); return log_error_errno(r, "Failed to get property %s on interface %s: %s", *i, argv[3], bus_error_message(&error, r)); + } r = sd_bus_message_peek_type(reply, &type, &contents); if (r < 0) @@ -2267,10 +2286,12 @@ static int set_property(int argc, char **argv, void *userdata) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Too many parameters for signature."); r = sd_bus_call(bus, m, arg_timeout, &error, NULL); - if (r < 0) + if (r < 0) { + notify_bus_error(&error); return log_error_errno(r, "Failed to set property %s on interface %s: %s", argv[4], argv[3], bus_error_message(&error, r)); + } return 0; } |