]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add public API definition for data stream handling
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 10 Jul 2009 11:18:12 +0000 (12:18 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 29 Sep 2009 14:48:52 +0000 (15:48 +0100)
* include/libvirt/libvirt.h.in: Public API contract for
  virStreamPtr object
* src/libvirt_public.syms: Export data stream APIs
* src/libvirt_private.syms: Export internal helper APIs
* src/libvirt.c: Data stream API driver dispatch
* src/datatypes.h, src/datatypes.c: Internal helpers for virStreamPtr
  object
* src/driver.h: Define internal driver API for streams
* .x-sc_avoid_write: Ignore src/libvirt.c because it trips
  up on comments including write()
* python/Makefile.am: Add libvirt-override-virStream.py
* python/generator.py: Add rules for virStreamPtr class
* python/typewrappers.h, python/typewrappers.c: Wrapper
  for virStreamPtr
* docs/libvirt-api.xml, docs/libvirt-refs.xml: Regenerate
  with new APIs

15 files changed:
.x-sc_avoid_write
docs/libvirt-api.xml
docs/libvirt-refs.xml
include/libvirt/libvirt.h.in
python/Makefile.am
python/generator.py
python/libvirt-override-virStream.py [new file with mode: 0644]
python/typewrappers.c
python/typewrappers.h
src/datatypes.c
src/datatypes.h
src/driver.h
src/libvirt.c
src/libvirt_private.syms
src/libvirt_public.syms

index e0f94d60273109ac6de8df11702c0d968178dcbf..9e37248b243c0a3ec738a82adaf3e3523b06321d 100644 (file)
@@ -1,3 +1,4 @@
+^src/libvirt\.c$
 ^src/util/util\.c$
 ^src/xen/xend_internal\.c$
 ^daemon/libvirtd.c$
index f5018b9d6c0588473b6f6a9e787be7f0be2d9b66..5981c0ed685803c99beeb0035d9fbb83b7df7794 100644 (file)
@@ -25,6 +25,7 @@
      <exports symbol='VIR_EVENT_HANDLE_READABLE' type='enum'/>
      <exports symbol='VIR_DOMAIN_SHUTDOWN' type='enum'/>
      <exports symbol='VIR_DOMAIN_SCHED_FIELD_UINT' type='enum'/>
+     <exports symbol='VIR_STREAM_NONBLOCK' type='enum'/>
      <exports symbol='VIR_STORAGE_POOL_BUILDING' type='enum'/>
      <exports symbol='VIR_CRED_CNONCE' type='enum'/>
      <exports symbol='VIR_CRED_ECHOPROMPT' type='enum'/>
      <exports symbol='VIR_STORAGE_POOL_BUILD_REPAIR' type='enum'/>
      <exports symbol='VIR_CRED_LANGUAGE' type='enum'/>
      <exports symbol='VIR_CRED_NOECHOPROMPT' type='enum'/>
+     <exports symbol='VIR_STREAM_EVENT_ERROR' type='enum'/>
      <exports symbol='VIR_DOMAIN_EVENT_UNDEFINED' type='enum'/>
      <exports symbol='VIR_MIGRATE_LIVE' type='enum'/>
      <exports symbol='VIR_DOMAIN_EVENT_STOPPED_DESTROYED' type='enum'/>
      <exports symbol='VIR_DOMAIN_EVENT_DEFINED_ADDED' type='enum'/>
+     <exports symbol='VIR_VCPU_BLOCKED' type='enum'/>
      <exports symbol='VIR_SECRET_USAGE_TYPE_NONE' type='enum'/>
      <exports symbol='VIR_DOMAIN_EVENT_STARTED_MIGRATED' type='enum'/>
-     <exports symbol='VIR_VCPU_BLOCKED' type='enum'/>
+     <exports symbol='VIR_STREAM_EVENT_HANGUP' type='enum'/>
      <exports symbol='VIR_MEMORY_VIRTUAL' type='enum'/>
      <exports symbol='VIR_CRED_USERNAME' type='enum'/>
      <exports symbol='VIR_DOMAIN_EVENT_RESUMED_UNPAUSED' type='enum'/>
@@ -77,6 +80,7 @@
      <exports symbol='VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED' type='enum'/>
      <exports symbol='VIR_DOMAIN_CRASHED' type='enum'/>
      <exports symbol='VIR_VCPU_RUNNING' type='enum'/>
+     <exports symbol='VIR_STREAM_EVENT_WRITABLE' type='enum'/>
      <exports symbol='VIR_DOMAIN_SCHED_FIELD_DOUBLE' type='enum'/>
      <exports symbol='VIR_DOMAIN_SCHED_FIELD_LLONG' type='enum'/>
      <exports symbol='VIR_DOMAIN_SCHED_FIELD_BOOLEAN' type='enum'/>
@@ -90,6 +94,7 @@
      <exports symbol='VIR_DOMAIN_EVENT_STOPPED_SAVED' type='enum'/>
      <exports symbol='VIR_DOMAIN_EVENT_STOPPED_MIGRATED' type='enum'/>
      <exports symbol='VIR_STORAGE_POOL_INACTIVE' type='enum'/>
+     <exports symbol='VIR_STREAM_EVENT_READABLE' type='enum'/>
      <exports symbol='VIR_DOMAIN_XML_SECURE' type='enum'/>
      <exports symbol='VIR_DOMAIN_EVENT_SUSPENDED' type='enum'/>
      <exports symbol='virDomainBlockStatsStruct' type='typedef'/>
      <exports symbol='virEventHandleType' type='typedef'/>
      <exports symbol='virStoragePool' type='typedef'/>
      <exports symbol='virDomainEventType' type='typedef'/>
+     <exports symbol='virStream' type='typedef'/>
      <exports symbol='virDomainInterfaceStatsStruct' type='typedef'/>
      <exports symbol='virStoragePoolInfo' type='typedef'/>
      <exports symbol='virSecret' type='typedef'/>
+     <exports symbol='virStreamPtr' type='typedef'/>
      <exports symbol='virDomainState' type='typedef'/>
      <exports symbol='virDomain' type='typedef'/>
      <exports symbol='virDomainInterfaceStatsPtr' type='typedef'/>
      <exports symbol='virConnectPtr' type='typedef'/>
      <exports symbol='virStorageVol' type='typedef'/>
      <exports symbol='virNodeDevicePtr' type='typedef'/>
+     <exports symbol='virStreamEventType' type='typedef'/>
      <exports symbol='virInterface' type='typedef'/>
      <exports symbol='virSchedParameter' type='typedef'/>
      <exports symbol='virConnectFlags' type='typedef'/>
      <exports symbol='virDomainEventDefinedDetailType' type='typedef'/>
      <exports symbol='virInterfacePtr' type='typedef'/>
+     <exports symbol='virStreamFlags' type='typedef'/>
      <exports symbol='virDomainMemoryFlags' type='typedef'/>
      <exports symbol='virDomainEventStoppedDetailType' type='typedef'/>
      <exports symbol='virStorageVolPtr' type='typedef'/>
      <exports symbol='virDomainGetSchedulerParameters' type='function'/>
      <exports symbol='virDomainLookupByUUIDString' type='function'/>
      <exports symbol='virConnectNumOfDefinedNetworks' type='function'/>
+     <exports symbol='virStreamRecvAll' type='function'/>
      <exports symbol='virConnectListStoragePools' type='function'/>
      <exports symbol='virNetworkGetUUID' type='function'/>
      <exports symbol='virInterfaceGetXMLDesc' type='function'/>
      <exports symbol='virStoragePoolDefineXML' type='function'/>
      <exports symbol='virStorageVolLookupByPath' type='function'/>
      <exports symbol='virStorageVolLookupByName' type='function'/>
+     <exports symbol='virStreamSinkFunc' type='function'/>
      <exports symbol='virNetworkCreate' type='function'/>
      <exports symbol='virSecretLookupByUUID' type='function'/>
      <exports symbol='virDomainSetMaxMemory' type='function'/>
      <exports symbol='virInterfaceDefineXML' type='function'/>
      <exports symbol='virDomainMigrate' type='function'/>
      <exports symbol='virDomainSuspend' type='function'/>
+     <exports symbol='virStreamSourceFunc' type='function'/>
      <exports symbol='virDomainCreateLinux' type='function'/>
      <exports symbol='virNodeDeviceGetXMLDesc' type='function'/>
      <exports symbol='virEventUpdateHandleFunc' type='function'/>
      <exports symbol='virNetworkDestroy' type='function'/>
      <exports symbol='virStoragePoolLookupByName' type='function'/>
      <exports symbol='virStoragePoolCreateXML' type='function'/>
+     <exports symbol='virStreamFree' type='function'/>
      <exports symbol='virNetworkGetAutostart' type='function'/>
      <exports symbol='virNetworkGetBridgeName' type='function'/>
      <exports symbol='virStorageVolGetXMLDesc' type='function'/>
      <exports symbol='virStorageVolCreateXML' type='function'/>
      <exports symbol='virDomainSave' type='function'/>
      <exports symbol='virDomainCreate' type='function'/>
+     <exports symbol='virStreamEventAddCallback' type='function'/>
      <exports symbol='virConnectListDomains' type='function'/>
      <exports symbol='virDomainCoreDump' type='function'/>
      <exports symbol='virDomainSetMemory' type='function'/>
      <exports symbol='virNetworkSetAutostart' type='function'/>
      <exports symbol='virSecretLookupByUUIDString' type='function'/>
      <exports symbol='virDomainGetMaxMemory' type='function'/>
+     <exports symbol='virStreamRef' type='function'/>
+     <exports symbol='virStreamAbort' type='function'/>
      <exports symbol='virStoragePoolFree' type='function'/>
      <exports symbol='virConnectNumOfDefinedInterfaces' type='function'/>
      <exports symbol='virFreeCallback' type='function'/>
      <exports symbol='virNetworkDefineXML' type='function'/>
      <exports symbol='virNodeDeviceListCaps' type='function'/>
      <exports symbol='virDomainBlockStats' type='function'/>
+     <exports symbol='virStreamFinish' type='function'/>
      <exports symbol='virConnectOpenAuth' type='function'/>
      <exports symbol='virStoragePoolDelete' type='function'/>
      <exports symbol='virDomainResume' type='function'/>
      <exports symbol='virStorageVolGetName' type='function'/>
+     <exports symbol='virStreamNew' type='function'/>
      <exports symbol='virStoragePoolGetAutostart' type='function'/>
      <exports symbol='virDomainGetAutostart' type='function'/>
      <exports symbol='virStoragePoolListVolumes' type='function'/>
      <exports symbol='virStorageVolCreateXMLFrom' type='function'/>
      <exports symbol='virConnectClose' type='function'/>
      <exports symbol='virDomainReboot' type='function'/>
+     <exports symbol='virStreamEventCallback' type='function'/>
      <exports symbol='virNetworkGetUUIDString' type='function'/>
      <exports symbol='virNetworkLookupByName' type='function'/>
      <exports symbol='virDomainGetMaxVcpus' type='function'/>
+     <exports symbol='virStreamEventUpdateCallback' type='function'/>
      <exports symbol='virEventHandleCallback' type='function'/>
      <exports symbol='virDomainGetSchedulerType' type='function'/>
      <exports symbol='virNodeDeviceReset' type='function'/>
      <exports symbol='virStorageVolGetConnect' type='function'/>
      <exports symbol='virNodeNumOfDevices' type='function'/>
      <exports symbol='virStoragePoolDestroy' type='function'/>
+     <exports symbol='virStreamRecv' type='function'/>
      <exports symbol='virStoragePoolLookupByVolume' type='function'/>
      <exports symbol='virDomainLookupByUUID' type='function'/>
+     <exports symbol='virStreamSend' type='function'/>
      <exports symbol='virDomainGetOSType' type='function'/>
      <exports symbol='virStoragePoolBuild' type='function'/>
      <exports symbol='virConnectGetMaxVcpus' type='function'/>
      <exports symbol='virNodeDeviceGetParent' type='function'/>
      <exports symbol='virConnectOpen' type='function'/>
      <exports symbol='virDomainCreateXML' type='function'/>
+     <exports symbol='virStreamEventRemoveCallback' type='function'/>
+     <exports symbol='virStreamSendAll' type='function'/>
      <exports symbol='virNodeDeviceRef' type='function'/>
      <exports symbol='virInterfaceUndefine' type='function'/>
      <exports symbol='virDomainSetVcpus' type='function'/>
     <enum name='VIR_STORAGE_VOL_DELETE_NORMAL' file='libvirt' value='0' type='virStorageVolDeleteFlags' info='Delete metadata only    (fast)'/>
     <enum name='VIR_STORAGE_VOL_DELETE_ZEROED' file='libvirt' value='1' type='virStorageVolDeleteFlags' info=' Clear all data to zeros (slow)'/>
     <enum name='VIR_STORAGE_VOL_FILE' file='libvirt' value='0' type='virStorageVolType' info='Regular file based volumes'/>
+    <enum name='VIR_STREAM_EVENT_ERROR' file='libvirt' value='4' type='virStreamEventType'/>
+    <enum name='VIR_STREAM_EVENT_HANGUP' file='libvirt' value='8' type='virStreamEventType'/>
+    <enum name='VIR_STREAM_EVENT_READABLE' file='libvirt' value='1' type='virStreamEventType'/>
+    <enum name='VIR_STREAM_EVENT_WRITABLE' file='libvirt' value='2' type='virStreamEventType'/>
+    <enum name='VIR_STREAM_NONBLOCK' file='libvirt' value='1' type='virStreamFlags'/>
     <enum name='VIR_VCPU_BLOCKED' file='libvirt' value='2' type='virVcpuState' info=' the virtual CPU is blocked on resource'/>
     <enum name='VIR_VCPU_OFFLINE' file='libvirt' value='0' type='virVcpuState' info='the virtual CPU is offline'/>
     <enum name='VIR_VCPU_RUNNING' file='libvirt' value='1' type='virVcpuState' info='the virtual CPU is running'/>
@@ -881,6 +910,12 @@ see note above'/>
       <info><![CDATA[a virStorageVolPtr is pointer to a virStorageVol private structure, this is the type used to reference a storage volume in the API.]]></info>
     </typedef>
     <typedef name='virStorageVolType' file='libvirt' type='enum'/>
+    <struct name='virStream' file='libvirt' type='struct _virStream'/>
+    <typedef name='virStreamEventType' file='libvirt' type='enum'/>
+    <typedef name='virStreamFlags' file='libvirt' type='enum'/>
+    <typedef name='virStreamPtr' file='libvirt' type='virStream *'>
+      <info><![CDATA[a virStreamPtr is pointer to a virStream private structure, this is the type used to reference a data stream in the API.]]></info>
+    </typedef>
     <struct name='virVcpuInfo' file='libvirt' type='struct _virVcpuInfo'>
       <field name='number' type='unsigned int' info=' virtual CPU number'/>
       <field name='state' type='int' info=' value from virVcpuState'/>
@@ -2657,5 +2692,289 @@ the reference count.]]></info>
       <return type='int' info='0 in case of success, -1 in case of failure.'/>
       <arg name='vol' type='virStorageVolPtr' info='the vol to hold a reference on'/>
     </function>
