]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Introduce virStorageVol{Download,Upload}Flags
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 8 Apr 2016 13:41:18 +0000 (15:41 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 18 May 2017 05:42:13 +0000 (07:42 +0200)
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>
include/libvirt/libvirt-storage.h
src/libvirt-storage.c
src/remote/remote_protocol.x
src/storage/storage_driver.c
src/storage/storage_util.c

index 45ec72065620e589a305ca0ad972c8680e4b45a9..4517f713c36e73d087ca7edceb7ca8447f30c734 100644 (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,
index 05eec8a9d421a31dce01035f8bb930da66b2d052..35f9926d524e8afb7a02a7bcad6ba91ebf32110b 100644 (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
index 87b2bd365a0b27280d4480937a82ce9a312c4e57..25e62a181c3c3f5d0e878a0bb543a1db93abf3fa 100644 (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,
index 2103ed11dfeecd2d9c8e43b1ff0ec01bd3269607..1b0d776c726378cd0a627a763dc6521b4cd080b0 100644 (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;
index 908cad8746c4b7bef24deac26557343242aba3ee..493c651b7f5484d422e30f96f820e085d51e151f 100644 (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);