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@xxxxxxxxxx> --- 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list
Attachment:
signature.asc
Description: Digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list