render / rpms / libvirt

Forked from rpms/libvirt 10 months ago
Clone
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