+    <function name='virStreamAbort' file='libvirt' module='libvirt'>
+      <info><![CDATA[Request that the in progress data transfer be cancelled
+abnormally before the end of the stream has been reached.
+For output streams this can be used to inform the driver
+that the stream is being terminated early. For input
+streams this can be used to inform the driver that it
+should stop sending data.]]></info>
+      <return type='int' info='0 on success, -1 upon error'/>
+      <arg name='stream' type='virStreamPtr' info='pointer to the stream object'/>
+    </function>
+    <function name='virStreamEventAddCallback' file='libvirt' module='libvirt'>
+      <info><![CDATA[]]></info>
+      <return type='int' info=''/>
+      <arg name='stream' type='virStreamPtr' info=''/>
+      <arg name='events' type='int' info=''/>
+      <arg name='cb' type='virStreamEventCallback' info=''/>
+      <arg name='opaque' type='void *' info=''/>
+      <arg name='ff' type='virFreeCallback' info=''/>
+    </function>
+    <functype name='virStreamEventCallback' file='libvirt' module='libvirt'>
+      <info><![CDATA[Callback for receiving stream events. The callback will
+be invoked once for each event which is pending.]]></info>
+      <return type='void'/>
+      <arg name='stream' type='virStreamPtr' info='stream on which the event occurred'/>
+      <arg name='events' type='int' info='bitset of events from virEventHandleType constants'/>
+      <arg name='opaque' type='void *' info='user data registered with handle'/>
+    </functype>
+    <function name='virStreamEventRemoveCallback' file='libvirt' module='libvirt'>
+      <info><![CDATA[]]></info>
+      <return type='int' info=''/>
+      <arg name='stream' type='virStreamPtr' info=''/>
+    </function>
+    <function name='virStreamEventUpdateCallback' file='libvirt' module='libvirt'>
+      <info><![CDATA[]]></info>
+      <return type='int' info=''/>
+      <arg name='stream' type='virStreamPtr' info=''/>
+      <arg name='events' type='int' info=''/>
+    </function>
+    <function name='virStreamFinish' file='libvirt' module='libvirt'>
+      <info><![CDATA[Indicate that there is no further data is to be transmitted
+on the stream. For output streams this should be called once
+all data has been written. For input streams this should be
+called once virStreamRecv returns end-of-file.
+
+This method is a synchronization point for all asynchronous
+errors, so if this returns a success code the application can
+be sure that all data has been successfully processed.]]></info>
+      <return type='int' info='0 on success, -1 upon error'/>
+      <arg name='stream' type='virStreamPtr' info='pointer to the stream object'/>
+    </function>
+    <function name='virStreamFree' file='libvirt' module='libvirt'>
+      <info><![CDATA[Decrement the reference count on a stream, releasing
+the stream object if the reference count has hit zero.
+
+There must not be a active data transfer in progress
+when releasing the stream. If a stream needs to be
+disposed of prior to end of stream being reached, then
+the virStreamAbort function should be called first.]]></info>
+      <return type='int' info='0 upon success, or -1 on error'/>
+      <arg name='stream' type='virStreamPtr' info='pointer to the stream object'/>
+    </function>
+    <function name='virStreamNew' file='libvirt' module='libvirt'>
+      <info><![CDATA[Creates a new stream object which can be used to perform
+streamed I/O with other public API function.
+
+When no longer needed, a stream object must be released
+with virStreamFree. If a data stream has been used,
+then the application must call virStreamFinish or
+virStreamAbort before free'ing to, in order to notify
+the driver of termination.
+
+If a non-blocking data stream is required passed
+VIR_STREAM_NONBLOCK for flags, otherwise pass 0.]]></info>
+      <return type='virStreamPtr' info='the new stream, or NULL upon error'/>
+      <arg name='conn' type='virConnectPtr' info='pointer to the connection'/>
+      <arg name='flags' type='unsigned int' info='control features of the stream'/>
+    </function>
+    <function name='virStreamRecv' file='libvirt' module='libvirt'>
+      <info><![CDATA[Write a series of bytes to the stream. This method may
+block the calling application for an arbitrary amount
+of time.
+
+Errors are not guaranteed to be reported synchronously
+with the call, but may instead be delayed until a
+subsequent call.
+
+A example using this with a hypothetical file download
+API looks like
+
+  virStreamPtr st = virStreamNew(conn, 0);
+  int fd = open("demo.iso", O_WRONLY, 0600)
+
+  virConnectDownloadFile(conn, "demo.iso", st);
+
+  while (1) {
+      char buf[1024];
+      int got = virStreamRecv(st, buf, 1024);
+      if (got < 0)
+         break;
+      if (got == 0) {
+         virStreamFinish(st);
+         break;
+      }
+      int offset = 0;
+      while (offset < got) {
+         int sent = write(fd, buf+offset, got-offset)
+         if (sent < 0) {
+            virStreamAbort(st);
+            goto done;
+         }
+         offset += sent;
+      }
+  }
+  if (virStreamFinish(st) < 0)
+     ... report an error ....
+done:
+  virStreamFree(st);
+  close(fd);]]></info>
+      <return type='int' info='the number of bytes read, which may be less than requested.  Returns 0 when the end of the stream is reached, at which time the caller should invoke virStreamFinish() to get confirmation of stream completion.  Returns -1 upon error, at which time the stream will be marked as aborted, and the caller should now release the stream with virStreamFree.  Returns -2 if there is no data pending to be read &amp; the stream is marked as non-blocking.'/>
+      <arg name='stream' type='virStreamPtr' info='pointer to the stream object'/>
+      <arg name='data' type='char *' info='buffer to write to stream'/>
+      <arg name='nbytes' type='size_t' info='size of @data buffer'/>
+    </function>
+    <function name='virStreamRecvAll' file='libvirt' module='libvirt'>
+      <info><![CDATA[Receive the entire data stream, sending the data to the
+requested data sink. This is simply a convenient alternative
+to virStreamRecv, for apps that do blocking-I/o.
+
+A example using this with a hypothetical file download
+API looks like
+
+  int mysink(virStreamPtr st, const char *buf, int nbytes, void *opaque) {
+      int *fd = opaque;
+
+      return write(*fd, buf, nbytes);
+  }
+
+  virStreamPtr st = virStreamNew(conn, 0);
+  int fd = open("demo.iso", O_WRONLY)
+
+  virConnectUploadFile(conn, st);
+  if (virStreamRecvAll(st, mysink, &fd) < 0) {
+     ...report an error ...
+     goto done;
+  }
+  if (virStreamFinish(st) < 0)
+     ...report an error...
+  virStreamFree(st);
+  close(fd);]]></info>
+      <return type='int' info='0 if all the data was succesfully received. The caller should invoke virStreamFinish(st) to flush the stream upon success and then virStreamFree  Returns -1 upon any error, with virStreamAbort() already having been called,  so the caller need only call virStreamFree()'/>
+      <arg name='stream' type='virStreamPtr' info='pointer to the stream object'/>
+      <arg name='handler' type='virStreamSinkFunc' info='sink callback for writing data to application'/>
+      <arg name='opaque' type='void *' info='application defined data'/>
+    </function>
+    <function name='virStreamRef' file='libvirt' module='libvirt'>
+      <info><![CDATA[Increment the reference count on the stream. For each
+additional call to this method, there shall be a corresponding
+call to virStreamFree to release the reference count, once
+the caller no longer needs the reference to this object.]]></info>
+      <return type='int' info='0 in case of success, -1 in case of failure'/>
+      <arg name='stream' type='virStreamPtr' info='pointer to the stream'/>
+    </function>
+    <function name='virStreamSend' file='libvirt' module='libvirt'>
+      <info><![CDATA[Write a series of bytes to the stream. This method may
+block the calling application for an arbitrary amount
+of time. Once an application has finished sending data
+it should call virStreamFinish to wait for succesful
+confirmation from the driver, or detect any error
+
+This method may not be used if a stream source has been
+registered
+
+Errors are not guaranteed to be reported synchronously
+with the call, but may instead be delayed until a
+subsequent call.
+
+A example using this with a hypothetical file upload
+API looks like
+
+  virStreamPtr st = virStreamNew(conn, 0);
+  int fd = open("demo.iso", O_RDONLY)
+
+  virConnectUploadFile(conn, "demo.iso", st);
+
+  while (1) {
+      char buf[1024];
+      int got = read(fd, buf, 1024);
+      if (got < 0) {
+         virStreamAbort(st);
+         break;
+      }
+      if (got == 0) {
+         virStreamFinish(st);
+         break;
+      }
+      int offset = 0;
+      while (offset < got) {
+         int sent = virStreamSend(st, buf+offset, got-offset)
+         if (sent < 0) {
+            virStreamAbort(st);
+            goto done;
+         }
+         offset += sent;
+      }
+  }
+  if (virStreamFinish(st) < 0)
+     ... report an error ....
+done:
+  virStreamFree(st);
+  close(fd);]]></info>
+      <return type='int' info='the number of bytes written, which may be less than requested.  Returns -1 upon error, at which time the stream will be marked as aborted, and the caller should now release the stream with virStreamFree.  Returns -2 if the outgoing transmit buffers are full &amp; the stream is marked as non-blocking.'/>
+      <arg name='stream' type='virStreamPtr' info='pointer to the stream object'/>
+      <arg name='data' type='const char *' info='buffer to write to stream'/>
+      <arg name='nbytes' type='size_t' info='size of @data buffer'/>
+    </function>
+    <function name='virStreamSendAll' file='libvirt' module='libvirt'>
+      <info><![CDATA[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.
+
+A example using this with a hypothetical file upload
+API looks like
+
+  int mysource(virStreamPtr st, char *buf, int nbytes, void *opaque) {
+      int *fd = opaque;
+
+      return read(*fd, buf, nbytes);
+  }
+
+  virStreamPtr st = virStreamNew(conn, 0);
+  int fd = open("demo.iso", O_RDONLY)
+
+  virConnectUploadFile(conn, st);
+  if (virStreamSendAll(st, mysource, &fd) < 0) {
+     ...report an error ...
+     goto done;
+  }
+  if (virStreamFinish(st) < 0)
+     ...report an error...
+  virStreamFree(st);
+  close(fd);]]></info>
+      <return type='int' info='0 if all the data was succesfully sent. The caller should invoke virStreamFinish(st) to flush the stream upon success and then virStreamFree  Returns -1 upon any error, with virStreamAbort() already having been called,  so the caller need only call virStreamFree()'/>
+      <arg name='stream' type='virStreamPtr' info='pointer to the stream object'/>
+      <arg name='handler' type='virStreamSourceFunc' info='source callback for reading data from application'/>
+      <arg name='opaque' type='void *' info='application defined data'/>
+    </function>
+    <functype name='virStreamSinkFunc' file='libvirt' module='libvirt'>
+      <info><![CDATA[The virStreamSinkFunc callback is used together
+with the virStreamRecvAll function for libvirt to
+provide the data that has been received.
+
+The callback will be invoked multiple times,
+providing data in small chunks. The application
+should consume up 'nbytes' from the 'data' array
+of data and then return the number actual number
+of bytes consumed. The callback will continue to be
+invoked until it indicates the end of the stream
+has been reached. A return value of -1 at any time
+will abort the receive operation]]></info>
+      <return type='int' info='the number of bytes consumed or -1 upon error'/>
+      <arg name='st' type='virStreamPtr' info='the stream object'/>
+      <arg name='data' type='const char *' info='preallocated array to be filled with data'/>
+      <arg name='nbytes' type='size_t' info='size of the data array'/>
+      <arg name='opaque' type='void *' info='optional application provided data'/>
+    </functype>
+    <functype name='virStreamSourceFunc' file='libvirt' module='libvirt'>
+      <info><![CDATA[The virStreamSourceFunc callback is used together
+with the virStreamSendAll function for libvirt to
+obtain the data that is to be sent.
+
+The callback will be invoked multiple times,
+fetching data in small chunks. The application
+should fill the 'data' array with upto 'nbytes'
+of data and then return the number actual number
+of bytes. The callback will continue to be
+invoked until it indicates the end of the source
+has been reached by returning 0. A return value
+of -1 at any time will abort the send operation]]></info>
+      <return type='int' info='the number of bytes filled, 0 upon end of file, or -1 upon error'/>
+      <arg name='st' type='virStreamPtr' info='the stream object'/>
+      <arg name='data' type='char *' info='preallocated array to be filled with data'/>
+      <arg name='nbytes' type='size_t' info='size of the data array'/>
+      <arg name='opaque' type='void *' info='optional application provided data'/>
+    </functype>
   </symbols>
 </api>
index d7255de3fe5ceccbcfd702fa5e2a8cd558951193..e7fbedf8c5b80dc7797b0fb2144648adf75373a5 100644 (file)
     <reference name='VIR_STORAGE_VOL_DELETE_NORMAL' href='html/libvirt-libvirt.html#VIR_STORAGE_VOL_DELETE_NORMAL'/>
     <reference name='VIR_STORAGE_VOL_DELETE_ZEROED' href='html/libvirt-libvirt.html#VIR_STORAGE_VOL_DELETE_ZEROED'/>
     <reference name='VIR_STORAGE_VOL_FILE' href='html/libvirt-libvirt.html#VIR_STORAGE_VOL_FILE'/>
+    <reference name='VIR_STREAM_EVENT_ERROR' href='html/libvirt-libvirt.html#VIR_STREAM_EVENT_ERROR'/>
+    <reference name='VIR_STREAM_EVENT_HANGUP' href='html/libvirt-libvirt.html#VIR_STREAM_EVENT_HANGUP'/>
+    <reference name='VIR_STREAM_EVENT_READABLE' href='html/libvirt-libvirt.html#VIR_STREAM_EVENT_READABLE'/>
+    <reference name='VIR_STREAM_EVENT_WRITABLE' href='html/libvirt-libvirt.html#VIR_STREAM_EVENT_WRITABLE'/>
+    <reference name='VIR_STREAM_NONBLOCK' href='html/libvirt-libvirt.html#VIR_STREAM_NONBLOCK'/>
     <reference name='VIR_UNUSE_CPU' href='html/libvirt-libvirt.html#VIR_UNUSE_CPU'/>
     <reference name='VIR_USE_CPU' href='html/libvirt-libvirt.html#VIR_USE_CPU'/>
     <reference name='VIR_UUID_BUFLEN' href='html/libvirt-libvirt.html#VIR_UUID_BUFLEN'/>
     <reference name='virStorageVolPtr' href='html/libvirt-libvirt.html#virStorageVolPtr'/>
     <reference name='virStorageVolRef' href='html/libvirt-libvirt.html#virStorageVolRef'/>
     <reference name='virStorageVolType' href='html/libvirt-libvirt.html#virStorageVolType'/>
+    <reference name='virStream' href='html/libvirt-libvirt.html#virStream'/>
+    <reference name='virStreamAbort' href='html/libvirt-libvirt.html#virStreamAbort'/>
+    <reference name='virStreamEventAddCallback' href='html/libvirt-libvirt.html#virStreamEventAddCallback'/>
+    <reference name='virStreamEventCallback' href='html/libvirt-libvirt.html#virStreamEventCallback'/>
+    <reference name='virStreamEventRemoveCallback' href='html/libvirt-libvirt.html#virStreamEventRemoveCallback'/>
+    <reference name='virStreamEventType' href='html/libvirt-libvirt.html#virStreamEventType'/>
+    <reference name='virStreamEventUpdateCallback' href='html/libvirt-libvirt.html#virStreamEventUpdateCallback'/>
+    <reference name='virStreamFinish' href='html/libvirt-libvirt.html#virStreamFinish'/>
+    <reference name='virStreamFlags' href='html/libvirt-libvirt.html#virStreamFlags'/>
+    <reference name='virStreamFree' href='html/libvirt-libvirt.html#virStreamFree'/>
+    <reference name='virStreamNew' href='html/libvirt-libvirt.html#virStreamNew'/>
+    <reference name='virStreamPtr' href='html/libvirt-libvirt.html#virStreamPtr'/>
+    <reference name='virStreamRecv' href='html/libvirt-libvirt.html#virStreamRecv'/>
+    <reference name='virStreamRecvAll' href='html/libvirt-libvirt.html#virStreamRecvAll'/>
+    <reference name='virStreamRef' href='html/libvirt-libvirt.html#virStreamRef'/>
+    <reference name='virStreamSend' href='html/libvirt-libvirt.html#virStreamSend'/>
+    <reference name='virStreamSendAll' href='html/libvirt-libvirt.html#virStreamSendAll'/>
+    <reference name='virStreamSinkFunc' href='html/libvirt-libvirt.html#virStreamSinkFunc'/>
+    <reference name='virStreamSourceFunc' href='html/libvirt-libvirt.html#virStreamSourceFunc'/>
     <reference name='virVcpuInfo' href='html/libvirt-libvirt.html#virVcpuInfo'/>
     <reference name='virVcpuInfoPtr' href='html/libvirt-libvirt.html#virVcpuInfoPtr'/>
     <reference name='virVcpuState' href='html/libvirt-libvirt.html#virVcpuState'/>
       <ref name='VIR_STORAGE_VOL_DELETE_NORMAL'/>
       <ref name='VIR_STORAGE_VOL_DELETE_ZEROED'/>
       <ref name='VIR_STORAGE_VOL_FILE'/>
