Blame SOURCES/0002-vddk-Remove-compile-time-dependency-on-VDDK-library.patch

fe7475
From 15c68a414dee20d5ac60936bddb640fb1262c641 Mon Sep 17 00:00:00 2001
fe7475
From: "Richard W.M. Jones" <rjones@redhat.com>
fe7475
Date: Tue, 24 Jul 2018 12:11:17 +0100
fe7475
Subject: [PATCH] vddk: Remove compile-time dependency on VDDK library.
fe7475
MIME-Version: 1.0
fe7475
Content-Type: text/plain; charset=UTF-8
fe7475
Content-Transfer-Encoding: 8bit
fe7475
fe7475
Allow the plugin to be compiled without needing the library.  Instead
fe7475
of linking to the library at compile time we open the library at
fe7475
runtime using dlopen.
fe7475
fe7475
The plugin is now compiled unconditionally, unless you use
fe7475
‘./configure --disable-vddk’.  (Of course you still need the VDDK
fe7475
library if you want to use the plugin.  We cannot even test the plugin
fe7475
loads without the library.).
fe7475
fe7475
This change also moves the initialization of VDDK (calling InitEx)
fe7475
into the config_complete method instead of the load method.  This
fe7475
later initialization allows the "config=FILENAME" and
fe7475
"libdir=PATHNAME" parameters to have an effect whereas previously they
fe7475
were silently ignored.
fe7475
fe7475
(cherry picked from commit 8d7f7c26eb435334d7fa35e84ceee7d266dfae4c)
fe7475
---
fe7475
 README                              |   4 --
fe7475
 configure.ac                        |  75 ++--------------------
fe7475
 plugins/vddk/Makefile.am            |  13 ++--
fe7475
 plugins/vddk/README.VDDK            |  25 ++------
fe7475
 plugins/vddk/nbdkit-vddk-plugin.pod |  48 ++++++++++----
fe7475
 plugins/vddk/vddk-structs.h         | 125 ++++++++++++++++++++++++++++++++++++
fe7475
 plugins/vddk/vddk.c                 |  89 ++++++++++++++++++-------
fe7475
 7 files changed, 244 insertions(+), 135 deletions(-)
fe7475
 create mode 100644 plugins/vddk/vddk-structs.h
fe7475
fe7475
diff --git a/README b/README
fe7475
index 9ef251d..ae79dec 100644
fe7475
--- a/README
fe7475
+++ b/README
fe7475
@@ -79,10 +79,6 @@ For the ext2 plugin:
fe7475
 
fe7475
  - com_err
fe7475
 
fe7475
-For the VDDK plugin:
fe7475
-
fe7475
- - VDDK (see plugins/vddk/README.VDDK)
fe7475
-
fe7475
 For the Perl, example4 and tar plugins:
fe7475
 
fe7475
  - perl interpreter
