On 17.10.2013 14:40, Daniel P. Berrange wrote: > On Tue, Oct 15, 2013 at 06:03:27PM +0200, Christophe Fergeau wrote: >> Hey, >> >> Due to a configuration issue on my system, libvirtd is not starting on my >> system (not complaining about this!): >> 2013-10-15 15:40:51.024+0000: 10222: info : libvirt version: 1.1.3 >> 2013-10-15 15:40:51.024+0000: 10222: error : virNetTLSContextCheckCertFile:117 : Cannot read CA certificate >> '/home/teuf/usr/etc/pki/CA/cacert.pem': No such file or directory >> >> However, before libvirtd exits, I get another error message from the netcf >> code, which is unexpected this time: >> 2013-10-15 15:49:18.361+0000: 10222: error : netcfStateCleanup:105 : >> internal error: Attempt to close netcf state driver already closed >> >> This message comes from the call of virStateCleanup() at the end of main() >> in libvirtd.c. virStateCleanup() should not be called before >> daemonStateInit() has been called in main. >> After this call, things get more ugly as daemonStateInit() calls >> virStateInitialize() from a thread, so there's probably a small window for >> virStateInitialize() and virStateCleanup() running concurrently if an error >> occurs between the call to daemonStateInit() and the call to >> virNetServerRun(). >> >> I'm sending this email rather than a patch as I'm not sure what is the best >> way to fix it. The easy way would be for virStateCleanup() to be a noop >> when virStateInitialize() hasn't been called (iow remove the error message >> from netcfStateCleanup). However, this would leave this small race >> condition around (which is not that bad as it would only occurs in >> situations when the daemon fails to start). So another approach would be to >> set a vir_state_initialized boolean once the thread has called >> ivrStateInitialize, and only call virStateCleanup() when it's set. >> >> Or maybe there's a 3rd way to fix this? >> >> Let me know if you have any guidance into the best way to fix this, > > Yeah, I've known about this issue for a while and its a bit horrible > to solve. I think we probably need to have a global mutex to serialize > the virStateInitialize, virStateReload and virStateCleanup calls so > that none of them can run in parallel. > > I'd have virGlobalInit create the mutex instance, since we know that > is run from thread safe context. > > Then make the virState* calls hold that mutex while executing. > > We don't want virStateCleanup to skip execution if virStateInitialize > has failed though - every callback in virStateCleanup should be written > to be safe if its corresponding init function hasn't run. Just the > mutex serialization ought to be sufficient I think. > > > Daniel > Sorry for bringing up a dead thread, but as you both may have noticed I was trying to solve this too: https://www.redhat.com/archives/libvir-list/2013-November/msg01311.html And I don't think Dan, your approach is gonna work. I mean, the reason for running virStateInitialize in thread is - it may take ages to complete. Hence, serializing virState* will lead to main thread waiting for the virStateInitialize to complete (which may not happen, i.e. in case of deadlock somewhere in a driver). But I was thinking of rather refined locking. Turning each of vir*DriverTab into virObjectLockable(). Then, each access would require object to lock itself. Moreover, the virStateCleanup would unregister the driver. Unfortunately, it could only unregister stateful drivers. Michal -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list