+      <ref name='VIR_STREAM_EVENT_ERROR'/>
+      <ref name='VIR_STREAM_EVENT_HANGUP'/>
+      <ref name='VIR_STREAM_EVENT_READABLE'/>
+      <ref name='VIR_STREAM_EVENT_WRITABLE'/>
+      <ref name='VIR_STREAM_NONBLOCK'/>
       <ref name='VIR_UNUSE_CPU'/>
       <ref name='VIR_USE_CPU'/>
       <ref name='VIR_UUID_BUFLEN'/>
       <ref name='virStorageVolPtr'/>
       <ref name='virStorageVolRef'/>
       <ref name='virStorageVolType'/>
+      <ref name='virStream'/>
+      <ref name='virStreamAbort'/>
+      <ref name='virStreamEventAddCallback'/>
+      <ref name='virStreamEventCallback'/>
+      <ref name='virStreamEventRemoveCallback'/>
+      <ref name='virStreamEventType'/>
+      <ref name='virStreamEventUpdateCallback'/>
+      <ref name='virStreamFinish'/>
+      <ref name='virStreamFlags'/>
+      <ref name='virStreamFree'/>
+      <ref name='virStreamNew'/>
+      <ref name='virStreamPtr'/>
+      <ref name='virStreamRecv'/>
+      <ref name='virStreamRecvAll'/>
+      <ref name='virStreamRef'/>
+      <ref name='virStreamSend'/>
+      <ref name='virStreamSendAll'/>
+      <ref name='virStreamSinkFunc'/>
+      <ref name='virStreamSourceFunc'/>
       <ref name='virVcpuInfo'/>
       <ref name='virVcpuInfoPtr'/>
       <ref name='virVcpuState'/>
       <ref name='virStorageVolLookupByName'/>
       <ref name='virStorageVolLookupByPath'/>
     </type>
+    <type name='virStreamPtr'>
+      <ref name='virStreamNew'/>
+    </type>
   </constructors>
   <functions>
     <type name='char **'>
       <ref name='virDomainInterfaceStats'/>
       <ref name='virDomainMemoryPeek'/>
       <ref name='virSecretSetValue'/>
+      <ref name='virStreamRecv'/>
+      <ref name='virStreamSend'/>
+      <ref name='virStreamSinkFunc'/>
+      <ref name='virStreamSourceFunc'/>
     </type>
     <type name='size_t *'>
       <ref name='virSecretGetValue'/>
       <ref name='virStorageVolCreateXMLFrom'/>
       <ref name='virStorageVolDelete'/>
       <ref name='virStorageVolGetXMLDesc'/>
+      <ref name='virStreamNew'/>
     </type>
     <type name='unsigned long'>
       <ref name='virDomainMigrate'/>
       <ref name='virStoragePoolLookupByUUIDString'/>
       <ref name='virStorageVolLookupByKey'/>
       <ref name='virStorageVolLookupByPath'/>
+      <ref name='virStreamNew'/>
     </type>
     <type name='virDomainBlockStatsPtr'>
       <ref name='virDomainBlockStats'/>
       <ref name='virConnectDomainEventRegister'/>
       <ref name='virEventAddHandleFunc'/>
       <ref name='virEventAddTimeoutFunc'/>
+      <ref name='virStreamEventAddCallback'/>
     </type>
     <type name='virInterfacePtr'>
       <ref name='virInterfaceCreate'/>
       <ref name='virStorageVolGetXMLDesc'/>
       <ref name='virStorageVolRef'/>
     </type>
+    <type name='virStreamEventCallback'>
+      <ref name='virStreamEventAddCallback'/>
+    </type>
+    <type name='virStreamPtr'>
+      <ref name='virStreamAbort'/>
+      <ref name='virStreamEventAddCallback'/>
+      <ref name='virStreamEventCallback'/>
+      <ref name='virStreamEventRemoveCallback'/>
+      <ref name='virStreamEventUpdateCallback'/>
+      <ref name='virStreamFinish'/>
+      <ref name='virStreamFree'/>
+      <ref name='virStreamRecv'/>
+      <ref name='virStreamRecvAll'/>
+      <ref name='virStreamRef'/>
+      <ref name='virStreamSend'/>
+      <ref name='virStreamSendAll'/>
+      <ref name='virStreamSinkFunc'/>
+      <ref name='virStreamSourceFunc'/>
+    </type>
+    <type name='virStreamSinkFunc'>
+      <ref name='virStreamRecvAll'/>
+    </type>
+    <type name='virStreamSourceFunc'>
+      <ref name='virStreamSendAll'/>
+    </type>
     <type name='virVcpuInfoPtr'>
       <ref name='virDomainGetVcpus'/>
     </type>
       <ref name='virEventTimeoutCallback'/>
       <ref name='virFreeCallback'/>
       <ref name='virSetErrorFunc'/>
+      <ref name='virStreamEventAddCallback'/>
+      <ref name='virStreamEventCallback'/>
+      <ref name='virStreamRecvAll'/>
+      <ref name='virStreamSendAll'/>
+      <ref name='virStreamSinkFunc'/>
+      <ref name='virStreamSourceFunc'/>
     </type>
   </functions>
   <files>
       <ref name='VIR_STORAGE_VOL_DELETE_NORMAL'/>
       <ref name='VIR_STORAGE_VOL_DELETE_ZEROED'/>
       <ref name='VIR_STORAGE_VOL_FILE'/>
+      <ref name='VIR_STREAM_EVENT_ERROR'/>
+      <ref name='VIR_STREAM_EVENT_HANGUP'/>
+      <ref name='VIR_STREAM_EVENT_READABLE'/>
+      <ref name='VIR_STREAM_EVENT_WRITABLE'/>
+      <ref name='VIR_STREAM_NONBLOCK'/>
       <ref name='VIR_UNUSE_CPU'/>
       <ref name='VIR_USE_CPU'/>
       <ref name='VIR_UUID_BUFLEN'/>
       <ref name='virStorageVolPtr'/>
       <ref name='virStorageVolRef'/>
       <ref name='virStorageVolType'/>
+      <ref name='virStream'/>
+      <ref name='virStreamAbort'/>
+      <ref name='virStreamEventAddCallback'/>
+      <ref name='virStreamEventCallback'/>
+      <ref name='virStreamEventRemoveCallback'/>
+      <ref name='virStreamEventType'/>
+      <ref name='virStreamEventUpdateCallback'/>
+      <ref name='virStreamFinish'/>
+      <ref name='virStreamFlags'/>
+      <ref name='virStreamFree'/>
+      <ref name='virStreamNew'/>
+      <ref name='virStreamPtr'/>
+      <ref name='virStreamRecv'/>
+      <ref name='virStreamRecvAll'/>
+      <ref name='virStreamRef'/>
+      <ref name='virStreamSend'/>
+      <ref name='virStreamSendAll'/>
+      <ref name='virStreamSinkFunc'/>
+      <ref name='virStreamSourceFunc'/>
       <ref name='virVcpuInfo'/>
       <ref name='virVcpuInfoPtr'/>
       <ref name='virVcpuState'/>
           <ref name='virConnGetLastError'/>
           <ref name='virDomainCreateLinux'/>
           <ref name='virDomainGetVcpus'/>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='APIs'>
           <ref name='VIR_COPY_CPUMAP'/>
           <ref name='virConnectDomainEventDeregister'/>
           <ref name='virConnectDomainEventRegister'/>
           <ref name='virEventHandleCallback'/>
+          <ref name='virStreamEventCallback'/>
         </word>
         <word name='Change'>
           <ref name='virDomainSetSchedulerParameters'/>
           <ref name='virStorageVolCreateXML'/>
           <ref name='virStorageVolCreateXMLFrom'/>
         </word>
+        <word name='Creates'>
+          <ref name='virStreamNew'/>
+        </word>
         <word name='Current'>
           <ref name='_virStoragePoolInfo'/>
           <ref name='_virStorageVolInfo'/>
         <word name='De-registering'>
           <ref name='virConnectDomainEventDeregister'/>
         </word>
+        <word name='Decrement'>
+          <ref name='virStreamFree'/>
+        </word>
         <word name='Default'>
           <ref name='virDefaultErrorFunc'/>
         </word>
         <word name='Each'>
           <ref name='virDomainPinVcpu'/>
         </word>
+        <word name='Errors'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='Event'>
           <ref name='virConnectDomainEventDeregister'/>
           <ref name='virConnectDomainEventRegister'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamRef'/>
         </word>
         <word name='Free'>
           <ref name='virDomainFree'/>
           <ref name='virStoragePoolGetInfo'/>
         </word>
       </letter>
+    </chunk>
+    <chunk name='chunk1'>
       <letter name='H'>
         <word name='HBAs'>
           <ref name='virNodeDeviceCreateXML'/>
           <ref name='virConnectOpenAuth'/>
         </word>
       </letter>
-    </chunk>
-    <chunk name='chunk1'>
       <letter name='I'>
         <word name='IDs'>
           <ref name='virConnectListDomains'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamRef'/>
+        </word>
+        <word name='Indicate'>
+          <ref name='virStreamFinish'/>
         </word>
         <word name='Individual'>
           <ref name='virDomainBlockStats'/>
           <ref name='virDomainGetVcpus'/>
           <ref name='virGetVersion'/>
         </word>
+        <word name='O_RDONLY'>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='O_WRONLY'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+        </word>
         <word name='Once'>
           <ref name='virNodeDeviceDettach'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='One'>
           <ref name='_virConnectCredential'/>
         <word name='Reboot'>
           <ref name='virDomainReboot'/>
         </word>
+        <word name='Receive'>
+          <ref name='virStreamRecvAll'/>
+        </word>
         <word name='Record'>
           <ref name='virDomainBlockPeek'/>
         </word>
         </word>
         <word name='Request'>
           <ref name='virStoragePoolRefresh'/>
+          <ref name='virStreamAbort'/>
         </word>
         <word name='Reset'>
           <ref name='virConnResetLastError'/>
         </word>
         <word name='Returns'>
           <ref name='virConnectDomainEventRegister'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
         </word>
       </letter>
       <letter name='S'>
           <ref name='virConnectOpenAuth'/>
           <ref name='virConnectOpenReadOnly'/>
         </word>
+        <word name='Send'>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='Set'>
           <ref name='virConnSetErrorFunc'/>
           <ref name='virSetErrorFunc'/>
         </word>
         <word name='There'>
           <ref name='virDomainMigrate'/>
+          <ref name='virStreamFree'/>
         </word>
         <word name='Try'>
           <ref name='virDomainLookupByID'/>
           <ref name='virDomainBlockPeek'/>
         </word>
       </letter>
+    </chunk>
+    <chunk name='chunk2'>
       <letter name='U'>
         <word name='URI'>
           <ref name='virConnectGetURI'/>
           <ref name='virSecretLookupByUUIDString'/>
         </word>
       </letter>
-    </chunk>
-    <chunk name='chunk2'>
       <letter name='V'>
         <word name='VIR_COPY_CPUMAP'>
           <ref name='VIR_COPY_CPUMAP'/>
         <word name='VIR_SECRET_USAGE_TYPE_VOLUME'>
           <ref name='virSecretGetUsageID'/>
         </word>
+        <word name='VIR_STREAM_NONBLOCK'>
+          <ref name='virStreamNew'/>
+        </word>
         <word name='VIR_UUID_BUFLEN'>
           <ref name='virDomainGetUUID'/>
           <ref name='virNetworkGetUUID'/>
           <ref name='virSecretGetConnect'/>
           <ref name='virStoragePoolGetConnect'/>
           <ref name='virStorageVolGetConnect'/>
+          <ref name='virStreamNew'/>
+        </word>
+        <word name='Write'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
       </letter>
       <letter name='X'>
           <ref name='virDomainBlockPeek'/>
           <ref name='virDomainMemoryPeek'/>
         </word>
+        <word name='abnormally'>
+          <ref name='virStreamAbort'/>
+        </word>
+        <word name='abort'>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
+        <word name='aborted'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='about'>
           <ref name='virConnectOpenAuth'/>
           <ref name='virConnectOpenReadOnly'/>
           <ref name='virDomainGetSecurityLabel'/>
           <ref name='virDomainSuspend'/>
           <ref name='virStoragePoolDestroy'/>
+          <ref name='virStreamFree'/>
+        </word>
+        <word name='actual'>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='add'>
           <ref name='virDomainShutdown'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamRef'/>
         </word>
         <word name='address'>
           <ref name='virDomainMigrate'/>
           <ref name='virStorageVolCreateXML'/>
           <ref name='virStorageVolGetXMLDesc'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='allocated'>
           <ref name='cpumap'/>
           <ref name='virDomainDefineXML'/>
           <ref name='virDomainDestroy'/>
           <ref name='virNetworkDestroy'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='also'>
           <ref name='virConnCopyLastError'/>
         <word name='also:'>
           <ref name='virConnectGetType'/>
         </word>
+        <word name='alternative'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='always'>
           <ref name='virConnCopyLastError'/>
           <ref name='virConnGetLastError'/>
           <ref name='virDomainSetMaxMemory'/>
           <ref name='virDomainSetMemory'/>
           <ref name='virNodeGetCellsFreeMemory'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='analysis'>
           <ref name='virDomainCoreDump'/>
           <ref name='virNodeDeviceDettach'/>
           <ref name='virSecretDefineXML'/>
           <ref name='virStoragePoolDestroy'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='anymore'>
           <ref name='virConnectDomainEventRegister'/>
           <ref name='virDomainGetMaxMemory'/>
           <ref name='virDomainSetMaxMemory'/>
           <ref name='virDomainSetMemory'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='applications'>
           <ref name='virConnectRef'/>
           <ref name='virConnectFindStoragePoolSources'/>
           <ref name='virNodeDeviceReAttach'/>
         </word>
+        <word name='apps'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='arbitrary'>
           <ref name='virDomainSetVcpus'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='architecture'>
           <ref name='virDomainMigrate'/>
           <ref name='virDomainGetVcpus'/>
           <ref name='virGetVersion'/>
         </word>
+        <word name='asynchronous'>
+          <ref name='virStreamFinish'/>
+        </word>
         <word name='attached'>
           <ref name='virDomainBlockStats'/>
           <ref name='virDomainInterfaceStats'/>
         <word name='because'>
           <ref name='virDomainMemoryPeek'/>
         </word>
+        <word name='been'>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='before'>
           <ref name='virNodeDeviceReset'/>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='behaviour'>
           <ref name='virStoragePoolRefresh'/>
           <ref name='virEventRemoveHandleFunc'/>
           <ref name='virResetError'/>
           <ref name='virSecretGetUUID'/>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFree'/>
         </word>
         <word name='below'>
           <ref name='virDomainMemoryPeek'/>
         <word name='bitset'>
           <ref name='virEventAddHandleFunc'/>
           <ref name='virEventHandleCallback'/>
+          <ref name='virStreamEventCallback'/>
         </word>
         <word name='blob'>
           <ref name='virEventAddHandleFunc'/>
         <word name='block'>
           <ref name='virDomainBlockPeek'/>
           <ref name='virDomainBlockStats'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
+        <word name='blocking-I'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='boolean'>
           <ref name='virDomainGetAutostart'/>
           <ref name='virNetworkGetAutostart'/>
           <ref name='virNetworkSetAutostart'/>
         </word>
+        <word name='break'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='bridge'>
           <ref name='virNetworkGetBridgeName'/>
         </word>
+        <word name='buf'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='buf+offset'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='buffer'>
           <ref name='VIR_UUID_BUFLEN'/>
           <ref name='VIR_UUID_STRING_BUFLEN'/>
           <ref name='virSecretGetUUID'/>
           <ref name='virStoragePoolGetUUID'/>
           <ref name='virStoragePoolGetUUIDString'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
