[libvirt] [PATCH 6/6] Allow caller to handle DBus error messages

Daniel P. Berrange berrange at redhat.com
Thu Mar 20 12:28:45 UTC 2014


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 at 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




More information about the libvir-list mailing list