From b736619f6ead844dc6c096f0d80a6834c21ea65f Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 26 Jul 2019 14:28:44 -0500 Subject: [PATCH] backup: Add list of checkpoints to domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Daniel P. Berrangé --- src/conf/checkpoint_conf.c | 62 +++++++++++++++++++++++++++++++++++++ src/conf/checkpoint_conf.h | 7 +++++ src/conf/domain_conf.c | 6 ++++ src/conf/domain_conf.h | 2 ++ src/conf/virdomainobjlist.c | 11 +++++++ src/conf/virdomainobjlist.h | 7 ++++- src/libvirt_private.syms | 1 + 7 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/conf/checkpoint_conf.c b/src/conf/checkpoint_conf.c index 69c9040a43..30c6d2e717 100644 --- a/src/conf/checkpoint_conf.c +++ b/src/conf/checkpoint_conf.c @@ -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; +} diff --git a/src/conf/checkpoint_conf.h b/src/conf/checkpoint_conf.h index 0114fa37da..03dd6b7bde 100644 --- a/src/conf/checkpoint_conf.h +++ b/src/conf/checkpoint_conf.h @@ -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); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d60ef81061..441eb1a5a2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -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); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index dc480bc7c5..8a4425df64 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2562,6 +2562,8 @@ struct _virDomainObj { bool hasManagedSave; + virDomainCheckpointObjListPtr checkpoints; + void *privateData; void (*privateDataFreeFunc)(void *); diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c index d58d25f847..d640da6205 100644 --- a/src/conf/virdomainobjlist.c +++ b/src/conf/virdomainobjlist.c @@ -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 diff --git a/src/conf/virdomainobjlist.h b/src/conf/virdomainobjlist.h index bf3ab396fa..7d71bc54d0 100644 --- a/src/conf/virdomainobjlist.h +++ b/src/conf/virdomainobjlist.h @@ -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, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index aec174d874..c323f679b3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -75,6 +75,7 @@ virDomainCheckpointDefFormat; virDomainCheckpointDefNew; virDomainCheckpointDefParseString; virDomainCheckpointFormatConvertXMLFlags; +virDomainCheckpointRedefinePrep; virDomainCheckpointTypeFromString; virDomainCheckpointTypeToString;