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(a)redhat.com>
---
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