[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH v2 03/32] Introduce virStreamSkip



This API can be 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 just one argument @length, which says how big the hole
is. 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 |  3 +++
 src/driver-stream.h              |  5 ++++
 src/libvirt-stream.c             | 57 ++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms          |  1 +
 4 files changed, 66 insertions(+)

diff --git a/include/libvirt/libvirt-stream.h b/include/libvirt/libvirt-stream.h
index bee2516..4e0a599 100644
--- a/include/libvirt/libvirt-stream.h
+++ b/include/libvirt/libvirt-stream.h
@@ -50,6 +50,9 @@ int virStreamRecvFlags(virStreamPtr st,
                        size_t nbytes,
                        unsigned int flags);
 
+int virStreamSkip(virStreamPtr st,
+                  unsigned long long length);
+
 
 /**
  * virStreamSourceFunc:
diff --git a/src/driver-stream.h b/src/driver-stream.h
index d4b0480..20ea13f 100644
--- a/src/driver-stream.h
+++ b/src/driver-stream.h
@@ -42,6 +42,10 @@ typedef int
                          unsigned int flags);
 
 typedef int
+(*virDrvStreamSkip)(virStreamPtr st,
+                    unsigned long long length);
+
+typedef int
 (*virDrvStreamEventAddCallback)(virStreamPtr stream,
                                 int events,
                                 virStreamEventCallback cb,
@@ -68,6 +72,7 @@ struct _virStreamDriver {
     virDrvStreamSend streamSend;
     virDrvStreamRecv streamRecv;
     virDrvStreamRecvFlags streamRecvFlags;
+    virDrvStreamSkip streamSkip;
     virDrvStreamEventAddCallback streamEventAddCallback;
     virDrvStreamEventUpdateCallback streamEventUpdateCallback;
     virDrvStreamEventRemoveCallback streamEventRemoveCallback;
diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c
index 80b2d47..55f3ef5 100644
--- a/src/libvirt-stream.c
+++ b/src/libvirt-stream.c
@@ -346,6 +346,63 @@ virStreamRecvFlags(virStreamPtr stream,
 
 
 /**
+ * virStreamSkip:
+ * @stream: pointer to the stream object
+ * @length: number of bytes to skip
+ *
+ * Skip @length bytes in the stream. This is useful when there's
+ * no actual data in the stream, just a hole. If that's the case,
+ * this API can be used to skip the hole properly instead of
+ * transmitting zeroes to the other side.
+ *
+ * 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...
+ *       virStreamSkip(st, len);
+ *     } else {
+ *       ...read len bytes...
+ *       virStreamSend(st, buf, len);
+ *     }
+ *   }
+ *
+ * Returns 0 on success,
+ *        -1 error
+ */
+int
+virStreamSkip(virStreamPtr stream,
+              unsigned long long length)
+{
+    VIR_DEBUG("stream=%p, length=%llu", stream, length);
+
+    virResetLastError();
+
+    virCheckStreamReturn(stream, -1);
+
+    if (stream->driver &&
+        stream->driver->streamSkip) {
+        int ret;
+        ret = (stream->driver->streamSkip)(stream, length);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(stream->conn);
+    return -1;
+}
+
+
+/**
  * virStreamSendAll:
  * @stream: pointer to the stream object
  * @handler: source callback for reading data from application
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 4cb0ce6..d781a5b 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -735,6 +735,7 @@ LIBVIRT_1.3.3 {
 LIBVIRT_1.3.5 {
     global:
         virStreamRecvFlags;
+        virStreamSkip;
 } LIBVIRT_1.3.3;
 
 
-- 
2.8.3


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]