]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Introduce virStreamSendHole
authorMichal Privoznik <mprivozn@redhat.com>
Sun, 10 Apr 2016 10:01:20 +0000 (12:01 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 18 May 2017 05:42:13 +0000 (07:42 +0200)
This API is used to tell the other side of the stream to skip
some bytes in the stream. This can be used to create a sparse
file on the receiving side of a stream.

It takes @length argument, which says how big the hole is. This
skipping is done from the current point of stream. Since our
streams are not rewindable like regular files, we don't need
@whence argument like seek(2) has.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
include/libvirt/libvirt-stream.h
src/driver-stream.h
src/libvirt-stream.c
src/libvirt_public.syms

index bee25168b4fd2f6db764d8ffc6ec8a646c022a91..14c9af142984eccd6285a7618b9b6c2e0ac95e12 100644 (file)
@@ -50,6 +50,10 @@ int virStreamRecvFlags(virStreamPtr st,
                        size_t nbytes,
                        unsigned int flags);
 
+int virStreamSendHole(virStreamPtr st,
+                      long long length,
+                      unsigned int flags);
+
 
 /**
  * virStreamSourceFunc:
index d4b048018d3c438afe99b73ee46f2ebc21c06271..0a52014312ad6c01299cd349c726f79b53a24a11 100644 (file)
@@ -41,6 +41,11 @@ typedef int
                          size_t nbytes,
                          unsigned int flags);
 
+typedef int
+(*virDrvStreamSendHole)(virStreamPtr st,
+                        long long length,
+                        unsigned int flags);
+
 typedef int
 (*virDrvStreamEventAddCallback)(virStreamPtr stream,
                                 int events,
@@ -68,6 +73,7 @@ struct _virStreamDriver {
     virDrvStreamSend streamSend;
     virDrvStreamRecv streamRecv;
     virDrvStreamRecvFlags streamRecvFlags;
+    virDrvStreamSendHole streamSendHole;
     virDrvStreamEventAddCallback streamEventAddCallback;
     virDrvStreamEventUpdateCallback streamEventUpdateCallback;
     virDrvStreamEventRemoveCallback streamEventRemoveCallback;
index 7535deb3c73a2d48bbdb4744442a2071de85f09e..a09896dcdfa23abb379291a455bd9ff9e9180057 100644 (file)
@@ -344,6 +344,67 @@ virStreamRecvFlags(virStreamPtr stream,
 }
 
 
+/**
+ * virStreamSendHole:
+ * @stream: pointer to the stream object
+ * @length: number of bytes to skip
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Rather than transmitting empty file space, this API directs
+ * the @stream target to create @length bytes of empty space.
+ * This API would be used when uploading or downloading sparsely
+ * populated files to avoid the needless copy of empty file
+ * space.
+ *
+ * An example using this with a hypothetical file upload API
+ * looks like:
+ *
+ *   virStream st;
+ *
+ *   while (1) {
+ *     char buf[4096];
+ *     size_t len;
+ *     if (..in hole...) {
+ *       ..get hole size...
+ *       virStreamSendHole(st, len, 0);
+ *     } else {
+ *       ...read len bytes...
+ *       virStreamSend(st, buf, len);
+ *     }
+ *   }
+ *
+ * Returns 0 on success,
+ *        -1 error
+ */
+int
+virStreamSendHole(virStreamPtr stream,
+                  long long length,
+                  unsigned int flags)
+{
+    VIR_DEBUG("stream=%p, length=%lld flags=%x",
+              stream, length, flags);
+
+    virResetLastError();
+
+    virCheckStreamReturn(stream, -1);
+
+    if (stream->driver &&
+        stream->driver->streamSendHole) {
+        int ret;
+        ret = (stream->driver->streamSendHole)(stream, length, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(stream->conn);
+    return -1;
+}
+
+
 /**
  * virStreamSendAll:
  * @stream: pointer to the stream object
index d50b36a247832541dddf4b236dba3ce3d2c42bf3..3be7cc6a0b3dc725d2d7f1a354dee666438fffd9 100644 (file)
@@ -762,6 +762,7 @@ LIBVIRT_3.1.0 {
 LIBVIRT_3.4.0 {
     global:
         virStreamRecvFlags;
+        virStreamSendHole;
 } LIBVIRT_3.1.0;
 
 # .... define new API here using predicted next version number ....