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

Peter Krempa pkrempa at redhat.com
Mon Nov 25 19:11:48 UTC 2013


This is a basic implementation of snapshots on gluster. Many things are
lacking, especially cleanup after a failed snapshot.
---
 src/qemu/qemu_command.c |   2 +-
 src/qemu/qemu_command.h |   9 ++++
 src/qemu/qemu_driver.c  | 106 ++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 109 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 7a6e322..200ba45 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 e6d4f47..4aa88c8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11412,6 +11412,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,
@@ -11792,6 +11810,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:
@@ -12101,6 +12142,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     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;
@@ -12114,8 +12158,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
         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
@@ -12126,14 +12169,22 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     virStorageFileFreeMetadata(disk->backingChain);
     disk->backingChain = NULL;

+    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. */
@@ -12153,6 +12204,27 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
         }
         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"),
@@ -12171,16 +12243,33 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,

     /* 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:
@@ -12188,7 +12277,10 @@ cleanup:
         VIR_WARN("unable to unlink just-created %s", source);
     VIR_FREE(device);
     VIR_FREE(source);
+    VIR_FREE(newsource);
     VIR_FREE(persistSource);
+    virDomainDiskHostDefFree(snap->nhosts, newhosts);
+    virDomainDiskHostDefFree(snap->nhosts, persistHosts);
     return ret;
 }

-- 
1.8.4.3




More information about the libvir-list mailing list