import nbdkit-1.4.2-4.module+el8+2586+bf759444

c8-stream-rhel imports/c8-stream-rhel/nbdkit-1.4.2-4.module+el8+2586+bf759444
CentOS Sources 4 years ago committed by Andrew Lukoshko
commit 85c87d495d

2
.gitignore vendored

@ -0,0 +1,2 @@
SOURCES/libguestfs.keyring
SOURCES/nbdkit-1.4.2.tar.gz

@ -0,0 +1,2 @@
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
183de3c31d768148c49456732c3a86350126c101 SOURCES/nbdkit-1.4.2.tar.gz

@ -0,0 +1,117 @@
From f8b15da031cbbc9ec3d21d056cd1cdf673416bbc Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 24 Jul 2018 12:08:41 +0100
Subject: [PATCH] vddk: Remove vimapiver parameter.
VDDK never used this, setting it is useless.
(cherry picked from commit ecface865aa121a601c571831d78f4ea1f0574b8)
---
plugins/vddk/nbdkit-vddk-plugin.pod | 12 ++----------
plugins/vddk/vddk.c | 20 +++-----------------
2 files changed, 5 insertions(+), 27 deletions(-)
diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod
index 4d9c6e9..c5486a3 100644
--- a/plugins/vddk/nbdkit-vddk-plugin.pod
+++ b/plugins/vddk/nbdkit-vddk-plugin.pod
@@ -10,7 +10,7 @@ nbdkit-vddk-plugin - VMware VDDK plugin for nbdkit
[vm=moref=ID] [server=HOSTNAME] [user=USERNAME]
[password=PASSWORD | password=- | password=+FILENAME]
[cookie=COOKIE] [thumbprint=THUMBPRINT]
- [vimapiver=APIVER] [port=PORT] [nfchostport=PORT]
+ [port=PORT] [nfchostport=PORT]
[snapshot=MOREF] [transports=MODE:MODE:...]
nbdkit vddk --dump-plugin
@@ -177,10 +177,7 @@ L<https://blogs.vmware.com/vsphere/2012/02/uniquely-identifying-virtual-machines
=item B<vimapiver=APIVER>
-Optional. Specify the VIM API version. If not given it defaults to
-the current version.
-
-(Only supported in VDDK ≥ 6.5.0)
+This parameter is ignored for backwards compatibility.
=back
@@ -271,11 +268,6 @@ at runtime.
If this is printed then the C<nfchostport=PORT> parameter is supported
by this build.
-=item C<vddk_has_vimapiver=1>
-
-If this is printed then the C<vimapiver=APIVER> parameter is supported
-by this build.
-
=back
=head1 DEBUGGING VDDK
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index 8bc1517..7e0590e 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -1,5 +1,5 @@
/* nbdkit
- * Copyright (C) 2013-2017 Red Hat Inc.
+ * Copyright (C) 2013-2018 Red Hat Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -59,7 +59,6 @@ static const char *snapshot_moref = NULL; /* snapshot */
static const char *thumb_print = NULL; /* thumbprint */
static const char *transport_modes = NULL; /* transports */
static const char *username = NULL; /* user */
-static const char *vim_api_ver = NULL; /* vimapiver */
static const char *vmx_spec = NULL; /* vm */
static int is_remote = 0;
@@ -208,12 +207,7 @@ vddk_config (const char *key, const char *value)
username = value;
}
else if (strcmp (key, "vimapiver") == 0) {
-#if HAVE_VIXDISKLIBCONNECTPARAMS_VIMAPIVER
- vim_api_ver = value;
-#else
- nbdkit_error ("this version of VDDK is too old to support vimapiver");
- return -1;
-#endif
+ /* Ignored for backwards compatibility. */
}
else if (strcmp (key, "vm") == 0) {
vmx_spec = value;
@@ -248,8 +242,7 @@ vddk_config_complete (void)
cookie ||
thumb_print ||
port ||
- nfc_host_port ||
- vim_api_ver;
+ nfc_host_port;
if (is_remote) {
#define missing(test, param) \
@@ -281,10 +274,6 @@ vddk_dump_plugin (void)
printf ("vddk_has_nfchostport=1\n");
#endif
-#if HAVE_VIXDISKLIBCONNECTPARAMS_VIMAPIVER
- printf ("vddk_has_vimapiver=1\n");
-#endif
-
/* XXX We really need to print the version of the dynamically
* linked library here, but VDDK does not provide it.
*/
@@ -337,9 +326,6 @@ vddk_open (int readonly)
#if HAVE_VIXDISKLIBCONNECTPARAMS_NFCHOSTPORT
params.nfcHostPort = nfc_host_port;
#endif
-#if HAVE_VIXDISKLIBCONNECTPARAMS_VIMAPIVER
- params.vimApiVer = (char *) vim_api_ver;
-#endif
}
/* XXX Some documentation suggests we should call
--
1.8.3.1

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

@ -0,0 +1,29 @@
From 1041402b8d919bd794ee0ca72017fa6e04d4675b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 24 Jul 2018 15:35:20 +0100
Subject: [PATCH] vddk: Add comment about my experiment with PrepareForAccess.
(cherry picked from commit ba593d2dfa3b3ccd4073f7bad7bcd2d67ce23b64)
---
plugins/vddk/vddk.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index 748f1b3..54b95fb 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -370,8 +370,9 @@ vddk_open (int readonly)
}
/* XXX Some documentation suggests we should call
- * VixDiskLib_PrepareForAccess here. However we need the true VM
- * name to do that.
+ * VixDiskLib_PrepareForAccess here. It may be required for
+ * Advanced Transport modes, but I could not make it work with
+ * either ESXi or vCenter servers.
*/
DEBUG_CALL ("VixDiskLib_ConnectEx",
--
1.8.3.1

@ -0,0 +1,50 @@
From 901f42bd3fc61af0a4b864d4961fc4b02bec0541 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 25 Jul 2018 09:10:03 +0100
Subject: [PATCH] vddk: Make dlsym variables static.
Fixes commit 8d7f7c26eb435334d7fa35e84ceee7d266dfae4c.
(cherry picked from commit 168364eff47004e64d0880516de5744fecaa8047)
---
plugins/vddk/vddk.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index 54b95fb..e8b1be5 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -48,19 +48,19 @@
/* The VDDK APIs that we call. These globals are initialized when the
* plugin is loaded (by vddk_load).
*/
-char *(*VixDiskLib_GetErrorText) (VixError err, const char *unused);
-void (*VixDiskLib_FreeErrorText) (char *text);
-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);
+static char *(*VixDiskLib_GetErrorText) (VixError err, const char *unused);
+static void (*VixDiskLib_FreeErrorText) (char *text);
+static 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);
void (*VixDiskLib_Exit) (void);
-VixError (*VixDiskLib_ConnectEx) (const VixDiskLibConnectParams *params, char read_only, const char *snapshot_ref, const char *transport_modes, VixDiskLibConnection *connection);
-VixError (*VixDiskLib_Open) (const VixDiskLibConnection connection, const char *path, uint32_t flags, VixDiskLibHandle *handle);
+static VixError (*VixDiskLib_ConnectEx) (const VixDiskLibConnectParams *params, char read_only, const char *snapshot_ref, const char *transport_modes, VixDiskLibConnection *connection);
+static VixError (*VixDiskLib_Open) (const VixDiskLibConnection connection, const char *path, uint32_t flags, VixDiskLibHandle *handle);
const char *(*VixDiskLib_GetTransportMode) (VixDiskLibHandle handle);
-VixError (*VixDiskLib_Close) (VixDiskLibHandle handle);
-VixError (*VixDiskLib_Disconnect) (VixDiskLibConnection connection);
-VixError (*VixDiskLib_GetInfo) (VixDiskLibHandle handle, VixDiskLibInfo **info);
-void (*VixDiskLib_FreeInfo) (VixDiskLibInfo *info);
-VixError (*VixDiskLib_Read) (VixDiskLibHandle handle, uint64_t start_sector, uint64_t nr_sectors, unsigned char *buf);
-VixError (*VixDiskLib_Write) (VixDiskLibHandle handle, uint64_t start_sector, uint64_t nr_sectors, const unsigned char *buf);
+static VixError (*VixDiskLib_Close) (VixDiskLibHandle handle);
+static VixError (*VixDiskLib_Disconnect) (VixDiskLibConnection connection);
+static VixError (*VixDiskLib_GetInfo) (VixDiskLibHandle handle, VixDiskLibInfo **info);
+static void (*VixDiskLib_FreeInfo) (VixDiskLibInfo *info);
+static VixError (*VixDiskLib_Read) (VixDiskLibHandle handle, uint64_t start_sector, uint64_t nr_sectors, unsigned char *buf);
+static VixError (*VixDiskLib_Write) (VixDiskLibHandle handle, uint64_t start_sector, uint64_t nr_sectors, const unsigned char *buf);
/* Parameters passed to InitEx. */
#define VDDK_MAJOR 5
--
1.8.3.1

