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.
This commit is contained in:
Peter Krempa 2014-07-07 16:50:11 +02:00
parent b02fca79e8
commit 589c2ad93f
9 changed files with 93 additions and 32 deletions

View 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,

View 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);

View File

@ -792,4 +792,6 @@ virStorageBackend virStorageBackendDisk = {
.createVol = virStorageBackendDiskCreateVol,
.deleteVol = virStorageBackendDiskDeleteVol,
.buildVolFrom = virStorageBackendDiskBuildVolFrom,
.uploadVol = virStorageBackendVolUploadLocal,
.downloadVol = virStorageBackendVolDownloadLocal,
};

View 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,
};

View File

@ -474,4 +474,6 @@ virStorageBackend virStorageBackendISCSI = {
.refreshPool = virStorageBackendISCSIRefreshPool,
.stopPool = virStorageBackendISCSIStopPool,
.findPoolSources = virStorageBackendISCSIFindPoolSources,
.uploadVol = virStorageBackendVolUploadLocal,
.downloadVol = virStorageBackendVolDownloadLocal,
};

View File

@ -841,4 +841,6 @@ virStorageBackend virStorageBackendLogical = {
.buildVolFrom = virStorageBackendLogicalBuildVolFrom,
.createVol = virStorageBackendLogicalCreateVol,
.deleteVol = virStorageBackendLogicalDeleteVol,
.uploadVol = virStorageBackendVolUploadLocal,
.downloadVol = virStorageBackendVolDownloadLocal,
};

View File

@ -287,4 +287,6 @@ virStorageBackend virStorageBackendMpath = {
.checkPool = virStorageBackendMpathCheckPool,
.refreshPool = virStorageBackendMpathRefreshPool,
.uploadVol = virStorageBackendVolUploadLocal,
.downloadVol = virStorageBackendVolDownloadLocal,
};

View File

@ -728,4 +728,6 @@ virStorageBackend virStorageBackendSCSI = {
.refreshPool = virStorageBackendSCSIRefreshPool,
.startPool = virStorageBackendSCSIStartPool,
.stopPool = virStorageBackendSCSIStopPool,
.uploadVol = virStorageBackendVolUploadLocal,
.downloadVol = virStorageBackendVolDownloadLocal,
};

View 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);