On Tue, Jan 05, 2016 at 11:38:07 +1100, Michael Chapman wrote: > On Mon, 4 Jan 2016, Peter Krempa wrote: > > On Thu, Dec 31, 2015 at 16:42:52 +1100, Michael Chapman wrote: ... > >> @@ -188,8 +182,8 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver, > >> if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) > >> VIR_WARN("Unable to save status on vm %s after block job", > >> vm->def->name); > >> - if (persistDisk && virDomainSaveConfig(cfg->configDir, > >> - vm->newDef) < 0) > >> + if (vm->persistent && persistDisk && > > > > I'm not quite sure how this would happen. If there isn't a persistent > > configuration, how did we get to having the persistDisk object? > > > > If this happened in some way, the problem then is that vm->newDef was > > not freed or is present in any way so we should fix the origin and not > > this symptom. > > I spent a lot of time trying to work this out myself, and although I can > see what the code is doing I don't really understand the rationale or > history behind it all. > > vm->newDef is supposed to be the "new domain definition to activate on > shutdown", according to domain_conf.h. What's confusing though is that it > is possible for this to exist even on transient domains. That is not confusing but a bug. The newDef should not exist if the domain is transient. Basically the relationship between vm->persistent and vm->def and vm->newDef should be that vm->newDef implies vm->persistent. (Offline vms can't be transient) > > qemuProcessInit calls virDomainObjSetDefTransient ("so any part of the > startup process can add runtime state to vm->def that won't be > persisted"), and virDomainObjSetDefTransient actually *sets* vm->newDef. > If the domain is subsequently undefined, vm->persistent is set to 0 but > vm->newDef is left alone. So this is probably the buggy code path. Setting vm->newDef in virDomainObjSetDefTransient is desired so that we can fill in a lot of runtime stuff into the definition object without persisting it. The function even checks whether the object is persistent and does not perform the copy in such place. > > So it's possible for vm->newDef to be non-NULL even though > vm->persistent is 0. Bug. > > I had initially thought about putting the vm->persistent test at the top > of this code block, so persistDisk was never set if the domain was > transient. However the problem with that approach is that it means > vm->newDef never gets updated at the completion of the block job, yet it's > still possible to get this "inactive" domain XML via virDomainGetXMLDesc. Not really. To be consistent the part that sets the domain to be transient should kill the persistent definition. Otherwise that would imply that we need a lot of fallback code stuff to handle the corner case when the vm was undefined while running. > > I thought it would be simplest and safest to keep updating vm->newDef as > before, but just not write out the config to disk if the domain wasn't > actually persistent. As a side note, all the naming of def, newDef and virDomainObjSetDefTransient is very unfortunate. Having a persistentDef and liveDef or similarly named pointers would be more clear, easier to differentiate states and would additionally allow to get rid of vm->persistent since it would be equal to vm->persistentDef being set or not. If you want to fix the undefine bug you are welcome, otherwise I'll do it in a few days. Peter
Attachment:
signature.asc
Description: Digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list