mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
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:
parent
b02fca79e8
commit
589c2ad93f
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -792,4 +792,6 @@ virStorageBackend virStorageBackendDisk = {
|
||||
.createVol = virStorageBackendDiskCreateVol,
|
||||
.deleteVol = virStorageBackendDiskDeleteVol,
|
||||
.buildVolFrom = virStorageBackendDiskBuildVolFrom,
|
||||
.uploadVol = virStorageBackendVolUploadLocal,
|
||||
.downloadVol = virStorageBackendVolDownloadLocal,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
@ -474,4 +474,6 @@ virStorageBackend virStorageBackendISCSI = {
|
||||
.refreshPool = virStorageBackendISCSIRefreshPool,
|
||||
.stopPool = virStorageBackendISCSIStopPool,
|
||||
.findPoolSources = virStorageBackendISCSIFindPoolSources,
|
||||
.uploadVol = virStorageBackendVolUploadLocal,
|
||||
.downloadVol = virStorageBackendVolDownloadLocal,
|
||||
};
|
||||
|
@ -841,4 +841,6 @@ virStorageBackend virStorageBackendLogical = {
|
||||
.buildVolFrom = virStorageBackendLogicalBuildVolFrom,
|
||||
.createVol = virStorageBackendLogicalCreateVol,
|
||||
.deleteVol = virStorageBackendLogicalDeleteVol,
|
||||
.uploadVol = virStorageBackendVolUploadLocal,
|
||||
.downloadVol = virStorageBackendVolDownloadLocal,
|
||||
};
|
||||
|
@ -287,4 +287,6 @@ virStorageBackend virStorageBackendMpath = {
|
||||
|
||||
.checkPool = virStorageBackendMpathCheckPool,
|
||||
.refreshPool = virStorageBackendMpathRefreshPool,
|
||||
.uploadVol = virStorageBackendVolUploadLocal,
|
||||
.downloadVol = virStorageBackendVolDownloadLocal,
|
||||
};
|
||||
|
@ -728,4 +728,6 @@ virStorageBackend virStorageBackendSCSI = {
|
||||
.refreshPool = virStorageBackendSCSIRefreshPool,
|
||||
.startPool = virStorageBackendSCSIStartPool,
|
||||
.stopPool = virStorageBackendSCSIStopPool,
|
||||
.uploadVol = virStorageBackendVolUploadLocal,
|
||||
.downloadVol = virStorageBackendVolDownloadLocal,
|
||||
};
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user