[libvirt] [PATCH RFC 27/27] qemu: snapshot: Add support for external active snapshots on gluster

Peter Krempa pkrempa at redhat.com
Mon Dec 16 16:32:55 UTC 2013


---
 src/qemu/qemu_command.c |   2 +-
 src/qemu/qemu_command.h |   9 ++++
 src/qemu/qemu_driver.c  | 113 +++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 116 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a80559e..d742248 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3826,7 +3826,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 fad8c60..872634f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11492,6 +11492,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,
@@ -11872,6 +11890,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:
@@ -12183,6 +12224,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;
@@ -12197,8 +12241,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
@@ -12212,14 +12255,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. */
@@ -12239,6 +12290,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"),
@@ -12273,17 +12345,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:
@@ -12299,7 +12387,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;
 }

@@ -12351,12 +12442,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.1




More information about the libvir-list mailing list