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 | 31 +++++++++++++++++++++++
src/storage/storage_backend.h | 30 ++++++++++++++++++++++
src/storage/storage_backend_disk.c | 2 ++
src/storage/storage_backend_fs.c | 7 ++++++
src/storage/storage_backend_iscsi.c | 2 ++
src/storage/storage_backend_logical.c | 2 ++
src/storage/storage_backend_mpath.c | 2 ++
src/storage/storage_backend_scsi.c | 2 ++
src/storage/storage_driver.c | 47 +++++++++++------------------------
9 files changed, 93 insertions(+), 32 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index e83a108..7b17ca4 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -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,
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index 76c1afa..4d7d4b0 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -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);
diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c
index 8e12974..f900dee 100644
--- a/src/storage/storage_backend_disk.c
+++ b/src/storage/storage_backend_disk.c
@@ -792,4 +792,6 @@ virStorageBackend virStorageBackendDisk = {
.createVol = virStorageBackendDiskCreateVol,
.deleteVol = virStorageBackendDiskDeleteVol,
.buildVolFrom = virStorageBackendDiskBuildVolFrom,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index c93fc1e..1615c12 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -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,
};
diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c
index 3aac9d3..7345571 100644
--- a/src/storage/storage_backend_iscsi.c
+++ b/src/storage/storage_backend_iscsi.c
@@ -474,4 +474,6 @@ virStorageBackend virStorageBackendISCSI = {
.refreshPool = virStorageBackendISCSIRefreshPool,
.stopPool = virStorageBackendISCSIStopPool,
.findPoolSources = virStorageBackendISCSIFindPoolSources,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
diff --git a/src/storage/storage_backend_logical.c
b/src/storage/storage_backend_logical.c
index a597e67..faa9a4b 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -841,4 +841,6 @@ virStorageBackend virStorageBackendLogical = {
.buildVolFrom = virStorageBackendLogicalBuildVolFrom,
.createVol = virStorageBackendLogicalCreateVol,
.deleteVol = virStorageBackendLogicalDeleteVol,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
diff --git a/src/storage/storage_backend_mpath.c b/src/storage/storage_backend_mpath.c
index 8c3b0df..402faa0 100644
--- a/src/storage/storage_backend_mpath.c
+++ b/src/storage/storage_backend_mpath.c
@@ -287,4 +287,6 @@ virStorageBackend virStorageBackendMpath = {
.checkPool = virStorageBackendMpathCheckPool,
.refreshPool = virStorageBackendMpathRefreshPool,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c
index f6f3ca2..0b44f71 100644
--- a/src/storage/storage_backend_scsi.c
+++ b/src/storage/storage_backend_scsi.c
@@ -728,4 +728,6 @@ virStorageBackend virStorageBackendSCSI = {
.refreshPool = virStorageBackendSCSIRefreshPool,
.startPool = virStorageBackendSCSIStartPool,
.stopPool = virStorageBackendSCSIStopPool,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 7303dbf..ba20c2d 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -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);
--
2.0.0