[libvirt] [PATCH v7 03/23] snapshot: Refactor qemu to utilize virDomainMoment more

Eric Blake eblake at redhat.com
Wed Mar 27 10:10:34 UTC 2019


Use the common base class virDomainMoment for iterator callbacks
related to snapshots from the qemu code, so that when checkpoint
operations are introduced, they can share the same callbacks.

Simplify the code for qemuDomainSnapshotCurrent by better utilizing
virDomainMoment helpers.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 src/qemu/qemu_domain.h | 20 +++++++++-------
 src/qemu/qemu_domain.c | 33 +++++++++++++-------------
 src/qemu/qemu_driver.c | 53 +++++++++++++++++++++++-------------------
 3 files changed, 57 insertions(+), 49 deletions(-)

diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index ca24de15e5..00b497e6a6 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1,7 +1,7 @@
 /*
  * qemu_domain.h: QEMU domain private state
  *
- * Copyright (C) 2006-2016 Red Hat, Inc.
+ * Copyright (C) 2006-2019 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -38,6 +38,7 @@
 # include "virchrdev.h"
 # include "virobject.h"
 # include "logging/log_manager.h"
+# include "virdomainmomentobjlist.h"

 # define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \
     (VIR_DOMAIN_XML_SECURE)
@@ -698,19 +699,22 @@ int qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
                               bool update_current,
                               bool metadata_only);

-typedef struct _virQEMUSnapRemove virQEMUSnapRemove;
-typedef virQEMUSnapRemove *virQEMUSnapRemovePtr;
-struct _virQEMUSnapRemove {
+typedef struct _virQEMUMomentRemove virQEMUMomentRemove;
+typedef virQEMUMomentRemove *virQEMUMomentRemovePtr;
+struct _virQEMUMomentRemove {
     virQEMUDriverPtr driver;
     virDomainObjPtr vm;
     int err;
     bool metadata_only;
-    bool current;
+    virDomainMomentObjPtr current;
+    bool found;
+    int (*momentDiscard)(virQEMUDriverPtr, virDomainObjPtr,
+                         virDomainMomentObjPtr, bool, bool);
 };

-int qemuDomainSnapshotDiscardAll(void *payload,
-                                 const void *name,
-                                 void *data);
+int qemuDomainMomentDiscardAll(void *payload,
+                               const void *name,
+                               void *data);

 int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver,
                                          virDomainObjPtr vm);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 9ca4ca33e5..54afb6dd7b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1,7 +1,7 @@
 /*
  * qemu_domain.c: QEMU domain private state
  *
- * Copyright (C) 2006-2016 Red Hat, Inc.
+ * Copyright (C) 2006-2019 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -8650,18 +8650,18 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
 }

 /* Hash iterator callback to discard multiple snapshots.  */
-int qemuDomainSnapshotDiscardAll(void *payload,
-                                 const void *name ATTRIBUTE_UNUSED,
-                                 void *data)
+int qemuDomainMomentDiscardAll(void *payload,
+                               const void *name ATTRIBUTE_UNUSED,
+                               void *data)
 {
-    virDomainMomentObjPtr snap = payload;
-    virQEMUSnapRemovePtr curr = data;
+    virDomainMomentObjPtr moment = payload;
+    virQEMUMomentRemovePtr curr = data;
     int err;

-    if (virDomainSnapshotGetCurrent(curr->vm->snapshots) == snap)
-        curr->current = true;
-    err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap, false,
-                                    curr->metadata_only);
+    if (!curr->found && curr->current == moment)
+        curr->found = true;
+    err = curr->momentDiscard(curr->driver, curr->vm, moment, false,
+                              curr->metadata_only);
     if (err && !curr->err)
         curr->err = err;
     return 0;
