conf: checkpoint: Split virDomainCheckpointRedefinePrep into two functions

First one prepares and validates the definition, the second one actually
either updates an existing checkpoint or assigns definition for the new
one.

This will allow driver code to add extra validation between those
steps.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2020-11-04 10:10:56 +01:00
parent f37d306f6e
commit 93873c9bcc
5 changed files with 37 additions and 29 deletions

View File

@ -513,16 +513,11 @@ virDomainCheckpointDefFormat(virDomainCheckpointDefPtr def,
int
virDomainCheckpointRedefinePrep(virDomainObjPtr vm,
virDomainCheckpointDefPtr *defptr,
virDomainMomentObjPtr *chk,
virDomainXMLOptionPtr xmlopt,
virDomainCheckpointDefPtr def,
bool *update_current)
{
virDomainCheckpointDefPtr def = *defptr;
char uuidstr[VIR_UUID_STRING_BUFLEN];
virDomainMomentObjPtr parent = NULL;
virDomainMomentObjPtr other = NULL;
virDomainCheckpointDefPtr otherdef = NULL;
virUUIDFormat(vm->def->uuid, uuidstr);
@ -550,12 +545,26 @@ virDomainCheckpointRedefinePrep(virDomainObjPtr vm,
if (virDomainCheckpointGetCurrent(vm->checkpoints) == NULL)
*update_current = true;
return 0;
}
virDomainMomentObjPtr
virDomainCheckpointRedefineCommit(virDomainObjPtr vm,
virDomainCheckpointDefPtr *defptr,
virDomainXMLOptionPtr xmlopt)
{
virDomainCheckpointDefPtr def = *defptr;
virDomainMomentObjPtr other = NULL;
virDomainCheckpointDefPtr otherdef = NULL;
virDomainMomentObjPtr chk = NULL;
other = virDomainCheckpointFindByName(vm->checkpoints, def->parent.name);
if (other) {
otherdef = virDomainCheckpointObjGetDef(other);
if (!virDomainDefCheckABIStability(otherdef->parent.dom,
def->parent.dom, xmlopt))
return -1;
return NULL;
/* Drop and rebuild the parent relationship, but keep all
* child relations by reusing chk. */
@ -563,8 +572,11 @@ virDomainCheckpointRedefinePrep(virDomainObjPtr vm,
virObjectUnref(otherdef);
other->def = &(*defptr)->parent;
*defptr = NULL;
*chk = other;
chk = other;
} else {
chk = virDomainCheckpointAssignDef(vm->checkpoints, def);
*defptr = NULL;
}
return 0;
return chk;
}

View File

@ -90,10 +90,14 @@ virDomainCheckpointDefFormat(virDomainCheckpointDefPtr def,
int
virDomainCheckpointAlignDisks(virDomainCheckpointDefPtr checkpoint);
int virDomainCheckpointRedefinePrep(virDomainObjPtr vm,
virDomainCheckpointDefPtr *def,
virDomainMomentObjPtr *checkpoint,
virDomainXMLOptionPtr xmlopt,
bool *update_current);
int
virDomainCheckpointRedefinePrep(virDomainObjPtr vm,
virDomainCheckpointDefPtr def,
bool *update_current);
virDomainMomentObjPtr
virDomainCheckpointRedefineCommit(virDomainObjPtr vm,
virDomainCheckpointDefPtr *defptr,
virDomainXMLOptionPtr xmlopt);
VIR_ENUM_DECL(virDomainCheckpoint);

View File

@ -86,6 +86,7 @@ virDomainCheckpointDefFormat;
virDomainCheckpointDefNew;
virDomainCheckpointDefParseString;
virDomainCheckpointFormatConvertXMLFlags;
virDomainCheckpointRedefineCommit;
virDomainCheckpointRedefinePrep;
virDomainCheckpointTypeFromString;
virDomainCheckpointTypeToString;

View File

@ -377,22 +377,14 @@ qemuCheckpointRedefine(virQEMUDriverPtr driver,
virDomainCheckpointDefPtr *def,
bool *update_current)
{
virDomainMomentObjPtr chk = NULL;
if (virDomainCheckpointRedefinePrep(vm, def, &chk, driver->xmlopt,
update_current) < 0)
if (virDomainCheckpointRedefinePrep(vm, *def, update_current) < 0)
return NULL;
/* XXX Should we validate that the redefined checkpoint even
* makes sense, such as checking that qemu-img recognizes the
* checkpoint bitmap name in at least one of the domain's disks? */
if (chk)
return chk;
chk = virDomainCheckpointAssignDef(vm->checkpoints, *def);
*def = NULL;
return chk;
return virDomainCheckpointRedefineCommit(vm, def, driver->xmlopt);
}

View File

@ -8989,9 +8989,10 @@ testDomainCheckpointCreateXML(virDomainPtr domain,
goto cleanup;
if (redefine) {
if (virDomainCheckpointRedefinePrep(vm, &def, &chk,
privconn->xmlopt,
&update_current) < 0)
if (virDomainCheckpointRedefinePrep(vm, def, &update_current) < 0)
goto cleanup;
if (!(chk = virDomainCheckpointRedefineCommit(vm, &def, privconn->xmlopt)))
goto cleanup;
} else {
if (!(def->parent.dom = virDomainDefCopy(vm->def,
@ -9002,9 +9003,7 @@ testDomainCheckpointCreateXML(virDomainPtr domain,
if (virDomainCheckpointAlignDisks(def) < 0)
goto cleanup;
}
if (!chk) {
if (!(chk = virDomainCheckpointAssignDef(vm->checkpoints, def)))
goto cleanup;