@ -0,0 +1,37 @@
From a4e54de2e1ddbf7bd52e2b2e9857402ad93d5286 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 25 Jul 2018 09:28:04 +0100
Subject: [PATCH] vddk: Improve error message if the proprietary library cannot
be found.
(cherry picked from commit 94e791f87c6029983befa6199771345fd9cdfcc9)
---
plugins/vddk/vddk.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index e8b1be5..67aaa61 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -142,12 +142,16 @@ error_function (const char *fs, va_list args)
static void
vddk_load (void)
{
- const char *soname = "libvixDiskLib.so.6";
+ static const char soname[] = "libvixDiskLib.so.6";
/* Load the plugin and set the entry points. */
dl = dlopen (soname, RTLD_NOW);
if (dl == NULL) {
- nbdkit_error ("%s: %s", soname, dlerror ());
+ nbdkit_error ("%s\n\n"
+ "If '%s' is located on a non-standard path you may need to\n"
+ "set $LD_LIBRARY_PATH or edit /etc/ld.so.conf.\n\n"
+ "See the nbdkit-vddk-plugin(1) man page for details.",
+ dlerror (), soname);
exit (EXIT_FAILURE);
}
--
1.8.3.1

@ -0,0 +1,79 @@
From 7aa9fbe2dc6ef46b4701f13584c88d657255bdbf Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 25 Jul 2018 09:28:32 +0100
Subject: [PATCH] vddk: If relative libdir parameter is passed, make it
absolute.
(cherry picked from commit 8838497c44d51f2c3ea12adad89fd836116af201)
---
plugins/vddk/nbdkit-vddk-plugin.pod | 3 +--
plugins/vddk/vddk.c | 14 ++++++++++----
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod
index ba7806d..57a039f 100644
--- a/plugins/vddk/nbdkit-vddk-plugin.pod
+++ b/plugins/vddk/nbdkit-vddk-plugin.pod
@@ -87,8 +87,7 @@ L</NOTES> below).
=item B<libdir=PATHNAME>
-Optional. This sets the path of the VMware VDDK distribution. It
-must be an absolute path.
+Optional. This sets the path of the VMware VDDK distribution.
VDDK uses this to load its own plugins, if this path is unspecified or
wrong then VDDK will work with reduced functionality.
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index 67aaa61..a8216fc 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -72,7 +72,7 @@ static int init_called = 0; /* was InitEx called */
static char *config = NULL; /* config */
static const char *cookie = NULL; /* cookie */
static const char *filename = NULL; /* file */
-static const char *libdir = VDDK_LIBDIR; /* libdir */
+static char *libdir = NULL; /* libdir */
static int nfc_host_port = 0; /* nfchostport */
static char *password = NULL; /* password */
static int port = 0; /* port */
@@ -180,6 +180,7 @@ vddk_unload (void)
if (dl)
dlclose (dl);
free (config);
+ free (libdir);
free (password);
}
@@ -205,7 +206,11 @@ vddk_config (const char *key, const char *value)
filename = value;
}
else if (strcmp (key, "libdir") == 0) {
- libdir = value;
+ /* See FILENAMES AND PATHS in nbdkit-plugin(3). */
+ free (libdir);
+ libdir = nbdkit_realpath (value);
+ if (!libdir)
+ return -1;
}
else if (strcmp (key, "nfchostport") == 0) {
if (sscanf (value, "%d", &nfc_host_port) != 1) {
@@ -296,12 +301,13 @@ vddk_config_complete (void)
/* Initialize VDDK library. */
DEBUG_CALL ("VixDiskLib_InitEx",
"%d, %d, &debug_fn, &error_fn, &error_fn, %s, %s",
- VDDK_MAJOR, VDDK_MINOR, libdir, config ? : "NULL");
+ VDDK_MAJOR, VDDK_MINOR,
+ libdir ? : VDDK_LIBDIR, config ? : "NULL");
err = VixDiskLib_InitEx (VDDK_MAJOR, VDDK_MINOR,
&debug_function, /* log function */
&error_function, /* warn function */
&error_function, /* panic function */
- libdir, config);
+ libdir ? : VDDK_LIBDIR, config);
if (err != VIX_OK) {
VDDK_ERROR (err, "VixDiskLib_InitEx");
exit (EXIT_FAILURE);
--
1.8.3.1

@ -0,0 +1,33 @@
From f44a56ae2818daf71851aab1c6e930b365ee9012 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 25 Jul 2018 14:02:32 +0100
Subject: [PATCH] vddk: Two more static dlsym variables.
Fixes commit 168364eff47004e64d0880516de5744fecaa8047
and commit 8d7f7c26eb435334d7fa35e84ceee7d266dfae4c.
(cherry picked from commit b776d1f5e59faef659f0d6e7fbffec614d58a368)
---
plugins/vddk/vddk.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index a8216fc..df7a7e0 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -51,10 +51,10 @@
static char *(*VixDiskLib_GetErrorText) (VixError err, const char *unused);
static void (*VixDiskLib_FreeErrorText) (char *text);
static 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);
-void (*VixDiskLib_Exit) (void);
+static void (*VixDiskLib_Exit) (void);
static VixError (*VixDiskLib_ConnectEx) (const VixDiskLibConnectParams *params, char read_only, const char *snapshot_ref, const char *transport_modes, VixDiskLibConnection *connection);
static VixError (*VixDiskLib_Open) (const VixDiskLibConnection connection, const char *path, uint32_t flags, VixDiskLibHandle *handle);
-const char *(*VixDiskLib_GetTransportMode) (VixDiskLibHandle handle);
+static const char *(*VixDiskLib_GetTransportMode) (VixDiskLibHandle handle);
static VixError (*VixDiskLib_Close) (VixDiskLibHandle handle);
static VixError (*VixDiskLib_Disconnect) (VixDiskLibConnection connection);
static VixError (*VixDiskLib_GetInfo) (VixDiskLibHandle handle, VixDiskLibInfo **info);
--
1.8.3.1

