The caller may not want all DBus error conditions to be turned into libvirt errors, so provide a way for the caller to get back the full DBusError object. They can then check the errors and only report those that they consider to be fatal. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/util/virdbus.c | 46 ++++++++++++++++++++++++++++++++++++---------- src/util/virdbus.h | 5 ++++- src/util/virsystemd.c | 2 ++ 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/util/virdbus.c b/src/util/virdbus.c index d208646..1eaac23 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1386,6 +1386,7 @@ int virDBusCreateReply(DBusMessage **reply, * @conn: a DBus connection * @call: pointer to a message to send * @replyout: pointer to receive reply message, or NULL + * @error: pointer to receive error message * * This invokes a method encoded in @call on a remote * service on the DBus bus @conn. The optional @replyout @@ -1393,31 +1394,43 @@ int virDBusCreateReply(DBusMessage **reply, * call. The virDBusMethodReply method can be used to * decode the return values. * + * If @error is NULL then a libvirt error will be raised + * when a DBus error is received and the return value will + * be -1. If @error is non-NULL then any DBus error will + * be saved into that object and the return value will + * be 0. + * * Returns 0 on success, or -1 upon error */ int virDBusCall(DBusConnection *conn, DBusMessage *call, - DBusMessage **replyout) + DBusMessage **replyout, + DBusError *error) { DBusMessage *reply = NULL; - DBusError error; + DBusError localerror; int ret = -1; - dbus_error_init(&error); + if (!error) + dbus_error_init(&localerror); if (!(reply = dbus_connection_send_with_reply_and_block(conn, call, VIR_DBUS_METHOD_CALL_TIMEOUT_MILLIS, - &error))) { - virReportDBusServiceError(error.message ? error.message : "unknown error", - error.name); + error ? error : &localerror))) { + if (error) + ret = 0; + else + virReportDBusServiceError(localerror.message ? localerror.message : "unknown error", + localerror.name); goto cleanup; } ret = 0; cleanup: - dbus_error_free(&error); + if (!error) + dbus_error_free(&localerror); if (reply) { if (ret == 0 && replyout) *replyout = reply; @@ -1452,10 +1465,20 @@ int virDBusCall(DBusConnection *conn, * as variadic args. See virDBusCreateMethodV for a * description of this parameter. * - * Returns: 0 on success, -1 on error + * + * If @error is NULL then a libvirt error will be raised + * when a DBus error is received and the return value will + * be -1. If @error is non-NULL then any DBus error will + * be saved into that object and the return value will + * be 0. If an error occurs while encoding method args + * the return value will always be -1 regardless of whether + * @error is set. + * + * Returns 0 on success, or -1 upon error */ int virDBusCallMethod(DBusConnection *conn, DBusMessage **replyout, + DBusError *error, const char *destination, const char *path, const char *iface, @@ -1475,7 +1498,7 @@ int virDBusCallMethod(DBusConnection *conn, ret = -1; - ret = virDBusCall(conn, call, replyout); + ret = virDBusCall(conn, call, replyout, error); cleanup: if (call) @@ -1525,6 +1548,7 @@ static int virDBusIsServiceInList(const char *listMethod, const char *name) if (virDBusCallMethod(conn, &reply, + NULL, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", @@ -1648,7 +1672,8 @@ int virDBusCreateMethodV(DBusMessage **call ATTRIBUTE_UNUSED, int virDBusCall(DBusConnection *conn ATTRIBUTE_UNUSED, DBusMessage *call ATTRIBUTE_UNUSED, - DBusMessage **reply ATTRIBUTE_UNUSED) + DBusMessage **reply ATTRIBUTE_UNUSED, + DBusError *error ATTRIBUTE_UNUSED) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("DBus support not compiled into this binary")); @@ -1657,6 +1682,7 @@ int virDBusCall(DBusConnection *conn ATTRIBUTE_UNUSED, int virDBusCallMethod(DBusConnection *conn ATTRIBUTE_UNUSED, DBusMessage **reply ATTRIBUTE_UNUSED, + DBusError *error ATTRIBUTE_UNUSED, const char *destination ATTRIBUTE_UNUSED, const char *path ATTRIBUTE_UNUSED, const char *iface ATTRIBUTE_UNUSED, diff --git a/src/util/virdbus.h b/src/util/virdbus.h index 4fbda87..0f21821 100644 --- a/src/util/virdbus.h +++ b/src/util/virdbus.h @@ -28,6 +28,7 @@ # else # define DBusConnection void # define DBusMessage void +# define DBusError void # endif # include "internal.h" @@ -61,6 +62,7 @@ int virDBusCreateReplyV(DBusMessage **reply, int virDBusCallMethod(DBusConnection *conn, DBusMessage **reply, + DBusError *error, const char *destination, const char *path, const char *iface, @@ -68,7 +70,8 @@ int virDBusCallMethod(DBusConnection *conn, const char *types, ...); int virDBusCall(DBusConnection *conn, DBusMessage *call, - DBusMessage **reply); + DBusMessage **reply, + DBusError *error); int virDBusMessageRead(DBusMessage *msg, const char *types, ...); diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c index f2eeb8c..0281158 100644 --- a/src/util/virsystemd.c +++ b/src/util/virsystemd.c @@ -236,6 +236,7 @@ int virSystemdCreateMachine(const char *name, VIR_DEBUG("Attempting to create machine via systemd"); if (virDBusCallMethod(conn, NULL, + NULL, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", @@ -301,6 +302,7 @@ int virSystemdTerminateMachine(const char *name, VIR_DEBUG("Attempting to terminate machine via systemd"); if (virDBusCallMethod(conn, NULL, + NULL, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", -- 1.8.5.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list