Add support for gluster backed images as sources for snapshots in the
qemu driver. This will also simplify adding further network backed
volumes as sources for snapshot in case qemu will support them.
---
docs/formatsnapshot.html.in | 4 +-
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_command.h | 9 ++++
src/qemu/qemu_driver.c | 113 +++++++++++++++++++++++++++++++++++++++++---
4 files changed, 118 insertions(+), 10 deletions(-)
diff --git a/docs/formatsnapshot.html.in b/docs/formatsnapshot.html.in
index c2cd18c..d990c39 100644
--- a/docs/formatsnapshot.html.in
+++ b/docs/formatsnapshot.html.in
@@ -183,8 +183,8 @@
documentation for further information.
Libvirt currently supports the <code>type</code> element in the
qemu
- driver and supported values are <code>file</code> and
- <code>block</code> <span class="since">(since
1.2.2)</span>.
+ driver and supported values are <code>file</code>,
<code>block</code>
+ and <code>gluster</code> <span
class="since">(since 1.2.2)</span>.
</dd>
</dl>
</dd>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 35b7c67..4607740 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3822,7 +3822,7 @@ cleanup:
}
-static int
+int
qemuGetDriveSourceString(int type,
const char *src,
int protocol,
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 66c23cc..ec944ea 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -312,4 +312,13 @@ qemuParseKeywords(const char *str,
int *retnkeywords,
int allowEmptyValue);
+int qemuGetDriveSourceString(int type,
+ const char *src,
+ int protocol,
+ size_t nhosts,
+ virDomainDiskHostDefPtr hosts,
+ const char *username,
+ const char *secret,
+ char **path);
+
#endif /* __QEMU_COMMAND_H__*/
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f9ffe2e..a57c0be 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11502,6 +11502,24 @@ cleanup:
return ret;
}
+
+static int
+qemuDomainSnapshotDiskGetSourceString(virDomainSnapshotDiskDefPtr disk,
+ char **source)
+{
+ *source = NULL;
+
+ return qemuGetDriveSourceString(qemuSnapshotDiskGetActualType(disk),
+ disk->file,
+ disk->protocol,
+ disk->nhosts,
+ disk->hosts,
+ NULL,
+ NULL,
+ source);
+}
+
+
typedef enum {
VIR_DISK_CHAIN_NO_ACCESS,
VIR_DISK_CHAIN_READ_ONLY,
@@ -11882,6 +11900,29 @@
qemuDomainSnapshotPrepareDiskExternalOverlayActive(virDomainSnapshotDiskDefPtr d
return 0;
case VIR_DOMAIN_DISK_TYPE_NETWORK:
+ switch ((enum virDomainDiskProtocol) disk->protocol) {
+ case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
+ return 0;
+
+ case VIR_DOMAIN_DISK_PROTOCOL_NBD:
+ case VIR_DOMAIN_DISK_PROTOCOL_RBD:
+ case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
+ case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
+ case VIR_DOMAIN_DISK_PROTOCOL_HTTP:
+ case VIR_DOMAIN_DISK_PROTOCOL_HTTPS:
+ case VIR_DOMAIN_DISK_PROTOCOL_FTP:
+ case VIR_DOMAIN_DISK_PROTOCOL_FTPS:
+ case VIR_DOMAIN_DISK_PROTOCOL_TFTP:
+ case VIR_DOMAIN_DISK_PROTOCOL_LAST:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("external active snapshots are not supported on "
+ "'network' disks using '%s'
protocol"),
+ virDomainDiskProtocolTypeToString(disk->protocol));
+ return -1;
+
+ }
+ break;
+
case VIR_DOMAIN_DISK_TYPE_DIR:
case VIR_DOMAIN_DISK_TYPE_VOLUME:
case VIR_DOMAIN_DISK_TYPE_LAST:
@@ -12192,6 +12233,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virConnectPtr conn,
qemuDomainObjPrivatePtr priv = vm->privateData;
char *device = NULL;
char *source = NULL;
+ char *newsource = NULL;
+ virDomainDiskHostDefPtr newhosts = NULL;
+ virDomainDiskHostDefPtr persistHosts = NULL;
int format = snap->format;
const char *formatStr = NULL;
char *persistSource = NULL;
@@ -12206,8 +12250,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virConnectPtr conn,
return -1;
}
- if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0 ||
- (persistDisk && VIR_STRDUP(persistSource, source) < 0))
+ if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0)
goto cleanup;
/* XXX Here, we know we are about to alter disk->backingChain if
@@ -12221,14 +12264,22 @@ qemuDomainSnapshotCreateSingleDiskActive(virConnectPtr conn,
if (!(temppool = virStorageEphemeralFromSnapshotDiskDef(conn, snap)))
goto cleanup;
+ if (qemuDomainSnapshotDiskGetSourceString(snap, &source) < 0)
+ goto cleanup;
+
+ if (VIR_STRDUP(newsource, snap->file) < 0)
+ goto cleanup;
+
+ if (persistDisk &&
+ VIR_STRDUP(persistSource, snap->file) < 0)
+ goto cleanup;
+
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. */
@@ -12248,6 +12299,27 @@ qemuDomainSnapshotCreateSingleDiskActive(virConnectPtr conn,
}
break;
+ case VIR_DOMAIN_DISK_TYPE_NETWORK:
+ switch (snap->protocol) {
+ case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
+ if (!(newhosts = virDomainDiskHostDefCopy(snap->nhosts, snap->hosts)))
+ goto cleanup;
+
+ if (persistDisk &&
+ !(persistHosts = virDomainDiskHostDefCopy(snap->nhosts,
snap->hosts)))
+ goto cleanup;
+
+ break;
+
+ default:
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("snapshots on volumes using '%s' protocol
"
+ "are not supported"),
+ virDomainDiskProtocolTypeToString(snap->protocol));
+ goto cleanup;
+ }
+ break;
+
default:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("snapshots are not supported on '%s'
volumes"),
@@ -12266,17 +12338,33 @@ qemuDomainSnapshotCreateSingleDiskActive(virConnectPtr conn,
/* Update vm in place to match changes. */
need_unlink = false;
+
VIR_FREE(disk->src);
- disk->src = source;
- source = NULL;
+ virDomainDiskHostDefFree(disk->nhosts, disk->hosts);
+
+ disk->src = newsource;
disk->format = format;
disk->type = snap->type;
+ disk->protocol = snap->protocol;
+ disk->nhosts = snap->nhosts;
+ disk->hosts = newhosts;
+
+ newsource = NULL;
+ newhosts = NULL;
+
if (persistDisk) {
VIR_FREE(persistDisk->src);
+ virDomainDiskHostDefFree(persistDisk->nhosts, persistDisk->hosts);
+
persistDisk->src = persistSource;
- persistSource = NULL;
persistDisk->format = format;
persistDisk->type = snap->type;
+ persistDisk->protocol = snap->protocol;
+ persistDisk->nhosts = snap->nhosts;
+ persistDisk->hosts = persistHosts;
+
+ persistSource = NULL;
+ persistHosts = NULL;
}
cleanup:
@@ -12292,7 +12380,10 @@ cleanup:
virStorageEphemeralFree(temppool);
VIR_FREE(device);
VIR_FREE(source);
+ VIR_FREE(newsource);
VIR_FREE(persistSource);
+ virDomainDiskHostDefFree(snap->nhosts, newhosts);
+ virDomainDiskHostDefFree(snap->nhosts, persistHosts);
return ret;
}
@@ -12344,12 +12435,20 @@ qemuDomainSnapshotUndoSingleDiskActive(virConnectPtr conn,
source = NULL;
disk->format = origdisk->format;
disk->type = origdisk->type;
+ disk->protocol = origdisk->protocol;
+ virDomainDiskHostDefFree(disk->nhosts, disk->hosts);
+ disk->nhosts = origdisk->nhosts;
+ disk->hosts = virDomainDiskHostDefCopy(origdisk->nhosts, origdisk->hosts);
if (persistDisk) {
VIR_FREE(persistDisk->src);
persistDisk->src = persistSource;
persistSource = NULL;
persistDisk->format = origdisk->format;
persistDisk->type = origdisk->type;
+ persistDisk->protocol = origdisk->protocol;
+ virDomainDiskHostDefFree(persistDisk->nhosts, persistDisk->hosts);
+ persistDisk->nhosts = origdisk->nhosts;
+ persistDisk->hosts = virDomainDiskHostDefCopy(origdisk->nhosts,
origdisk->hosts);
}
cleanup:
--
1.8.5.2