@@ -8671,14 +8671,13 @@ int
 qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver,
                                      virDomainObjPtr vm)
 {
-    virQEMUSnapRemove rem;
+    virQEMUMomentRemove rem = {
+        .driver = driver,
+        .vm = vm,
+        .metadata_only = true
+    };

-    rem.driver = driver;
-    rem.vm = vm;
-    rem.metadata_only = true;
-    rem.err = 0;
-    virDomainSnapshotForEach(vm->snapshots, qemuDomainSnapshotDiscardAll,
-                             &rem);
+    virDomainSnapshotForEach(vm->snapshots, qemuDomainMomentDiscardAll, &rem);
     virDomainSnapshotObjListRemoveAll(vm->snapshots);

     return rem.err;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 930ce9d401..62d8d977c5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16126,6 +16126,7 @@ qemuDomainSnapshotCurrent(virDomainPtr domain,
 {
     virDomainObjPtr vm;
     virDomainSnapshotPtr snapshot = NULL;
+    const char *name;

     virCheckFlags(0, NULL);

@@ -16135,13 +16136,14 @@ qemuDomainSnapshotCurrent(virDomainPtr domain,
     if (virDomainSnapshotCurrentEnsureACL(domain->conn, vm->def) < 0)
         goto cleanup;

-    if (!virDomainSnapshotGetCurrent(vm->snapshots)) {
+    name = virDomainSnapshotGetCurrentName(vm->snapshots);
+    if (!name) {
         virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s",
                        _("the domain does not have a current snapshot"));
         goto cleanup;
     }

-    snapshot = virGetDomainSnapshot(domain, virDomainSnapshotGetCurrentName(vm->snapshots));
+    snapshot = virGetDomainSnapshot(domain, name);

  cleanup:
     virDomainObjEndAPI(&vm);
@@ -16673,40 +16675,41 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
 }


-typedef struct _virQEMUSnapReparent virQEMUSnapReparent;
-typedef virQEMUSnapReparent *virQEMUSnapReparentPtr;
-struct _virQEMUSnapReparent {
-    virQEMUDriverConfigPtr cfg;
+typedef struct _virQEMUMomentReparent virQEMUMomentReparent;
+typedef virQEMUMomentReparent *virQEMUMomentReparentPtr;
+struct _virQEMUMomentReparent {
+    const char *dir;
     virDomainMomentObjPtr parent;
     virDomainObjPtr vm;
     virCapsPtr caps;
     virDomainXMLOptionPtr xmlopt;
     int err;
+    int (*writeMetadata)(virDomainObjPtr, virDomainMomentObjPtr,
+                         virCapsPtr, virDomainXMLOptionPtr, const char *);
 };


 static int
-qemuDomainSnapshotReparentChildren(void *payload,
-                                   const void *name ATTRIBUTE_UNUSED,
-                                   void *data)
+qemuDomainMomentReparentChildren(void *payload,
+                                 const void *name ATTRIBUTE_UNUSED,
+                                 void *data)
 {
-    virDomainMomentObjPtr snap = payload;
-    virQEMUSnapReparentPtr rep = data;
+    virDomainMomentObjPtr moment = payload;
+    virQEMUMomentReparentPtr rep = data;

     if (rep->err < 0)
         return 0;

-    VIR_FREE(snap->def->parent);
+    VIR_FREE(moment->def->parent);

     if (rep->parent->def &&
-        VIR_STRDUP(snap->def->parent, rep->parent->def->name) < 0) {
+        VIR_STRDUP(moment->def->parent, rep->parent->def->name) < 0) {
         rep->err = -1;
         return 0;
     }

-    rep->err = qemuDomainSnapshotWriteMetadata(rep->vm, snap,
-                                               rep->caps, rep->xmlopt,
-                                               rep->cfg->snapshotDir);
+    rep->err = rep->writeMetadata(rep->vm, moment, rep->caps, rep->xmlopt,
+                                  rep->dir);
     return 0;
 }

@@ -16719,8 +16722,8 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
     virDomainObjPtr vm = NULL;
     int ret = -1;
     virDomainMomentObjPtr snap = NULL;
-    virQEMUSnapRemove rem;
-    virQEMUSnapReparent rep;
+    virQEMUMomentRemove rem;
+    virQEMUMomentReparent rep;
     bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY);
     int external = 0;
     virQEMUDriverConfigPtr cfg = NULL;
@@ -16766,13 +16769,14 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
         rem.vm = vm;
         rem.metadata_only = metadata_only;
         rem.err = 0;
-        rem.current = false;
-        virDomainMomentForEachDescendant(snap,
-                                         qemuDomainSnapshotDiscardAll,
+        rem.current = virDomainSnapshotGetCurrent(vm->snapshots);
+        rem.found = false;
+        rem.momentDiscard = qemuDomainSnapshotDiscard;
+        virDomainMomentForEachDescendant(snap, qemuDomainMomentDiscardAll,
                                          &rem);
         if (rem.err < 0)
             goto endjob;
-        if (rem.current) {
+        if (rem.found) {
             virDomainSnapshotSetCurrent(vm->snapshots, snap);
             if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
                 if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps,
@@ -16787,14 +16791,15 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
             }
         }
     } else if (snap->nchildren) {
-        rep.cfg = cfg;
+        rep.dir = cfg->snapshotDir;
         rep.parent = snap->parent;
         rep.vm = vm;
         rep.err = 0;
         rep.caps = driver->caps;
         rep.xmlopt = driver->xmlopt;
+        rep.writeMetadata = qemuDomainSnapshotWriteMetadata;
         virDomainMomentForEachChild(snap,
-                                    qemuDomainSnapshotReparentChildren,
+                                    qemuDomainMomentReparentChildren,
                                     &rep);
         if (rep.err < 0)
             goto endjob;
-- 
2.20.1




More information about the libvir-list mailing list