+        <word name='buffers'>
+          <ref name='virStreamSend'/>
         </word>
         <word name='but'>
           <ref name='VIR_NODEINFO_MAXCPUS'/>
           <ref name='virNodeDeviceReset'/>
           <ref name='virNodeGetFreeMemory'/>
           <ref name='virStoragePoolDestroy'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='byte'>
           <ref name='virDomainBlockPeek'/>
           <ref name='virConnectOpenReadOnly'/>
           <ref name='virEventAddHandleFunc'/>
           <ref name='virSetErrorFunc'/>
-        </word>
-        <word name='caller'>
-          <ref name='cpumap'/>
-          <ref name='virConnectDomainXMLFromNative'/>
-          <ref name='virConnectDomainXMLToNative'/>
-          <ref name='virConnectGetHostname'/>
-          <ref name='virConnectGetURI'/>
-          <ref name='virConnectListDefinedStoragePools'/>
-          <ref name='virConnectListStoragePools'/>
-          <ref name='virConnectRef'/>
-          <ref name='virDomainGetOSType'/>
-          <ref name='virDomainGetSchedulerType'/>
-          <ref name='virDomainGetXMLDesc'/>
-          <ref name='virDomainRef'/>
-          <ref name='virInterfaceGetXMLDesc'/>
-          <ref name='virInterfaceRef'/>
-          <ref name='virNetworkGetBridgeName'/>
-          <ref name='virNetworkGetXMLDesc'/>
-          <ref name='virNetworkRef'/>
-          <ref name='virNodeDeviceRef'/>
-          <ref name='virNodeGetCellsFreeMemory'/>
-          <ref name='virSaveLastError'/>
-          <ref name='virSecretGetValue'/>
-          <ref name='virSecretGetXMLDesc'/>
-          <ref name='virSecretRef'/>
-          <ref name='virStoragePoolRef'/>
-          <ref name='virStorageVolRef'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='callers'>
           <ref name='virDomainCreateLinux'/>
           <ref name='virConnectDomainEventRegister'/>
           <ref name='virDomainBlockStats'/>
           <ref name='virDomainResume'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='calloc'>
           <ref name='virDomainGetVcpus'/>
           <ref name='virNodeGetCellsFreeMemory'/>
           <ref name='virResetLastError'/>
           <ref name='virStoragePoolDestroy'/>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamNew'/>
+        </word>
+        <word name='cancelled'>
+          <ref name='virStreamAbort'/>
         </word>
         <word name='cannot'>
           <ref name='virDomainLookupByID'/>
         <word name='char'>
           <ref name='virConnectListDefinedStoragePools'/>
           <ref name='virConnectListStoragePools'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='choose'>
           <ref name='virDomainMigrate'/>
         <word name='chosen'>
           <ref name='virSecretDefineXML'/>
         </word>
+        <word name='chunks'>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='clean'>
           <ref name='virResetError'/>
         </word>
         <word name='clonevol'>
           <ref name='virStorageVolCreateXMLFrom'/>
         </word>
+        <word name='close'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='closes'>
           <ref name='virConnectClose'/>
         </word>
           <ref name='virCopyLastError'/>
           <ref name='virDomainPinVcpu'/>
           <ref name='virGetVersion'/>
+          <ref name='virStreamFinish'/>
         </word>
         <word name='coherently'>
           <ref name='virDomainMemoryPeek'/>
         <word name='completed'>
           <ref name='virDomainBlockPeek'/>
         </word>
+        <word name='completion'>
+          <ref name='virStreamRecv'/>
+        </word>
         <word name='concurrently'>
           <ref name='virConnResetLastError'/>
           <ref name='virCopyLastError'/>
           <ref name='virDomainGetAutostart'/>
           <ref name='virNetworkGetAutostart'/>
         </word>
+        <word name='confirmation'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='conjunction'>
           <ref name='VIR_COPY_CPUMAP'/>
           <ref name='VIR_CPU_MAPLEN'/>
           <ref name='VIR_UNUSE_CPU'/>
           <ref name='VIR_USE_CPU'/>
         </word>
+        <word name='conn'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='connect'>
           <ref name='virConnectGetURI'/>
           <ref name='virDomainMigrate'/>
         <word name='consisting'>
           <ref name='virConnectFindStoragePoolSources'/>
         </word>
+        <word name='const'>
+          <ref name='virStreamRecvAll'/>
+        </word>
         <word name='constants'>
           <ref name='_virConnectCredential'/>
           <ref name='virEventHandleCallback'/>
           <ref name='virSecretGetUsageType'/>
+          <ref name='virStreamEventCallback'/>
+        </word>
+        <word name='consume'>
+          <ref name='virStreamSinkFunc'/>
+        </word>
+        <word name='consumed'>
+          <ref name='virStreamSinkFunc'/>
         </word>
         <word name='containing'>
           <ref name='virConnectFindStoragePoolSources'/>
           <ref name='virDomainMemoryPeek'/>
           <ref name='virDomainSave'/>
         </word>
+        <word name='continue'>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='continues'>
           <ref name='virSecretFree'/>
           <ref name='virStorageVolFree'/>
         <word name='control'>
           <ref name='virConnectOpenReadOnly'/>
           <ref name='virStoragePoolRefresh'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='controlled'>
           <ref name='virDomainMemoryPeek'/>
         </word>
+        <word name='convenient'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='copied'>
           <ref name='virSaveLastError'/>
         </word>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamRef'/>
         </word>
         <word name='corresponds'>
           <ref name='virConnectGetMaxVcpus'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamRef'/>
         </word>
         <word name='counter'>
           <ref name='virDomainGetConnect'/>
         <word name='daemon'>
           <ref name='virConnectOpen'/>
         </word>
-        <word name='data'>
-          <ref name='virConnSetErrorFunc'/>
-          <ref name='virConnectDomainEventCallback'/>
-          <ref name='virConnectDomainEventRegister'/>
-          <ref name='virConnectDomainXMLFromNative'/>
-          <ref name='virConnectDomainXMLToNative'/>
-          <ref name='virDomainFree'/>
-          <ref name='virErrorFunc'/>
-          <ref name='virEventAddHandleFunc'/>
-          <ref name='virEventAddTimeoutFunc'/>
-          <ref name='virEventHandleCallback'/>
-          <ref name='virEventRemoveHandleFunc'/>
-          <ref name='virEventRemoveTimeoutFunc'/>
-          <ref name='virEventTimeoutCallback'/>
-          <ref name='virInterfaceFree'/>
-          <ref name='virNetworkFree'/>
-          <ref name='virSecretLookupByUUID'/>
-          <ref name='virSetErrorFunc'/>
-        </word>
         <word name='datafile'>
           <ref name='virConnectDomainXMLToNative'/>
         </word>
           <ref name='virNetworkCreate'/>
           <ref name='virNetworkUndefine'/>
           <ref name='virSecretGetUsageType'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='defining'>
           <ref name='virConnectGetCapabilities'/>
         <word name='defresult'>
           <ref name='_virConnectCredential'/>
         </word>
+        <word name='delayed'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='delivery'>
           <ref name='virConnectDomainEventDeregister'/>
           <ref name='virConnectDomainEventRegister'/>
         </word>
+        <word name='demo'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='dependant'>
           <ref name='virConnectDomainXMLFromNative'/>
           <ref name='virConnectDomainXMLToNative'/>
         <word name='detail'>
           <ref name='virConnectDomainEventCallback'/>
         </word>
+        <word name='detect'>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='determine'>
           <ref name='virConnectOpen'/>
           <ref name='virDomainBlockPeek'/>
           <ref name='virDomainRestore'/>
           <ref name='virDomainSave'/>
         </word>
+        <word name='disposed'>
+          <ref name='virStreamFree'/>
+        </word>
         <word name='dname'>
           <ref name='virDomainMigrate'/>
         </word>
         <word name='done'>
           <ref name='virConnectOpen'/>
           <ref name='virDomainLookupByID'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='done:'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='down'>
           <ref name='virDomainDestroy'/>
           <ref name='virNetworkDestroy'/>
         </word>
+        <word name='download'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+        </word>
         <word name='driver'>
           <ref name='virConnectGetCapabilities'/>
           <ref name='virConnectGetURI'/>
           <ref name='virNodeDeviceDettach'/>
           <ref name='virNodeDeviceReAttach'/>
           <ref name='virNodeGetSecurityModel'/>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='drivers'>
           <ref name='virConnectOpenAuth'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamEventCallback'/>
+          <ref name='virStreamRef'/>
+        </word>
+        <word name='early'>
+          <ref name='virStreamAbort'/>
         </word>
         <word name='effect'>
           <ref name='virConnectOpenAuth'/>
           <ref name='virInterfaceGetXMLDesc'/>
           <ref name='virNetworkGetXMLDesc'/>
         </word>
+        <word name='end'>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
+        <word name='end-of-file'>
+          <ref name='virStreamFinish'/>
+        </word>
         <word name='ensures'>
           <ref name='virDomainMemoryPeek'/>
         </word>
+        <word name='entire'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='entirely'>
           <ref name='virDomainBlockPeek'/>
         </word>
         <word name='errors'>
           <ref name='virConnCopyLastError'/>
           <ref name='virConnGetLastError'/>
+          <ref name='virStreamFinish'/>
         </word>
         <word name='especially'>
           <ref name='virConnectClose'/>
           <ref name='virEventHandleCallback'/>
           <ref name='virEventTimeoutCallback'/>
           <ref name='virEventUpdateTimeoutFunc'/>
+          <ref name='virStreamEventCallback'/>
         </word>
         <word name='events'>
           <ref name='virConnectDomainEventDeregister'/>
           <ref name='virEventHandleCallback'/>
           <ref name='virEventTimeoutCallback'/>
           <ref name='virEventUpdateHandleFunc'/>
+          <ref name='virStreamEventCallback'/>
         </word>
         <word name='ever'>
           <ref name='virSecretGetUsageID'/>
           <ref name='virDomainMigrate'/>
           <ref name='virNodeDeviceCreateXML'/>
           <ref name='virNodeDeviceReset'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='execution'>
           <ref name='virConnectDomainEventRegister'/>
         </word>
         <word name='features'>
           <ref name='virDomainMigrate'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='feeding'>
           <ref name='virStoragePoolGetXMLDesc'/>
         </word>
         <word name='fetching'>
           <ref name='virConnectOpenAuth'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='field'>
           <ref name='VIR_DOMAIN_SCHED_FIELD_LENGTH'/>
           <ref name='virEventHandleCallback'/>
           <ref name='virEventRemoveHandleFunc'/>
           <ref name='virEventUpdateHandleFunc'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='filesystems'>
           <ref name='virDomainBlockPeek'/>
         <word name='fill'>
           <ref name='virConnectListDefinedStoragePools'/>
           <ref name='virConnectListStoragePools'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='filled'>
           <ref name='_virConnectCredential'/>
           <ref name='virDomainGetVcpus'/>
           <ref name='virNodeGetCellsFreeMemory'/>
           <ref name='virSecretGetUUID'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='find'>
           <ref name='virDomainLookupByID'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='fire'>
           <ref name='virEventAddHandleFunc'/>
           <ref name='virConnectOpenAuth'/>
           <ref name='virConnectOpenReadOnly'/>
           <ref name='virNodeGetCellsFreeMemory'/>
+          <ref name='virStreamFree'/>
         </word>
         <word name='flag'>
           <ref name='virStoragePoolGetAutostart'/>
           <ref name='virStoragePoolSetAutostart'/>
         </word>
+        <word name='flush'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='following:'>
           <ref name='virDomainMigrate'/>
         </word>
         <word name='frequency'>
           <ref name='_virNodeInfo'/>
         </word>
-        <word name='from'>
-          <ref name='VIR_COPY_CPUMAP'/>
-          <ref name='VIR_GET_CPUMAP'/>
-          <ref name='_virVcpuInfo'/>
-          <ref name='virConnCopyLastError'/>
-          <ref name='virConnGetLastError'/>
-          <ref name='virConnectDomainXMLFromNative'/>
-          <ref name='virDomainBlockPeek'/>
-          <ref name='virDomainCreate'/>
-          <ref name='virDomainGetVcpus'/>
-          <ref name='virDomainMigrate'/>
-          <ref name='virDomainPinVcpu'/>
-          <ref name='virDomainResume'/>
-          <ref name='virEventHandleCallback'/>
-          <ref name='virInterfaceDestroy'/>
-          <ref name='virInterfaceUndefine'/>
-          <ref name='virNetworkCreate'/>
-          <ref name='virNodeDeviceDestroy'/>
-          <ref name='virNodeDeviceDettach'/>
-          <ref name='virNodeDeviceReAttach'/>
-          <ref name='virSecretDefineXML'/>
-          <ref name='virStorageVolDelete'/>
-          <ref name='virStorageVolGetKey'/>
-        </word>
         <word name='frozen'>
           <ref name='virDomainResume'/>
           <ref name='virDomainSuspend'/>
         </word>
+        <word name='full'>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='fully'>
           <ref name='virSecretGetUsageID'/>
         </word>
         <word name='further'>
           <ref name='virConnectClose'/>
           <ref name='virDomainSuspend'/>
+          <ref name='virStreamFinish'/>
         </word>
         <word name='future'>
           <ref name='virSecretGetUsageType'/>
           <ref name='virDomainInterfaceStats'/>
           <ref name='virDomainMigrate'/>
           <ref name='virSetErrorFunc'/>
+          <ref name='virStreamRecv'/>
         </word>
         <word name='gethostname'>
           <ref name='virConnectGetHostname'/>
           <ref name='virStorageVolGetKey'/>
           <ref name='virStorageVolLookupByKey'/>
         </word>
+        <word name='got'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
+        <word name='got-offset'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
+        <word name='goto'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='growing'>
           <ref name='virDomainSetVcpus'/>
         </word>
+        <word name='guaranteed'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='guest'>
           <ref name='virConnectGetMaxVcpus'/>
           <ref name='virDomainCreateXML'/>
           <ref name='virEventTimeoutCallback'/>
           <ref name='virSecretFree'/>
           <ref name='virStorageVolFree'/>
+          <ref name='virStreamEventCallback'/>
         </word>
         <word name='handler'>
           <ref name='virConnSetErrorFunc'/>
           <ref name='virNodeDeviceGetParent'/>
           <ref name='virNodeGetSecurityModel'/>
           <ref name='virStoragePoolDestroy'/>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='have'>
           <ref name='virConnectOpenAuth'/>
           <ref name='virStorageVolGetKey'/>
           <ref name='virStorageVolRef'/>
         </word>
+        <word name='having'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='here'>
           <ref name='virConnectGetMaxVcpus'/>
         </word>
+        <word name='hit'>
+          <ref name='virStreamFree'/>
+        </word>
         <word name='hold'>
           <ref name='virConnectRef'/>
           <ref name='virDomainRef'/>
         <word name='hypervisors'>
           <ref name='virDomainMigrate'/>
         </word>
+        <word name='hypothetical'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
       </letter>
     </chunk>
     <chunk name='chunk6'>
         <word name='indicates'>
           <ref name='virDomainBlockStats'/>
           <ref name='virDomainInterfaceStats'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='indicating'>
           <ref name='_virNodeInfo'/>
           <ref name='virStoragePoolGetInfo'/>
           <ref name='virStorageVolGetInfo'/>
         </word>
+        <word name='inform'>
+          <ref name='virStreamAbort'/>
+        </word>
         <word name='information'>
           <ref name='_virError'/>
           <ref name='virConnectDomainEventCallback'/>
         <word name='ing'>
           <ref name='virEventAddHandleFunc'/>
           <ref name='virEventAddTimeoutFunc'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='initialized'>
           <ref name='virDomainGetSecurityLabel'/>
         </word>
         <word name='input'>
           <ref name='virStorageVolCreateXMLFrom'/>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFinish'/>
         </word>
         <word name='inside'>
           <ref name='virDomainGetVcpus'/>
         </word>
         <word name='instead'>
           <ref name='virDomainLookupByID'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='int'>
           <ref name='virDomainGetID'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='integer'>
           <ref name='virSecretGetUsageType'/>
           <ref name='virConnCopyLastError'/>
           <ref name='virConnGetLastError'/>
         </word>
