26ba25
From e58ce3910208fead9e24eb08e19a11bb2eba2f1e Mon Sep 17 00:00:00 2001
26ba25
From: "Danilo C. L. de Paula" <ddepaula@redhat.com>
26ba25
Date: Wed, 7 Mar 2018 13:05:43 -0300
26ba25
Subject: block/vxhs: modularize VXHS via g_module
26ba25
26ba25
RH-Author: Jeffrey Cody <jcody@redhat.com>
26ba25
Message-id: <8a91a423440b7a5a14e868279c772e99b865bfc6.1494281291.git.jcody@redhat.com>
26ba25
Patchwork-id: 75046
26ba25
O-Subject: [RHEV-7.4 qemu-kvm-rhev 4/4] block/vxhs: modularize VXHS via g_module Bugzilla: 1265869
26ba25
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
26ba25
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
26ba25
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
26ba25
26ba25
This converts the VXHS driver to be a runtime loaded module, with no
26ba25
external build dependencies on libvxhs / libqnio.   This (libvxhs) is a
26ba25
3rd party library, written by Veritas, to interface with the VXHS
26ba25
server.
26ba25
26ba25
Red Hat is not going to distribute libvxhs, nor will Red Hat use libvxhs
26ba25
in the build systems.  So that creates two criteria for the
26ba25
modularization, for business reasons:
26ba25
26ba25
1. No runtime dependencies on libvxhs (aside from opening the library on
26ba25
vxhs open)
26ba25
26ba25
2. No build dependencies on libvxhs packages.
26ba25
26ba25
There is support in QEMU for modular block drivers, however there are
26ba25
two issues with using the built-in support:
26ba25
26ba25
    A. It is all-or-none; if modules are enabled all protocols are built
26ba25
       as modules.  This wouldn't be that bad, as it would of course
26ba25
       enable more granular dependencies for qemu rpm packages. But...
26ba25
26ba25
    B. It is not designed with criteria #2 in mind; it reduces runtime
26ba25
       dependencies, not build dependencies.  The protocol libraries
26ba25
       that are still built linked against external libraries and using
26ba25
       external headers.
26ba25
26ba25
This patch uses g_module to load the libvxhs library, and incorporates
26ba25
the libvxhs.h header in the build tree.  If block driver protocols are
26ba25
also built as modules, libvxhs will still work and be built as a module
26ba25
too, except the shared library will still not have any dependency on
26ba25
libvxhs.
26ba25
26ba25
There are a few changes in this patch from upstream (aside from the
26ba25
module loading aspects):
26ba25
26ba25
1. It enables VXHS support to be built as a protocl module if
26ba25
--enable-modules is used during configure.
26ba25
26ba25
2. If the init call to iio_init() fails, populate errp with a
26ba25
meaningful error message.
26ba25
26ba25
3. Since we are loading the library dynamically, make check the min and
26ba25
max supported versions in the libvxhs library on load.
26ba25
26ba25
Patches for items #1 and #2 have been posted upstream.
26ba25
26ba25
It is expected that the libvxhs library is located at the following
26ba25
pathname: /usr/lib64/qemu/libvxhs.so.1
26ba25
26ba25
VXHS support is only built for x86_64 in RHEV.
26ba25
26ba25
Signed-off-by: Jeff Cody <jcody@redhat.com>
26ba25
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26ba25
26ba25
block/vxhs: improve error message for missing / bad vxhs module
26ba25
26ba25
RH-Author: Jeffrey Cody <jcody@redhat.com>
26ba25
Message-id: <59af10d83125fff42beacd30dbca83d50409bbed.1513031708.git.jcody@redhat.com>
26ba25
Patchwork-id: 78305
26ba25
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] block/vxhs: improve error message for missing / bad vxhs module
26ba25
Bugzilla: 1505654
26ba25
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
26ba25
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
26ba25
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
26ba25
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
26ba25
26ba25
[Downstream only, as the module load of libvxhs is downstream only]
26ba25
26ba25
In the case of missing libvxhs libraries, the original error message,
26ba25
while technically accurate, may lead a user to think there is a QEMU bug
26ba25
if trying to using the VXHS protocol.  Update the message so that it is
26ba25
clear that the likely issue is that the Veritas QEMU libvxhs RPM is not
26ba25
installed (or not installed correctly, if there are permission or file
26ba25
corruption issues, etc.).
26ba25
26ba25
An example error message before this change:
26ba25
26ba25
> qemu-img info vxhs://localhost/test
26ba25
qemu-img: Could not open 'vxhs://localhost/test': \
26ba25
        error loading libvxhs: /usr/lib64/qemu/libvxhs.so.1: \
