backup: Add list of checkpoints to domain

Wire up the use of a checkpoint list into each domain, similar to the
existing snapshot list.  This includes adding a function for checking
that a redefine operation fits in with the existing list, as well as
various filtering capabilities over the list contents.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Eric Blake 2019-07-26 14:28:44 -05:00
parent 2795d85647
commit b736619f6e
7 changed files with 95 additions and 1 deletions

View File

@ -36,6 +36,7 @@
#include "virerror.h"
#include "virxml.h"
#include "virstring.h"
#include "virdomaincheckpointobjlist.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN_CHECKPOINT
@ -533,3 +534,64 @@ virDomainCheckpointDefFormat(virDomainCheckpointDefPtr def,
return virBufferContentAndReset(&buf);
}
int
virDomainCheckpointRedefinePrep(virDomainPtr domain,
virDomainObjPtr vm,
virDomainCheckpointDefPtr *defptr,
virDomainMomentObjPtr *chk,
virDomainXMLOptionPtr xmlopt,
bool *update_current)
{
virDomainCheckpointDefPtr def = *defptr;
char uuidstr[VIR_UUID_STRING_BUFLEN];
virDomainMomentObjPtr other = NULL;
virDomainCheckpointDefPtr otherdef = NULL;
virUUIDFormat(domain->uuid, uuidstr);
if (virDomainCheckpointCheckCycles(vm->checkpoints, def, vm->def->name) < 0)
return -1;
if (!def->parent.dom ||
memcmp(def->parent.dom->uuid, domain->uuid, VIR_UUID_BUFLEN)) {
virReportError(VIR_ERR_INVALID_ARG,
_("definition for checkpoint %s must use uuid %s"),
def->parent.name, uuidstr);
return -1;
}
if (virDomainCheckpointAlignDisks(def) < 0)
return -1;
if (def->parent.parent_name)
other = virDomainCheckpointFindByName(vm->checkpoints,
def->parent.parent_name);
if (other == virDomainCheckpointGetCurrent(vm->checkpoints)) {
*update_current = true;
virDomainCheckpointSetCurrent(vm->checkpoints, NULL);
}
other = virDomainCheckpointFindByName(vm->checkpoints, def->parent.name);
if (other) {
otherdef = virDomainCheckpointObjGetDef(other);
if (!virDomainDefCheckABIStability(otherdef->parent.dom,
def->parent.dom, xmlopt))
return -1;
if (other == virDomainCheckpointGetCurrent(vm->checkpoints)) {
*update_current = true;
virDomainCheckpointSetCurrent(vm->checkpoints, NULL);
}
/* Drop and rebuild the parent relationship, but keep all
* child relations by reusing chk. */
virDomainMomentDropParent(other);
virObjectUnref(otherdef);
other->def = &(*defptr)->parent;
*defptr = NULL;
*chk = other;
}
return 0;
}

View File

@ -89,4 +89,11 @@ virDomainCheckpointDefFormat(virDomainCheckpointDefPtr def,
int
virDomainCheckpointAlignDisks(virDomainCheckpointDefPtr checkpoint);
int virDomainCheckpointRedefinePrep(virDomainPtr domain,
virDomainObjPtr vm,
virDomainCheckpointDefPtr *def,
virDomainMomentObjPtr *checkpoint,
virDomainXMLOptionPtr xmlopt,
bool *update_current);
VIR_ENUM_DECL(virDomainCheckpoint);

View File

@ -29,6 +29,7 @@
#include "configmake.h"
#include "internal.h"
#include "virerror.h"
#include "checkpoint_conf.h"
#include "datatypes.h"
#include "domain_addr.h"
#include "domain_conf.h"
@ -60,6 +61,7 @@
#include "virhostdev.h"
#include "virmdev.h"
#include "virdomainsnapshotobjlist.h"
#include "virdomaincheckpointobjlist.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
@ -3486,6 +3488,7 @@ static void virDomainObjDispose(void *obj)
(dom->privateDataFreeFunc)(dom->privateData);
virDomainSnapshotObjListFree(dom->snapshots);
virDomainCheckpointObjListFree(dom->checkpoints);
}
virDomainObjPtr
@ -3515,6 +3518,9 @@ virDomainObjNew(virDomainXMLOptionPtr xmlopt)
if (!(domain->snapshots = virDomainSnapshotObjListNew()))
goto error;
if (!(domain->checkpoints = virDomainCheckpointObjListNew()))
goto error;
virObjectLock(domain);
virDomainObjSetState(domain, VIR_DOMAIN_SHUTOFF,
VIR_DOMAIN_SHUTOFF_UNKNOWN);

View File

@ -2562,6 +2562,8 @@ struct _virDomainObj {
bool hasManagedSave;
virDomainCheckpointObjListPtr checkpoints;
void *privateData;
void (*privateDataFreeFunc)(void *);

View File

@ -25,12 +25,14 @@
#include "internal.h"
#include "datatypes.h"
#include "virdomainobjlist.h"
#include "checkpoint_conf.h"
#include "snapshot_conf.h"
#include "viralloc.h"
#include "virfile.h"
#include "virlog.h"
#include "virstring.h"
#include "virdomainsnapshotobjlist.h"
#include "virdomaincheckpointobjlist.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
@ -887,6 +889,15 @@ virDomainObjMatchFilter(virDomainObjPtr vm,
return false;
}
/* filter by checkpoint existence */
if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_CHECKPOINT)) {
int nchk = virDomainListCheckpoints(vm->checkpoints, NULL, NULL,
NULL, 0);
if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_CHECKPOINT) && nchk > 0) ||
(MATCH(VIR_CONNECT_LIST_DOMAINS_NO_CHECKPOINT) && nchk <= 0)))
return false;
}
return true;
}
#undef MATCH

View File

@ -120,13 +120,18 @@ int virDomainObjListForEach(virDomainObjListPtr doms,
(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT | \
VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT)
#define VIR_CONNECT_LIST_DOMAINS_FILTERS_CHECKPOINT \
(VIR_CONNECT_LIST_DOMAINS_HAS_CHECKPOINT | \
VIR_CONNECT_LIST_DOMAINS_NO_CHECKPOINT)
#define VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL \
(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE | \
VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | \
VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE | \
VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE | \
VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART | \
VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)
VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT | \
VIR_CONNECT_LIST_DOMAINS_FILTERS_CHECKPOINT)
int virDomainObjListCollect(virDomainObjListPtr doms,
virConnectPtr conn,

View File

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