[libvirt] virConnectClose question

Matthias Bolte matthias.bolte at googlemail.com
Tue Oct 19 18:07:47 UTC 2010


2010/10/19 Radek Hladik <radek at eadresa.cz>:
> Dne 19.10.2010 17:32, Matthias Bolte napsal(a):
>>
>> 2010/10/19 Radek Hladik<radek at eadresa.cz>:
>>>
>>> Hello,
>>>        I did find out that in some cases virConnectClose does not close
>>> the
>>> connection at all. It only returns -1 which by the documentation means
>>> error:
>>> Returns: 0 in case of success or -1 in case of error.
>>
>> Check virGetLastError() for the error.
>
> There were no errors reported neither by virGetLastError nor Error callback
> function.

That's strange. What version of libvirt are you using?

>>
>>> But there is no other indication of what error it is. I am almost sure
>>> that
>>> it is because some open domains or other libvirt objects. If this is the
>>> case it would be good to add notice like: "You need to free all
>>> domains,....,etc before calling virConnectClose". And is there any
>>> possibility how to force closing the connection? I know that it is a good
>>> programming manner to close all objects before closing the master object
>>> but
>>> I did run into this in php-libvrit development and it is quite painful.
>>> PHP is keeping a list of all resources (objects from libvirt) and is
>>> calling
>>> my destructors to close it. Unfortunately there are some problems with
>>> this:
>>> * when garbage collector clears my resource my destructor is not called.
>>> It
>>> is probably my mistake that I do not set it correctly somewhere but I am
>>> not
>>> able to find out where.
>>> * I can not influence the order of calls. It seems that there were some
>>> discussions and that for quite some time PHP is calling destructors in
>>> reverse order of creation. That would be good but I am not sure whether
>>> it
>>> is granted.
>>> The problem with this all is that if I for some reason fail to free some
>>> domain object the connection is not closed. But as PHP does reuse threads
>>> the connection will be open forever and connection limit for libvirtd get
>>> drained very fast.
>>> So basically my question is: should I implement some list of all objects
>>> I
>>> did create and free them before calling virConnectClose or is there any
>>> other way how to "terminate" libvirt connection for good?
>>>
>>> Radek
>>>
>>
>> Okay, all libvirt objects like connection, domain, storage pool etc
>> are reference counted. When you lookup a domain over a connection then
>> the domain adds an additional reference to the connection. This
>> ensures that the connection is open as long as there are objects that
>> have been looked up over it.
>>
>> You don't need to free all objects before you can close the
>> connection. You just need to match all virConnectOpen calls by a
>> virConnectClose call and all lookup calls for other objects by the
>> matching free calls.
>>
>> virConnectPtr conn = virConnectOpen("qemu:///system", 0); // conn.refs = 1
>> virDomainPtr domain = virDomainLookupByName(conn, "vm1"); // conn.refs
>> = 2, domain.refs = 1
>> ...
>> virConnectClose(conn); // conn.refs = 1, but conn is still open
>> because domain has a reference to it
>> virDomainFree(domain); // conn.refs = 0, domain.refs = 0, domain gets
>> freed and releases its reference to conn, no conn gets closed
>>
>> So virConnectClose returning -1 has nothing to do with the order of
>> close/free calls.
>>
>> I think you can only make virConnectClose return -1 when you call it
>> on an invalid or already closed connection.
>>
>> Matthias
>
> My problem is that I may not close some i.e. domain or storage pool and I
> still need to close the connection. Basically I need to destroy the libvirt
> connection because PHP script is already ended.*

There is no way to force a connection to close.

> Normally when PHP script "generates" objects, i.e. lookup, I just pass it to
> PHP as resource and expect PHP calling my destructor for that resource and
> that it will call it in correct order (domains before connection). This
> seems to fail in some cases (as I did say before).
> So I am thinking about having list of all abjects and checking whether they
> are freed. I just wanted to know whether something like this is not already
> in libvirt.
> You saying that libvirt keeps only reference count means that this must be
> done in my layer.

No, there is no function in libvirt to expose a list of all objects
libvirt currently knows about.

> I do understand that the order of freeing is not important but it is
> important to i.e. close all domains before closing connection. And as PHP
> does not know about the content of the resource it does the most clever
> thing to do - call destructors in reverse order. But this does not seem to
> be guaranteed.

But that's the point I'm trying to make. You can close the connection
_before_ all other objects that have references to it, and it'll work.

Actually that's only true for libvirt >= 0.7.1. There was a bug fixed
in 0.7.1 that forced you to close all other objects first. So if you
use libvirt < 0.7.1 this would explain why you say that you need to
close the connection last.

Matthias




More information about the libvir-list mailing list