[libvirt] [PATCH 7/9] virt-admin: Introduce vshAdmCatchDisconnect handler

Erik Skultety eskultet at redhat.com
Tue Oct 13 13:38:20 UTC 2015


Since close callback and URI support was introduced in the earlier patches, it
is now the right time to implement the disconnect handler itself and switch the
dummy NULL reference in virAdmConnectRegisterCloseCallback for this new handler.
The handler itself is the same as the one used in virsh, it only remembers that
the event occurs, lets the user know, but no other useful logic is present.
---
 tools/virt-admin.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/tools/virt-admin.c b/tools/virt-admin.c
index a202ce2..3069d48 100644
--- a/tools/virt-admin.c
+++ b/tools/virt-admin.c
@@ -77,6 +77,51 @@ static const vshClientHooks hooks;
  */
 static int disconnected; /* we may have been disconnected */
 
+/*
+ * vshAdmCatchDisconnect:
+ *
+ * We get here when the connection was closed. Right now, we only save the fact
+ * the event was raised.
+ */
+static void
+vshAdmCatchDisconnect(virAdmConnectPtr conn ATTRIBUTE_UNUSED,
+                      int reason,
+                      void *opaque)
+{
+    if (reason != VIR_CONNECT_CLOSE_REASON_CLIENT) {
+        vshControl *ctl = opaque;
+        const char *str = "unknown reason";
+        virErrorPtr error;
+        char *uri = NULL;
+
+        error = virSaveLastError();
+        uri = virAdmConnectGetURI(conn);
+
+        switch ((virConnectCloseReason) reason) {
+        case VIR_CONNECT_CLOSE_REASON_ERROR:
+            str = N_("Disconnected from %s due to I/O error");
+            break;
+        case VIR_CONNECT_CLOSE_REASON_EOF:
+            str = N_("Disconnected from %s due to end of file");
+            break;
+        case VIR_CONNECT_CLOSE_REASON_KEEPALIVE:
+            str = N_("Disconnected from %s due to keepalive timeout");
+            break;
+        /* coverity[dead_error_condition] */
+        case VIR_CONNECT_CLOSE_REASON_CLIENT:
+        case VIR_CONNECT_CLOSE_REASON_LAST:
+            break;
+        }
+        vshError(ctl, _(str), NULLSTR(uri));
+
+        if (error) {
+            virSetError(error);
+            virFreeError(error);
+        }
+        disconnected++;
+    }
+}
+
 static virAdmConnectPtr
 vshAdmConnect(vshControl *ctl, unsigned int flags)
 {
@@ -91,8 +136,8 @@ vshAdmConnect(vshControl *ctl, unsigned int flags)
             vshError(ctl, "%s", _("Failed to connect to the admin server"));
         return NULL;
     } else {
-        if (virAdmConnectRegisterCloseCallback(priv->conn, NULL, NULL,
-                                               NULL) < 0)
+        if (virAdmConnectRegisterCloseCallback(priv->conn, vshAdmCatchDisconnect,
+                                               NULL, NULL) < 0)
             vshError(ctl, "%s", _("Unable to register disconnect callback"));
 
         if (priv->wantReconnect)
@@ -112,7 +157,7 @@ vshAdmDisconnectInternal(vshControl *ctl, virAdmConnectPtr *conn)
     if (!*conn)
         return ret;
 
-    virAdmConnectUnregisterCloseCallback(*conn, NULL);
+    virAdmConnectUnregisterCloseCallback(*conn, vshAdmCatchDisconnect);
     ret = virAdmConnectClose(*conn);
     if (ret < 0)
         vshError(ctl, "%s", _("Failed to disconnect from the admin server"));
-- 
2.4.3




More information about the libvir-list mailing list