@ -0,0 +1,179 @@
From 80b83f39a8b365455880d8dabbcb86249c1ecd6b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 25 Jul 2018 14:09:58 +0100
Subject: [PATCH] vddk: Add a very simple test.
We cannot do anything like a real test without the proprietary
library. However by making a dummy library which contains some stub
functions we can test --dump-plugin output.
(cherry picked from commit 70f7227ecc9b7c8d628987cb12ca7541bf485d66)
---
tests/Makefile.am | 21 ++++++++++++++++++
tests/dummy-vddk.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/test-vddk.sh | 45 +++++++++++++++++++++++++++++++++++++++
3 files changed, 128 insertions(+)
create mode 100644 tests/dummy-vddk.c
create mode 100755 tests/test-vddk.sh
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c0c2155..2973268 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -75,6 +75,7 @@ EXTRA_DIST = \
test-random-sock.sh \
test-tls.sh \
test-tls-psk.sh \
+ test-vddk.sh \
test-version.sh \
test-version-filter.sh \
test-version-plugin.sh \
@@ -365,6 +366,26 @@ test_streaming_SOURCES = test-streaming.c test.h
test_streaming_CFLAGS = $(WARNINGS_CFLAGS) $(LIBGUESTFS_CFLAGS)
test_streaming_LDADD = libtest.la $(LIBGUESTFS_LIBS)
+# VDDK plugin test.
+# This only tests that the plugin can be loaded against a
+# dummy VDDK library, it is not a detailed test.
+
+# check_LTLIBRARIES won't build a shared library (see automake manual).
+# So we have to do this and add a dependency.
+noinst_LTLIBRARIES += libvixDiskLib.la
+TESTS += test-vddk.sh
+
+libvixDiskLib_la_SOURCES = \
+ dummy-vddk.c
+libvixDiskLib_la_CPPFLAGS = \
+ -I$(top_srcdir)/plugins/vddk
+libvixDiskLib_la_CXXFLAGS = \
+ $(WARNINGS_CFLAGS)
+# For use of the -rpath option, see:
+# https://lists.gnu.org/archive/html/libtool/2007-07/msg00067.html
+libvixDiskLib_la_LDFLAGS = \
+ -shared -version-number 6:0:0 -rpath /nowhere
+
# xz plugin test.
if HAVE_LIBLZMA
if HAVE_GUESTFISH
diff --git a/tests/dummy-vddk.c b/tests/dummy-vddk.c
new file mode 100644
index 0000000..e9069c9
--- /dev/null
+++ b/tests/dummy-vddk.c
@@ -0,0 +1,62 @@
+/* nbdkit
+ * Copyright (C) 2018 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Red Hat nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* This file pretends to be libvixDiskLib.so.6.
+ *
+ * In fact because we don't check the result from dlsym and because we
+ * only call a few APIs in the --dump-plugin path there are only a few
+ * stub functions needed.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "vddk-structs.h"
+
+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)
+{
+ /* Do nothing, only exit with no error. */
+ return VIX_OK;
+}
+
+void
+VixDiskLib_Exit (void)
+{
+ /* Do nothing. */
+}
diff --git a/tests/test-vddk.sh b/tests/test-vddk.sh
new file mode 100755
index 0000000..5ccfff1
--- /dev/null
+++ b/tests/test-vddk.sh
@@ -0,0 +1,45 @@
+#!/bin/bash -
+# nbdkit
+# Copyright (C) 2018 Red Hat Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Red Hat nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+set -x
+set -e
+
+rm -f test-vddk.out
+
+LD_LIBRARY_PATH=.libs:$LD_LIBRARY_PATH \
+nbdkit vddk --dump-plugin > test-vddk.out
+cat test-vddk.out
+
+grep ^vddk_default_libdir= test-vddk.out
+
+rm test-vddk.out
--
1.8.3.1