+        <word name='invoke'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='invoked'>
           <ref name='virEventAddHandleFunc'/>
           <ref name='virEventAddTimeoutFunc'/>
           <ref name='virEventHandleCallback'/>
           <ref name='virEventRemoveHandleFunc'/>
           <ref name='virEventRemoveTimeoutFunc'/>
+          <ref name='virStreamEventCallback'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='involve'>
           <ref name='virNodeDeviceDettach'/>
         <word name='isn'>
           <ref name='virDomainGetVcpus'/>
         </word>
+        <word name='iso'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='itself'>
           <ref name='virInterfaceFree'/>
           <ref name='virNodeDeviceDettach'/>
         </word>
         <word name='less'>
           <ref name='virDomainSetSchedulerParameters'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='level'>
           <ref name='virConnectGetVersion'/>
           <ref name='virSecretGetConnect'/>
           <ref name='virStoragePoolGetConnect'/>
           <ref name='virStorageVolGetConnect'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='libvirtd'>
           <ref name='virConnectOpen'/>
           <ref name='virInterfaceGetName'/>
           <ref name='virNetworkGetName'/>
         </word>
+        <word name='like'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='limit'>
           <ref name='virDomainBlockPeek'/>
           <ref name='virDomainMemoryPeek'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamRef'/>
         </word>
         <word name='look'>
           <ref name='virConnectFindStoragePoolSources'/>
         <word name='looked'>
           <ref name='virGetVersion'/>
         </word>
+        <word name='looks'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='lookup'>
           <ref name='virDomainLookupByID'/>
           <ref name='virDomainLookupByName'/>
           <ref name='virDomainGetVcpus'/>
           <ref name='virDomainPinVcpu'/>
         </word>
+        <word name='marked'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='matching'>
           <ref name='virStoragePoolLookupByName'/>
           <ref name='virStoragePoolLookupByUUID'/>
         <word name='message'>
           <ref name='_virError'/>
         </word>
-        <word name='method'>
-          <ref name='virConnCopyLastError'/>
-          <ref name='virConnGetLastError'/>
-          <ref name='virConnectRef'/>
-          <ref name='virDomainCoreDump'/>
-          <ref name='virDomainMigrate'/>
-          <ref name='virDomainRef'/>
-          <ref name='virDomainRestore'/>
-          <ref name='virDomainSave'/>
-          <ref name='virInterfaceRef'/>
-          <ref name='virNetworkRef'/>
-          <ref name='virNodeDeviceDettach'/>
-          <ref name='virNodeDeviceReAttach'/>
-          <ref name='virNodeDeviceRef'/>
-          <ref name='virSecretRef'/>
-          <ref name='virStoragePoolGetXMLDesc'/>
-          <ref name='virStoragePoolRef'/>
-          <ref name='virStorageVolRef'/>
-        </word>
         <word name='methods'>
           <ref name='virConnectOpenReadOnly'/>
         </word>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='multithreaded'>
           <ref name='virInitialize'/>
           <ref name='virNodeGetCellsFreeMemory'/>
           <ref name='virSecretGetValue'/>
           <ref name='virSecretGetXMLDesc'/>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamNew'/>
+        </word>
+        <word name='mysink'>
+          <ref name='virStreamRecvAll'/>
+        </word>
+        <word name='mysource'>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='mysterious'>
           <ref name='_virDomainBlockStats'/>
           <ref name='virConnectDomainXMLFromNative'/>
           <ref name='virConnectDomainXMLToNative'/>
         </word>
+        <word name='nbytes'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='necessary'>
           <ref name='VIR_NODEINFO_MAXCPUS'/>
           <ref name='virConnectOpenAuth'/>
           <ref name='virInterfaceGetMACString'/>
           <ref name='virInterfaceGetName'/>
           <ref name='virNetworkGetName'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='needed'>
           <ref name='virConnectClose'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='needs'>
           <ref name='virConnectRef'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamRef'/>
         </word>
         <word name='networks'>
           <ref name='virConnectListDefinedNetworks'/>
           <ref name='virNodeListDevices'/>
           <ref name='virNodeNumOfDevices'/>
         </word>
+        <word name='non-blocking'>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='non-overlapping'>
           <ref name='virEventAddHandleFunc'/>
         </word>
           <ref name='virEventRemoveHandleFunc'/>
           <ref name='virEventUpdateHandleFunc'/>
         </word>
+        <word name='notify'>
+          <ref name='virStreamNew'/>
+        </word>
         <word name='now'>
           <ref name='virSecretDefineXML'/>
           <ref name='virSecretGetValue'/>
           <ref name='virStoragePoolCreateXML'/>
           <ref name='virStoragePoolDefineXML'/>
           <ref name='virStorageVolDelete'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='nparams'>
           <ref name='virDomainGetSchedulerParameters'/>
         <word name='obliteration'>
           <ref name='virStoragePoolDelete'/>
         </word>
+        <word name='obtain'>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='occured'>
           <ref name='virConnectDomainEventCallback'/>
         </word>
           <ref name='virConnGetLastError'/>
           <ref name='virEventHandleCallback'/>
           <ref name='virGetLastError'/>
+          <ref name='virStreamEventCallback'/>
         </word>
         <word name='occurrs'>
           <ref name='virEventAddHandleFunc'/>
         </word>
         <word name='offset'>
           <ref name='virDomainBlockPeek'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='once'>
           <ref name='virConnectDomainEventRegister'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamEventCallback'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamRef'/>
         </word>
         <word name='one'>
           <ref name='_virDomainInfo'/>
           <ref name='virDomainGetInfo'/>
           <ref name='virResetLastError'/>
           <ref name='virSecretGetUsageID'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='oo_req'>
           <ref name='_virDomainBlockStats'/>
           <ref name='virConnectDomainEventRegister'/>
           <ref name='virEventAddHandleFunc'/>
           <ref name='virEventAddTimeoutFunc'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='open'>
           <ref name='virConnectRef'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='opening'>
           <ref name='virConnectOpenAuth'/>
           <ref name='virDomainGetOSType'/>
           <ref name='virDomainReboot'/>
           <ref name='virStoragePoolDelete'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='operations'>
           <ref name='virNodeDeviceDettach'/>
           <ref name='virDomainMigrate'/>
           <ref name='virNodeListDevices'/>
           <ref name='virNodeNumOfDevices'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='options'>
           <ref name='virStoragePoolGetXMLDesc'/>
           <ref name='virDomainMemoryPeek'/>
           <ref name='virDomainMigrate'/>
           <ref name='virNetworkGetBridgeName'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='order:'>
           <ref name='virDomainPinVcpu'/>
           <ref name='virSecretGetConnect'/>
           <ref name='virStoragePoolGetConnect'/>
           <ref name='virStorageVolGetConnect'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='otherwise'>
           <ref name='VIR_CPU_USABLE'/>
           <ref name='virInterfaceDefineXML'/>
           <ref name='virNetworkDefineXML'/>
           <ref name='virNodeDeviceLookupByName'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='out'>
           <ref name='virDomainBlockPeek'/>
         </word>
+        <word name='outgoing'>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='output'>
           <ref name='virDomainSave'/>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFinish'/>
         </word>
         <word name='over'>
           <ref name='virDomainBlockPeek'/>
           <ref name='virStorageVolCreateXML'/>
           <ref name='virStorageVolCreateXMLFrom'/>
           <ref name='virStorageVolGetXMLDesc'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='passed'>
           <ref name='virConnectDomainEventRegister'/>
           <ref name='virConnectGetURI'/>
           <ref name='virStorageVolCreateXMLFrom'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='path'>
           <ref name='virDomainBlockPeek'/>
         </word>
         <word name='pending'>
           <ref name='virEventHandleCallback'/>
+          <ref name='virStreamEventCallback'/>
+          <ref name='virStreamRecv'/>
         </word>
         <word name='per'>
           <ref name='_virNodeInfo'/>
         </word>
         <word name='perform'>
           <ref name='virDomainMigrate'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='performed'>
           <ref name='virConnectOpenAuth'/>
           <ref name='virDomainSetMaxMemory'/>
           <ref name='virDomainSetMemory'/>
         </word>
+        <word name='point'>
+          <ref name='virStreamFinish'/>
+        </word>
         <word name='pointed'>
           <ref name='virResetError'/>
         </word>
         <word name='potential'>
           <ref name='virInitialize'/>
         </word>
+        <word name='preallocated'>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='precise'>
           <ref name='virDomainBlockPeek'/>
         </word>
         <word name='printing'>
           <ref name='virSetErrorFunc'/>
         </word>
+        <word name='prior'>
+          <ref name='virStreamFree'/>
+        </word>
         <word name='privileged'>
           <ref name='virConnectGetVersion'/>
           <ref name='virDomainCreateXML'/>
           <ref name='virDomainSuspend'/>
           <ref name='virStoragePoolDelete'/>
         </word>
+        <word name='processed'>
+          <ref name='virStreamFinish'/>
+        </word>
         <word name='processors'>
           <ref name='virDomainMigrate'/>
         </word>
           <ref name='virDomainBlockPeek'/>
           <ref name='virDomainMemoryPeek'/>
         </word>
+        <word name='progress'>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFree'/>
+        </word>
         <word name='protected'>
           <ref name='virConnCopyLastError'/>
           <ref name='virConnGetLastError'/>
         </word>
         <word name='provide'>
           <ref name='virNodeGetFreeMemory'/>
+          <ref name='virStreamSinkFunc'/>
         </word>
         <word name='provided'>
           <ref name='virConnSetErrorFunc'/>
           <ref name='virErrorFunc'/>
           <ref name='virEventAddHandleFunc'/>
           <ref name='virSetErrorFunc'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='provides'>
           <ref name='VIR_UUID_BUFLEN'/>
           <ref name='VIR_SECURITY_LABEL_BUFLEN'/>
           <ref name='VIR_SECURITY_MODEL_BUFLEN'/>
           <ref name='virDomainCreateLinux'/>
+          <ref name='virStreamSinkFunc'/>
         </word>
         <word name='public'>
           <ref name='virDomainGetName'/>
           <ref name='virInterfaceGetName'/>
           <ref name='virNetworkGetName'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='purpose'>
           <ref name='virDomainMigrate'/>
         <word name='re-attached'>
           <ref name='virNodeDeviceDettach'/>
         </word>
+        <word name='reached'>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='reactivate'>
           <ref name='virDomainSuspend'/>
         </word>
           <ref name='_virDomainBlockStats'/>
           <ref name='virDomainBlockPeek'/>
           <ref name='virDomainMemoryPeek'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='reading'>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='real'>
           <ref name='_virVcpuInfo'/>
         <word name='receive'>
           <ref name='virConnCopyLastError'/>
           <ref name='virCopyLastError'/>
+          <ref name='virStreamSinkFunc'/>
+        </word>
+        <word name='received'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSinkFunc'/>
         </word>
         <word name='receiving'>
           <ref name='virEventHandleCallback'/>
           <ref name='virEventTimeoutCallback'/>
+          <ref name='virStreamEventCallback'/>
         </word>
         <word name='redefine'>
           <ref name='virInterfaceGetXMLDesc'/>
           <ref name='virEventRemoveHandleFunc'/>
           <ref name='virEventRemoveTimeoutFunc'/>
           <ref name='virEventTimeoutCallback'/>
+          <ref name='virStreamEventCallback'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='related'>
           <ref name='VIR_UNUSE_CPU'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRef'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='released'>
           <ref name='virConnectDomainEventRegister'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='releasing'>
           <ref name='virStoragePoolFree'/>
+          <ref name='virStreamFree'/>
         </word>
         <word name='reliably'>
           <ref name='virDomainBlockPeek'/>
         <word name='replaces'>
           <ref name='virSecretDefineXML'/>
         </word>
+        <word name='report'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='reported'>
           <ref name='virConnCopyLastError'/>
           <ref name='virConnGetLastError'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='reporting'>
           <ref name='virDefaultErrorFunc'/>
         <word name='requested'>
           <ref name='virEventAddHandleFunc'/>
           <ref name='virNodeGetCellsFreeMemory'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='requests'>
           <ref name='_virDomainBlockStats'/>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamNew'/>
         </word>
         <word name='requires'>
           <ref name='virConnectOpen'/>
           <ref name='virGetVersion'/>
           <ref name='virNodeDeviceGetName'/>
           <ref name='virNodeGetCellsFreeMemory'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='returned'>
           <ref name='virConnectDomainXMLFromNative'/>
           <ref name='virNodeGetFreeMemory'/>
           <ref name='virSecretGetUsageType'/>
         </word>
+        <word name='returning'>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='returns'>
           <ref name='VIR_CPU_MAPLEN'/>
           <ref name='VIR_CPU_USABLE'/>
           <ref name='virDomainBlockStats'/>
           <ref name='virDomainInterfaceStats'/>
           <ref name='virNodeGetCellsFreeMemory'/>
+          <ref name='virStreamFinish'/>
         </word>
         <word name='reused'>
           <ref name='virDomainGetXMLDesc'/>
         <word name='semantics'>
           <ref name='virNodeDeviceReset'/>
         </word>
+        <word name='send'>
+          <ref name='virStreamSourceFunc'/>
+        </word>
+        <word name='sending'>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+        </word>
+        <word name='sent'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='separate'>
           <ref name='virConnResetLastError'/>
           <ref name='virCopyLastError'/>
           <ref name='virGetLastError'/>
           <ref name='virResetLastError'/>
         </word>
+        <word name='series'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='server'>
           <ref name='virStoragePoolRefresh'/>
         </word>
           <ref name='virSecretRef'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamRef'/>
         </word>
         <word name='sharing'>
           <ref name='virSecretGetUsageID'/>
           <ref name='virSecretLookupByUsage'/>
         </word>
-        <word name='should'>
-          <ref name='virConnectClose'/>
-          <ref name='virConnectOpen'/>
-          <ref name='virConnectOpenAuth'/>
-          <ref name='virConnectOpenReadOnly'/>
-          <ref name='virDomainBlockPeek'/>
-          <ref name='virDomainBlockStats'/>
-          <ref name='virDomainCreateLinux'/>
-          <ref name='virDomainCreateXML'/>
-          <ref name='virDomainFree'/>
-          <ref name='virDomainGetSchedulerParameters'/>
-          <ref name='virDomainInterfaceStats'/>
-          <ref name='virDomainMemoryPeek'/>
-          <ref name='virDomainSetAutostart'/>
-          <ref name='virDomainSetSchedulerParameters'/>
-          <ref name='virDomainShutdown'/>
-          <ref name='virInterfaceFree'/>
-          <ref name='virNetworkFree'/>
-          <ref name='virNetworkSetAutostart'/>
-          <ref name='virNodeDeviceCreateXML'/>
-          <ref name='virSecretGetUsageType'/>
-        </word>
         <word name='show'>
           <ref name='_virConnectCredential'/>
         </word>
           <ref name='virDomainCreateXML'/>
           <ref name='virNetworkCreateXML'/>
         </word>
+        <word name='simply'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='single'>
           <ref name='VIR_CPU_MAPLEN'/>
         </word>
+        <word name='sink'>
+          <ref name='virStreamRecvAll'/>
+        </word>
         <word name='sizes'>
           <ref name='virNodeGetFreeMemory'/>
         </word>
+        <word name='small'>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='smaller'>
           <ref name='virNodeGetCellsFreeMemory'/>
         </word>
           <ref name='virConnectFindStoragePoolSources'/>
           <ref name='virDomainBlockPeek'/>
           <ref name='virDomainMigrate'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='sources'>
           <ref name='virConnectFindStoragePoolSources'/>
           <ref name='virDomainUndefine'/>
           <ref name='virEventRemoveHandleFunc'/>
           <ref name='virNetworkUndefine'/>
