|
|
c401cc |
From feb9d3652c97e848158cc22b5a6e28f0a90b6c8f Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <feb9d3652c97e848158cc22b5a6e28f0a90b6c8f@dist-git>
|
|
|
c401cc |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
c401cc |
Date: Wed, 26 Feb 2014 14:55:30 +0100
|
|
|
c401cc |
Subject: [PATCH] qemu: snapshot: Add support for external active snapshots on
|
|
|
c401cc |
gluster
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
|
|
|
c401cc |
|
|
|
c401cc |
Add support for gluster backed images as sources for snapshots in the
|
|
|
c401cc |
qemu driver. This will also simplify adding further network backed
|
|
|
c401cc |
volumes as sources for snapshot in case qemu will support them.
|
|
|
c401cc |
|
|
|
c401cc |
(cherry picked from commit 3cf074ee40b4df4123732a1591aa3b4308e9c634)
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
docs/formatsnapshot.html.in | 5 +-
|
|
|
c401cc |
src/qemu/qemu_command.c | 2 +-
|
|
|
c401cc |
src/qemu/qemu_command.h | 9 ++++
|
|
|
c401cc |
src/qemu/qemu_driver.c | 108 +++++++++++++++++++++++++++++++++++++++++---
|
|
|
c401cc |
4 files changed, 114 insertions(+), 10 deletions(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/docs/formatsnapshot.html.in b/docs/formatsnapshot.html.in
|
|
|
c401cc |
index 44ed4fd..1f9a6c6 100644
|
|
|
c401cc |
--- a/docs/formatsnapshot.html.in
|
|
|
c401cc |
+++ b/docs/formatsnapshot.html.in
|
|
|
c401cc |
@@ -183,8 +183,9 @@
|
|
|
c401cc |
documentation for further information.
|
|
|
c401cc |
|
|
|
c401cc |
Libvirt currently supports the type element in the qemu
|
|
|
c401cc |
- driver and supported values are file and
|
|
|
c401cc |
- block (since 1.2.2).
|
|
|
c401cc |
+ driver and supported values are file , block
|
|
|
c401cc |
+ and network with a protocol of gluster
|
|
|
c401cc |
+ (since 1.2.2).
|
|
|
c401cc |
|
|
|
c401cc |
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|
|
c401cc |
index 8923b09..54c36e3 100644
|
|
|
c401cc |
--- a/src/qemu/qemu_command.c
|
|
|
c401cc |
+++ b/src/qemu/qemu_command.c
|
|
|
c401cc |
@@ -3727,7 +3727,7 @@ cleanup:
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
|
|
|
c401cc |
-static int
|
|
|
c401cc |
+int
|
|
|
c401cc |
qemuGetDriveSourceString(int type,
|
|
|
c401cc |
const char *src,
|
|
|
c401cc |
int protocol,
|
|
|
c401cc |
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
|
|
|
c401cc |
index 22b7aa7..105389b 100644
|
|
|
c401cc |
--- a/src/qemu/qemu_command.h
|
|
|
c401cc |
+++ b/src/qemu/qemu_command.h
|
|
|
c401cc |
@@ -319,4 +319,13 @@ qemuParseKeywords(const char *str,
|
|
|
c401cc |
char ***retvalues,
|
|
|
c401cc |
int allowEmptyValue);
|
|
|
c401cc |
|
|
|
c401cc |
+int qemuGetDriveSourceString(int type,
|
|
|
c401cc |
+ const char *src,
|
|
|
c401cc |
+ int protocol,
|
|
|
c401cc |
+ size_t nhosts,
|
|
|
c401cc |
+ virDomainDiskHostDefPtr hosts,
|
|
|
c401cc |
+ const char *username,
|
|
|
c401cc |
+ const char *secret,
|
|
|
c401cc |
+ char **path);
|
|
|
c401cc |
+
|
|
|
c401cc |
#endif /* __QEMU_COMMAND_H__*/
|
|
|
c401cc |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
c401cc |
index 86f2775..cc6c133 100644
|
|
|
c401cc |
--- a/src/qemu/qemu_driver.c
|
|
|
c401cc |
+++ b/src/qemu/qemu_driver.c
|
|
|
c401cc |
@@ -11816,6 +11816,24 @@ cleanup:
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
+
|
|
|
c401cc |
+static int
|
|
|
c401cc |
+qemuDomainSnapshotDiskGetSourceString(virDomainSnapshotDiskDefPtr disk,
|
|
|
c401cc |
+ char **source)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ *source = NULL;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ return qemuGetDriveSourceString(virDomainSnapshotDiskGetActualType(disk),
|
|
|
c401cc |
+ disk->file,
|
|
|
c401cc |
+ disk->protocol,
|
|
|
c401cc |
+ disk->nhosts,
|
|
|
c401cc |
+ disk->hosts,
|
|
|
c401cc |
+ NULL,
|
|
|
c401cc |
+ NULL,
|
|
|
c401cc |
+ source);
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
typedef enum {
|
|
|
c401cc |
VIR_DISK_CHAIN_NO_ACCESS,
|
|
|
c401cc |
VIR_DISK_CHAIN_READ_ONLY,
|
|
|
c401cc |
@@ -12208,6 +12226,24 @@ qemuDomainSnapshotPrepareDiskExternalOverlayActive(virDomainSnapshotDiskDefPtr d
|
|
|
c401cc |
return 0;
|
|
|
c401cc |
|
|
|
c401cc |
case VIR_DOMAIN_DISK_TYPE_NETWORK:
|
|
|
c401cc |
+ switch ((enum virDomainDiskProtocol) disk->protocol) {
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
|
|
|
c401cc |
+ return 0;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_PROTOCOL_NBD:
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_PROTOCOL_RBD:
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_PROTOCOL_LAST:
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c401cc |
+ _("external active snapshots are not supported on "
|
|
|
c401cc |
+ "'network' disks using '%s' protocol"),
|
|
|
c401cc |
+ virDomainDiskProtocolTypeToString(disk->protocol));
|
|
|
c401cc |
+ return -1;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ break;
|
|
|
c401cc |
+
|
|
|
c401cc |
case VIR_DOMAIN_DISK_TYPE_DIR:
|
|
|
c401cc |
case VIR_DOMAIN_DISK_TYPE_VOLUME:
|
|
|
c401cc |
case VIR_DOMAIN_DISK_TYPE_LAST:
|
|
|
c401cc |
@@ -12510,6 +12546,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
c401cc |
char *device = NULL;
|
|
|
c401cc |
char *source = NULL;
|
|
|
c401cc |
+ char *newsource = NULL;
|
|
|
c401cc |
+ virDomainDiskHostDefPtr newhosts = NULL;
|
|
|
c401cc |
+ virDomainDiskHostDefPtr persistHosts = NULL;
|
|
|
c401cc |
int format = snap->format;
|
|
|
c401cc |
const char *formatStr = NULL;
|
|
|
c401cc |
char *persistSource = NULL;
|
|
|
c401cc |
@@ -12524,8 +12563,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
return -1;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
- if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0 ||
|
|
|
c401cc |
- (persistDisk && VIR_STRDUP(persistSource, source) < 0))
|
|
|
c401cc |
+ if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0)
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
|
|
|
c401cc |
/* XXX Here, we know we are about to alter disk->backingChain if
|
|
|
c401cc |
@@ -12539,13 +12577,21 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
if (!(snapfile = virStorageFileInitFromSnapshotDef(snap)))
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
|
|
|
c401cc |
+ if (qemuDomainSnapshotDiskGetSourceString(snap, &source) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (VIR_STRDUP(newsource, snap->file) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (persistDisk &&
|
|
|
c401cc |
+ VIR_STRDUP(persistSource, snap->file) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
switch (snap->type) {
|
|
|
c401cc |
case VIR_DOMAIN_DISK_TYPE_BLOCK:
|
|
|
c401cc |
reuse = true;
|
|
|
c401cc |
/* fallthrough */
|
|
|
c401cc |
case VIR_DOMAIN_DISK_TYPE_FILE:
|
|
|
c401cc |
- if (VIR_STRDUP(source, snap->file) < 0)
|
|
|
c401cc |
- goto cleanup;
|
|
|
c401cc |
|
|
|
c401cc |
/* create the stub file and set selinux labels; manipulate disk in
|
|
|
c401cc |
* place, in a way that can be reverted on failure. */
|
|
|
c401cc |
@@ -12565,6 +12611,27 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
}
|
|
|
c401cc |
break;
|
|
|
c401cc |
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_TYPE_NETWORK:
|
|
|
c401cc |
+ switch (snap->protocol) {
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
|
|
|
c401cc |
+ if (!(newhosts = virDomainDiskHostDefCopy(snap->nhosts, snap->hosts)))
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (persistDisk &&
|
|
|
c401cc |
+ !(persistHosts = virDomainDiskHostDefCopy(snap->nhosts, snap->hosts)))
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ break;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ default:
|
|
|
c401cc |
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
|
|
c401cc |
+ _("snapshots on volumes using '%s' protocol "
|
|
|
c401cc |
+ "are not supported"),
|
|
|
c401cc |
+ virDomainDiskProtocolTypeToString(snap->protocol));
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ break;
|
|
|
c401cc |
+
|
|
|
c401cc |
default:
|
|
|
c401cc |
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
|
|
c401cc |
_("snapshots are not supported on '%s' volumes"),
|
|
|
c401cc |
@@ -12600,17 +12667,33 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
|
|
|
c401cc |
/* Update vm in place to match changes. */
|
|
|
c401cc |
need_unlink = false;
|
|
|
c401cc |
+
|
|
|
c401cc |
VIR_FREE(disk->src);
|
|
|
c401cc |
- disk->src = source;
|
|
|
c401cc |
- source = NULL;
|
|
|
c401cc |
+ virDomainDiskHostDefFree(disk->nhosts, disk->hosts);
|
|
|
c401cc |
+
|
|
|
c401cc |
+ disk->src = newsource;
|
|
|
c401cc |
disk->format = format;
|
|
|
c401cc |
disk->type = snap->type;
|
|
|
c401cc |
+ disk->protocol = snap->protocol;
|
|
|
c401cc |
+ disk->nhosts = snap->nhosts;
|
|
|
c401cc |
+ disk->hosts = newhosts;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ newsource = NULL;
|
|
|
c401cc |
+ newhosts = NULL;
|
|
|
c401cc |
+
|
|
|
c401cc |
if (persistDisk) {
|
|
|
c401cc |
VIR_FREE(persistDisk->src);
|
|
|
c401cc |
+ virDomainDiskHostDefFree(persistDisk->nhosts, persistDisk->hosts);
|
|
|
c401cc |
+
|
|
|
c401cc |
persistDisk->src = persistSource;
|
|
|
c401cc |
- persistSource = NULL;
|
|
|
c401cc |
persistDisk->format = format;
|
|
|
c401cc |
persistDisk->type = snap->type;
|
|
|
c401cc |
+ persistDisk->protocol = snap->protocol;
|
|
|
c401cc |
+ persistDisk->nhosts = snap->nhosts;
|
|
|
c401cc |
+ persistDisk->hosts = persistHosts;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ persistSource = NULL;
|
|
|
c401cc |
+ persistHosts = NULL;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
cleanup:
|
|
|
c401cc |
@@ -12619,7 +12702,10 @@ cleanup:
|
|
|
c401cc |
virStorageFileFree(snapfile);
|
|
|
c401cc |
VIR_FREE(device);
|
|
|
c401cc |
VIR_FREE(source);
|
|
|
c401cc |
+ VIR_FREE(newsource);
|
|
|
c401cc |
VIR_FREE(persistSource);
|
|
|
c401cc |
+ virDomainDiskHostDefFree(snap->nhosts, newhosts);
|
|
|
c401cc |
+ virDomainDiskHostDefFree(snap->nhosts, persistHosts);
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
@@ -12658,12 +12744,20 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
source = NULL;
|
|
|
c401cc |
disk->format = origdisk->format;
|
|
|
c401cc |
disk->type = origdisk->type;
|
|
|
c401cc |
+ disk->protocol = origdisk->protocol;
|
|
|
c401cc |
+ virDomainDiskHostDefFree(disk->nhosts, disk->hosts);
|
|
|
c401cc |
+ disk->nhosts = origdisk->nhosts;
|
|
|
c401cc |
+ disk->hosts = virDomainDiskHostDefCopy(origdisk->nhosts, origdisk->hosts);
|
|
|
c401cc |
if (persistDisk) {
|
|
|
c401cc |
VIR_FREE(persistDisk->src);
|
|
|
c401cc |
persistDisk->src = persistSource;
|
|
|
c401cc |
persistSource = NULL;
|
|
|
c401cc |
persistDisk->format = origdisk->format;
|
|
|
c401cc |
persistDisk->type = origdisk->type;
|
|
|
c401cc |
+ persistDisk->protocol = origdisk->protocol;
|
|
|
c401cc |
+ virDomainDiskHostDefFree(persistDisk->nhosts, persistDisk->hosts);
|
|
|
c401cc |
+ persistDisk->nhosts = origdisk->nhosts;
|
|
|
c401cc |
+ persistDisk->hosts = virDomainDiskHostDefCopy(origdisk->nhosts, origdisk->hosts);
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
cleanup:
|
|
|
c401cc |
--
|
|
|
c401cc |
1.9.0
|
|
|
c401cc |
|