[libvirt] [PATCH] qemu: save config after pivot only if domain is persistent

Peter Krempa pkrempa at redhat.com
Wed Jan 6 06:01:41 UTC 2016


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20160106/113e7e00/attachment-0001.sig>


More information about the libvir-list mailing list