On Thu, Aug 13, 2009 at 10:51:46AM +0200, Chris Lalancette wrote:
Currently the reference counting for connections is busted. I
first noticed it while trying to use virConnectRef; it would
eventually cause a crash in the remote_internal driver, although
that was really just a victim. Really, we should only call the
close callbacks on the methods when the references drop to 0. To
accomplish this, move all of the close callbacks into
virUnrefConnect (since there are lots of internal users of that
function), and arrange for virConnectClose to call that.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
src/datatypes.c | 10 ++++++++++
src/libvirt.c | 14 +-------------
2 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/src/datatypes.c b/src/datatypes.c
index 9d556c8..83260c1 100644
--- a/src/datatypes.c
+++ b/src/datatypes.c
@@ -237,6 +237,16 @@ virUnrefConnect(virConnectPtr conn)
conn->refs--;
refs = conn->refs;
if (refs == 0) {
+ if (conn->networkDriver)
+ conn->networkDriver->close (conn);
+ if (conn->interfaceDriver)
+ conn->interfaceDriver->close (conn);
+ if (conn->storageDriver)
+ conn->storageDriver->close (conn);
+ if (conn->deviceMonitor)
+ conn->deviceMonitor->close (conn);
+ conn->driver->close (conn);
+
virReleaseConnect(conn);
/* Already unlocked mutex */
return (0);
There's a minor annoying problem there in that you will deadlock
if any of those driver functions try to raise an error, since
you are holding the connection lock. So after if(ref ==0) you
need to release the lock, and then re-aquire it before calling
the virReleaseConnect().
diff --git a/src/libvirt.c b/src/libvirt.c
index 5aa7f83..472c19b 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1231,19 +1231,7 @@ virConnectClose(virConnectPtr conn)
return (-1);
}
- if (conn->networkDriver)
- conn->networkDriver->close (conn);
- if (conn->interfaceDriver)
- conn->interfaceDriver->close (conn);
- if (conn->storageDriver)
- conn->storageDriver->close (conn);
- if (conn->deviceMonitor)
- conn->deviceMonitor->close (conn);
- conn->driver->close (conn);
-
- if (virUnrefConnect(conn) < 0)
- return (-1);
- return (0);
+ return virUnrefConnect(conn);
}
/**
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|