+          <ref name='virStreamAbort'/>
         </word>
         <word name='stopped'>
           <ref name='virDomainReboot'/>
         <word name='storing'>
           <ref name='virSecretGetValue'/>
         </word>
+        <word name='streamed'>
+          <ref name='virStreamNew'/>
+        </word>
+        <word name='streams'>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFinish'/>
+        </word>
         <word name='structure'>
           <ref name='virDomainBlockStats'/>
           <ref name='virDomainFree'/>
         <word name='structures'>
           <ref name='virDomainGetVcpus'/>
         </word>
+        <word name='subsequent'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='succeed'>
           <ref name='virDomainBlockPeek'/>
           <ref name='virDomainCreate'/>
           <ref name='virDomainMemoryPeek'/>
           <ref name='virNetworkCreate'/>
         </word>
+        <word name='succesful'>
+          <ref name='virStreamSend'/>
+        </word>
+        <word name='succesfully'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='successful'>
           <ref name='virDomainMigrate'/>
           <ref name='virDomainSave'/>
         </word>
         <word name='successfully'>
           <ref name='virConnectOpen'/>
+          <ref name='virStreamFinish'/>
         </word>
         <word name='such'>
           <ref name='virConnCopyLastError'/>
         <word name='supports'>
           <ref name='virDomainMigrate'/>
         </word>
+        <word name='sure'>
+          <ref name='virStreamFinish'/>
+        </word>
         <word name='suspend'>
           <ref name='virDomainSave'/>
         </word>
         <word name='suspended'>
           <ref name='virDomainResume'/>
         </word>
+        <word name='synchronization'>
+          <ref name='virStreamFinish'/>
+        </word>
+        <word name='synchronously'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='system'>
           <ref name='virConnectGetHostname'/>
           <ref name='virDomainGetOSType'/>
           <ref name='virInterfaceGetXMLDesc'/>
           <ref name='virNetworkGetBridgeName'/>
           <ref name='virNetworkGetXMLDesc'/>
+          <ref name='virStreamAbort'/>
+        </word>
+        <word name='termination'>
+          <ref name='virStreamNew'/>
         </word>
         <word name='test'>
           <ref name='virDomainBlockPeek'/>
           <ref name='virDomainGetSchedulerParameters'/>
           <ref name='virDomainInterfaceStats'/>
           <ref name='virDomainSetSchedulerParameters'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='their'>
           <ref name='virConnectListDefinedInterfaces'/>
           <ref name='virNodeListDevices'/>
           <ref name='virResetLastError'/>
         </word>
-        <word name='then'>
-          <ref name='virConnCopyLastError'/>
-          <ref name='virConnGetLastError'/>
-          <ref name='virConnectGetHostname'/>
-          <ref name='virConnectGetURI'/>
-          <ref name='virConnectOpen'/>
-          <ref name='virConnectOpenReadOnly'/>
-          <ref name='virDomainGetMaxMemory'/>
-          <ref name='virDomainGetVcpus'/>
-          <ref name='virDomainLookupByID'/>
-          <ref name='virDomainLookupByName'/>
-          <ref name='virDomainLookupByUUID'/>
-          <ref name='virDomainLookupByUUIDString'/>
-          <ref name='virDomainMemoryPeek'/>
-          <ref name='virDomainMigrate'/>
-          <ref name='virDomainSetMaxMemory'/>
-          <ref name='virDomainSetMemory'/>
-          <ref name='virEventAddHandleFunc'/>
-          <ref name='virEventAddTimeoutFunc'/>
-          <ref name='virInterfaceLookupByMACString'/>
-          <ref name='virInterfaceLookupByName'/>
-          <ref name='virNetworkLookupByName'/>
-          <ref name='virNetworkLookupByUUID'/>
-          <ref name='virNetworkLookupByUUIDString'/>
-          <ref name='virNodeListDevices'/>
-          <ref name='virNodeNumOfDevices'/>
-          <ref name='virSecretLookupByUUID'/>
-          <ref name='virSecretLookupByUUIDString'/>
-          <ref name='virSecretLookupByUsage'/>
-        </word>
         <word name='there'>
           <ref name='virConnectClose'/>
           <ref name='virConnectGetHostname'/>
           <ref name='virSetErrorFunc'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRef'/>
         </word>
         <word name='thereafter'>
           <ref name='virDomainFree'/>
           <ref name='virEventRemoveHandleFunc'/>
           <ref name='virEventRemoveTimeoutFunc'/>
           <ref name='virStoragePoolGetAutostart'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='timeout'>
           <ref name='virEventAddTimeoutFunc'/>
         </word>
         <word name='times'>
           <ref name='virEventAddHandleFunc'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='together'>
           <ref name='virDomainGetConnect'/>
           <ref name='virSecretGetConnect'/>
           <ref name='virStoragePoolGetConnect'/>
           <ref name='virStorageVolGetConnect'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='total'>
           <ref name='VIR_NODEINFO_MAXCPUS'/>
         </word>
+        <word name='transfer'>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFree'/>
+        </word>
+        <word name='transmit'>
+          <ref name='virStreamSend'/>
+        </word>
+        <word name='transmitted'>
+          <ref name='virStreamFinish'/>
+        </word>
         <word name='transport'>
           <ref name='virDomainMigrate'/>
         </word>
           <ref name='virStoragePoolDefineXML'/>
           <ref name='virStoragePoolRef'/>
           <ref name='virStorageVolRef'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='unused'>
           <ref name='virConnectDomainXMLFromNative'/>
         <word name='updating'>
           <ref name='virEventAddHandleFunc'/>
         </word>
+        <word name='upload'>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='upon'>
           <ref name='virConnectDomainEventRegister'/>
           <ref name='virSecretGetUUID'/>
           <ref name='virSecretGetUsageID'/>
           <ref name='virSecretGetUsageType'/>
           <ref name='virStoragePoolBuild'/>
+          <ref name='virStreamAbort'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSinkFunc'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='upto'>
           <ref name='virConnectListDefinedStoragePools'/>
           <ref name='virConnectListStoragePools'/>
+          <ref name='virStreamSourceFunc'/>
         </word>
         <word name='uri'>
           <ref name='virConnectOpen'/>
           <ref name='virEventTimeoutCallback'/>
           <ref name='virNodeGetInfo'/>
           <ref name='virSetErrorFunc'/>
+          <ref name='virStreamEventCallback'/>
         </word>
         <word name='user-defined'>
           <ref name='virEventAddTimeoutFunc'/>
           <ref name='virDomainBlockPeek'/>
           <ref name='virSecretGetUsageType'/>
         </word>
-        <word name='using'>
-          <ref name='virConnectRef'/>
-          <ref name='virDomainRef'/>
-          <ref name='virInterfaceRef'/>
-          <ref name='virNetworkRef'/>
-          <ref name='virNodeDeviceCreateXML'/>
-          <ref name='virNodeDeviceDettach'/>
-          <ref name='virNodeDeviceRef'/>
-          <ref name='virSecretGetUsageID'/>
-          <ref name='virSecretLookupByUsage'/>
-          <ref name='virSecretRef'/>
-          <ref name='virStoragePoolRef'/>
-          <ref name='virStorageVolCreateXMLFrom'/>
-          <ref name='virStorageVolRef'/>
-        </word>
         <word name='usual'>
           <ref name='virDomainMigrate'/>
         </word>
           <ref name='_virConnectAuth'/>
           <ref name='_virConnectCredential'/>
         </word>
+        <word name='virConnectDownloadFile'>
+          <ref name='virStreamRecv'/>
+        </word>
         <word name='virConnectGetCapabilities'>
           <ref name='virDomainMigrate'/>
         </word>
           <ref name='virStoragePoolGetConnect'/>
           <ref name='virStorageVolGetConnect'/>
         </word>
+        <word name='virConnectUploadFile'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='virDomainCreateXML'>
           <ref name='virDomainCreateLinux'/>
           <ref name='virDomainGetXMLDesc'/>
         </word>
         <word name='virEventHandleType'>
           <ref name='virEventHandleCallback'/>
+          <ref name='virStreamEventCallback'/>
         </word>
         <word name='virEventTimeoutFreeFunc'>
           <ref name='virEventRemoveTimeoutFunc'/>
         <word name='virStorageVolType'>
           <ref name='_virStorageVolInfo'/>
         </word>
+        <word name='virStreamAbort'>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='virStreamFinish'>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='virStreamFree'>
+          <ref name='virStreamNew'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamRef'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='virStreamNew'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='virStreamPtr'>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='virStreamRecv'>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+        </word>
+        <word name='virStreamRecvAll'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSinkFunc'/>
+        </word>
+        <word name='virStreamSend'>
+          <ref name='virStreamSend'/>
+          <ref name='virStreamSendAll'/>
+        </word>
+        <word name='virStreamSendAll'>
+          <ref name='virStreamSendAll'/>
+          <ref name='virStreamSourceFunc'/>
+        </word>
+        <word name='virStreamSinkFunc'>
+          <ref name='virStreamSinkFunc'/>
+        </word>
+        <word name='virStreamSourceFunc'>
+          <ref name='virStreamSourceFunc'/>
+        </word>
         <word name='virSuspendDomain'>
           <ref name='virDomainResume'/>
         </word>
           <ref name='virDomainPinVcpu'/>
           <ref name='virDomainSetVcpus'/>
         </word>
+        <word name='void'>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
+        </word>
         <word name='vol'>
           <ref name='virStorageVolRef'/>
         </word>
         </word>
       </letter>
       <letter name='w'>
+        <word name='wait'>
+          <ref name='virStreamSend'/>
+        </word>
         <word name='want'>
           <ref name='virDomainMemoryPeek'/>
         </word>
           <ref name='virGetVersion'/>
           <ref name='virNodeDeviceFree'/>
           <ref name='virStoragePoolRefresh'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSendAll'/>
         </word>
         <word name='watch'>
           <ref name='virEventAddHandleFunc'/>
           <ref name='virNetworkGetAutostart'/>
           <ref name='virNetworkSetAutostart'/>
           <ref name='virStoragePoolCreateXML'/>
+          <ref name='virStreamFree'/>
+          <ref name='virStreamRecv'/>
         </word>
         <word name='where'>
           <ref name='virConnectFindStoragePoolSources'/>
         </word>
         <word name='while'>
           <ref name='virGetVersion'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='wishes'>
           <ref name='virConnectDomainEventRegister'/>
         </word>
         <word name='write'>
           <ref name='_virDomainBlockStats'/>
+          <ref name='virStreamRecv'/>
+          <ref name='virStreamRecvAll'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='writing'>
           <ref name='virDomainGetConnect'/>
           <ref name='virSecretGetConnect'/>
           <ref name='virStoragePoolGetConnect'/>
           <ref name='virStorageVolGetConnect'/>
+          <ref name='virStreamRecvAll'/>
         </word>
         <word name='written'>
           <ref name='_virDomainBlockStats'/>
           <ref name='virDomainBlockPeek'/>
+          <ref name='virStreamFinish'/>
+          <ref name='virStreamSend'/>
         </word>
         <word name='www'>
           <ref name='virConnectGetType'/>
           <ref name='VIR_CPU_USABLE'/>
           <ref name='virConnectGetType'/>
           <ref name='virDomainPinVcpu'/>
+          <ref name='virStreamFree'/>
         </word>
       </letter>
     </chunk>
     <chunks>
-      <chunk name='chunk0' start='A' end='H'/>
-      <chunk name='chunk1' start='I' end='U'/>
-      <chunk name='chunk2' start='V' end='a'/>
+      <chunk name='chunk0' start='A' end='G'/>
+      <chunk name='chunk1' start='H' end='T'/>
+      <chunk name='chunk2' start='U' end='a'/>
       <chunk name='chunk3' start='b' end='c'/>
       <chunk name='chunk4' start='d' end='e'/>
       <chunk name='chunk5' start='f' end='h'/>
index 6028d5fa9e5427ee86df44533d069c6756aa7f5a..4e63e48980eb003874bf7e4efed3c0530b8ede3c 100644 (file)
@@ -110,6 +110,24 @@ typedef enum {
      VIR_DOMAIN_NONE = 0
 } virDomainCreateFlags;
 
+
+
+/**
+ * virStream:
+ *
+ * a virStream is a private structure representing a data stream.
+ */
+typedef struct _virStream virStream;
+
+/**
+ * virStreamPtr:
+ *
+ * a virStreamPtr is pointer to a virStream private structure, this is the
+ * type used to reference a data stream in the API.
+ */
+typedef virStream *virStreamPtr;
+
+
 /**
  * VIR_SECURITY_LABEL_BUFLEN:
  *
@@ -1502,6 +1520,127 @@ int                     virSecretUndefine       (virSecretPtr secret);
 int                     virSecretRef            (virSecretPtr secret);
 int                     virSecretFree           (virSecretPtr secret);
 
+typedef enum {
+    VIR_STREAM_NONBLOCK = (1 << 0),
+} virStreamFlags;
+
+virStreamPtr virStreamNew(virConnectPtr conn,
+                          unsigned int flags);
+int virStreamRef(virStreamPtr st);
+
+int virStreamSend(virStreamPtr st,
+                  const char *data,
+                  size_t nbytes);
+
+int virStreamRecv(virStreamPtr st,
+                  char *data,
+                  size_t nbytes);
+
+
+/**
+ * virStreamSourceFunc:
+ *
+ * @st: the stream object
+ * @data: preallocated array to be filled with data
+ * @nbytes: size of the data array
+ * @opaque: optional application provided data
+ *
+ * The virStreamSourceFunc callback is used together
+ * with the virStreamSendAll function for libvirt to
+ * obtain the data that is to be sent.
+ *
+ * The callback will be invoked multiple times,
+ * fetching data in small chunks. The application
+ * should fill the 'data' array with upto 'nbytes'
+ * of data and then return the number actual number
+ * of bytes. The callback will continue to be
+ * invoked until it indicates the end of the source
+ * has been reached by returning 0. A return value
+ * of -1 at any time will abort the send operation
+ *
+ * Returns the number of bytes filled, 0 upon end
+ * of file, or -1 upon error
+ */
+typedef int (*virStreamSourceFunc)(virStreamPtr st,
+                                   char *data,
+                                   size_t nbytes,
+                                   void *opaque);
+
+int virStreamSendAll(virStreamPtr st,
+                     virStreamSourceFunc handler,
+                     void *opaque);
+
+/**
+ * virStreamSinkFunc:
+ *
+ * @st: the stream object
+ * @data: preallocated array to be filled with data
+ * @nbytes: size of the data array
+ * @opaque: optional application provided data
+ *
+ * The virStreamSinkFunc callback is used together
+ * with the virStreamRecvAll function for libvirt to
+ * provide the data that has been received.
+ *
+ * The callback will be invoked multiple times,
+ * providing data in small chunks. The application
+ * should consume up 'nbytes' from the 'data' array
+ * of data and then return the number actual number
+ * of bytes consumed. The callback will continue to be
+ * invoked until it indicates the end of the stream
+ * has been reached. A return value of -1 at any time
+ * will abort the receive operation
+ *
+ * Returns the number of bytes consumed or -1 upon
+ * error
+ */
+typedef int (*virStreamSinkFunc)(virStreamPtr st,
+                                 const char *data,
+                                 size_t nbytes,
+                                 void *opaque);
+
+int virStreamRecvAll(virStreamPtr st,
+                     virStreamSinkFunc handler,
+                     void *opaque);
+
+typedef enum {
+    VIR_STREAM_EVENT_READABLE  = (1 << 0),
+    VIR_STREAM_EVENT_WRITABLE  = (1 << 1),
+    VIR_STREAM_EVENT_ERROR     = (1 << 2),
+    VIR_STREAM_EVENT_HANGUP    = (1 << 3),
+} virStreamEventType;
+
+
+/**
+ * virStreamEventCallback:
+ *
+ * @stream: stream on which the event occurred
+ * @events: bitset of events from virEventHandleType constants
+ * @opaque: user data registered with handle
+ *
+ * Callback for receiving stream events. The callback will
+ * be invoked once for each event which is pending.
+ */
+typedef void (*virStreamEventCallback)(virStreamPtr stream, int events, void *opaque);
+
+int virStreamEventAddCallback(virStreamPtr stream,
+                              int events,
+                              virStreamEventCallback cb,
+                              void *opaque,
+                              virFreeCallback ff);
+
+int virStreamEventUpdateCallback(virStreamPtr stream,
+                                 int events);
+
+int virStreamEventRemoveCallback(virStreamPtr stream);
+
+
+int virStreamFinish(virStreamPtr st);
+int virStreamAbort(virStreamPtr st);
+
+int virStreamFree(virStreamPtr st);
+
+
 #ifdef __cplusplus
 }
 #endif
