From nobody Wed Jul 9 23:57:33 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1495549729298685.5386322437714; Tue, 23 May 2017 07:28:49 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 63004C059732; Tue, 23 May 2017 14:28:47 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 168B17D65E; Tue, 23 May 2017 14:28:46 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id AA3174A48D; Tue, 23 May 2017 14:28:44 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v4NEQM2R028677 for ; Tue, 23 May 2017 10:26:22 -0400 Received: by smtp.corp.redhat.com (Postfix) id 3E63E7BCA1; Tue, 23 May 2017 14:26:22 +0000 (UTC) Received: from moe.brq.redhat.com (dhcp129-131.brq.redhat.com [10.34.129.131]) by smtp.corp.redhat.com (Postfix) with ESMTP id BA1277BB1D for ; Tue, 23 May 2017 14:26:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 63004C059732 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 63004C059732 From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 23 May 2017 16:26:10 +0200 Message-Id: <6d3dc2933c887ea910fa735a9711efe2e7cf1426.1495549496.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Subject: [libvirt] [libvirt-python][PATCH v2 3/4] virStream: Introduce virStreamSparse{Recv, Send}All X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 23 May 2017 14:28:48 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" 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 --- 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 =3D ( '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 =20 '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 =3D 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 o= paque + fd =3D 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 =3D opaque + cur =3D os.lseek(fd, length, os.SEEK_CUR) + return os.ftruncate(fd, cur) # take this extra step to + # actually allocate the hole + """ + while True: + want =3D 64 * 1024 + got =3D self.recvFlags(want, VIR_STREAM_RECV_STOP_AT_HOLE) + if got =3D=3D -2: + raise libvirtError("cannot use sparseRecvAll with " + "nonblocking stream") + if got =3D=3D -3: + length =3D self.recvHole() + if length is None: + self.abort() + raise RuntimeError("recvHole handler failed") + ret =3D 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) =3D=3D 0: + break + + try: + ret =3D handler(self, got, opaque) + if type(ret) is int and ret < 0: + raise RuntimeError("sparseRecvAll handler returned %d"= % ret) + except Exception as e: + 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 o= paque + fd =3D opaque + return os.read(fd, nbytes) + + def holeHandler(stream, # virStream instance + opaque): # extra data passed to sparseSendAll = as opaque + fd =3D opaque + cur =3D os.lseek(fd, 0, os.SEEK_CUR) + # ... find out current section and its boundaries + # and set inData =3D True/False and sectionLen correspondi= ngly + 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 =3D opaque + return os.lseek(fd, length, os.SEEK_CUR) + + """ + while True: + [inData, sectionLen] =3D holeHandler(self, opaque) + if (inData =3D=3D False and sectionLen > 0): + if (self.sendHole(sectionLen) < 0 or + skipHandler(self, sectionLen, opaque) < 0): + self.abort() + continue + + want =3D 64 * 1024 + if (want > sectionLen): + want =3D sectionLen + + try: + got =3D handler(self, want, opaque) + except Exception as e: + self.abort() + raise e + + if not got: + break + + ret =3D self.send(got) + if ret =3D=3D -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", "virStreamEven= tCallback", - "virEventHandleCallback", "virEventTimeoutCallback", "virF= reeCallback"]: + "virEventHandleCallback", "virEventTimeoutCallback", "virF= reeCallback", + "virStreamSinkHoleFunc", "virStreamSourceHoleFunc", "virSt= reamSourceSkipFunc"]: continue if name[0:21] =3D=3D "virConnectDomainEvent" and name[-8:] =3D=3D "Cal= lback": continue @@ -373,7 +374,8 @@ for name in sorted(finalklassmap): =20 # 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 =20 try: --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list