]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
backup: Add list of checkpoints to domain
authorEric Blake <eblake@redhat.com>
Fri, 26 Jul 2019 19:28:44 +0000 (14:28 -0500)
committerEric Blake <eblake@redhat.com>
Fri, 26 Jul 2019 21:48:58 +0000 (16:48 -0500)
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>
src/conf/checkpoint_conf.c
src/conf/checkpoint_conf.h
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/virdomainobjlist.c
src/conf/virdomainobjlist.h
src/libvirt_private.syms

index 69c9040a431cb7263ada4458298557d0a47d855f..30c6d2e7171898b33192f331672c9900cd9cdd2c 100644 (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;
+}
index 0114fa37daecd61918c7f1bb84a306a99f1a22dc..03dd6b7bde250e890ceef3e71bdbbac102f72049 100644 (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);
index d60ef8106118ddd9ad8d027050505a0836bb55f2..441eb1a5a2a1d4807aae57487be053d2b90f71fa 100644 (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);
index dc480bc7c5f5ac2b02eed7e0076a72ad2a31dd8a..8a4425df64334b4e7fbe707a330f25e00d7c73df 100644 (file)
@@ -2562,6 +2562,8 @@ struct _virDomainObj {
 
     bool hasManagedSave;
 
+    virDomainCheckpointObjListPtr checkpoints;
+
     void *privateData;
     void (*privateDataFreeFunc)(void *);
 
index d58d25f847b7579892c8fad1eac880e40c982db2..d640da6205dde422f1eb748fcf77fbf451abbfd7 100644 (file)
 #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
index bf3ab396fad59bf020e31fe212779491d04cdf5e..7d71bc54d08bea5a5b556402425a5388286d991c 100644 (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,
index aec174d874e88712c81208cec3d7be9b067eb0e8..c323f679b3ced05a09d7d7227dbd40a293445a00 100644 (file)
@@ -75,6 +75,7 @@ virDomainCheckpointDefFormat;
 virDomainCheckpointDefNew;
 virDomainCheckpointDefParseString;
 virDomainCheckpointFormatConvertXMLFlags;
+virDomainCheckpointRedefinePrep;
 virDomainCheckpointTypeFromString;
 virDomainCheckpointTypeToString;