]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
snapshot: Factor out redefine cycle validation
authorEric Blake <eblake@redhat.com>
Sat, 6 Jul 2019 02:07:43 +0000 (21:07 -0500)
committerEric Blake <eblake@redhat.com>
Fri, 12 Jul 2019 20:12:29 +0000 (15:12 -0500)
The code to check whether a redefined snapshot/checkpoint XML is
attempting to create a cycle in the list of moments is lengthy, and
common between the two types of list. Therefore, it belongs in the
shared base file.

Signed-off-by: Eric Blake <eblake@redhat.com>
Acked-by: Peter Krempa <pkrempa@redhat.com>
src/conf/snapshot_conf.c
src/conf/virdomainmomentobjlist.c
src/conf/virdomainmomentobjlist.h
src/conf/virdomainsnapshotobjlist.c
src/conf/virdomainsnapshotobjlist.h
tests/virsh-snapshot

index ea04413aec1befe1924674dba7c5bbca30aa7cdb..130a9cee03e9a6aa1d80caef87db75beaf1ac44e 100644 (file)
@@ -966,46 +966,15 @@ virDomainSnapshotRedefinePrep(virDomainPtr domain,
 {
     virDomainSnapshotDefPtr def = *defptr;
     virDomainMomentObjPtr other;
-    virDomainSnapshotDefPtr otherdef;
+    virDomainSnapshotDefPtr otherdef = NULL;
     bool check_if_stolen;
 
-    /* Prevent circular chains */
-    if (def->parent.parent_name) {
-        if (STREQ(def->parent.name, def->parent.parent_name)) {
-            virReportError(VIR_ERR_INVALID_ARG,
-                           _("cannot set snapshot %s as its own parent"),
-                           def->parent.name);
-            return -1;
-        }
-        other = virDomainSnapshotFindByName(vm->snapshots,
-                                            def->parent.parent_name);
-        if (!other) {
-            virReportError(VIR_ERR_INVALID_ARG,
-                           _("parent %s for snapshot %s not found"),
-                           def->parent.parent_name, def->parent.name);
-            return -1;
-        }
-        otherdef = virDomainSnapshotObjGetDef(other);
-        while (otherdef->parent.parent_name) {
-            if (STREQ(otherdef->parent.parent_name, def->parent.name)) {
-                virReportError(VIR_ERR_INVALID_ARG,
-                               _("parent %s would create cycle to %s"),
-                               otherdef->parent.name, def->parent.name);
-                return -1;
-            }
-            other = virDomainSnapshotFindByName(vm->snapshots,
-                                                otherdef->parent.parent_name);
-            if (!other) {
-                VIR_WARN("snapshots are inconsistent for %s",
-                         vm->def->name);
-                break;
-            }
-            otherdef = virDomainSnapshotObjGetDef(other);
-        }
-    }
+    if (virDomainSnapshotCheckCycles(vm->snapshots, def, vm->def->name) < 0)
+        return -1;
 
     other = virDomainSnapshotFindByName(vm->snapshots, def->parent.name);
-    otherdef = other ? virDomainSnapshotObjGetDef(other) : NULL;
+    if (other)
+        otherdef = virDomainSnapshotObjGetDef(other);
     check_if_stolen = other && otherdef->parent.dom;
     if (virDomainSnapshotRedefineValidate(def, domain->uuid, other, xmlopt,
                                           flags) < 0) {
index f56b516343cc8bf02095164e2976b8e07f40d45e..7cb1745525fe11a447aed90abf8a1bee51a692b2 100644 (file)
@@ -519,3 +519,47 @@ virDomainMomentUpdateRelations(virDomainMomentObjListPtr moments)
         moments->current = NULL;
     return act.err;
 }
+
+
+/* Check that inserting def into list would not create any impossible
+ * parent-child relationships (cycles or missing parents).  Return 0
+ * on success, or report an error on behalf of domname before
+ * returning -1. */
+int
+virDomainMomentCheckCycles(virDomainMomentObjListPtr list,
+                           virDomainMomentDefPtr def,
+                           const char *domname)
+{
+    virDomainMomentObjPtr other;
+
+    if (def->parent_name) {
+        if (STREQ(def->name, def->parent_name)) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("cannot set moment %s as its own parent"),
+                           def->name);
+            return -1;
+        }
+        other = virDomainMomentFindByName(list, def->parent_name);
+        if (!other) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("parent %s for moment %s not found"),
+                           def->parent_name, def->name);
+            return -1;
+        }
+        while (other->def->parent_name) {
+            if (STREQ(other->def->parent_name, def->name)) {
+                virReportError(VIR_ERR_INVALID_ARG,
+                               _("parent %s would create cycle to %s"),
+                               other->def->name, def->name);
+                return -1;
+            }
+            other = virDomainMomentFindByName(list, other->def->parent_name);
+            if (!other) {
+                VIR_WARN("moments are inconsistent for domain %s",
+                         domname);
+                break;
+            }
+        }
+    }
+    return 0;
+}
index 68f00a114fcc1f84cc8d61093ed9bd85d4c5b596..4067e928f4656253d0d847577bf5867e331a9a84 100644 (file)
@@ -117,3 +117,6 @@ int virDomainMomentForEach(virDomainMomentObjListPtr moments,
                            virHashIterator iter,
                            void *data);
 int virDomainMomentUpdateRelations(virDomainMomentObjListPtr moments);
+int virDomainMomentCheckCycles(virDomainMomentObjListPtr list,
+                               virDomainMomentDefPtr def,
+                               const char *domname);
index 9bcc8d10369d972b22e911a2c8a82c9b65a9f1d0..99bc4bb0c521b65a8a4be801ab667f57ad135588 100644 (file)
@@ -234,6 +234,15 @@ virDomainSnapshotUpdateRelations(virDomainSnapshotObjListPtr snapshots)
 }
 
 
+int
+virDomainSnapshotCheckCycles(virDomainSnapshotObjListPtr snapshots,
+                             virDomainSnapshotDefPtr def,
+                             const char *domname)
+{
+    return virDomainMomentCheckCycles(snapshots->base, &def->parent, domname);
+}
+
+
 int
 virDomainListSnapshots(virDomainSnapshotObjListPtr snapshots,
                        virDomainMomentObjPtr from,
index 26fa456730fe6719911f184c1c448dfc46d891d0..fed8d22bc869eb50fe85609502b131f2225f170e 100644 (file)
@@ -52,6 +52,9 @@ int virDomainSnapshotForEach(virDomainSnapshotObjListPtr snapshots,
                              virHashIterator iter,
                              void *data);
 int virDomainSnapshotUpdateRelations(virDomainSnapshotObjListPtr snapshots);
+int virDomainSnapshotCheckCycles(virDomainSnapshotObjListPtr snapshots,
+                                 virDomainSnapshotDefPtr def,
+                                 const char *domname);
 
 #define VIR_DOMAIN_SNAPSHOT_FILTERS_METADATA \
                (VIR_DOMAIN_SNAPSHOT_LIST_METADATA     | \
index 8eab67c9e09e07ac1e0f771f4b183413bf75ff0b..510904f470d731d14a47474b93237d14da586419 100755 (executable)
@@ -206,7 +206,7 @@ Metadata:       yes
 EOF
 
 cat <<EOF > exp || fail=1
-error: invalid argument: parent s3 for snapshot s2 not found
+error: invalid argument: parent s3 for moment s2 not found
 error: marker
 EOF
 compare exp err || fail=1