index 95ae84d2e466f8cf0d97d730cdf7a34c97176203..cda655981ed012d1cf7ca3ba5268978e83076a16 100644 (file)
@@ -13,7 +13,9 @@ DOCS_DIR = $(datadir)/doc/libvirt-python-$(LIBVIRT_VERSION)
 
 DOCS = ${srcdir}/TODO
 
-CLASSES_EXTRA = libvirt-override-virConnect.py
+CLASSES_EXTRA = \
+       libvirt-override-virConnect.py \
+       libvirt-override-virStream.py
 
 EXTRA_DIST =                   \
        generator.py            \
index 178a415183c1a59f05e37a2082c8d233ec5e773b..48ad14b855632e0cb7d78b308ea759379e5ef561 100755 (executable)
@@ -282,6 +282,11 @@ py_types = {
     'const virSecretPtr':  ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
     'virSecret *':  ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
     'const virSecret *':  ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
+
+    'virStreamPtr':  ('O', "virStream", "virStreamPtr", "virStreamPtr"),
+    'const virStreamPtr':  ('O', "virStream", "virStreamPtr", "virStreamPtr"),
+    'virStream *':  ('O', "virStream", "virStreamPtr", "virStreamPtr"),
+    'const virStream *':  ('O', "virStream", "virStreamPtr", "virStreamPtr"),
 }
 
 py_return_types = {
@@ -338,6 +343,8 @@ skip_impl = (
     'virSecretGetUUID',
     'virSecretGetUUIDString',
     'virSecretLookupByUUID',
+    'virStreamRecv',
+    'virStreamSend',
     'virStoragePoolGetUUID',
     'virStoragePoolGetUUIDString',
     'virStoragePoolLookupByUUID',
@@ -373,6 +380,11 @@ skip_function = (
     'virConnectDomainEventDeregister', # overridden in virConnect.py
     'virSaveLastError', # We have our own python error wrapper
     'virFreeError', # Only needed if we use virSaveLastError
+    'virStreamEventAddCallback',
+    'virStreamRecvAll',
+    'virStreamSendAll',
+    'virStreamRef',
+    'virStreamFree',
 )
 
 
@@ -643,6 +655,8 @@ classes_type = {
     "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
     "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
     "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
+    "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"),
+    "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
     "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
     "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
 }
@@ -652,7 +666,8 @@ converter_type = {
 
 primary_classes = ["virDomain", "virNetwork", "virInterface",
                    "virStoragePool", "virStorageVol",
-                   "virConnect", "virNodeDevice", "virSecret" ]
+                   "virConnect", "virNodeDevice", "virSecret",
+                   "virStream"]
 
 classes_ancestor = {
 }
@@ -663,7 +678,9 @@ classes_destructors = {
     "virStoragePool": "virStoragePoolFree",
     "virStorageVol": "virStorageVolFree",
     "virNodeDevice" : "virNodeDeviceFree",
-    "virSecret": "virSecretFree"
+    "virSecret": "virSecretFree",
+    # We hand-craft __del__ for this one
+    #"virStream": "virStreamFree",
 }
 
 functions_noexcept = {
@@ -782,6 +799,11 @@ def nameFixup(name, classe, type, file):
     elif name[0:9] == 'virSecret':
         func = name[9:]
         func = string.lower(func[0:1]) + func[1:]
+    elif name[0:12] == 'virStreamNew':
+        func = "newStream"
+    elif name[0:9] == 'virStream':
+        func = name[9:]
+        func = string.lower(func[0:1]) + func[1:]
     elif name[0:17] == "virStoragePoolGet":
         func = name[17:]
         func = string.lower(func[0:1]) + func[1:]
@@ -1059,7 +1081,8 @@ def buildWrappers():
                              classes_ancestor[classname]))
            else:
                classes.write("class %s:\n" % (classname))
-                if classname in [ "virDomain", "virNetwork", "virInterface", "virStoragePool", "virStorageVol", "virNodeDevice", "virSecret" ]:
+                if classname in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
+                                  "virStorageVol", "virNodeDevice", "virSecret","virStream" ]:
                     classes.write("    def __init__(self, conn, _obj=None):\n")
                 else:
                     classes.write("    def __init__(self, _obj=None):\n")
@@ -1067,7 +1090,8 @@ def buildWrappers():
                    list = reference_keepers[classname]
                    for ref in list:
                        classes.write("        self.%s = None\n" % ref[1])
-                if classname in [ "virDomain", "virNetwork", "virInterface", "virNodeDevice", "virSecret" ]:
+                if classname in [ "virDomain", "virNetwork", "virInterface",
+                                  "virNodeDevice", "virSecret", "virStream" ]:
                     classes.write("        self._conn = conn\n")
                 elif classname in [ "virStorageVol", "virStoragePool" ]:
                     classes.write("        self._conn = conn\n" + \
diff --git a/python/libvirt-override-virStream.py b/python/libvirt-override-virStream.py
new file mode 100644 (file)
index 0000000..f50a7ef
--- /dev/null
@@ -0,0 +1,20 @@
+    def __del__(self):
+        try:
+            if self.cb:
+                libvirtmod.virStreamEventRemoveCallback(self._o)
+        except AttributeError:
+           pass
+
+        if self._o != None:
+            libvirtmod.virStreamFree(self._o)
+        self._o = None
+
+    def eventAddCallback(self, cb, opaque):
+        """ """
+        try:
+            self.cb = cb
+            self.opaque = opaque
+            ret = libvirtmod.virStreamEventAddCallback(self._o, self)
+            if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed', conn=self._conn)
+        except AttributeError:
+            pass
index 0d8ac9758385aaf53555363bca34a8ffa3e52ca7..9ba99de0dbd78cb69ddbaa25f98be999ff704330 100644 (file)
@@ -206,6 +206,19 @@ libvirt_virSecretPtrWrap(virSecretPtr node)
     return (ret);
 }
 
+PyObject *
+libvirt_virStreamPtrWrap(virStreamPtr node)
+{
+    PyObject *ret;
+
+    if (node == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    ret = PyCObject_FromVoidPtrAndDesc(node, (char *) "virStreamPtr", NULL);
+    return (ret);
+}
+
 PyObject *
 libvirt_virEventHandleCallbackWrap(virEventHandleCallback node)
 {
index 99d5805f2b9aaad734f4cf6dc4bcbd1e3ad4dafe..61f72490be127245b3b385576b9d61f30bb0a719 100644 (file)
@@ -92,6 +92,15 @@ typedef struct {
 } PyvirSecret_Object;
 
 
+#define PyvirStream_Get(v) (((v) == Py_None) ? NULL : \
+        (((PyvirStream_Object *)(v))->obj))
+
+typedef struct {
+    PyObject_HEAD
+    virStreamPtr obj;
+} PyvirStream_Object;
+
+
 #define PyvirEventHandleCallback_Get(v) (((v) == Py_None) ? NULL : \
         (((PyvirEventHandleCallback_Object *)(v))->obj))
 
@@ -144,6 +153,7 @@ PyObject * libvirt_virFreeCallbackWrap(virFreeCallback node);
 PyObject * libvirt_virVoidPtrWrap(void* node);
 PyObject * libvirt_virNodeDevicePtrWrap(virNodeDevicePtr node);
 PyObject * libvirt_virSecretPtrWrap(virSecretPtr node);
+PyObject * libvirt_virStreamPtrWrap(virStreamPtr node);
 
 
 /* Provide simple macro statement wrappers (adapted from GLib, in turn from Perl):
index 530076c0ba804d2bd9d74a5372bd29ea1f62c595..6741b9e4dd33978c251c2ff20f136a5bdc08c3b4 100644 (file)
@@ -1162,6 +1162,7 @@ virUnrefNodeDevice(virNodeDevicePtr dev) {
     return (refs);
 }
 
+
 /**
  * virGetSecret:
  * @conn: the hypervisor connection
@@ -1297,3 +1298,61 @@ virUnrefSecret(virSecretPtr secret) {
     virMutexUnlock(&secret->conn->lock);
     return refs;
 }
+
+virStreamPtr virGetStream(virConnectPtr conn) {
+    virStreamPtr ret = NULL;
+
+    virMutexLock(&conn->lock);
+
+    if (VIR_ALLOC(ret) < 0) {
+        virReportOOMError(conn);
+        goto error;
+    }
+    ret->magic = VIR_STREAM_MAGIC;
+    ret->conn = conn;
+    conn->refs++;
+    ret->refs++;
+    virMutexUnlock(&conn->lock);
+    return(ret);
+
+error:
+    virMutexUnlock(&conn->lock);
+    VIR_FREE(ret);
+    return(NULL);
+}
+
+static void
+virReleaseStream(virStreamPtr st) {
+    virConnectPtr conn = st->conn;
+    DEBUG("release dev %p", st);
+
+    st->magic = -1;
+    VIR_FREE(st);
+
+    DEBUG("unref connection %p %d", conn, conn->refs);
+    conn->refs--;
+    if (conn->refs == 0) {
+        virReleaseConnect(conn);
+        /* Already unlocked mutex */
+        return;
+    }
+
+    virMutexUnlock(&conn->lock);
+}
+
+int virUnrefStream(virStreamPtr st) {
+    int refs;
+
+    virMutexLock(&st->conn->lock);
+    DEBUG("unref stream %p %d", st, st->refs);
+    st->refs--;
+    refs = st->refs;
+    if (refs == 0) {
+        virReleaseStream(st);
+        /* Already unlocked mutex */
+        return (0);
+    }
+
+    virMutexUnlock(&st->conn->lock);
+    return (refs);
+}
index a33c365a6a502acb24cfae4d1185177c6d458688..afb51dcbd69731c562003031d978dca44d5da2f6 100644 (file)
 #define VIR_IS_CONNECTED_SECRET(obj)   (VIR_IS_SECRET(obj) && VIR_IS_CONNECT((obj)->conn))
 
 
