Introduce virStorageVol{Download,Upload}Flags

These flags to APIs will tell if caller wants to use sparse
stream for storage transfer. At the same time, it's safe to
enable them in storage driver frontend and rely on our backends
checking the flags. This way we can enable specific flags only on
some specific backends, e.g. enable
VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM for filesystem backend but
not iSCSI backend.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2016-04-08 15:41:18 +02:00
parent 8f08f28f74
commit 1f43aa67c5
5 changed files with 33 additions and 8 deletions

View File

@ -346,11 +346,20 @@ virStorageVolPtr virStorageVolCreateXMLFrom (virStoragePoolPtr pool,
const char *xmldesc,
virStorageVolPtr clonevol,
unsigned int flags);
typedef enum {
VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM = 1 << 0, /* Use sparse stream */
} virStorageVolDownloadFlags;
int virStorageVolDownload (virStorageVolPtr vol,
virStreamPtr stream,
unsigned long long offset,
unsigned long long length,
unsigned int flags);
typedef enum {
VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM = 1 << 0, /* Use sparse stream */
} virStorageVolUploadFlags;
int virStorageVolUpload (virStorageVolPtr vol,
virStreamPtr stream,
unsigned long long offset,

View File

@ -1549,12 +1549,19 @@ virStorageVolCreateXMLFrom(virStoragePoolPtr pool,
* @stream: stream to use as output
* @offset: position in @vol to start reading from
* @length: limit on amount of data to download
* @flags: extra flags; not used yet, so callers should always pass 0
* @flags: bitwise-OR of virStorageVolDownloadFlags
*
* Download the content of the volume as a stream. If @length
* is zero, then the remaining contents of the volume after
* @offset will be downloaded.
*
* If VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM is set in @flags
* effective transmission of holes is enabled. This assumes using
* the @stream with combination of virStreamSparseRecvAll() or
* virStreamRecvFlags(stream, ..., flags =
* VIR_STREAM_RECV_STOP_AT_HOLE) for honouring holes sent by
* server.
*
* This call sets up an asynchronous stream; subsequent use of
* stream APIs is necessary to transfer the actual data,
* determine how much data is successfully transferred, and
@ -1613,7 +1620,7 @@ virStorageVolDownload(virStorageVolPtr vol,
* @stream: stream to use as input
* @offset: position to start writing to
* @length: limit on amount of data to upload
* @flags: extra flags; not used yet, so callers should always pass 0
* @flags: bitwise-OR of virStorageVolUploadFlags
*
* Upload new content to the volume from a stream. This call
* will fail if @offset + @length exceeds the size of the
@ -1621,6 +1628,11 @@ virStorageVolDownload(virStorageVolPtr vol,
* will be raised if an attempt is made to upload greater
* than @length bytes of data.
*
* If VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM is set in @flags
* effective transmission of holes is enabled. This assumes using
* the @stream with combination of virStreamSparseSendAll() or
* virStreamSendHole() to preserve source file sparseness.
*
* This call sets up an asynchronous stream; subsequent use of
* stream APIs is necessary to transfer the actual data,
* determine how much data is successfully transferred, and

View File

@ -4896,6 +4896,7 @@ enum remote_procedure {
/**
* @generate: both
* @writestream: 1
* @sparseflag: VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM
* @acl: storage_vol:data_write
*/
REMOTE_PROC_STORAGE_VOL_UPLOAD = 208,
@ -4903,6 +4904,7 @@ enum remote_procedure {
/**
* @generate: both
* @readstream: 1
* @sparseflag: VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM
* @acl: storage_vol:data_read
*/
REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209,

View File

@ -2117,7 +2117,7 @@ storageVolDownload(virStorageVolPtr obj,
virStorageVolDefPtr vol = NULL;
int ret = -1;
virCheckFlags(0, -1);
virCheckFlags(VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM, -1);
if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
return -1;
@ -2285,7 +2285,7 @@ storageVolUpload(virStorageVolPtr obj,
virStorageVolStreamInfoPtr cbdata = NULL;
int ret = -1;
virCheckFlags(0, -1);
virCheckFlags(VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM, -1);
if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
return -1;

View File

@ -2401,8 +2401,9 @@ virStorageBackendVolUploadLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
char *target_path = vol->target.path;
int ret = -1;
int has_snap = 0;
bool sparse = flags & VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM;
virCheckFlags(0, -1);
virCheckFlags(VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM, -1);
/* if volume has target format VIR_STORAGE_FILE_PLOOP
* we need to restore DiskDescriptor.xml, according to
* new contents of volume. This operation will be perfomed
@ -2427,7 +2428,7 @@ virStorageBackendVolUploadLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
/* Not using O_CREAT because the file is required to already exist at
* this point */
ret = virFDStreamOpenBlockDevice(stream, target_path,
offset, len, false, O_WRONLY);
offset, len, sparse, O_WRONLY);
cleanup:
VIR_FREE(path);
@ -2447,8 +2448,9 @@ virStorageBackendVolDownloadLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
char *target_path = vol->target.path;
int ret = -1;
int has_snap = 0;
bool sparse = flags & VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM;
virCheckFlags(0, -1);
virCheckFlags(VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM, -1);
if (vol->target.format == VIR_STORAGE_FILE_PLOOP) {
has_snap = storageBackendPloopHasSnapshots(vol->target.path);
if (has_snap < 0) {
@ -2465,7 +2467,7 @@ virStorageBackendVolDownloadLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
}
ret = virFDStreamOpenBlockDevice(stream, target_path,
offset, len, false, O_RDONLY);
offset, len, sparse, O_RDONLY);
cleanup:
VIR_FREE(path);