#include "stat-time.h"
#include "virstring.h"
#include "virxml.h"
+#include "fdstream.h"
#if WITH_STORAGE_LVM
# include "storage_backend_logical.h"
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,
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,
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;
virStorageBackendRefreshVol refreshVol;
virStorageBackendDeleteVol deleteVol;
virStorageBackendVolumeResize resizeVol;
+ virStorageBackendVolumeUpload uploadVol;
+ virStorageBackendVolumeDownload downloadVol;
};
virStorageBackendPtr virStorageBackendForType(int type);
.createVol = virStorageBackendDiskCreateVol,
.deleteVol = virStorageBackendDiskDeleteVol,
.buildVolFrom = virStorageBackendDiskBuildVolFrom,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
}
}
+
virStorageBackend virStorageBackendDirectory = {
.type = VIR_STORAGE_POOL_DIR,
.refreshVol = virStorageBackendFileSystemVolRefresh,
.deleteVol = virStorageBackendFileSystemVolDelete,
.resizeVol = virStorageBackendFileSystemVolResize,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
#if WITH_STORAGE_FS
.refreshVol = virStorageBackendFileSystemVolRefresh,
.deleteVol = virStorageBackendFileSystemVolDelete,
.resizeVol = virStorageBackendFileSystemVolResize,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
virStorageBackend virStorageBackendNetFileSystem = {
.type = VIR_STORAGE_POOL_NETFS,
.refreshVol = virStorageBackendFileSystemVolRefresh,
.deleteVol = virStorageBackendFileSystemVolDelete,
.resizeVol = virStorageBackendFileSystemVolResize,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
.refreshPool = virStorageBackendISCSIRefreshPool,
.stopPool = virStorageBackendISCSIStopPool,
.findPoolSources = virStorageBackendISCSIFindPoolSources,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
.buildVolFrom = virStorageBackendLogicalBuildVolFrom,
.createVol = virStorageBackendLogicalCreateVol,
.deleteVol = virStorageBackendLogicalDeleteVol,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
.checkPool = virStorageBackendMpathCheckPool,
.refreshPool = virStorageBackendMpathRefreshPool,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
.refreshPool = virStorageBackendSCSIRefreshPool,
.startPool = virStorageBackendSCSIStartPool,
.stopPool = virStorageBackendSCSIStopPool,
+ .uploadVol = virStorageBackendVolUploadLocal,
+ .downloadVol = virStorageBackendVolDownloadLocal,
};
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)
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);
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)
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);