+/**
+ * VIR_STREAM_MAGIC:
+ *
+ * magic value used to protect the API when pointers to stream structures
+ * are passed down by the users.
+ */
+#define VIR_STREAM_MAGIC                   0x1DEAD666
+#define VIR_IS_STREAM(obj)                 ((obj) && (obj)->magic==VIR_STREAM_MAGIC)
+#define VIR_IS_CONNECTED_STREAM(obj)       (VIR_IS_STREAM(obj) && VIR_IS_CONNECT((obj)->conn))
+
+
 /**
  * _virConnect:
  *
@@ -261,6 +272,25 @@ struct _virSecret {
 };
 
 
+typedef int (*virStreamAbortFunc)(virStreamPtr, void *opaque);
+typedef int (*virStreamFinishFunc)(virStreamPtr, void *opaque);
+
+/**
+ * _virStream:
+ *
+ * Internal structure associated with an input stream
+ */
+struct _virStream {
+    unsigned int magic;
+    virConnectPtr conn;
+    int refs;
+    int flags;
+
+    virStreamDriverPtr driver;
+    void *privateData;
+};
+
+
 /************************************************************************
  *                                                                     *
  *     API for domain/connections (de)allocations and lookups          *
@@ -303,4 +333,7 @@ virSecretPtr virGetSecret(virConnectPtr conn,
                           const char *usageID);
 int virUnrefSecret(virSecretPtr secret);
 
+virStreamPtr virGetStream(virConnectPtr conn);
+int virUnrefStream(virStreamPtr st);
+
 #endif
index d4f972f3e9e76d48856e1ca830dab1ce52faa860..6a3dcc2891bf246e6dce27b0ec22b8033c1fa5ca 100644 (file)
@@ -879,6 +879,41 @@ struct _virSecretDriver {
     virDrvSecretUndefine undefine;
 };
 
+
+typedef struct _virStreamDriver virStreamDriver;
+typedef virStreamDriver *virStreamDriverPtr;
+
+typedef int (*virDrvStreamSend)(virStreamPtr st,
+                                const char *data,
+                                size_t nbytes);
+typedef int (*virDrvStreamRecv)(virStreamPtr st,
+                                char *data,
+                                size_t nbytes);
+
+typedef int (*virDrvStreamEventAddCallback)(virStreamPtr stream,
+                                            int events,
+                                            virStreamEventCallback cb,
+                                            void *opaque,
+                                            virFreeCallback ff);
+
+typedef int (*virDrvStreamEventUpdateCallback)(virStreamPtr stream,
+                                               int events);
+typedef int (*virDrvStreamEventRemoveCallback)(virStreamPtr stream);
+typedef int (*virDrvStreamFinish)(virStreamPtr st);
+typedef int (*virDrvStreamAbort)(virStreamPtr st);
+
+
+struct _virStreamDriver {
+    virDrvStreamSend streamSend;
+    virDrvStreamRecv streamRecv;
+    virDrvStreamEventAddCallback streamAddCallback;
+    virDrvStreamEventUpdateCallback streamUpdateCallback;
+    virDrvStreamEventRemoveCallback streamRemoveCallback;
+    virDrvStreamFinish streamFinish;
+    virDrvStreamAbort streamAbort;
+};
+
+
 /*
  * Registration
  * TODO: also need ways to (des)activate a given driver
index f164f60650c811be9bce67fe28d6bc2e877ac266..48e7b5bcb23b4cd0df05b6663e57d8aa77b4a1cb 100644 (file)
@@ -561,6 +561,10 @@ virLibNodeDeviceError(virNodeDevicePtr dev, virErrorNumber error,
                     errmsg, info, NULL, 0, 0, errmsg, info);
 }
 
+#define virLibStreamError(conn, code, fmt...)                   \
+    virReportErrorHelper(conn, VIR_FROM_NONE, code, __FILE__,   \
+                         __FUNCTION__, __LINE__, fmt)
+
 /**
  * virLibSecretError:
  * @secret: the secret if available
@@ -9394,3 +9398,700 @@ virSecretFree(virSecretPtr secret)
         return -1;
     return 0;
 }
+
+
+/**
+ * virStreamNew:
+ * @conn: pointer to the connection
+ * @flags: control features of the stream
+ *
+ * Creates a new stream object which can be used to perform
+ * streamed I/O with other public API function.
+ *
+ * When no longer needed, a stream object must be released
+ * with virStreamFree. If a data stream has been used,
+ * then the application must call virStreamFinish or
+ * virStreamAbort before free'ing to, in order to notify
+ * the driver of termination.
+ *
+ * If a non-blocking data stream is required passed
+ * VIR_STREAM_NONBLOCK for flags, otherwise pass 0.
+ *
+ * Returns the new stream, or NULL upon error
+ */
+virStreamPtr
+virStreamNew(virConnectPtr conn,
+             unsigned int flags)
+{
+    virStreamPtr st;
+
+    DEBUG("conn=%p, flags=%u", conn, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (NULL);
+    }
+
+    st = virGetStream(conn);
+    if (st)
+        st->flags = flags;
+
+    return st;
+}
+
+
+/**
+ * virStreamRef:
+ * @stream: pointer to the stream
+ *
+ * Increment the reference count on the stream. For each
+ * additional call to this method, there shall be a corresponding
+ * call to virStreamFree to release the reference count, once
+ * the caller no longer needs the reference to this object.
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+int
+virStreamRef(virStreamPtr stream)
+{
+    if ((!VIR_IS_CONNECTED_STREAM(stream))) {
+        virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+    virMutexLock(&stream->conn->lock);
+    DEBUG("stream=%p refs=%d", stream, stream->refs);
+    stream->refs++;
+    virMutexUnlock(&stream->conn->lock);
+    return 0;
+}
+
+
+/**
+ * virStreamSend:
+ * @stream: pointer to the stream object
+ * @data: buffer to write to stream
+ * @nbytes: size of @data buffer
+ *
+ * Write a series of bytes to the stream. This method may
+ * block the calling application for an arbitrary amount
+ * of time. Once an application has finished sending data
+ * it should call virStreamFinish to wait for succesful
+ * confirmation from the driver, or detect any error
+ *
+ * This method may not be used if a stream source has been
+ * registered
+ *
+ * Errors are not guaranteed to be reported synchronously
+ * with the call, but may instead be delayed until a
+ * subsequent call.
+ *
+ * A example using this with a hypothetical file upload
+ * API looks like
+ *
+ *   virStreamPtr st = virStreamNew(conn, 0);
+ *   int fd = open("demo.iso", O_RDONLY)
+ *
+ *   virConnectUploadFile(conn, "demo.iso", st);
+ *
+ *   while (1) {
+ *       char buf[1024];
+ *       int got = read(fd, buf, 1024);
+ *       if (got < 0) {
+ *          virStreamAbort(st);
+ *          break;
+ *       }
+ *       if (got == 0) {
+ *          virStreamFinish(st);
+ *          break;
+ *       }
+ *       int offset = 0;
+ *       while (offset < got) {
+ *          int sent = virStreamSend(st, buf+offset, got-offset)
+ *          if (sent < 0) {
+ *             virStreamAbort(st);
+ *             goto done;
+ *          }
+ *          offset += sent;
+ *       }
+ *   }
+ *   if (virStreamFinish(st) < 0)
+ *      ... report an error ....
+ * done:
+ *   virStreamFree(st);
+ *   close(fd);
+ *
+ * Returns the number of bytes written, which may be less
+ * than requested.
+ *
+ * Returns -1 upon error, at which time the stream will
+ * be marked as aborted, and the caller should now release
+ * the stream with virStreamFree.
+ *
+ * Returns -2 if the outgoing transmit buffers are full &
+ * the stream is marked as non-blocking.
+ */
+int virStreamSend(virStreamPtr stream,
+                  const char *data,
+                  size_t nbytes)
+{
+    DEBUG("stream=%p, data=%p, nbytes=%zi", stream, data, nbytes);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (stream->driver &&
+        stream->driver->streamSend) {
+        int ret;
+        ret = (stream->driver->streamSend)(stream, data, nbytes);
+        if (ret == -2)
+            return -2;
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(stream->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(stream->conn);
+    return -1;
+}
+
+
+/**
+ * virStreamRecv:
+ * @stream: pointer to the stream object
+ * @data: buffer to write to stream
+ * @nbytes: size of @data buffer
+ *
+ * Write a series of bytes to the stream. This method may
+ * block the calling application for an arbitrary amount
+ * of time.
+ *
+ * Errors are not guaranteed to be reported synchronously
+ * with the call, but may instead be delayed until a
+ * subsequent call.
+ *
+ * A example using this with a hypothetical file download
+ * API looks like
+ *
+ *   virStreamPtr st = virStreamNew(conn, 0);
+ *   int fd = open("demo.iso", O_WRONLY, 0600)
+ *
+ *   virConnectDownloadFile(conn, "demo.iso", st);
+ *
+ *   while (1) {
+ *       char buf[1024];
+ *       int got = virStreamRecv(st, buf, 1024);
+ *       if (got < 0)
+ *          break;
+ *       if (got == 0) {
+ *          virStreamFinish(st);
+ *          break;
+ *       }
+ *       int offset = 0;
+ *       while (offset < got) {
+ *          int sent = write(fd, buf+offset, got-offset)
+ *          if (sent < 0) {
+ *             virStreamAbort(st);
+ *             goto done;
+ *          }
+ *          offset += sent;
+ *       }
+ *   }
+ *   if (virStreamFinish(st) < 0)
+ *      ... report an error ....
+ * done:
+ *   virStreamFree(st);
+ *   close(fd);
+ *
+ *
+ * Returns the number of bytes read, which may be less
+ * than requested.
+ *
+ * Returns 0 when the end of the stream is reached, at
+ * which time the caller should invoke virStreamFinish()
+ * to get confirmation of stream completion.
+ *
+ * Returns -1 upon error, at which time the stream will
+ * be marked as aborted, and the caller should now release
+ * the stream with virStreamFree.
+ *
+ * Returns -2 if there is no data pending to be read & the
+ * stream is marked as non-blocking.
+ */
+int virStreamRecv(virStreamPtr stream,
+                  char *data,
+                  size_t nbytes)
+{
+    DEBUG("stream=%p, data=%p, nbytes=%zi", stream, data, nbytes);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (stream->driver &&
+        stream->driver->streamRecv) {
+        int ret;
+        ret = (stream->driver->streamRecv)(stream, data, nbytes);
+        if (ret == -2)
+            return -2;
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(stream->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(stream->conn);
+    return -1;
+}
+
+
+/**
+ * virStreamSendAll:
+ * @stream: pointer to the stream object
+ * @handler: source callback for reading data from application
+ * @opaque: application defined data
+ *
+ * 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.
+ *
+ * A example using this with a hypothetical file upload
+ * API looks like
+ *
+ *   int mysource(virStreamPtr st, char *buf, int nbytes, void *opaque) {
+ *       int *fd = opaque;
+ *
+ *       return read(*fd, buf, nbytes);
+ *   }
+ *
+ *   virStreamPtr st = virStreamNew(conn, 0);
+ *   int fd = open("demo.iso", O_RDONLY)
+ *
+ *   virConnectUploadFile(conn, st);
+ *   if (virStreamSendAll(st, mysource, &fd) < 0) {
+ *      ...report an error ...
+ *      goto done;
+ *   }
+ *   if (virStreamFinish(st) < 0)
+ *      ...report an error...
+ *   virStreamFree(st);
+ *   close(fd);
+ *
+ * Returns 0 if all the data was succesfully sent. The caller
+ * should invoke virStreamFinish(st) to flush the stream upon
+ * success and then virStreamFree
+ *
+ * Returns -1 upon any error, with virStreamAbort() already
+ * having been called,  so the caller need only call
+ * virStreamFree()
+ */
+int virStreamSendAll(virStreamPtr stream,
+                     virStreamSourceFunc handler,
+                     void *opaque)
+{
+    char *bytes = NULL;
+    int want = 1024*64;
+    int ret = -1;
+    DEBUG("stream=%p, handler=%p, opaque=%p", stream, handler, opaque);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (stream->flags & VIR_STREAM_NONBLOCK) {
+        virLibConnError(NULL, VIR_ERR_OPERATION_INVALID,
+                        _("data sources cannot be used for non-blocking streams"));
+        goto cleanup;
+    }
+
+    if (VIR_ALLOC_N(bytes, want) < 0) {
+        virReportOOMError(stream->conn);
+        goto cleanup;
+    }
+
+    for (;;) {
+        int got, offset = 0;
+        got = (handler)(stream, bytes, want, opaque);
+        if (got < 0) {
+            virStreamAbort(stream);
+            goto cleanup;
+        }
+        if (got == 0)
+            break;
+        while (offset < got) {
+            int done;
+            done = virStreamSend(stream, bytes + offset, got - offset);
+            if (done < 0)
+                goto cleanup;
+            offset += done;
+        }
+    }
+    ret = 0;
+
+cleanup:
+    VIR_FREE(bytes);
+
+    /* Copy to connection error object for back compatability */
+    if (ret != 0)
+        virSetConnError(stream->conn);
+
+    return ret;
+}
+
+
+/**
+ * virStreamRecvAll:
+ * @stream: pointer to the stream object
+ * @handler: sink callback for writing data to application
+ * @opaque: application defined data
+ *
+ * Receive the entire data stream, sending the data to the
+ * requested data sink. This is simply a convenient alternative
+ * to virStreamRecv, for apps that do blocking-I/o.
+ *
+ * A example using this with a hypothetical file download
+ * API looks like
+ *
+ *   int mysink(virStreamPtr st, const char *buf, int nbytes, void *opaque) {
+ *       int *fd = opaque;
+ *
+ *       return write(*fd, buf, nbytes);
+ *   }
+ *
+ *   virStreamPtr st = virStreamNew(conn, 0);
+ *   int fd = open("demo.iso", O_WRONLY)
+ *
+ *   virConnectUploadFile(conn, st);
+ *   if (virStreamRecvAll(st, mysink, &fd) < 0) {
+ *      ...report an error ...
+ *      goto done;
+ *   }
+ *   if (virStreamFinish(st) < 0)
+ *      ...report an error...
+ *   virStreamFree(st);
+ *   close(fd);
+ *
+ * Returns 0 if all the data was succesfully received. The caller
+ * should invoke virStreamFinish(st) to flush the stream upon
+ * success and then virStreamFree
+ *
+ * Returns -1 upon any error, with virStreamAbort() already
+ * having been called,  so the caller need only call
+ * virStreamFree()
+ */
+int virStreamRecvAll(virStreamPtr stream,
+                     virStreamSinkFunc handler,
+                     void *opaque)
+{
+    char *bytes = NULL;
+    int want = 1024*64;
+    int ret = -1;
+    DEBUG("stream=%p, handler=%p, opaque=%p", stream, handler, opaque);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (stream->flags & VIR_STREAM_NONBLOCK) {
+        virLibConnError(NULL, VIR_ERR_OPERATION_INVALID,
+                        _("data sinks cannot be used for non-blocking streams"));
+        goto cleanup;
+    }
+
+
+    if (VIR_ALLOC_N(bytes, want) < 0) {
+        virReportOOMError(stream->conn);
+        goto cleanup;
+    }
+
+    for (;;) {
+        int got, offset = 0;
+        got = virStreamRecv(stream, bytes, want);
+        if (got < 0)
+            goto cleanup;
+        if (got == 0)
+            break;
+        while (offset < got) {
+            int done;
+            done = (handler)(stream, bytes + offset, got - offset, opaque);
+            if (done < 0) {
+                virStreamAbort(stream);
+                goto cleanup;
+            }
+            offset += done;
+        }
+    }
+    ret = 0;
+
+cleanup:
+    VIR_FREE(bytes);
+
+    /* Copy to connection error object for back compatability */
+    if (ret != 0)
+        virSetConnError(stream->conn);
+
+    return ret;
+}
+
+
+/**
+ * virStreamEventAddCallback
+ * @stream: pointer to the stream object
+ * @events: set of events to monitor
+ * @cb: callback to invoke when an event occurs
+ * @opaque: application defined data
+ * @ff: callback to free @opaque data
+ *
+ * Register a callback to be notified when a stream
+ * becomes writable, or readable. This is most commonly
+ * used in conjunction with non-blocking data streams
+ * to integrate into an event loop
+ *
+ * Returns 0 on success, -1 upon error
+ */
+int virStreamEventAddCallback(virStreamPtr stream,
+                              int events,
+                              virStreamEventCallback cb,
+                              void *opaque,
+                              virFreeCallback ff)
+{
+    DEBUG("stream=%p, events=%d, cb=%p, opaque=%p, ff=%p", stream, events, cb, opaque, ff);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (stream->driver &&
+        stream->driver->streamAddCallback) {
+        int ret;
+        ret = (stream->driver->streamAddCallback)(stream, events, cb, opaque, ff);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(stream->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(stream->conn);
+    return -1;
+}
+
+
+/**
+ * virStreamEventUpdateCallback
+ * @stream: pointer to the stream object
+ * @events: set of events to monitor
+ *
+ * Changes the set of events to monitor for a stream. This allows
+ * for event notification to be changed without having to
+ * unregister & register the callback completely. This method
+ * is guarenteed to succeed if a callback is already registered
+ *
+ * Returns 0 on success, -1 if no callback is registered
+ */
+int virStreamEventUpdateCallback(virStreamPtr stream,
+                                 int events)
+{
+    DEBUG("stream=%p, events=%d", stream, events);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (stream->driver &&
+        stream->driver->streamUpdateCallback) {
+        int ret;
+        ret = (stream->driver->streamUpdateCallback)(stream, events);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (stream->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(stream->conn);
+    return -1;
+}
+
+/**
+ * virStreamEventRemoveCallback
+ * @stream: pointer to the stream object
+ *
+ * Remove a event callback from the stream
+ *
+ * Returns 0 on success, -1 on error
+ */
+int virStreamEventRemoveCallback(virStreamPtr stream)
+{
+    DEBUG("stream=%p", stream);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (stream->driver &&
+        stream->driver->streamRemoveCallback) {
+        int ret;
+        ret = (stream->driver->streamRemoveCallback)(stream);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (stream->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(stream->conn);
+    return -1;
+}
+
+/**
+ * virStreamFinish:
+ * @stream: pointer to the stream object
+ *
+ * Indicate that there is no further data is to be transmitted
+ * on the stream. For output streams this should be called once
+ * all data has been written. For input streams this should be
+ * called once virStreamRecv returns end-of-file.
+ *
+ * This method is a synchronization point for all asynchronous
+ * errors, so if this returns a success code the application can
+ * be sure that all data has been successfully processed.
+ *
+ * Returns 0 on success, -1 upon error
+ */
+int virStreamFinish(virStreamPtr stream)
+{
+    DEBUG("stream=%p", stream);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (stream->driver &&
+        stream->driver->streamFinish) {
+        int ret;
+        ret = (stream->driver->streamFinish)(stream);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (stream->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(stream->conn);
+    return -1;
+}
+
+/**
+ * virStreamAbort:
+ * @stream: pointer to the stream object
+ *
+ * Request that the in progress data transfer be cancelled
+ * abnormally before the end of the stream has been reached.
+ * For output streams this can be used to inform the driver
+ * that the stream is being terminated early. For input
+ * streams this can be used to inform the driver that it
+ * should stop sending data.
+ *
+ * Returns 0 on success, -1 upon error
+ */
+int virStreamAbort(virStreamPtr stream)
+{
+    DEBUG("stream=%p", stream);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (stream->driver &&
+        stream->driver->streamAbort) {
+        int ret;
+        ret = (stream->driver->streamAbort)(stream);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (stream->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(stream->conn);
+    return -1;
+}
+
+/**
+ * virStreamFree:
+ * @stream: pointer to the stream object
+ *
+ * Decrement the reference count on a stream, releasing
+ * the stream object if the reference count has hit zero.
+ *
+ * There must not be a active data transfer in progress
+ * when releasing the stream. If a stream needs to be
+ * disposed of prior to end of stream being reached, then
+ * the virStreamAbort function should be called first.
+ *
+ * Returns 0 upon success, or -1 on error
+ */
+int virStreamFree(virStreamPtr stream)
+{
+    DEBUG("stream=%p", stream);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_STREAM(stream)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    /* XXX Enforce shutdown before free'ing resources ? */
+
+    if (virUnrefStream(stream) < 0)
+        return (-1);
+    return (0);
+}
index f8598c7649635fad1816124148bc31d580983c47..ad579d920a1bdccdd8c4079f9f7186dad06c68df 100644 (file)
@@ -78,6 +78,8 @@ virGetNodeDevice;
 virUnrefDomain;
 virUnrefConnect;
 virUnrefSecret;
+virGetStream;
+virUnrefStream;
 
 
 # domain_conf.h
index cff50d5d17b62868e4400fb49a2e28efb0871d85..7226e88a0d00dd5ed1cd48a179a12ccd2473a1c3 100644 (file)
@@ -312,4 +312,20 @@ LIBVIRT_0.7.1 {
         virSecretFree;
 } LIBVIRT_0.7.0;
 
+LIBVIRT_0.7.2 {
+    global:
+       virStreamNew;
+       virStreamRef;
+       virStreamSend;
+       virStreamRecv;
+       virStreamSendAll;
+       virStreamRecvAll;
+       virStreamEventAddCallback;
+       virStreamEventUpdateCallback;
+       virStreamEventRemoveCallback;
+       virStreamFinish;
+       virStreamAbort;
+       virStreamFree;
+} LIBVIRT_0.7.1;
+
 # .... define new API here using predicted next version number ....