From 7efe930ec3c81feefeea8ec9b7ad9c8a55f8f53d Mon Sep 17 00:00:00 2001
From: Eric Blake virDomainCheckpointCreateXML()
since
- 5.6.0.
+ 5.6.0. Likewise, the creation of checkpoints when
+ external snapshots exist is currently forbidden, although future
+ work will make it possible to integrate these two concepts.
Attributes of libvirt checkpoints are stored as child elements diff --git a/docs/formatsnapshot.html.in b/docs/formatsnapshot.html.in index 5081765178..d640deb86d 100644 --- a/docs/formatsnapshot.html.in +++ b/docs/formatsnapshot.html.in @@ -93,7 +93,9 @@ sets that snapshot as current, and the prior current snapshot is the parent of the new snapshot. Branches in the hierarchy can be formed by reverting to a snapshot with a child, then creating - another snapshot. + another snapshot. For now, the creation of external snapshots + when checkpoints exist is forbidden, although future work will + make it possible to integrate these two concepts.
The top-level domainsnapshot
element may contain
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 691e27fd9f..4ca3eb7bde 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15777,6 +15777,12 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
if (!(vm = qemuDomObjFromDomain(domain)))
goto cleanup;
+ if (virDomainListCheckpoints(vm->checkpoints, NULL, domain, NULL, 0) > 0) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("cannot create snapshot while checkpoint exists"));
+ goto cleanup;
+ }
+
cfg = virQEMUDriverGetConfig(driver);
if (virDomainSnapshotCreateXMLEnsureACL(domain->conn, vm->def, flags) < 0)
@@ -18515,6 +18521,12 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
if (virDomainBlockRebaseEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
+ if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, 0) > 0) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("cannot perform block rebase while checkpoint exists"));
+ goto cleanup;
+ }
+
/* For normal rebase (enhanced blockpull), the common code handles
* everything, including vm cleanup. */
if (!(flags & VIR_DOMAIN_BLOCK_REBASE_COPY))
@@ -18599,6 +18611,12 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *disk, const char *destxml,
if (virDomainBlockCopyEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
+ if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, 0) > 0) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("cannot perform block copy while checkpoint exists"));
+ goto cleanup;
+ }
+
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
@@ -18661,6 +18679,13 @@ qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth,
return -1;
}
+ if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, 0) > 0) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("cannot perform block pull while checkpoint exists"));
+ virDomainObjEndAPI(&vm);
+ return -1;
+ }
+
return qemuDomainBlockPullCommon(dom->conn->privateData,
vm, path, NULL, bandwidth, flags);
}
@@ -18711,6 +18736,12 @@ qemuDomainBlockCommit(virDomainPtr dom,
if (virDomainBlockCommitEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
+ if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, 0) > 0) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("cannot perform block commit while checkpoint exists"));
+ goto cleanup;
+ }
+
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
@@ -22431,6 +22462,12 @@ static int qemuDomainRename(virDomainPtr dom,
goto endjob;
}
+ if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, flags) > 0) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("cannot rename domain with checkpoints"));
+ goto endjob;
+ }
+
if (virDomainObjListRename(driver->domains, vm, new_name, flags,
qemuDomainRenameCallback, driver) < 0)
goto endjob;
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index ab0f8b06d6..e439b35d2f 100755
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -7698,6 +7698,12 @@ testDomainSnapshotCreateXML(virDomainPtr domain,
if (!(vm = testDomObjFromDomain(domain)))
goto cleanup;
+ if (virDomainListCheckpoints(vm->checkpoints, NULL, domain, NULL, 0) > 0) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("cannot create snapshot while checkpoint exists"));
+ goto cleanup;
+ }
+
if (!vm->persistent && (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT)) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("cannot halt after transient domain snapshot"));
@@ -8158,6 +8164,12 @@ testDomainCheckpointCreateXML(virDomainPtr domain,
if (!(vm = testDomObjFromDomain(domain)))
goto cleanup;
+ if (virDomainSnapshotObjListNum(vm->snapshots, NULL, 0) > 0) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("cannot create checkpoint while snapshot exists"));
+ goto cleanup;
+ }
+
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("cannot create checkpoint for inactive domain"));
diff --git a/tests/virsh-checkpoint b/tests/virsh-checkpoint
index 4fe111f5b7..75bdc293be 100755
--- a/tests/virsh-checkpoint
+++ b/tests/virsh-checkpoint
@@ -38,6 +38,10 @@ $abs_top_builddir/tools/virsh --connect test:///default >out 2>err '
checkpoint-create-as test c1
checkpoint-create-as test c3
checkpoint-create-as test c2
+ # snapshots cannot be created while checkpoints exist
+ echo --err marker
+ snapshot-create-as test s1
+ echo --err marker
# Checking tree view (siblings sorted alphabetically)
checkpoint-list test --tree
# Demonstrate list filtering
@@ -77,6 +81,9 @@ Domain checkpoint c1 created
Domain checkpoint c3 created
Domain checkpoint c2 created
+
+
+
c1
|
+- c3
@@ -126,6 +133,9 @@ compare exp out.cooked || fail=1
cat <