@ -0,0 +1,229 @@
From c713e3337d1227db68a4088096cd19ffed746e9f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 8 Aug 2018 13:50:23 +0100
Subject: [PATCH] python: Try harder to print the full traceback on error.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The tracebacks are compressed into a single line because we're using
PyObject_Str, but they are just about usable if not very readable.
For example you would see an error like this:
nbdkit: error: ./python-exception.py: config_complete: error: ['Traceback (most recent call last):\n', ' File "./python-exception.py", line 54, in config_complete\n raise_error1()\n', ' File "./python-exception.py", line 48, in raise_error1\n raise_error2()\n', ' File "./python-exception.py", line 45, in raise_error2\n raise RuntimeError("this is the test string")\n', 'RuntimeError: this is the test string\n']
which can be read by manually unfolding the exception in an editor as:
nbdkit: error: ./python-exception.py: config_complete: error:
Traceback (most recent call last):
File "./python-exception.py", line 54, in config_complete
raise_error1()
File "./python-exception.py", line 48, in raise_error1
raise_error2()
File "./python-exception.py", line 45, in raise_error2
raise RuntimeError("this is the test string")
RuntimeError: this is the test string
This also fixes the Python exception test:
(1) It originally was not testing anything. Adding set -e fixes
that.
(2) The valgrind test is always broken because of Python itself.
Skip the test under valgrind.
(3) This now tests both simple exceptions and full tracebacks.
Tested with Python 2.7.15 & 3.6.6.
(cherry picked from commit 72c0d64a47db642cafa89884f2ee554bd0b8e822)
---
plugins/python/python.c | 93 +++++++++++++++++++++++++++++++++++-------
tests/python-exception.py | 20 ++++++++-
tests/test-python-exception.sh | 20 ++++++++-
3 files changed, 117 insertions(+), 16 deletions(-)
diff --git a/plugins/python/python.c b/plugins/python/python.c
index 7eb91d7..ef1a2cf 100644
--- a/plugins/python/python.c
+++ b/plugins/python/python.c
@@ -129,27 +129,92 @@ python_to_string (PyObject *str)
return NULL;
}
+/* This is the fallback in case we cannot get the full traceback. */
+static void
+print_python_error (const char *callback, PyObject *error)
+{
+ PyObject *error_str;
+ char *error_cstr = NULL;
+
+ error_str = PyObject_Str (error);
+ error_cstr = python_to_string (error_str);
+ nbdkit_error ("%s: %s: error: %s",
+ script, callback,
+ error_cstr ? error_cstr : "<unknown>");
+ Py_DECREF (error_str);
+ free (error_cstr);
+}
+
+/* Convert the Python traceback to a string and call nbdkit_error.
+ * https://stackoverflow.com/a/15907460/7126113
+ */
+static int
+print_python_traceback (const char *callback,
+ PyObject *type, PyObject *error, PyObject *traceback)
+{
+ PyObject *module_name, *traceback_module, *format_exception_fn, *rv,
+ *traceback_str;
+ char *traceback_cstr;
+
+#ifdef HAVE_PYSTRING_FROMSTRING
+ module_name = PyString_FromString ("traceback");
+#else
+ module_name = PyUnicode_FromString ("traceback");
+#endif
+ traceback_module = PyImport_Import (module_name);
+ Py_DECREF (module_name);
+
+ /* couldn't 'import traceback' */
+ if (traceback_module == NULL)
+ return -1;
+
+ format_exception_fn = PyObject_GetAttrString (traceback_module,
+ "format_exception");
+ if (format_exception_fn == NULL)
+ return -1;
+ if (!PyCallable_Check (format_exception_fn))
+ return -1;
+
+ rv = PyObject_CallFunctionObjArgs (format_exception_fn,
+ type, error, traceback, NULL);
+ traceback_str = PyObject_Str (rv);
+ Py_DECREF (rv);
+ traceback_cstr = python_to_string (traceback_str);
+ if (traceback_cstr == NULL) {
+ Py_DECREF (traceback_str);
+ return -1;
+ }
+
+ nbdkit_error ("%s: %s: error: %s",
+ script, callback,
+ traceback_cstr);
+ Py_DECREF (traceback_str);
+ free (traceback_cstr);
+
+ /* This means we succeeded in calling nbdkit_error. */
+ return 0;
+}
+
static int
check_python_failure (const char *callback)
{
if (PyErr_Occurred ()) {
- PyObject *type, *error, *traceback, *error_str;
- char *error_cstr;
+ PyObject *type, *error, *traceback;
- /* Convert the Python exception to a string.
- * https://stackoverflow.com/a/1418703
- * But forget about the traceback, it's very hard to print.
- * https://stackoverflow.com/q/1796510
- */
PyErr_Fetch (&type, &error, &traceback);
PyErr_NormalizeException (&type, &error, &traceback);
- error_str = PyObject_Str (error);
- error_cstr = python_to_string (error_str);
- nbdkit_error ("%s: %s: error: %s",
- script, callback,
- error_cstr ? error_cstr : "<unknown>");
- Py_DECREF (error_str);
- free (error_cstr);
+
+ /* Try to print the full traceback. */
+ if (print_python_traceback (callback, type, error, traceback) == -1) {
+ /* Couldn't do that, so fall back to converting the Python error
+ * to a string.
+ */
+ print_python_error (callback, error);
+ }
+
+ /* In all cases this returns -1 to indicate that a Python error
+ * occurred.
+ */
return -1;
}
return 0;
diff --git a/tests/python-exception.py b/tests/python-exception.py
index 1debf51..739057f 100644
--- a/tests/python-exception.py
+++ b/tests/python-exception.py
@@ -32,10 +32,28 @@
# A dummy python plugin which just raises an exception in config_complete.
+test = "simple"
-def config_complete():
+def config(k, v):
+ global test
+ if k == "test":
+ test = v
+ else:
+ raise RuntimeError("unknown config parameter")
+
+def raise_error2():
raise RuntimeError("this is the test string")
+def raise_error1():
+ raise_error2()
+
+def config_complete():
+ if test == "simple":
+ raise RuntimeError("this is the test string")
+ elif test == "traceback":
+ raise_error1()
+ else:
+ raise RuntimeError("unknown test")
def open(readonly):
return 1
diff --git a/tests/test-python-exception.sh b/tests/test-python-exception.sh
index 83999af..fd94827 100755
--- a/tests/test-python-exception.sh
+++ b/tests/test-python-exception.sh
@@ -31,12 +31,30 @@
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
+set -e
+set -x
+
+# Python language leaks like a sieve as well as a lot of worrying
+# "Conditional jump or move depends on uninitialised value(s)".
+if test -n "$NBDKIT_VALGRIND"; then
+ echo "$0: skipping Python test under valgrind."
+ exit 77
+fi
+
output=test-python-exception.out
rm -f $output
-nbdkit -f -v python ./python-exception.py > $output 2>&1 ||:
+nbdkit -f -v python ./python-exception.py test=simple > $output 2>&1 ||:
+cat $output
grep 'this is the test string' $output
+nbdkit -f -v python ./python-exception.py test=traceback > $output 2>&1 ||:
+cat $output
+
+grep 'raise_error1' $output
+grep 'raise_error2' $output
+grep 'this is the test string' $output
+
rm $output
--
1.8.3.1

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIcBAABAgAGBQJbYeqVAAoJEJFzj3Pht2ig7A8P/3KbLzc8T0Nkjky1oJytaKU9
uOJyyma0AGW9WtWJ7Xe3xOAh89B8o6rq4eVv4TTHL1stxCuurv/eObOUBvRyFZd0
QV5ptkvK2B3Kwbtki67p+nzoYs7fxdsQ2sC0J9vfAiAk2b0eDVXlJO/Xqy+SKxnQ
Dr+iKI63cFaVyrAAc4H7kYd9Fxx1h47WW4HfSxb3EHZB8fUijQ6gq/LybFslm5Zc
vXWaq26ngb+4U7uaU/rdV2NfLoql1pKHcdnmb8e+CuE/HXIfGHyiT2mrYhQpPPwP
RXaMl1bZtOvM5CdyLxOUATPhsGMpYR+7DvOQrjV3ovsjB6/hIQOxy6iCwqe8tSOb
ZYc/AXbv/1FwGkJDVh+0Pi8RiF5GQHktMJsFV91zkw2fzSFHkdEXITcsrp+SaweJ
FEH5LfJkRe6ir0cKiWl+VYN0SbLQjrE/BsZdr9+vBbGDalBJQl8xJ53g5yMEoKTx
ksQQ+czJPbYlj9F9lyMMcncztxiPMIgcsZ81flWlmX2PfoWCEgD2A1e6cR3HWixF
fFW4Ya6gQMZ/3KzaHt7X3nDGpTg5bEJNvegIGC5XZiUCTZ8Uxn5d9DE4EEFQa2un
NRHSZgYP6+cvncs8OQiCrZtf+15e4q8wV8X+J8xXhpXmnTnJM/F9g+zqs4+eFTMq
+i/bx8RPkXTXtbg6x48W
=stIl
-----END PGP SIGNATURE-----

@ -0,0 +1,732 @@
%global _hardened_build 1
%ifarch aarch64 %{arm} %{ix86} x86_64 ppc %{power64}
%global have_libguestfs 1
%endif
# Architectures where the complete test suite must pass.
#
# On all other architectures, a simpler test suite must pass. This
# omits any tests that run full qemu, since running qemu under TCG is
# often broken on non-x86_64 arches.
%global complete_test_arches x86_64
# If we should verify tarball signature with GPGv2.
%global verify_tarball_signature 1
# If there are patches which touch autotools files, set this to 1.
%global patches_touch_autotools 1
# The source directory.
%global source_directory 1.4-stable
Name: nbdkit
Version: 1.4.2
Release: 4%{?dist}
Summary: NBD server
License: BSD
URL: https://github.com/libguestfs/nbdkit
Source0: http://libguestfs.org/download/nbdkit/%{source_directory}/%{name}-%{version}.tar.gz
%if 0%{verify_tarball_signature}
Source1: http://libguestfs.org/download/nbdkit/%{source_directory}/%{name}-%{version}.tar.gz.sig
# Keyring used to verify tarball signature.
Source2: libguestfs.keyring
%endif
# Patches come from:
# https://github.com/libguestfs/nbdkit/tree/rhel-8.0
# Patches.
Patch0001: 0001-vddk-Remove-vimapiver-parameter.patch
Patch0002: 0002-vddk-Remove-compile-time-dependency-on-VDDK-library.patch
Patch0003: 0003-vddk-Add-comment-about-my-experiment-with-PrepareFor.patch
Patch0004: 0004-vddk-Make-dlsym-variables-static.patch
Patch0005: 0005-vddk-Improve-error-message-if-the-proprietary-librar.patch
Patch0006: 0006-vddk-If-relative-libdir-parameter-is-passed-make-it-.patch
Patch0007: 0007-vddk-Two-more-static-dlsym-variables.patch
Patch0008: 0008-vddk-Add-a-very-simple-test.patch
Patch0009: 0009-python-Try-harder-to-print-the-full-traceback-on-err.patch
%if 0%{patches_touch_autotools}
BuildRequires: autoconf, automake, libtool
%endif
%if 0%{?rhel} == 8
# On RHEL 8, we cannot build the package on i686 (no virt stack).
ExcludeArch: i686
%endif
%ifnarch %{complete_test_arches}
BuildRequires: autoconf, automake, libtool
%endif
BuildRequires: /usr/bin/pod2man
BuildRequires: gnutls-devel
BuildRequires: libselinux-devel
%if 0%{?have_libguestfs}
BuildRequires: libguestfs-devel
%endif
BuildRequires: libvirt-devel
BuildRequires: xz-devel
BuildRequires: zlib-devel
BuildRequires: bash-completion
BuildRequires: perl-devel
BuildRequires: perl(ExtUtils::Embed)
BuildRequires: python3-devel
%if 0%{verify_tarball_signature}
BuildRequires: gnupg2
%endif
# Only for running the test suite:
BuildRequires: /usr/bin/certtool
BuildRequires: /usr/bin/qemu-img
BuildRequires: /usr/bin/socat
BuildRequires: /usr/sbin/ss
%description
NBD is a protocol for accessing block devices (hard disks and
disk-like things) over the network.
'nbdkit' is a toolkit for creating NBD servers.
The key features are:
* Multithreaded NBD server written in C with good performance.
* Well-documented, simple plugin API with a stable ABI guarantee.
Allows you to export "unconventional" block devices easily.
* Liberal license (BSD) allows nbdkit to be linked to proprietary
libraries or included in proprietary code.
You probably want to install one of more plugins (%{name}-plugin-*).
To develop plugins, install the %{name}-devel package and start by
reading the nbdkit(1) and nbdkit-plugin(3) manual pages.
%package basic-plugins
Summary: Basic plugins for %{name}
License: BSD
Requires: %{name}%{?_isa} = %{version}-%{release}
# For upgrade path, remove these in Fedora 30.
Obsoletes: %{name}-plugin-file < 1.1.19-1
Obsoletes: %{name}-plugin-nbd < 1.1.19-1
Obsoletes: %{name}-plugin-streaming < 1.1.19-1
%description basic-plugins
This package contains some basic plugins for %{name} which have only
trivial dependencies.
* nbdkit-file-plugin
A file serving plugin.
* nbdkit-memory-plugin
A virtual memory plugin.
* nbdkit-nbd-plugin
An NBD forwarding plugin.
It provides an NBD server that forwards all traffic as a client to
another existing NBD server. A primary usage of this setup is to
alter the set of features available to the ultimate end client,
without having to change the original server (for example, to
convert between oldstyle and newtyle, or to add TLS support where
the original server lacks it).
* nbdkit-null-plugin
A null (bitbucket) plugin.
* nbdkit-random-plugin
Random content plugin for testing.
* nbdkit-split-plugin
Concatenate one or more files into a single virtual disk.
* nbdkit-streaming-plugin
A streaming file serving plugin.
* nbdkit-zero-plugin
Zero-length plugin for testing.
%package example-plugins
Summary: Example plugins for %{name}
License: BSD
Requires: %{name}%{?_isa} = %{version}-%{release}
# For upgrade path, remove this in Fedora 30.
Obsoletes: %{name}-plugin-examples < 1.1.19-1
%description example-plugins
This package contains example plugins for %{name}.
# The plugins below have non-trivial dependencies are so are
# packaged separately.
%package plugin-gzip
Summary: GZip file serving plugin for %{name}
License: BSD
Requires: %{name}%{?_isa} = %{version}-%{release}
%description plugin-gzip
This package is a gzip file serving plugin for %{name}.
%package plugin-python-common
Summary: Python 2 and 3 plugin common files for %{name}
License: BSD
Requires: %{name}%{?_isa} = %{version}-%{release}
%description plugin-python-common
This package contains common files for Python %{name} plugins.
You should not install this package directly. Instead install
%{name}-plugin-python3.
%package plugin-python3
Summary: Python 3 plugin for %{name}
License: BSD
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: %{name}-plugin-python-common = %{version}-%{release}
%description plugin-python3
This package lets you write Python 3 plugins for %{name}.
%ifarch %{ix86} x86_64
%package plugin-vddk
Summary: VMware VDDK plugin for %{name}
License: BSD
Requires: %{name}%{?_isa} = %{version}-%{release}
%description plugin-vddk
This package is a plugin for %{name} which connects to
VMware VDDK for accessing VMware disks and servers.
%endif
%package plugin-xz
Summary: XZ file serving plugin for %{name}
License: BSD
Requires: %{name}%{?_isa} = %{version}-%{release}
%description plugin-xz
This package is a xz file serving plugin for %{name}.
%package devel
Summary: Development files and documentation for %{name}
License: BSD
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: pkgconfig
%description devel
This package contains development files and documentation
for %{name}. Install this package if you want to develop
plugins for %{name}.
%package bash-completion
Summary: Bash tab-completion for %{name}
BuildArch: noarch
Requires: bash-completion >= 2.0
Requires: %{name} = %{version}-%{release}
%description bash-completion
Install this package if you want intelligent bash tab-completion
for %{name}.
%prep
%if 0%{verify_tarball_signature}
tmphome="$(mktemp -d)"
gpgv2 --homedir "$tmphome" --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0}
%endif
%autosetup -p1
%if 0%{patches_touch_autotools}
autoreconf -i
%endif
%ifnarch %{complete_test_arches}
# Simplify the test suite so it doesn't require qemu.
sed -i -e '/^if HAVE_LIBGUESTFS/,/^endif HAVE_LIBGUESTFS/d' tests/Makefile.am
sed -i -e '/^if HAVE_GUESTFISH/,/^endif HAVE_GUESTFISH/d' tests/Makefile.am
autoreconf -i
%endif
%build
export PYTHON=%{__python3}
%configure --disable-static \
--with-tls-priority=@NBDKIT,SYSTEM \
--disable-perl \
--disable-ocaml \
--disable-ruby \
--disable-tcl \
--without-curl \
--without-libvirt \
--without-libguestfs
# Verify that it picked the correct version of Python
# to avoid RHBZ#1404631 happening again silently.
grep '^PYTHON_VERSION = 3' Makefile
make %{?_smp_mflags}
unset PYTHON
%install
%make_install
pushd $RPM_BUILD_ROOT%{_libdir}/nbdkit/plugins/
mv nbdkit-python-plugin.so nbdkit-python3-plugin.so
popd
# Disable built-in filters but leave the empty directory.
rm -r $RPM_BUILD_ROOT%{_libdir}/%{name}/filters/nbdkit-*-filter.so
rm -r $RPM_BUILD_ROOT%{_mandir}/man1/nbdkit-*-filter.1*
# Delete libtool crap.
find $RPM_BUILD_ROOT -name '*.la' -delete
# Delete the VDDK plugin on !x86 architectures since it is not
# applicable there.
%ifnarch %{ix86} x86_64
rm $RPM_BUILD_ROOT%{_libdir}/%{name}/plugins/nbdkit-vddk-plugin.so
rm $RPM_BUILD_ROOT%{_mandir}/man1/nbdkit-vddk-plugin.1*
%endif
%check
# Workaround for broken libvirt (RHBZ#1138604).
mkdir -p $HOME/.cache/libvirt
# Make sure we can see the debug messages (RHBZ#1230160).
export LIBGUESTFS_DEBUG=1
export LIBGUESTFS_TRACE=1
make check -j1 || {
cat tests/test-suite.log
exit 1
}
%files
%doc README
%license LICENSE
%{_sbindir}/nbdkit
%dir %{_libdir}/%{name}
%dir %{_libdir}/%{name}/plugins
%dir %{_libdir}/%{name}/filters
%{_mandir}/man1/nbdkit.1*
%files basic-plugins
%doc README
%license LICENSE
%{_libdir}/%{name}/plugins/nbdkit-file-plugin.so
%{_libdir}/%{name}/plugins/nbdkit-memory-plugin.so
%{_libdir}/%{name}/plugins/nbdkit-nbd-plugin.so
%{_libdir}/%{name}/plugins/nbdkit-null-plugin.so
%{_libdir}/%{name}/plugins/nbdkit-random-plugin.so
%{_libdir}/%{name}/plugins/nbdkit-split-plugin.so
%{_libdir}/%{name}/plugins/nbdkit-streaming-plugin.so
%{_libdir}/%{name}/plugins/nbdkit-zero-plugin.so
%{_mandir}/man1/nbdkit-file-plugin.1*
%{_mandir}/man1/nbdkit-memory-plugin.1*
%{_mandir}/man1/nbdkit-nbd-plugin.1*
%{_mandir}/man1/nbdkit-null-plugin.1*
%{_mandir}/man1/nbdkit-random-plugin.1*
%{_mandir}/man1/nbdkit-split-plugin.1*
%{_mandir}/man1/nbdkit-streaming-plugin.1*
%{_mandir}/man1/nbdkit-zero-plugin.1*
%files example-plugins
%doc README
%license LICENSE
%{_libdir}/%{name}/plugins/nbdkit-example*-plugin.so
%{_mandir}/man1/nbdkit-example*-plugin.1*
%files plugin-gzip
%doc README
%license LICENSE
%{_libdir}/%{name}/plugins/nbdkit-gzip-plugin.so
%{_mandir}/man1/nbdkit-gzip-plugin.1*
%files plugin-python-common
%doc README
%license LICENSE
%{_mandir}/man3/nbdkit-python-plugin.3*
%files plugin-python3
%{_libdir}/%{name}/plugins/nbdkit-python3-plugin.so
%ifarch %{ix86} x86_64
%files plugin-vddk
%doc README
%license LICENSE
%{_libdir}/%{name}/plugins/nbdkit-vddk-plugin.so
%{_mandir}/man1/nbdkit-vddk-plugin.1*
%endif
%files plugin-xz
%doc README
%license LICENSE
%{_libdir}/%{name}/plugins/nbdkit-xz-plugin.so
%{_mandir}/man1/nbdkit-xz-plugin.1*
%files devel
%doc OTHER_PLUGINS README TODO
%license LICENSE