26ba25
        cannot open shared object file: No such file or directory
26ba25
26ba25
An example error message after this change:
26ba25
26ba25
> qemu-img info vxhs://localhost/test
26ba25
qemu-img: Could not open 'vxhs://localhost/test': \
26ba25
        The VXHS library from Veritas might not be installed correctly \
26ba25
        (/usr/lib64/qemu/libvxhs.so.1: \
26ba25
         cannot open shared object file: No such file or directory)
26ba25
26ba25
Signed-off-by: Jeff Cody <jcody@redhat.com>
26ba25
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26ba25
---
26ba25
 block/vxhs.c                  | 123 ++++++++++++++++++++++++++++++++----
26ba25
 configure                     |  33 +---------
26ba25
 include/block/vxhs_shim.h     | 143 ++++++++++++++++++++++++++++++++++++++++++
26ba25
 redhat/build_configure.sh     |   9 ++-
26ba25
 redhat/qemu-kvm.spec.template |   7 +++
26ba25
 5 files changed, 273 insertions(+), 42 deletions(-)
26ba25
 create mode 100644 include/block/vxhs_shim.h
26ba25
26ba25
diff --git a/block/vxhs.c b/block/vxhs.c
26ba25
index 75cc6c8..68edb51 100644
26ba25
--- a/block/vxhs.c
26ba25
+++ b/block/vxhs.c
26ba25
@@ -9,7 +9,8 @@
26ba25
  */
26ba25
 
26ba25
 #include "qemu/osdep.h"
26ba25
-#include <qnio qnio_api.h="">
26ba25
+#include "block/vxhs_shim.h"
26ba25
+#include <gmodule.h>
26ba25
 #include <sys param.h="">
26ba25
 #include "block/block_int.h"
26ba25
 #include "qapi/qmp/qerror.h"
26ba25
@@ -58,6 +59,97 @@ typedef struct BDRVVXHSState {
26ba25
     char *tlscredsid; /* tlscredsid */
26ba25
 } BDRVVXHSState;
26ba25
 
