[libvirt] [PATCH] Fix up connection reference counting.
Daniel P. Berrange
berrange at redhat.com
Thu Aug 13 18:33:29 UTC 2009
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 at 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 :|
More information about the libvir-list
mailing list