[libvirt] [PATCH 04/27] Introduce virStreamSkip

Michal Privoznik mprivozn at redhat.com
Thu Apr 28 10:04:51 UTC 2016


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 @offset, 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 at redhat.com>
---
 include/libvirt/libvirt-stream.h |  3 +++
 src/driver-stream.h              |  5 +++++
 src/libvirt-stream.c             | 40 ++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms          |  5 +++++
 4 files changed, 53 insertions(+)

diff --git a/include/libvirt/libvirt-stream.h b/include/libvirt/libvirt-stream.h
index 831640d..f12d695 100644
--- a/include/libvirt/libvirt-stream.h
+++ b/include/libvirt/libvirt-stream.h
@@ -45,6 +45,9 @@ int virStreamRecv(virStreamPtr st,
                   char *data,
                   size_t nbytes);
 
+int virStreamSkip(virStreamPtr st,
+                  unsigned long long offset);
+
 
 /**
  * virStreamSourceFunc:
diff --git a/src/driver-stream.h b/src/driver-stream.h
index 85b4e3b..786d7b6 100644
--- a/src/driver-stream.h
+++ b/src/driver-stream.h
@@ -36,6 +36,10 @@ typedef int
                     size_t nbytes);
 
 typedef int
+(*virDrvStreamSkip)(virStreamPtr st,
+                    unsigned long long offset);
+
+typedef int
 (*virDrvStreamEventAddCallback)(virStreamPtr stream,
                                 int events,
                                 virStreamEventCallback cb,
@@ -61,6 +65,7 @@ typedef virStreamDriver *virStreamDriverPtr;
 struct _virStreamDriver {
     virDrvStreamSend streamSend;
     virDrvStreamRecv streamRecv;
+    virDrvStreamSkip streamSkip;
     virDrvStreamEventAddCallback streamEventAddCallback;
     virDrvStreamEventUpdateCallback streamEventUpdateCallback;
     virDrvStreamEventRemoveCallback streamEventRemoveCallback;
diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c
index 8384b37..1c9a12b 100644
--- a/src/libvirt-stream.c
+++ b/src/libvirt-stream.c
@@ -286,6 +286,46 @@ virStreamRecv(virStreamPtr stream,
 
 
 /**
+ * virStreamSkip:
+ * @stream: pointer to the stream object
+ * @offset: number of bytes to skip
+ *
+ * Skip @offset 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.
+ *
+ * Returns 0 on success,
+ *        -1 error
+ */
+int
+virStreamSkip(virStreamPtr stream,
+              unsigned long long offset)
+{
+    VIR_DEBUG("stream=%p, offset=%llu", stream, offset);
+
+    virResetLastError();
+
+    virCheckStreamReturn(stream, -1);
+
+    if (stream->driver &&
+        stream->driver->streamSkip) {
+        int ret;
+        ret = (stream->driver->streamSkip)(stream, offset);
+        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 1e920d6..b4c693a 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -732,4 +732,9 @@ LIBVIRT_1.3.3 {
         virDomainSetPerfEvents;
 } LIBVIRT_1.2.19;
 
+LIBVIRT_1.3.5 {
+    global:
+        virStreamSkip;
+} LIBVIRT_1.3.3;
+
 # .... define new API here using predicted next version number ....
-- 
2.8.1




More information about the libvir-list mailing list