2010/10/19 Radek Hladik <radek@xxxxxxxxxx>: > Dne 19.10.2010 17:32, Matthias Bolte napsal(a): >> >> 2010/10/19 Radek Hladik<radek@xxxxxxxxxx>: >>> >>> 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list