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(a)redhat.com>
---
include/libvirt/libvirt-storage.h | 9 +++++++++
src/libvirt-storage.c | 4 ++--
src/remote/remote_protocol.x | 2 ++
src/storage/storage_driver.c | 4 ++--
src/storage/storage_util.c | 10 ++++++----
5 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
index 45ec720..4517f71 100644
--- a/include/libvirt/libvirt-storage.h
+++ b/include/libvirt/libvirt-storage.h
@@ -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,
diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c
index 05eec8a..6420299 100644
--- a/src/libvirt-storage.c
+++ b/src/libvirt-storage.c
@@ -1549,7 +1549,7 @@ 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
@@ -1613,7 +1613,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
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 87b2bd3..25e62a1 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -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,
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 2103ed1..1b0d776 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -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;
diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c
index 3576435..b393795 100644
--- a/src/storage/storage_util.c
+++ b/src/storage/storage_util.c
@@ -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);
--
2.10.2