26ba25
+#define LIBVXHS_FULL_PATHNAME "/usr/lib64/qemu/libvxhs.so.1"
26ba25
+static bool libvxhs_loaded;
26ba25
+static GModule *libvxhs_handle;
26ba25
+
26ba25
+static LibVXHSFuncs libvxhs;
26ba25
+
26ba25
+typedef struct LibVXHSSymbols {
26ba25
+    const char *name;
26ba25
+    gpointer *addr;
26ba25
+} LibVXHSSymbols;
26ba25
+
26ba25
+static LibVXHSSymbols libvxhs_symbols[] = {
26ba25
+    {"iio_init",        (gpointer *) &libvxhs.iio_init},
26ba25
+    {"iio_fini",        (gpointer *) &libvxhs.iio_fini},
26ba25
+    {"iio_min_version", (gpointer *) &libvxhs.iio_min_version},
26ba25
+    {"iio_max_version", (gpointer *) &libvxhs.iio_max_version},
26ba25
+    {"iio_open",        (gpointer *) &libvxhs.iio_open},
26ba25
+    {"iio_close",       (gpointer *) &libvxhs.iio_close},
26ba25
+    {"iio_writev",      (gpointer *) &libvxhs.iio_writev},
26ba25
+    {"iio_readv",       (gpointer *) &libvxhs.iio_readv},
26ba25
+    {"iio_ioctl",       (gpointer *) &libvxhs.iio_ioctl},
26ba25
+    {NULL}
26ba25
+};
26ba25
+
26ba25
+static void bdrv_vxhs_set_funcs(GModule *handle, Error **errp)
26ba25
+{
26ba25
+    int i = 0;
26ba25
+    while (libvxhs_symbols[i].name) {
26ba25
+        const char *name = libvxhs_symbols[i].name;
26ba25
+        if (!g_module_symbol(handle, name, libvxhs_symbols[i].addr)) {
26ba25
+            error_setg(errp, "%s could not be loaded from libvxhs: %s",
26ba25
+                       name, g_module_error());
26ba25
+            return;
26ba25
+        }
26ba25
+        ++i;
26ba25
+    }
26ba25
+}
26ba25
+
26ba25
+static void bdrv_vxhs_load_libs(Error **errp)
26ba25
+{
26ba25
+    Error *local_err = NULL;
26ba25
+    int32_t ver;
26ba25
+
26ba25
+    if (libvxhs_loaded) {
26ba25
+        return;
26ba25
+    }
26ba25
+
26ba25
+    if (!g_module_supported()) {
26ba25
+        error_setg(errp, "modules are not supported on this platform: %s",
26ba25
+                     g_module_error());
26ba25
+        return;
26ba25
+    }
26ba25
+
26ba25
+    libvxhs_handle = g_module_open(LIBVXHS_FULL_PATHNAME,
26ba25
+                                   G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
26ba25
+    if (!libvxhs_handle) {
26ba25
+        error_setg(errp, "The VXHS library from Veritas might not be installed "
26ba25
+                   "correctly (%s)", g_module_error());
26ba25
+        return;
26ba25
+    }
26ba25
+
26ba25
+    g_module_make_resident(libvxhs_handle);
26ba25
+
26ba25
+    bdrv_vxhs_set_funcs(libvxhs_handle, &local_err);
26ba25
+    if (local_err) {
26ba25
+        error_propagate(errp, local_err);
26ba25
+        return;
26ba25
+    }
26ba25
+
26ba25
+    /* Now check to see if the libvxhs we are using here is supported
26ba25
+     * by the loaded version */
26ba25
+
26ba25
+    ver = (*libvxhs.iio_min_version)();
26ba25
+    if (ver > QNIO_VERSION) {
26ba25
+        error_setg(errp, "Trying to use libvxhs version %"PRId32" API, but "
26ba25
+                         "only %"PRId32" or newer is supported by %s",
26ba25
+                          QNIO_VERSION, ver, LIBVXHS_FULL_PATHNAME);
26ba25
+        return;
26ba25
+    }
26ba25
+
26ba25
+    ver = (*libvxhs.iio_max_version)();
26ba25
+    if (ver < QNIO_VERSION) {
26ba25
+        error_setg(errp, "Trying to use libvxhs version %"PRId32" API, but "
26ba25
+                         "only %"PRId32" or earlier is supported by %s",
26ba25
+                          QNIO_VERSION, ver, LIBVXHS_FULL_PATHNAME);
26ba25
+        return;
26ba25
+    }
26ba25
+
26ba25
+    libvxhs_loaded = true;
26ba25
+}
26ba25
+
26ba25
 static void vxhs_complete_aio_bh(void *opaque)
26ba25
 {
26ba25
     VXHSAIOCB *acb = opaque;
26ba25
@@ -219,7 +311,7 @@ static void vxhs_parse_filename(const char *filename, QDict *options,
26ba25
 static int vxhs_init_and_ref(void)
26ba25
 {
26ba25
     if (vxhs_ref++ == 0) {
26ba25
-        if (iio_init(QNIO_VERSION, vxhs_iio_callback)) {
26ba25
+        if ((*libvxhs.iio_init)(QNIO_VERSION, vxhs_iio_callback)) {
26ba25
             return -ENODEV;
26ba25
         }
26ba25
     }
26ba25
@@ -229,7 +321,7 @@ static int vxhs_init_and_ref(void)
26ba25
 static void vxhs_unref(void)
26ba25
 {
26ba25
     if (--vxhs_ref == 0) {
26ba25
-        iio_fini();
26ba25
+        (*libvxhs.iio_fini)();
26ba25
     }
26ba25
 }
26ba25
 
26ba25
@@ -299,8 +391,17 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
26ba25
     char *client_key = NULL;
26ba25
     char *client_cert = NULL;
26ba25
 
26ba25
+    bdrv_vxhs_load_libs(&local_err);
26ba25
+    if (local_err) {
26ba25
+        error_propagate(errp, local_err);
26ba25
+        /* on error, cannot cleanup because the iio_fini() function
26ba25
+         * is not loaded */
26ba25
+        return -EINVAL;
26ba25
+    }
26ba25
+
26ba25
     ret = vxhs_init_and_ref();
26ba25
     if (ret < 0) {
26ba25
+        error_setg(&local_err, "libvxhs iio_init() failed");
26ba25
         ret = -EINVAL;
26ba25
         goto out;
26ba25
     }
26ba25
@@ -385,8 +486,8 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
26ba25
     /*
26ba25
      * Open qnio channel to storage agent if not opened before
26ba25
      */
26ba25
-    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0,
26ba25
-                           cacert, client_key, client_cert);
26ba25
+    dev_handlep = (*libvxhs.iio_open)(of_vsa_addr, s->vdisk_guid, 0,
26ba25
+                                      cacert, client_key, client_cert);
26ba25
     if (dev_handlep == NULL) {
26ba25
         trace_vxhs_open_iio_open(of_vsa_addr);
26ba25
         ret = -ENODEV;
26ba25
@@ -450,12 +551,12 @@ static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, int64_t sector_num,
26ba25
 
26ba25
     switch (iodir) {
26ba25
     case VDISK_AIO_WRITE:
26ba25
-            ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
26ba25
-                             offset, (uint64_t)size, iio_flags);
26ba25
+            ret = (*libvxhs.iio_writev)(dev_handle, acb, qiov->iov, qiov->niov,
26ba25
+                                        offset, (uint64_t)size, iio_flags);
26ba25
             break;
26ba25
     case VDISK_AIO_READ:
26ba25
-            ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
26ba25
-                            offset, (uint64_t)size, iio_flags);
26ba25
+            ret = (*libvxhs.iio_readv)(dev_handle, acb, qiov->iov, qiov->niov,
26ba25
+                                       offset, (uint64_t)size, iio_flags);
26ba25
             break;
26ba25
     default:
26ba25
             trace_vxhs_aio_rw_invalid(iodir);
26ba25
@@ -505,7 +606,7 @@ static void vxhs_close(BlockDriverState *bs)
26ba25
      * Close vDisk device
26ba25
      */
26ba25
     if (s->vdisk_hostinfo.dev_handle) {
26ba25
-        iio_close(s->vdisk_hostinfo.dev_handle);
26ba25
+        (*libvxhs.iio_close)(s->vdisk_hostinfo.dev_handle);
26ba25
         s->vdisk_hostinfo.dev_handle = NULL;
26ba25
     }
26ba25
 
26ba25
@@ -527,7 +628,7 @@ static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s)
26ba25
     int ret = 0;
26ba25
     void *dev_handle = s->vdisk_hostinfo.dev_handle;
26ba25
 
26ba25
-    ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
26ba25
+    ret = (*libvxhs.iio_ioctl)(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
26ba25
     if (ret < 0) {
26ba25
         trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno);
26ba25
         return -EIO;
26ba25
diff --git a/configure b/configure
26ba25
index 0a19b03..7358269 100755
26ba25
--- a/configure
26ba25
+++ b/configure
26ba25
@@ -3369,7 +3369,7 @@ else
26ba25
     glib_req_ver=2.22
26ba25
 fi
26ba25
 glib_modules=gthread-2.0
26ba25
-if test "$modules" = yes; then
26ba25
+if test "$modules" = yes -o "$vxhs" = yes; then
26ba25
     glib_modules="$glib_modules gmodule-export-2.0"
26ba25
 fi
26ba25
 
26ba25
@@ -5314,33 +5314,6 @@ if compile_prog "" "" ; then
26ba25
 fi
26ba25
 
26ba25
 ##########################################
26ba25
-# Veritas HyperScale block driver VxHS
26ba25
-# Check if libvxhs is installed
26ba25
-
26ba25
-if test "$vxhs" != "no" ; then
26ba25
-  cat > $TMPC <
26ba25
-#include <stdint.h>
26ba25
-#include <qnio qnio_api.h="">
26ba25
-
26ba25
-void *vxhs_callback;
26ba25
-
26ba25
-int main(void) {
26ba25
-    iio_init(QNIO_VERSION, vxhs_callback);
26ba25
-    return 0;
26ba25
-}
26ba25
-EOF
26ba25
-  vxhs_libs="-lvxhs -lssl"
26ba25
-  if compile_prog "" "$vxhs_libs" ; then
26ba25
-    vxhs=yes
26ba25
-  else
26ba25
-    if test "$vxhs" = "yes" ; then
26ba25
-      feature_not_found "vxhs block device" "Install libvxhs See github"
26ba25
-    fi
26ba25
-    vxhs=no
26ba25
-  fi
26ba25
-fi
26ba25
-
26ba25
-##########################################
26ba25
 # check for _Static_assert()
26ba25
 
26ba25
 have_static_assert=no
26ba25
@@ -6614,8 +6587,8 @@ if test "$pthread_setname_np" = "yes" ; then
26ba25
 fi
26ba25
 
26ba25
 if test "$vxhs" = "yes" ; then
26ba25
-  echo "CONFIG_VXHS=y" >> $config_host_mak
26ba25
-  echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak
26ba25
+  echo "CONFIG_VXHS=m" >> $config_host_mak
26ba25
+  echo "VXHS_LIBS= -lssl" >> $config_host_mak
26ba25
 fi
26ba25
 
26ba25
 if test "$tcg_interpreter" = "yes"; then
26ba25
diff --git a/include/block/vxhs_shim.h b/include/block/vxhs_shim.h
26ba25
new file mode 100644
26ba25
index 0000000..42519ae
26ba25
--- /dev/null
26ba25
+++ b/include/block/vxhs_shim.h
26ba25
@@ -0,0 +1,143 @@
26ba25
+/*
26ba25
+ * Network IO library for VxHS QEMU block driver (Veritas Technologies)
26ba25
+ *
26ba25
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
26ba25
+ * the COPYING file in the top-level directory.
26ba25
+ *
26ba25
+ * Contributions after 2014-08-15 are licensed under the terms of the
26ba25
+ * GNU GPL, version 2 or (at your option) any later version.
26ba25
+ */
26ba25
+
26ba25
+#ifndef QNIO_API_H
26ba25
+#define QNIO_API_H
26ba25
+
26ba25
+#include <sys uio.h="">
26ba25
+
26ba25
+/*
26ba25
+ * Bump up the version everytime this file is modified
26ba25
+ */
26ba25
+#define QNIO_VERSION    34
26ba25
+
26ba25
+/*
26ba25
+ * These are the opcodes referenced by callback routine.
26ba25
+ */
26ba25
+#define IRP_READ_REQUEST                    0x1FFF
26ba25
+#define IRP_WRITE_REQUEST                   0x2FFF
26ba25
+#define IRP_VDISK_CHECK_IO_FAILOVER_READY   2020
26ba25
+
26ba25
+/*
26ba25
+ * opcodes for iio_ioctl.
26ba25
+ */
26ba25
+#define IOR_VDISK_STAT                      1005
26ba25
+
26ba25
+/*
26ba25
+ * Error values for iio_cb_t callback function.
26ba25
+ */
26ba25
+#define QNIOERROR_HUP                       901 /* Retriable error */
26ba25
+#define QNIOERROR_NOCONN                    902 /* Non-retriable error */
26ba25
+
26ba25
+
26ba25
+/* Operation Flags */
26ba25
+#define IIO_FLAG_ASYNC        0x0001   /* Do an async send */
26ba25
+
26ba25
+/*
26ba25
+ * INPUT:
26ba25
+ *     ctx - opaque context
26ba25
+ *     opcode - Operation
26ba25
+ *     error - 0 for sucess, non-zero for failure.
26ba25
+ * RETURNS:
26ba25
+ *     void
26ba25
+ * DESCRIPTION:
26ba25
+ *     This callback is called, after Async request completes.
26ba25
+ *
26ba25
+ * CONTEXT:
26ba25
+ *     The callback should be wait-free.
26ba25
+ */
26ba25
+typedef void (*iio_cb_t) (void *ctx, uint32_t opcode, uint32_t error);
26ba25
+
26ba25
+typedef struct LibVXHSFuncs {
26ba25
+/*
26ba25
+ * RETURNS:
26ba25
+ *     0 for sucess, non-zero for failure.
26ba25
+ * DESCRIPTION:
26ba25
+ *     Intilize the library state. This should be called at the
26ba25
+ *     begining before issuing any library call.
26ba25
+ */
26ba25
+    int     (*iio_init)(int32_t version, iio_cb_t cb);
26ba25
+/*
26ba25
+ * RETURNS:
26ba25
+ *     void
26ba25
+ * DESCRIPTION:
26ba25
+ *     Relinquish library resources. This should be called on the
26ba25
+ *     close of last open device.
26ba25
+ */
26ba25
+    void    (*iio_fini)(void);
26ba25
+/*
26ba25
+ * DESCRIPTION:
26ba25
+ *     Returns minimum QNIO API version supported by library.
26ba25
+ */
26ba25
+    int32_t (*iio_min_version)(void);
26ba25
+/*
26ba25
+ * DESCRIPTION:
26ba25
+ *     Returns maximum QNIO API version supported by library.
26ba25
+ */
26ba25
+    int32_t (*iio_max_version)(void);
26ba25
+/*
26ba25
+ * INPUT:
26ba25
+ *    uri - const string of the format of://<hostname|ip>:port
26ba25
+ *    devid - Device ID.
26ba25
+ *    flags - currently unused, this must be set to 0
26ba25
+ *    cacert - CA certificates file in PEM format
26ba25
+ *    client_key - Client private key file in PEM format
26ba25
+ *    client_cert - Client certificate file in PEM format
26ba25
+ * RETURNS:
26ba25
+ *    opeque device handle on success, NULL on failure.
26ba25
+ * DESCRIPTION:
26ba25
+ *    This call returns device handle on success. Returns NULL on
26ba25
+ *    failure with errno set
26ba25
+ *    errno can be one of:
26ba25
+ *        ENODEV - remote device not found
26ba25
+ *        EBADF  - Unable to open communication channel.
26ba25
+ *        EBUSY  - The call cannot be completed right now
26ba25
+ */
26ba25
+    void   *(*iio_open)(const char *uri, const char *devid, uint32_t flags,
26ba25
+                        const char *cacert, const char *client_key,
26ba25
+                        const char *client_cert);
26ba25
+/*
26ba25
+ * Close the device.
26ba25
+ *    For every matching iio_open() there should be a matching iio_close()
26ba25
+ *    The last close free all data structures associated with the device.
26ba25
+ */
26ba25
+    int32_t (*iio_close)(void *dev_handle);
26ba25
+/*
26ba25
+ * INPUT:
26ba25
+ *    dev_handle - device descriptor on which read/write needs to be performed
26ba25
+ *    ctx - an opaque context that is not interpreted This is set for
26ba25
+ *          async calls only. It can be NULL.
26ba25
+ *    iov    - an array of iovecs (This is a scatter gather operation)
26ba25
+ *    iovcnt  - the number of iovecs
26ba25
+ *    offset - an offset to perform the write
26ba25
+ *    size   - I/O size
26ba25
+ *    flags  - can be one of
26ba25
+ *        IIO_FLAG_ASYNC - indicating this is a aio call.
26ba25
+ * RETURNS:
26ba25
+ *        -1 on error, sets errno
26ba25
+ *        EBADF  - the remote fd is bad
26ba25
+ *        EBUSY  - The call cannot be completed right now
26ba25
+ *        EPIPE  - the channel got disconnected, call back would be called in
26ba25
+ *                 addition to this.
26ba25
+ */
26ba25
+    int32_t (*iio_writev)(void *dev_handle, void *ctx, struct iovec *iov,
26ba25
+                          int iovcnt, uint64_t offset, uint64_t size,
26ba25
+                          uint32_t flags);
26ba25
+
26ba25
+    int32_t (*iio_readv)(void *dev_handle, void *ctx, struct iovec *iov,
26ba25
+                         int iovcnt, uint64_t offset, uint64_t size,
26ba25
+                         uint32_t flags);
26ba25
+
26ba25
+    int32_t (*iio_ioctl)(void *dev_handle, uint32_t opcode, void *opaque,
26ba25
+                         uint32_t flags);
26ba25
+
26ba25
+} LibVXHSFuncs;
26ba25
+
26ba25
+#endif