]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: Split out volume upload/download as separate backend function
authorPeter Krempa <pkrempa@redhat.com>
Mon, 7 Jul 2014 14:50:11 +0000 (16:50 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 11 Jul 2014 07:54:08 +0000 (09:54 +0200)
For non-local storage drivers we can't expect to use the FDStream
backend for up/downloading volumes. Split the code into a separate
backend function so that we can add protocol specific code later.

src/storage/storage_backend.c
src/storage/storage_backend.h
src/storage/storage_backend_disk.c
src/storage/storage_backend_fs.c
src/storage/storage_backend_iscsi.c
src/storage/storage_backend_logical.c
src/storage/storage_backend_mpath.c
src/storage/storage_backend_scsi.c
src/storage/storage_driver.c

index e83a1088c98785175eb28d783fec3e4435f25e0e..7b17ca488155d94d0a86c5766cbb3794dbdd4f76 100644 (file)
@@ -56,6 +56,7 @@
 #include "stat-time.h"
 #include "virstring.h"
 #include "virxml.h"
+#include "fdstream.h"
 
 #if WITH_STORAGE_LVM
 # include "storage_backend_logical.h"
@@ -1669,6 +1670,36 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool,
     return stablepath;
 }
 
+int
+virStorageBackendVolUploadLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
+                                virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
+                                virStorageVolDefPtr vol,
+                                virStreamPtr stream,
+                                unsigned long long offset,
+                                unsigned long long len,
+                                unsigned int flags)
+{
+    virCheckFlags(0, -1);
+
+    /* Not using O_CREAT because the file is required to already exist at
+     * this point */
+    return virFDStreamOpenFile(stream, vol->target.path, offset, len, O_WRONLY);
+}
+
+int
+virStorageBackendVolDownloadLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
+                                  virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
+                                  virStorageVolDefPtr vol,
+                                  virStreamPtr stream,
+                                  unsigned long long offset,
+                                  unsigned long long len,
+                                  unsigned int flags)
+{
+    virCheckFlags(0, -1);
+
+    return virFDStreamOpenFile(stream, vol->target.path, offset, len, O_RDONLY);
+}
+
 #ifdef GLUSTER_CLI
 int
 virStorageBackendFindGlusterPoolSources(const char *host,
index 76c1afa52b99ce3b3b10d469961f4620d59c960d..4d7d4b0272a454bbbb4866b512f62607995d5d1e 100644 (file)
@@ -73,6 +73,20 @@ typedef int (*virStorageBackendVolumeResize)(virConnectPtr conn,
                                              virStorageVolDefPtr vol,
                                              unsigned long long capacity,
                                              unsigned int flags);
+typedef int (*virStorageBackendVolumeDownload)(virConnectPtr conn,
+                                               virStoragePoolObjPtr obj,
+                                               virStorageVolDefPtr vol,
+                                               virStreamPtr stream,
+                                               unsigned long long offset,
+                                               unsigned long long length,
+                                               unsigned int flags);
+typedef int (*virStorageBackendVolumeUpload)(virConnectPtr conn,
+                                             virStoragePoolObjPtr obj,
+                                             virStorageVolDefPtr vol,
+                                             virStreamPtr stream,
+                                             unsigned long long offset,
+                                             unsigned long long len,
+                                             unsigned int flags);
 
 /* File creation/cloning functions used for cloning between backends */
 int virStorageBackendCreateRaw(virConnectPtr conn,
@@ -91,6 +105,20 @@ int virStorageBackendFindGlusterPoolSources(const char *host,
                                             int pooltype,
                                             virStoragePoolSourceListPtr list);
 
+int virStorageBackendVolUploadLocal(virConnectPtr conn,
+                                    virStoragePoolObjPtr pool,
+                                    virStorageVolDefPtr vol,
+                                    virStreamPtr stream,
+                                    unsigned long long offset,
+                                    unsigned long long len,
+                                    unsigned int flags);
+int virStorageBackendVolDownloadLocal(virConnectPtr conn,
+                                      virStoragePoolObjPtr pool,
+                                      virStorageVolDefPtr vol,
+                                      virStreamPtr stream,
+                                      unsigned long long offset,
+                                      unsigned long long len,
+                                      unsigned int flags);
 
 typedef struct _virStorageBackend virStorageBackend;
 typedef virStorageBackend *virStorageBackendPtr;
@@ -114,6 +142,8 @@ struct _virStorageBackend {
     virStorageBackendRefreshVol refreshVol;
     virStorageBackendDeleteVol deleteVol;
     virStorageBackendVolumeResize resizeVol;
+    virStorageBackendVolumeUpload uploadVol;
+    virStorageBackendVolumeDownload downloadVol;
 };
 
 virStorageBackendPtr virStorageBackendForType(int type);
index 8e129741de2c15b0a0819cb522f8a55744d18655..f900dee5948e0e58b4627bb0ba449dece6c2086b 100644 (file)
@@ -792,4 +792,6 @@ virStorageBackend virStorageBackendDisk = {
     .createVol = virStorageBackendDiskCreateVol,
     .deleteVol = virStorageBackendDiskDeleteVol,
     .buildVolFrom = virStorageBackendDiskBuildVolFrom,
+    .uploadVol = virStorageBackendVolUploadLocal,
+    .downloadVol = virStorageBackendVolDownloadLocal,
 };
index c93fc1e1225b55e4fdf2b53ce74a610530a69244..1615c121ae56c737bb5d23cfb0f8a673904f918f 100644 (file)
@@ -1275,6 +1275,7 @@ virStorageBackendFileSystemVolResize(virConnectPtr conn ATTRIBUTE_UNUSED,
     }
 }
 
+
 virStorageBackend virStorageBackendDirectory = {
     .type = VIR_STORAGE_POOL_DIR,
 
@@ -1288,6 +1289,8 @@ virStorageBackend virStorageBackendDirectory = {
     .refreshVol = virStorageBackendFileSystemVolRefresh,
     .deleteVol = virStorageBackendFileSystemVolDelete,
     .resizeVol = virStorageBackendFileSystemVolResize,
+    .uploadVol = virStorageBackendVolUploadLocal,
+    .downloadVol = virStorageBackendVolDownloadLocal,
 };
 
 #if WITH_STORAGE_FS
@@ -1306,6 +1309,8 @@ virStorageBackend virStorageBackendFileSystem = {
     .refreshVol = virStorageBackendFileSystemVolRefresh,
     .deleteVol = virStorageBackendFileSystemVolDelete,
     .resizeVol = virStorageBackendFileSystemVolResize,
+    .uploadVol = virStorageBackendVolUploadLocal,
+    .downloadVol = virStorageBackendVolDownloadLocal,
 };
 virStorageBackend virStorageBackendNetFileSystem = {
     .type = VIR_STORAGE_POOL_NETFS,
@@ -1323,6 +1328,8 @@ virStorageBackend virStorageBackendNetFileSystem = {
     .refreshVol = virStorageBackendFileSystemVolRefresh,
     .deleteVol = virStorageBackendFileSystemVolDelete,
     .resizeVol = virStorageBackendFileSystemVolResize,
+    .uploadVol = virStorageBackendVolUploadLocal,
+    .downloadVol = virStorageBackendVolDownloadLocal,
 };
 
 
index 3aac9d3c38802c0f6a41997807ce095b34deb119..73455712f7bf4533e5eee6d2fba9824fc45bf850 100644 (file)
@@ -474,4 +474,6 @@ virStorageBackend virStorageBackendISCSI = {
     .refreshPool = virStorageBackendISCSIRefreshPool,
     .stopPool = virStorageBackendISCSIStopPool,
     .findPoolSources = virStorageBackendISCSIFindPoolSources,
+    .uploadVol = virStorageBackendVolUploadLocal,
+    .downloadVol = virStorageBackendVolDownloadLocal,
 };
index a597e6745c71334d97829cc880abc1c7e02c7099..faa9a4b7f24c766b03638c98124dd301b442a756 100644 (file)
@@ -841,4 +841,6 @@ virStorageBackend virStorageBackendLogical = {
     .buildVolFrom = virStorageBackendLogicalBuildVolFrom,
     .createVol = virStorageBackendLogicalCreateVol,
     .deleteVol = virStorageBackendLogicalDeleteVol,
+    .uploadVol = virStorageBackendVolUploadLocal,
+    .downloadVol = virStorageBackendVolDownloadLocal,
 };
index 8c3b0dfae5698e573aac48107315d824645998b7..402faa0935c004f415e0de37052bddf2837b89f4 100644 (file)
@@ -287,4 +287,6 @@ virStorageBackend virStorageBackendMpath = {
 
     .checkPool = virStorageBackendMpathCheckPool,
     .refreshPool = virStorageBackendMpathRefreshPool,
+    .uploadVol = virStorageBackendVolUploadLocal,
+    .downloadVol = virStorageBackendVolDownloadLocal,
 };
index f6f3ca28b6b69acd076cb3518461479c1d3efbfc..0b44f7145d6216bec55f5c3166d63569f7ecbdbc 100644 (file)
@@ -728,4 +728,6 @@ virStorageBackend virStorageBackendSCSI = {
     .refreshPool = virStorageBackendSCSIRefreshPool,
     .startPool = virStorageBackendSCSIStartPool,
     .stopPool = virStorageBackendSCSIStopPool,
+    .uploadVol = virStorageBackendVolUploadLocal,
+    .downloadVol = virStorageBackendVolDownloadLocal,
 };
index ae86c69d7bf494b93786b8c86ec45579ae50428c..5407dfb2a5e038fd1f6dcd91c859724e35724165 100644 (file)
@@ -1920,13 +1920,14 @@ storageVolDownload(virStorageVolPtr obj,
                    unsigned long long length,
                    unsigned int flags)
 {
+    virStorageBackendPtr backend;
     virStoragePoolObjPtr pool = NULL;
     virStorageVolDefPtr vol = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
 
-    if (!(vol = virStorageVolDefFromVol(obj, &pool, NULL)))
+    if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
         return -1;
 
     if (virStorageVolDownloadEnsureACL(obj->conn, pool->def, vol) < 0)
@@ -1939,13 +1940,14 @@ storageVolDownload(virStorageVolPtr obj,
         goto cleanup;
     }
 
-    if (virFDStreamOpenFile(stream,
-                            vol->target.path,
-                            offset, length,
-                            O_RDONLY) < 0)
+    if (!backend->downloadVol) {
+        virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                       _("storage pool doesn't support volume download"));
         goto cleanup;
+    }
 
-    ret = 0;
+    ret = backend->downloadVol(obj->conn, pool, vol, stream,
+                               offset, length, flags);
 
  cleanup:
     virStoragePoolObjUnlock(pool);
@@ -1961,13 +1963,14 @@ storageVolUpload(virStorageVolPtr obj,
                  unsigned long long length,
                  unsigned int flags)
 {
+    virStorageBackendPtr backend;
     virStoragePoolObjPtr pool = NULL;
     virStorageVolDefPtr vol = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
 
-    if (!(vol = virStorageVolDefFromVol(obj, &pool, NULL)))
+    if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
         return -1;
 
     if (virStorageVolUploadEnsureACL(obj->conn, pool->def, vol) < 0)
@@ -1987,34 +1990,14 @@ storageVolUpload(virStorageVolPtr obj,
         goto cleanup;
     }
 
-    switch ((virStoragePoolType) pool->def->type) {
-    case VIR_STORAGE_POOL_DIR:
-    case VIR_STORAGE_POOL_FS:
-    case VIR_STORAGE_POOL_NETFS:
-    case VIR_STORAGE_POOL_LOGICAL:
-    case VIR_STORAGE_POOL_DISK:
-    case VIR_STORAGE_POOL_ISCSI:
-    case VIR_STORAGE_POOL_SCSI:
-    case VIR_STORAGE_POOL_MPATH:
-        /* Not using O_CREAT because the file is required to already exist at
-         * this point */
-        if (virFDStreamOpenFile(stream, vol->target.path,
-                                offset, length, O_WRONLY) < 0)
-            goto cleanup;
-
-        break;
-
-    case VIR_STORAGE_POOL_SHEEPDOG:
-    case VIR_STORAGE_POOL_RBD:
-    case VIR_STORAGE_POOL_GLUSTER:
-    case VIR_STORAGE_POOL_LAST:
-        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
-                       _("volume upload is not supported with pools of type %s"),
-                       virStoragePoolTypeToString(pool->def->type));
+    if (!backend->uploadVol) {
+        virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                       _("storage pool doesn't support volume upload"));
         goto cleanup;
     }
 
-    ret = 0;
+    ret = backend->uploadVol(obj->conn, pool, vol, stream,
+                             offset, length, flags);
 
  cleanup:
     virStoragePoolObjUnlock(pool);