fe7475
diff --git a/configure.ac b/configure.ac
fe7475
index a970451..6bb9405 100644
fe7475
--- a/configure.ac
fe7475
+++ b/configure.ac
fe7475
@@ -502,77 +502,14 @@ AS_IF([test "$with_ext2" != "no"], [
fe7475
 AM_CONDITIONAL([HAVE_EXT2],
fe7475
                [test "x$EXT2FS_LIBS" != "x" && test "x$COM_ERR_LIBS" != "x"])
fe7475
 
fe7475
+dnl Check if the user wants to disable VDDK support.
fe7475
 dnl See plugins/vddk/README.VDDK.
fe7475
-AC_CHECK_SIZEOF([size_t])
fe7475
-AS_IF([test "x$ac_cv_sizeof_size_t" = "x4"],[bits=32],[bits=64])
fe7475
-AC_ARG_WITH([vddk],[
fe7475
-    AS_HELP_STRING([--with-vddk],
fe7475
-                   [enable VMware VDDK plugin @<:@default=no@:>@])],
fe7475
+AC_ARG_ENABLE([vddk],[
fe7475
+    AS_HELP_STRING([--disable-vddk],
fe7475
+                   [disable VMware VDDK plugin])],
fe7475
     [],
fe7475
-    [with_vddk=no])
fe7475
-AS_IF([test "$with_vddk" = "yes"],[
fe7475
-    VDDK_CFLAGS=
fe7475
-    VDDK_LIBS="-lvixDiskLib"
fe7475
-    # XXX Warning: stupid VMware API.
fe7475
-    VDDK_LIBDIR="$libdir/vmware-vix-disklib"
fe7475
-    AC_MSG_NOTICE([VDDK plugin enabled from $VDDK_LIBDIR])
fe7475
-    ],[
fe7475
-    AS_IF([test "$with_vddk" != "no"], [
fe7475
-        VDDK_CFLAGS="-I$with_vddk/include"
fe7475
-        VDDK_LIBS="-L$with_vddk/lib$bits -lvixDiskLib"
fe7475
-        VDDK_LIBDIR="$with_vddk"
fe7475
-        AC_MSG_NOTICE([VDDK plugin enabled from $with_vddk])
fe7475
-        ],
fe7475
-        [AC_MSG_NOTICE([VDDK plugin disabled])
fe7475
-    ])
fe7475
-])
fe7475
-
fe7475
-dnl If the VDDK plugin was enabled, compile and link a test program to make
fe7475
-dnl sure the library really works.
fe7475
-AS_IF([test "x$VDDK_LIBS" != "x"],[
fe7475
-    # Save CFLAGS etc while we do this test.
fe7475
-    acx_nbdkit_save_CFLAGS="${CFLAGS}"
fe7475
-    acx_nbdkit_save_LIBS="${LIBS}"
fe7475
-    CFLAGS="$CFLAGS $VDDK_CFLAGS"
fe7475
-    LIBS="$VDDK_LIBS $LIBS"
fe7475
-
fe7475
-    AC_MSG_CHECKING([if we can link to VDDK])
fe7475
-    AC_LINK_IFELSE([
fe7475
-        AC_LANG_SOURCE([[
fe7475
-#include <stdio.h>
fe7475
-#include <stdint.h>
fe7475
-#include <vixDiskLib.h>
fe7475
-
fe7475
-int
fe7475
-main ()
fe7475
-{
fe7475
-    VixDiskLib_Exit ();
fe7475
-}
fe7475
-]])
fe7475
-    ],[
fe7475
-        AC_MSG_RESULT([yes])
fe7475
-    ],[
fe7475
-        AC_MSG_RESULT([no])
fe7475
-        AC_MSG_ERROR([could not link to VDDK, see ‘config.log’ for more information])
fe7475
-    ])
fe7475
-
fe7475
-    dnl Check for optional fields in VixDiskLibConnectParams struct.
fe7475
-    AC_CHECK_MEMBERS([VixDiskLibConnectParams.nfcHostPort, VixDiskLibConnectParams.vimApiVer],
fe7475
-                    [], [], [[
fe7475
-#include <stdio.h>
fe7475
-#include <stdint.h>
fe7475
-#include <vixDiskLib.h>
fe7475
-]])
fe7475
-
fe7475
-    dnl Restore CFLAGS, etc.
fe7475
-    CFLAGS="${acx_nbdkit_save_CFLAGS}"
fe7475
-    LIBS="${acx_nbdkit_save_LIBS}"
fe7475
-])
fe7475
-
fe7475
-AC_SUBST([VDDK_CFLAGS])
fe7475
-AC_SUBST([VDDK_LIBS])
fe7475
-AC_DEFINE_UNQUOTED([VDDK_LIBDIR],["$VDDK_LIBDIR"],[VDDK 'libDir'.])
fe7475
-AM_CONDITIONAL([HAVE_VDDK],[test "x$VDDK_LIBS" != "x"])
fe7475
+    [enable_vddk=yes])
fe7475
+AM_CONDITIONAL([HAVE_VDDK], [test "x$enable_vddk" = "xyes"])
fe7475
 
fe7475
 dnl Produce output files.
fe7475
 AC_CONFIG_HEADERS([config.h])
fe7475
diff --git a/plugins/vddk/Makefile.am b/plugins/vddk/Makefile.am
fe7475
index 3b3e8aa..0f06768 100644
fe7475
--- a/plugins/vddk/Makefile.am
fe7475
+++ b/plugins/vddk/Makefile.am
fe7475
@@ -1,5 +1,5 @@
fe7475
 # nbdkit
fe7475
-# Copyright (C) 2013 Red Hat Inc.
fe7475
+# Copyright (C) 2013-2018 Red Hat Inc.
fe7475
 # All rights reserved.
fe7475
 #
fe7475
 # Redistribution and use in source and binary forms, with or without
fe7475
@@ -42,15 +42,16 @@ plugin_LTLIBRARIES = nbdkit-vddk-plugin.la
fe7475
 
fe7475
 nbdkit_vddk_plugin_la_SOURCES = \
fe7475
 	vddk.c \
fe7475
+	vddk-structs.h \
fe7475
 	$(top_srcdir)/include/nbdkit-plugin.h
fe7475
 
fe7475
 nbdkit_vddk_plugin_la_CPPFLAGS = \
fe7475
-	-I$(top_srcdir)/include
fe7475
+	-I$(top_srcdir)/include \
fe7475
+	-DVDDK_LIBDIR=\"$(libdir)/vmware-vix-disklib\"
fe7475
 nbdkit_vddk_plugin_la_CFLAGS = \
fe7475
-	$(WARNINGS_CFLAGS) \
fe7475
-	$(VDDK_CFLAGS)
fe7475
+	$(WARNINGS_CFLAGS)
fe7475
 nbdkit_vddk_plugin_la_LIBADD = \
fe7475
-	$(VDDK_LIBS)
fe7475
+	-ldl
fe7475
 nbdkit_vddk_plugin_la_LDFLAGS = \
fe7475
 	-module -avoid-version -shared
fe7475
 
fe7475
@@ -66,4 +67,4 @@ nbdkit-vddk-plugin.1: nbdkit-vddk-plugin.pod
fe7475
 
fe7475
 endif
fe7475
 
fe7475
-endif
fe7475
+endif HAVE_VDDK
fe7475
diff --git a/plugins/vddk/README.VDDK b/plugins/vddk/README.VDDK
fe7475
index d8c62b1..1e56631 100644
fe7475
--- a/plugins/vddk/README.VDDK
fe7475
+++ b/plugins/vddk/README.VDDK
fe7475
@@ -11,27 +11,14 @@ account and download it from:
fe7475
 This directory contains an nbdkit plugin which uses this library to
fe7475
 export VMDK files and VMware disks over NBD.
fe7475
 
fe7475
-VDDK >= 6.5 is required.
fe7475
-
fe7475
-Note: VDDK can do NBD on its own, so nbdkit might not be needed unless
fe7475
-you want the extra features and flexibility of nbdkit.
fe7475
-
fe7475
-It is never compiled by default.  To enable it you have to do:
fe7475
-
fe7475
-  ./configure --with-vddk
fe7475
-
fe7475
-If the VDDK library is located in a non-standard location, use this
fe7475
-instead:
fe7475
-
fe7475
-  ./configure --with-vddk=/path/to/vmware-vix-disklib-distrib
fe7475
-
fe7475
-(This looks for include/ and lib{32,64}/ subdirectories of the given
fe7475
-path for header files and libraries respectively.)
fe7475
+You do NOT require VDDK to compile the plugin, and the plugin does not
fe7475
+contain any VMware code.  You only need VDDK at runtime.  The plugin
fe7475
+uses dlopen to load the library from LD_LIBRARY_PATH (or else the
fe7475
+standard shared library paths).
fe7475
 
fe7475
 After building nbdkit-vddk-plugin.so, read the man page to find out
fe7475
-how to use it (nbdkit-vddk-plugin(1)).
fe7475
-
fe7475
-You'll probably also want to read the VDDK developer documentation.
fe7475
+how to use it (nbdkit-vddk-plugin(1)).  You'll probably also want to
fe7475
+read the VDDK developer documentation.
fe7475
 
fe7475
 Bugs
fe7475
 ----
fe7475
diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod
fe7475
index c5486a3..ba7806d 100644
fe7475
--- a/plugins/vddk/nbdkit-vddk-plugin.pod
fe7475
+++ b/plugins/vddk/nbdkit-vddk-plugin.pod
fe7475
@@ -16,21 +16,41 @@ nbdkit-vddk-plugin - VMware VDDK plugin for nbdkit
fe7475
 
fe7475
 =head1 DESCRIPTION
fe7475
 
fe7475
-C<nbdkit-vddk-plugin> is a L<nbdkit(1)> plugin that serves files from
fe7475
+C<nbdkit-vddk-plugin> is an L<nbdkit(1)> plugin that serves files from
fe7475
 local VMware VMDK files, VMware ESXi servers, VMware VCenter servers,
fe7475
-and other sources by using VMware's proprietary VDDK library.
fe7475
+and other sources.  It requires VMware's proprietary VDDK library that
fe7475
+you must download yourself separately.
fe7475
 
fe7475
 The plugin can serve read-only (if the I<-r> option is used) or
fe7475
 read/write.
fe7475
 
fe7475
-=head1 LIBRARY LOCATION
fe7475
+=head1 LIBRARY AND CONFIG FILE LOCATIONS
fe7475
 
fe7475
-If the VDDK library (C<libvixDiskLib.so>) is located on a non-standard
fe7475
-path, you may need to set C<LD_LIBRARY_PATH> or modify
fe7475
-C</etc/ld.so.conf> before this plugin will work.
fe7475
+If the VDDK library (F<libvixDiskLib.so.6>) is located on a
fe7475
+non-standard path, you may need to set C<LD_LIBRARY_PATH> or modify
fe7475
+F</etc/ld.so.conf> before this plugin will work.  In addition you may
fe7475
+want to set the C<libdir> parameter so that the VDDK library can load
fe7475
+plugins like Advanced Transport.
fe7475
 
fe7475
-The VDDK library may depend on C<libexpat.so.0> or other libraries
fe7475
-which you may have to install yourself.
fe7475
+For 64 bit platforms pass the F<lib64> subdirectory:
fe7475
+
fe7475
+ export LD_LIBRARY_PATH=/path/to/vmware-vix-disklib-distrib/lib64
fe7475
+
fe7475
+For 32 bit platforms pass the F<lib32> subdirectory:
fe7475
+
fe7475
+ export LD_LIBRARY_PATH=/path/to/vmware-vix-disklib-distrib/lib32
fe7475
+
fe7475
+Then pass the VDDK distribution directory as C<libdir> along with
fe7475
+other parameters as required:
fe7475
+
fe7475
+ nbdkit vddk \
fe7475
+     libdir=/path/to/vmware-vix-disklib-distrib \
fe7475
+     file=file.vmdk
fe7475
+
fe7475
+VDDK itself looks in a few default locations for the optional
fe7475
+configuration file, usually including F</etc/vmware/config> and
fe7475
+F<$HOME/.vmware/config>, but you can override this using the C<config>
fe7475
+parameter.
fe7475
 
fe7475
 =head1 PARAMETERS
fe7475
 
fe7475
@@ -67,11 +87,14 @@ L</NOTES> below).
fe7475
 
fe7475
 =item B<libdir=PATHNAME>
fe7475
 
fe7475
-Optional.  This sets the path of the VMware VDDK library.  It must be
fe7475
-an absolute path.
fe7475
+Optional.  This sets the path of the VMware VDDK distribution.  It
fe7475
+must be an absolute path.
fe7475
+
fe7475
+VDDK uses this to load its own plugins, if this path is unspecified or
fe7475
+wrong then VDDK will work with reduced functionality.
fe7475
 
fe7475
 If the parameter is not given, then a hard-coded path determined at
fe7475
-compile time is used.
fe7475
+compile time is used, see L</DUMP-PLUGIN OUTPUT> below.
fe7475
 
fe7475
 =item B<nfchostport=PORT>
fe7475
 
fe7475
@@ -307,7 +330,6 @@ support this.
fe7475
 
fe7475
 =head1 SEE ALSO
fe7475
 
fe7475
-L<https://github.com/libguestfs/nbdkit/blob/master/plugins/vddk/vddk.c>,
fe7475
 L<nbdkit(1)>,
fe7475
 L<nbdkit-plugin(3)>,
fe7475
 L<virsh(1)>,
fe7475
@@ -319,7 +341,7 @@ Richard W.M. Jones
fe7475
 
fe7475
 =head1 COPYRIGHT
fe7475
 
fe7475
-Copyright (C) 2013-2017 Red Hat Inc.
fe7475
+Copyright (C) 2013-2018 Red Hat Inc.
fe7475
 
fe7475
 =head1 LICENSE
fe7475
 
fe7475
diff --git a/plugins/vddk/vddk-structs.h b/plugins/vddk/vddk-structs.h
fe7475
new file mode 100644
fe7475
index 0000000..3e7a3c6
fe7475
--- /dev/null
fe7475
+++ b/plugins/vddk/vddk-structs.h
fe7475
@@ -0,0 +1,125 @@
fe7475
+/* nbdkit
fe7475
+ * Copyright (C) 2013-2018 Red Hat Inc.
fe7475
+ * All rights reserved.
fe7475
+ *
fe7475
+ * Redistribution and use in source and binary forms, with or without
fe7475
+ * modification, are permitted provided that the following conditions are
fe7475
+ * met:
fe7475
+ *
fe7475
+ * * Redistributions of source code must retain the above copyright
fe7475
+ * notice, this list of conditions and the following disclaimer.
fe7475
+ *
fe7475
+ * * Redistributions in binary form must reproduce the above copyright
fe7475
+ * notice, this list of conditions and the following disclaimer in the
fe7475
+ * documentation and/or other materials provided with the distribution.
fe7475
+ *
fe7475
+ * * Neither the name of Red Hat nor the names of its contributors may be
fe7475
+ * used to endorse or promote products derived from this software without
fe7475
+ * specific prior written permission.
fe7475
+ *
fe7475
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
fe7475
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
fe7475
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
fe7475
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
fe7475
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
fe7475
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
fe7475
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
fe7475
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
fe7475
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
fe7475
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
fe7475
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
fe7475
+ * SUCH DAMAGE.
fe7475
+ */
fe7475
+
fe7475
+/* Types and structs that we pass to or return from the VDDK API.
fe7475
+ *
fe7475
+ * Updated to VDDK 6.7
fe7475
+ */
fe7475
+
fe7475
+#ifndef NBDKIT_VDDK_STRUCTS_H
fe7475
+#define NBDKIT_VDDK_STRUCTS_H
fe7475
+
fe7475
+typedef uint64_t VixError;
fe7475
+#define VIX_OK 0
fe7475
+
fe7475
+#define VIXDISKLIB_FLAG_OPEN_READ_ONLY 4
fe7475
+#define VIXDISKLIB_SECTOR_SIZE 512
fe7475
+
fe7475
+typedef void *VixDiskLibConnection;
fe7475
+typedef void *VixDiskLibHandle;
fe7475
+
fe7475
+typedef void VixDiskLibGenericLogFunc (const char *fmt, va_list args);
fe7475
+
fe7475
+enum VixDiskLibCredType {
fe7475
+  VIXDISKLIB_CRED_UID       = 1,
fe7475
+  VIXDISKLIB_CRED_SESSIONID = 2,
fe7475
+  VIXDISKLIB_CRED_TICKETID  = 3,
fe7475
+  VIXDISKLIB_CRED_SSPI      = 4,
fe7475
+  VIXDISKLIB_CRED_UNKNOWN   = 256
fe7475
+};
fe7475
+
fe7475
+enum VixDiskLibSpecType {
fe7475
+  VIXDISKLIB_SPEC_VMX             = 0,
fe7475
+  VIXDISKLIB_SPEC_VSTORAGE_OBJECT = 1,
fe7475
+  VIXDISKLIB_SPEC_UNKNOWN         = 2
fe7475
+};
fe7475
+
fe7475
+struct VixDiskLibVStorageObjectSpec {
fe7475
+  char *id;
fe7475
+  char *datastoreMoRef;
fe7475
+  char *ssId;
fe7475
+};
fe7475
+
fe7475
+typedef struct VixDiskLibConnectParams {
fe7475
+  char *vmxSpec;
fe7475
+  char *serverName;
fe7475
+  char *thumbPrint;
fe7475
+  long reserved1;
fe7475
+  enum VixDiskLibCredType credType;
fe7475
+  union {
fe7475
+    struct {
fe7475
+      char *userName;
fe7475
+      char *password;
fe7475
+    } uid;
fe7475
+    struct {
fe7475
+      char *cookie;
fe7475
+      char *userName;
fe7475
+      char *key;
fe7475
+    } sessionId;
fe7475
+    void *reserved2;
fe7475
+  } creds;
fe7475
+  uint32_t port;
fe7475
+  uint32_t nfcHostPort;
fe7475
+  char *reserved3;
fe7475
+  char reserved4[8];
fe7475
+  void *reserved5;
fe7475
+  union {
fe7475
+    struct VixDiskLibVStorageObjectSpec vStorageObjSpec;
fe7475
+  } spec;
fe7475
+  enum VixDiskLibSpecType specType;
fe7475
+} VixDiskLibConnectParams;
fe7475
+
fe7475
+struct VixDiskLibGeometry {
fe7475
+  uint32_t cylinders;
fe7475
+  uint32_t heads;
fe7475
+  uint32_t sectors;
fe7475
+};
fe7475
+
fe7475
+enum VixDiskLibAdapterType {
fe7475
+  VIXDISKLIB_ADAPTER_IDE           = 1,
fe7475
+  VIXDISKLIB_ADAPTER_SCSI_BUSLOGIC = 2,
fe7475
+  VIXDISKLIB_ADAPTER_SCSI_LSILOGIC = 3,
fe7475
+  VIXDISKLIB_ADAPTER_UNKNOWN       = 256
fe7475
+};
fe7475
+
fe7475
+typedef struct VixDiskLibInfo {
fe7475
+  struct VixDiskLibGeometry biosGeo;
fe7475
+  struct VixDiskLibGeometry physGeo;
fe7475
+  uint64_t capacity;
fe7475
+  enum VixDiskLibAdapterType adapterType;
fe7475
+  int numLinks;
fe7475
+  char *parentFileNameHint;
fe7475
+  char *uuid;
fe7475
+} VixDiskLibInfo;
fe7475
+
fe7475
+#endif /* NBDKIT_VDDK_STRUCTS_H */
fe7475
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
fe7475
index 7e0590e..748f1b3 100644
fe7475
--- a/plugins/vddk/vddk.c
fe7475
+++ b/plugins/vddk/vddk.c
fe7475
@@ -39,14 +39,36 @@
fe7475
 #include <inttypes.h>
fe7475
 #include <string.h>
fe7475
 #include <unistd.h>
fe7475
+#include <dlfcn.h>
fe7475
 
fe7475
 #include <nbdkit-plugin.h>
fe7475
 
fe7475
-#include <vixDiskLib.h>
fe7475
+#include "vddk-structs.h"
fe7475
 
fe7475
+/* The VDDK APIs that we call.  These globals are initialized when the
fe7475
+ * plugin is loaded (by vddk_load).
fe7475
+ */
fe7475
+char *(*VixDiskLib_GetErrorText) (VixError err, const char *unused);
fe7475
+void (*VixDiskLib_FreeErrorText) (char *text);
fe7475
+VixError (*VixDiskLib_InitEx) (uint32_t major, uint32_t minor, VixDiskLibGenericLogFunc *log_function, VixDiskLibGenericLogFunc *warn_function, VixDiskLibGenericLogFunc *panic_function, const char *lib_dir, const char *config_file);
fe7475
+void (*VixDiskLib_Exit) (void);
fe7475
+VixError (*VixDiskLib_ConnectEx) (const VixDiskLibConnectParams *params, char read_only, const char *snapshot_ref, const char *transport_modes, VixDiskLibConnection *connection);
fe7475
+VixError (*VixDiskLib_Open) (const VixDiskLibConnection connection, const char *path, uint32_t flags, VixDiskLibHandle *handle);
fe7475
+const char *(*VixDiskLib_GetTransportMode) (VixDiskLibHandle handle);
fe7475
+VixError (*VixDiskLib_Close) (VixDiskLibHandle handle);
fe7475
+VixError (*VixDiskLib_Disconnect) (VixDiskLibConnection connection);
fe7475
+VixError (*VixDiskLib_GetInfo) (VixDiskLibHandle handle, VixDiskLibInfo **info);
fe7475
+void (*VixDiskLib_FreeInfo) (VixDiskLibInfo *info);
fe7475
+VixError (*VixDiskLib_Read) (VixDiskLibHandle handle, uint64_t start_sector, uint64_t nr_sectors, unsigned char *buf);
fe7475
+VixError (*VixDiskLib_Write) (VixDiskLibHandle handle, uint64_t start_sector, uint64_t nr_sectors, const unsigned char *buf);
fe7475
+
fe7475
+/* Parameters passed to InitEx. */
fe7475
 #define VDDK_MAJOR 5
fe7475
 #define VDDK_MINOR 1
fe7475
 
fe7475
+static void *dl = NULL;                    /* dlopen handle */
fe7475
+static int init_called = 0;                /* was InitEx called */
fe7475
+
fe7475
 static char *config = NULL;                /* config */
fe7475
 static const char *cookie = NULL;          /* cookie */
fe7475
 static const char *filename = NULL;        /* file */
fe7475
@@ -120,27 +142,39 @@ error_function (const char *fs, va_list args)
fe7475
 static void
fe7475
 vddk_load (void)
fe7475
 {
fe7475
-  VixError err;
fe7475
+  const char *soname = "libvixDiskLib.so.6";
fe7475
 
fe7475
-  DEBUG_CALL ("VixDiskLib_InitEx",
fe7475
-              "%d, %d, &debug_fn, &error_fn, &error_fn, %s, %s",
fe7475
-              VDDK_MAJOR, VDDK_MINOR, libdir, config ? : "NULL");
fe7475
-  err = VixDiskLib_InitEx (VDDK_MAJOR, VDDK_MINOR,
fe7475
-                           &debug_function, /* log function */
fe7475
-                           &error_function, /* warn function */
fe7475
-                           &error_function, /* panic function */
fe7475
-                           libdir, config);
fe7475
-  if (err != VIX_OK) {
fe7475
-    VDDK_ERROR (err, "VixDiskLib_InitEx");
fe7475
+  /* Load the plugin and set the entry points. */
fe7475
+  dl = dlopen (soname, RTLD_NOW);
fe7475
+  if (dl == NULL) {
fe7475
+    nbdkit_error ("%s: %s", soname, dlerror ());
fe7475
     exit (EXIT_FAILURE);
fe7475
   }
fe7475
+
fe7475
+  VixDiskLib_GetErrorText = dlsym (dl, "VixDiskLib_GetErrorText");
fe7475
+  VixDiskLib_FreeErrorText = dlsym (dl, "VixDiskLib_FreeErrorText");
fe7475
+  VixDiskLib_InitEx = dlsym (dl, "VixDiskLib_InitEx");
fe7475
+  VixDiskLib_Exit = dlsym (dl, "VixDiskLib_Exit");
fe7475
+  VixDiskLib_ConnectEx = dlsym (dl, "VixDiskLib_ConnectEx");
fe7475
+  VixDiskLib_Open = dlsym (dl, "VixDiskLib_Open");
fe7475
+  VixDiskLib_GetTransportMode = dlsym (dl, "VixDiskLib_GetTransportMode");
fe7475
+  VixDiskLib_Close = dlsym (dl, "VixDiskLib_Close");
fe7475
+  VixDiskLib_Disconnect = dlsym (dl, "VixDiskLib_Disconnect");
fe7475
+  VixDiskLib_GetInfo = dlsym (dl, "VixDiskLib_GetInfo");
fe7475
+  VixDiskLib_FreeInfo = dlsym (dl, "VixDiskLib_FreeInfo");
fe7475
+  VixDiskLib_Read = dlsym (dl, "VixDiskLib_Read");
fe7475
+  VixDiskLib_Write = dlsym (dl, "VixDiskLib_Write");
fe7475
 }
fe7475
 
fe7475
 static void
fe7475
 vddk_unload (void)
fe7475
 {
fe7475
-  DEBUG_CALL ("VixDiskLib_Exit", "");
fe7475
-  VixDiskLib_Exit ();
fe7475
+  if (init_called) {
fe7475
+    DEBUG_CALL ("VixDiskLib_Exit", "");
fe7475
+    VixDiskLib_Exit ();
fe7475
+  }
fe7475
+  if (dl)
fe7475
+    dlclose (dl);
fe7475
   free (config);
fe7475
   free (password);
fe7475
 }
fe7475
@@ -170,15 +204,10 @@ vddk_config (const char *key, const char *value)
fe7475
     libdir = value;
fe7475
   }
fe7475
   else if (strcmp (key, "nfchostport") == 0) {
fe7475
-#if HAVE_VIXDISKLIBCONNECTPARAMS_NFCHOSTPORT
fe7475
     if (sscanf (value, "%d", &nfc_host_port) != 1) {
fe7475
       nbdkit_error ("cannot parse nfchostport: %s", value);
fe7475
       return -1;
fe7475
     }
fe7475
-#else
fe7475
-    nbdkit_error ("this version of VDDK is too old to support nfchostpost");
fe7475
-    return -1;
fe7475
-#endif
fe7475
   }
fe7475
   else if (strcmp (key, "password") == 0) {
fe7475
     free (password);
fe7475
@@ -223,6 +252,8 @@ vddk_config (const char *key, const char *value)
fe7475
 static int
fe7475
 vddk_config_complete (void)
fe7475
 {
fe7475
+  VixError err;
fe7475
+
fe7475
   if (filename == NULL) {
fe7475
     nbdkit_error ("you must supply the file=<FILENAME> parameter after the plugin name on the command line");
fe7475
     return -1;
fe7475
@@ -258,6 +289,21 @@ vddk_config_complete (void)
fe7475
 #undef missing
fe7475
   }
fe7475
 
fe7475
+  /* Initialize VDDK library. */
fe7475
+  DEBUG_CALL ("VixDiskLib_InitEx",
fe7475
+              "%d, %d, &debug_fn, &error_fn, &error_fn, %s, %s",
fe7475
+              VDDK_MAJOR, VDDK_MINOR, libdir, config ? : "NULL");
fe7475
+  err = VixDiskLib_InitEx (VDDK_MAJOR, VDDK_MINOR,
fe7475
+                           &debug_function, /* log function */
fe7475
+                           &error_function, /* warn function */
fe7475
+                           &error_function, /* panic function */
fe7475
+                           libdir, config);
fe7475
+  if (err != VIX_OK) {
fe7475
+    VDDK_ERROR (err, "VixDiskLib_InitEx");
fe7475
+    exit (EXIT_FAILURE);
fe7475
+  }
fe7475
+  init_called = 1;
fe7475
+
fe7475
   return 0;
fe7475
 }
fe7475
 
fe7475
@@ -269,10 +315,7 @@ static void
fe7475
 vddk_dump_plugin (void)
fe7475
 {
fe7475
   printf ("vddk_default_libdir=%s\n", VDDK_LIBDIR);
fe7475
-
fe7475
-#if HAVE_VIXDISKLIBCONNECTPARAMS_NFCHOSTPORT
fe7475
   printf ("vddk_has_nfchostport=1\n");
fe7475
-#endif
fe7475
 
fe7475
   /* XXX We really need to print the version of the dynamically
fe7475
    * linked library here, but VDDK does not provide it.
fe7475
@@ -323,9 +366,7 @@ vddk_open (int readonly)
fe7475
     }
fe7475
     params.thumbPrint = (char *) thumb_print;
fe7475
     params.port = port;
fe7475
-#if HAVE_VIXDISKLIBCONNECTPARAMS_NFCHOSTPORT
fe7475
     params.nfcHostPort = nfc_host_port;
fe7475
-#endif
fe7475
   }
fe7475
 
fe7475
   /* XXX Some documentation suggests we should call
fe7475
-- 
fe7475
1.8.3.1
fe7475