Re: Bug? virGetLastError() returns NULL after virDomainCreate() if Domain running already

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am Freitag, 24. Februar 2012, 18:21:37 schrieb Guido Winkelmann:
> Am Donnerstag, 23. Februar 2012, 13:40:03 I wrote:
> > Am Mittwoch, 22. Februar 2012, 11:26:50 schrieb Eric Blake:
> > > Can you post the code snippet you are using to get this situation?
> > 
> > Unfortunately, the problem occurs inside a fairly large, and unfortunately
> > not Open-Source, C++ program. I will try to reduce it to a minimal
> > testcase
> > as soon as I get around to it.
> 
> Okay, I wrote a minimal testcase that does just the operations that lead to
> the problem, only to find out that this won't reproduce the bug either :-\
> 
> That means either I'm inadvertently triggering some rare corner case here
> who knows where in my code, or the bug is really in my code. I don't think
> it's the latter, though, because the relevant part of my code looks like
> this:
> 
> if(virDomainCreate(vserver.get_virdomain().get()) != 0) {
> 	// TODO clean up pointer
> 	virErrorPtr error = virGetLastError();
> 	if(error != 0) {
> 		syslog(LOG_ERR, "Could not start vserver, error code: %d", error->code);
> 		// VIR_ERR_OPERATION_INVALID means the vm was already in a started state
> 		if(error->code != VIR_ERR_OPERATION_INVALID)
> 			throw std::runtime_error("Could not start vserver");
> 		}
> 	else {
> 		syslog(LOG_ERR, "Could not start vserver, no error code from libvirt");
> 		throw std::runtime_error("Could not start vserver, no error code from
> libvirt");
> 		}
> 	}
> 
> There's nothing in there between calling virDomainCreate() and
> virGetLastError(). There are no other threads, either.
> 
> Anyway, I've fired up gdb now to see if I can find out where the error
> object gets lost.

I found out what is happening here:

I am using a C++ wrapper class for virDomainPtr, to make it fit better with 
the RAII principles in that language. That means that, in the above code 
snippet, even though it's not actually visible because it happens in the 
constructor and destructor of a temporary object, the virDomainPtr for domain 
gets copied once, virDomainRef() gets called on it, and after the attempt to 
start the domain, virDomainFree() gets called.

The problem is that virDomainFree() will unconditionally call 
virResetLastError().

With that info, I could work around the problem, however, I still think that, 
since virDomainFree() is a reference-counting free, it should only call 
virResetLastError() when the reference count has actually reached 0. In fact, 
it should probably even check whether the last error even belongs to the 
domain being deleted.

	Guido


[Index of Archives]     [Virt Tools]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]

  Powered by Linux