[libvirt] [libvirt-python][PATCH v2 3/4] virStream: Introduce virStreamSparse{Recv, Send}All
Martin Kletzander
mkletzan at redhat.com
Tue May 23 15:17:05 UTC 2017
On Tue, May 23, 2017 at 04:26:10PM +0200, Michal Privoznik wrote:
>Yet again, our parser is not capable of generating proper
>wrapper. To be fair, this one wold be really tough anyway.
>
>Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
>---
> generator.py | 2 +
> libvirt-override-virStream.py | 107 ++++++++++++++++++++++++++++++++++++++++++
> sanitytest.py | 6 ++-
> 3 files changed, 113 insertions(+), 2 deletions(-)
>
>diff --git a/generator.py b/generator.py
>index 0e07fc8..93d1dc3 100755
>--- a/generator.py
>+++ b/generator.py
>@@ -546,6 +546,8 @@ skip_function = (
> 'virStreamRecvHole', # overridden in libvirt-override-virStream.py
> 'virStreamSendHole', # overridden in libvirt-override-virStream.py
> 'virStreamRecvFlags', # overridden in libvirt-override-virStream.py
>+ 'virStreamSparseRecvAll', # overridden in libvirt-override-virStream.py
>+ 'virStreamSparseSendAll', # overridden in libvirt-override-virStream.py
>
> 'virConnectUnregisterCloseCallback', # overridden in virConnect.py
> 'virConnectRegisterCloseCallback', # overridden in virConnect.py
>diff --git a/libvirt-override-virStream.py b/libvirt-override-virStream.py
>index 66d2bf6..0ab7815 100644
>--- a/libvirt-override-virStream.py
>+++ b/libvirt-override-virStream.py
>@@ -164,3 +164,110 @@
> ret = libvirtmod.virStreamRecvFlags(self._o, nbytes, flags)
> if ret is None: raise libvirtError ('virStreamRecvFlags() failed')
> return ret
>+
>+ def sparseRecvAll(self, handler, holeHandler, opaque):
>+ """Receive the entire data stream, sending the data to
>+ the requested data sink handler and calling the skip
>+ holeHandler to generate holes for sparse stream targets.
>+ This is simply a convenient alternative to recvFlags, for
>+ apps that do blocking-I/O and want to preserve sparseness.
>+
>+ Hypothetical callbacks can look like this:
>+
>+ def handler(stream, # virStream instance
>+ buf, # string containing received data
>+ opaque): # extra data passed to sparseRecvAll as opaque
>+ fd = opaque
>+ return os.write(fd, buf)
>+
>+ def holeHandler(stream, # virStream instance
>+ length, # number of bytes to skip
>+ opaque): # extra data passed to sparseRecvAll as opaque
>+ fd = opaque
>+ cur = os.lseek(fd, length, os.SEEK_CUR)
>+ return os.ftruncate(fd, cur) # take this extra step to
>+ # actually allocate the hole
>+ """
>+ while True:
>+ want = 64 * 1024
>+ got = self.recvFlags(want, VIR_STREAM_RECV_STOP_AT_HOLE)
>+ if got == -2:
>+ raise libvirtError("cannot use sparseRecvAll with "
>+ "nonblocking stream")
>+ if got == -3:
>+ length = self.recvHole()
>+ if length is None:
>+ self.abort()
>+ raise RuntimeError("recvHole handler failed")
>+ ret = holeHandler(self, length, opaque)
>+ if type(ret) is int and ret < 0:
>+ self.abort()
>+ raise RuntimeError("holeHandler handler returned %d" % ret)
>+ continue
>+
>+ if len(got) == 0:
>+ break
>+
>+ try:
>+ ret = handler(self, got, opaque)
>+ if type(ret) is int and ret < 0:
>+ raise RuntimeError("sparseRecvAll handler returned %d" % ret)
>+ except Exception as e:
What exception are you trying to catch here? Exception means something
went wrong.
>+ self.abort()
>+ raise e
>+
>+ def sparseSendAll(self, handler, holeHandler, skipHandler, opaque):
>+ """Send the entire data stream, reading the data from the
>+ requested data source. This is simply a convenient
>+ alternative to virStreamSend, for apps that do
>+ blocking-I/O and want to preserve sparseness.
>+
>+ Hypothetical callbacks can look like this:
>+
>+ def handler(stream, # virStream instance
>+ nbytes, # int amt of data to read
>+ opaque): # extra data passed to sparseSendAll as opaque
>+ fd = opaque
>+ return os.read(fd, nbytes)
>+
>+ def holeHandler(stream, # virStream instance
>+ opaque): # extra data passed to sparseSendAll as opaque
>+ fd = opaque
>+ cur = os.lseek(fd, 0, os.SEEK_CUR)
>+ # ... find out current section and its boundaries
>+ # and set inData = True/False and sectionLen correspondingly
>+ os.lseek(fd, cur, os.SEEK_SET)
>+ return [inData, sectionLen]
>+
>+ def skipHandler(stream, # virStream instance
>+ length, # number of bytes to skip
>+ opaque): # extra data passed to sparseSendAll as opaque
>+ fd = opaque
>+ return os.lseek(fd, length, os.SEEK_CUR)
>+
>+ """
>+ while True:
>+ [inData, sectionLen] = holeHandler(self, opaque)
>+ if (inData == False and sectionLen > 0):
>+ if (self.sendHole(sectionLen) < 0 or
>+ skipHandler(self, sectionLen, opaque) < 0):
>+ self.abort()
>+ continue
>+
>+ want = 64 * 1024
>+ if (want > sectionLen):
>+ want = sectionLen
>+
>+ try:
>+ got = handler(self, want, opaque)
Why not the same comparison to < 0?
>+ except Exception as e:
>+ self.abort()
>+ raise e
>+
Again, no need for the exception.
ACK if you change those exceptions to checks for that ret is int < 0
>+ if not got:
>+ break
>+
>+ ret = self.send(got)
>+ if ret == -2:
>+ raise libvirtError("cannot use sparseSendAll with "
>+ "nonblocking stream")
>diff --git a/sanitytest.py b/sanitytest.py
>index 7183baa..deec200 100644
>--- a/sanitytest.py
>+++ b/sanitytest.py
>@@ -167,7 +167,8 @@ for cname in wantfunctions:
> # These aren't functions, they're callback signatures
> if name in ["virConnectAuthCallbackPtr", "virConnectCloseFunc",
> "virStreamSinkFunc", "virStreamSourceFunc", "virStreamEventCallback",
>- "virEventHandleCallback", "virEventTimeoutCallback", "virFreeCallback"]:
>+ "virEventHandleCallback", "virEventTimeoutCallback", "virFreeCallback",
>+ "virStreamSinkHoleFunc", "virStreamSourceHoleFunc", "virStreamSourceSkipFunc"]:
> continue
> if name[0:21] == "virConnectDomainEvent" and name[-8:] == "Callback":
> continue
>@@ -373,7 +374,8 @@ for name in sorted(finalklassmap):
>
> # These exist in C and exist in python, but we've got
> # a pure-python impl so don't check them
>- if name in ["virStreamRecvAll", "virStreamSendAll"]:
>+ if name in ["virStreamRecvAll", "virStreamSendAll",
>+ "virStreamSparseRecvAll", "virStreamSparseSendAll"]:
> continue
>
> try:
>--
>2.13.0
>
>--
>libvir-list mailing list
>libvir-list at redhat.com
>https://www.redhat.com/mailman/listinfo/libvir-list
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20170523/5f514238/attachment-0001.sig>
More information about the libvir-list
mailing list