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