[libvirt] virConnectClose question

Radek Hladik radek at eadresa.cz
Wed Oct 20 13:03:29 UTC 2010


Dne 19.10.2010 20:07, Matthias Bolte napsal(a):
> 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?

For that I was using libvirt-client-0.7.7-5.fc13.x86_64 . But the 
missing error could be lost somewhere I did not investigate it much deeper.

>
>>>
>>>> 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.

That would solve one of the problems but it seems that for now PHP calls 
in good order. The worse problem is that I may miss some domains 
entirely. But as I see I will need to do it myself or dig into PHP code 
deeper to find out why it is not calling my destructors on GC and hope 
that it is the only case  :-)

>
> Matthias

Radek




More information about the libvir-list mailing list