[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 3/3] virsh: Unregister the connection close notifier upon termination



Before closing the connection we unregister the close callback
to prevent a reference leak. We make sure that we only unregister
if we have previously registered a callback (not the case for
virsh connect!). Further, the messages on virConnectClose != 0
are a bit more specific now.

Signed-off-by: Viktor Mihajlovski <mihajlov linux vnet ibm com>
---
 tools/virsh.c |   23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index d822e09..4be8fa0 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -311,6 +311,8 @@ vshCatchDisconnect(virConnectPtr conn ATTRIBUTE_UNUSED,
         disconnected++;
 }
 
+static int callback_registered = 0;
+
 /*
  * vshReconnect:
  *
@@ -336,9 +338,13 @@ vshReconnect(vshControl *ctl)
         else
             vshError(ctl, "%s", _("failed to connect to the hypervisor"));
     } else {
-        if (virConnectRegisterCloseCallback(ctl->conn, vshCatchDisconnect,
-                                            NULL, NULL) < 0)
-            vshError(ctl, "%s", _("Unable to register disconnect callback"));
+        if (!callback_registered) {
+            if (virConnectRegisterCloseCallback(ctl->conn, vshCatchDisconnect,
+                                                NULL, NULL) == 0)
+                callback_registered = 1;
+            else
+                vshError(ctl, "%s", _("Unable to register disconnect callback"));
+        }
         if (connected)
             vshError(ctl, "%s", _("Reconnected to the hypervisor"));
     }
@@ -2672,9 +2678,14 @@ vshDeinit(vshControl *ctl)
     VIR_FREE(ctl->name);
     if (ctl->conn) {
         int ret;
-        if ((ret = virConnectClose(ctl->conn)) != 0) {
-            vshError(ctl, _("Failed to disconnect from the hypervisor, %d leaked reference(s)"), ret);
-        }
+        if (callback_registered &&
+            virConnectUnregisterCloseCallback(ctl->conn, vshCatchDisconnect) < 0)
+            vshError(ctl, "%s", _("Failed to unregister disconnect callback"));
+        ret = virConnectClose(ctl->conn);
+        if (ret < 0)
+            vshError(ctl, "%s", _("Failed to disconnect from the hypervisor"));
+        else if (ret > 0)
+            vshError(ctl, "%s", _("Leaked reference(s) after disconnect from the hypervisor"));
     }
     virResetLastError();
 
-- 
1.7.9.5


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]