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

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