From 589c2ad93fa0eab8a093037ee95391619f700eb0 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Mon, 7 Jul 2014 16:50:11 +0200 Subject: [PATCH] storage: Split out volume upload/download as separate backend function 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 e83a1088c9..7b17ca4881 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 76c1afa52b..4d7d4b0272 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 8e129741de..f900dee594 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 c93fc1e122..1615c121ae 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 3aac9d3c38..73455712f7 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 a597e6745c..faa9a4b7f2 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 8c3b0dfae5..402faa0935 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 f6f3ca28b6..0b44f7145d 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 ae86c69d7b..5407dfb2a5 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); -- GitLab