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

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

 



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@xxxxxxxxxxxxxxxxxx>
---
 tools/virsh.c |   23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index b574d7e..3c0b398 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"));
     }
@@ -2665,9 +2671,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

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]