Add support for specifying various types when doing snapshots. This will
later allow to do snapshots on network backed volumes.
RFC: This patch is lacking tests and domain schema touch up.
---
src/conf/snapshot_conf.c | 9 ++++++++
src/qemu/qemu_driver.c | 56 +++++++++++++++++++++++++++++++-----------------
2 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index 5958f13..f6f170e 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -108,6 +108,7 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
{
int ret = -1;
char *snapshot = NULL;
+ char *type = NULL;
xmlNodePtr cur;
def->name = virXMLPropString(node, "name");
@@ -129,6 +130,13 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
}
def->type = -1;
+ if ((type = virXMLPropString(node, "type"))) {
+ if ((def->type = virDomainDiskTypeFromString(type)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("unknown disk snapshot type '%s'"),
type);
+ goto cleanup;
+ }
+ }
for (cur = node->children; cur; cur = cur->next) {
if (cur->type != XML_ELEMENT_NODE)
@@ -174,6 +182,7 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
ret = 0;
cleanup:
VIR_FREE(snapshot);
+ VIR_FREE(type);
if (ret < 0)
virDomainSnapshotDiskDefClear(def);
return ret;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b9c270b..e6d4f47 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12115,33 +12115,48 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr
driver,
}
if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0 ||
- VIR_STRDUP(source, snap->file) < 0 ||
(persistDisk && VIR_STRDUP(persistSource, source) < 0))
goto cleanup;
- /* create the stub file and set selinux labels; manipulate disk in
- * place, in a way that can be reverted on failure. */
- if (!reuse) {
- fd = qemuOpenFile(driver, vm, source, O_WRONLY | O_TRUNC | O_CREAT,
- &need_unlink, NULL);
- if (fd < 0)
- goto cleanup;
- VIR_FORCE_CLOSE(fd);
- }
-
/* XXX Here, we know we are about to alter disk->backingChain if
- * successful, so we nuke the existing chain so that future
- * commands will recompute it. Better would be storing the chain
- * ourselves rather than reprobing, but this requires modifying
- * domain_conf and our XML to fully track the chain across
- * libvirtd restarts. */
+ * successful, so we nuke the existing chain so that future commands will
+ * recompute it. Better would be storing the chain ourselves rather than
+ * reprobing, but this requires modifying domain_conf and our XML to fully
+ * track the chain across libvirtd restarts. */
virStorageFileFreeMetadata(disk->backingChain);
disk->backingChain = NULL;
- if (qemuDomainPrepareDiskChainElement(driver, vm, disk, source,
- VIR_DISK_CHAIN_READ_WRITE) < 0) {
- qemuDomainPrepareDiskChainElement(driver, vm, disk, source,
- VIR_DISK_CHAIN_NO_ACCESS);
+ switch (snap->type) {
+ case VIR_DOMAIN_DISK_TYPE_BLOCK:
+ reuse = true;
+ /* fallthrough */
+ case -1: /* type was not provided in snapshot conf */
+ case VIR_DOMAIN_DISK_TYPE_FILE:
+ if (VIR_STRDUP(source, snap->file) < 0)
+ goto cleanup;
+
+ /* create the stub file and set selinux labels; manipulate disk in
+ * place, in a way that can be reverted on failure. */
+ if (!reuse) {
+ fd = qemuOpenFile(driver, vm, source, O_WRONLY | O_TRUNC | O_CREAT,
+ &need_unlink, NULL);
+ if (fd < 0)
+ goto cleanup;
+ VIR_FORCE_CLOSE(fd);
+ }
+
+ if (qemuDomainPrepareDiskChainElement(driver, vm, disk, source,
+ VIR_DISK_CHAIN_READ_WRITE) < 0) {
+ qemuDomainPrepareDiskChainElement(driver, vm, disk, source,
+ VIR_DISK_CHAIN_NO_ACCESS);
+ goto cleanup;
+ }
+ break;
+
+ default:
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("snapshots are not supported on '%s'
volumes"),
+ virDomainDiskTypeToString(snap->type));
goto cleanup;
}
@@ -12160,6 +12175,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
disk->src = source;
source = NULL;
disk->format = format;
+ disk->type = snap->type;
if (persistDisk) {
VIR_FREE(persistDisk->src);
persistDisk->src = persistSource;
--
1.8.4.3