import nbdkit-1.16.2-4.module+el8.3.0+6922+fd575af8

c8-stream-rhel imports/c8-stream-rhel/nbdkit-1.16.2-4.module+el8.3.0+6922+fd575af8
CentOS Sources 3 years ago committed by Andrew Lukoshko
parent 63ffbeb99a
commit 003a44a973

2
.gitignore vendored

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

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

@ -0,0 +1,75 @@
From d7836fb0a7131c725e3c02be7e48e99c671637c3 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 12 Dec 2019 08:57:15 +0000
Subject: [PATCH 01/19] server: Allow -D nbdkit.* debug flags for the core
server.
These work like plugin/filter debug flags, but apply to the internals
of the server.
(cherry picked from commit 3b45db234a691f8ff926a6fef583e11c3601f112)
---
docs/nbdkit.pod | 7 +++++++
docs/synopsis.txt | 2 +-
server/main.c | 3 +++
server/nbdkit.syms | 2 ++
4 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/docs/nbdkit.pod b/docs/nbdkit.pod
index a2e72b13..346d8332 100644
--- a/docs/nbdkit.pod
+++ b/docs/nbdkit.pod
@@ -177,6 +177,13 @@ Display brief command line usage information and exit.
Set the plugin or filter Debug Flag called C<FLAG> to the integer
value C<N>. See L<nbdkit-plugin(3)/Debug Flags>.
+=item B<-D> nbdkit.FLAG=N
+
+=item B<--debug> nbdkit.FLAG=N
+
+Set the nbdkit server Debug Flag called C<FLAG> to the integer value
+C<N>.
+
=item B<--dump-config>
Dump out the compile-time configuration values and exit.
diff --git a/docs/synopsis.txt b/docs/synopsis.txt
index 3c239373..c3675422 100644
--- a/docs/synopsis.txt
+++ b/docs/synopsis.txt
@@ -1,4 +1,4 @@
-nbdkit [-D|--debug PLUGIN|FILTER.FLAG=N]
+nbdkit [-D|--debug PLUGIN|FILTER|nbdkit.FLAG=N]
[-e|--exportname EXPORTNAME] [--exit-with-parent]
[--filter FILTER ...] [-f|--foreground]
[-g|--group GROUP] [-i|--ipaddr IPADDR]
diff --git a/server/main.c b/server/main.c
index d39941b1..11ba1e6d 100644
--- a/server/main.c
+++ b/server/main.c
@@ -563,6 +563,9 @@ main (int argc, char *argv[])
free (t);
}
+ /* Apply nbdkit.* flags for the server. */
+ apply_debug_flags (NULL, "nbdkit");
+
/* Check all debug flags were used, and free them. */
free_debug_flags ();
diff --git a/server/nbdkit.syms b/server/nbdkit.syms
index 390972e2..96c22c07 100644
--- a/server/nbdkit.syms
+++ b/server/nbdkit.syms
@@ -67,6 +67,8 @@
nbdkit_vdebug;
nbdkit_verror;
+ nbdkit_debug_*;
+
# Everything else is hidden.
local: *;
};
--
2.18.2

@ -1,117 +0,0 @@
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,67 @@
From e5d2d44fff9214725506cbc84e7b3c035ec0eae9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 12 Dec 2019 11:06:36 +0000
Subject: [PATCH 02/19] server: Allow -D debug flags to contain dots for
namespacing.
This is just a convenience. Either of:
-D myplugin.foo_bar=1
-D myplugin.foo.bar=1
correspond to the same plugin variable "myplugin_debug_foo_bar".
(cherry picked from commit a895fa84aaa50f52af68319523020046394c789f)
---
docs/nbdkit-plugin.pod | 8 ++++++++
server/debug-flags.c | 10 +++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/docs/nbdkit-plugin.pod b/docs/nbdkit-plugin.pod
index b69cb825..879ddf09 100644
--- a/docs/nbdkit-plugin.pod
+++ b/docs/nbdkit-plugin.pod
@@ -1298,6 +1298,14 @@ You should only use this feature for debug settings. For general
settings use ordinary plugin parameters. Debug Flags can only be C
ints. They are not supported by non-C language plugins.
+For convenience C<'.'> characters are replaced with C<'_'> characters
+in the variable name, so both of these parameters:
+
+ -D myplugin.foo_bar=1
+ -D myplugin.foo.bar=1
+
+correspond to the plugin variable C<myplugin_debug_foo_bar>.
+
=head1 INSTALLING THE PLUGIN
The plugin is a C<*.so> file and possibly a manual page. You can of
diff --git a/server/debug-flags.c b/server/debug-flags.c
index 9344d85c..5e06f5ed 100644
--- a/server/debug-flags.c
+++ b/server/debug-flags.c
@@ -56,12 +56,20 @@ static char *
symbol_of_debug_flag (const char *name, const char *flag)
{
char *var;
+ size_t i;
+ int len;
- if (asprintf (&var, "%s_debug_%s", name, flag) == -1) {
+ if ((len = asprintf (&var, "%s_debug_%s", name, flag)) == -1) {
perror ("asprintf");
exit (EXIT_FAILURE);
}
+ /* If there are any '.'s remaining in the name, convert them to '_'. */
+ for (i = 0; i < (size_t) len; ++i) {
+ if (var[i] == '.')
+ var[i] = '_';
+ }
+
return var; /* caller frees */
}
--
2.18.2

@ -1,600 +0,0 @@
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,451 @@
From 83c72d9bf9d6a9ccf6939b4ebd0028b62673a78a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 12 Dec 2019 10:57:52 +0000
Subject: [PATCH 03/19] server: Add -D nbdkit.backend.controlpath and -D
nbdkit.backend.datapath.
These can be used to suppress verbose debugging messages from the
backend.
BugLink: https://bugzilla.redhat.com/1782868
Cherry picked from commit 231717e8cd5f27d76631be6651062d5a5ccf7fdc.
Remove use of nofilter from the test.
---
docs/nbdkit.pod | 35 ++++++++++++-
server/backend.c | 83 ++++++++++++++++++------------
tests/Makefile.am | 4 ++
tests/test-nbdkit-backend-debug.sh | 70 +++++++++++++++++++++++++
4 files changed, 158 insertions(+), 34 deletions(-)
create mode 100755 tests/test-nbdkit-backend-debug.sh
diff --git a/docs/nbdkit.pod b/docs/nbdkit.pod
index 346d8332..38e6bfca 100644
--- a/docs/nbdkit.pod
+++ b/docs/nbdkit.pod
@@ -182,7 +182,7 @@ value C<N>. See L<nbdkit-plugin(3)/Debug Flags>.
=item B<--debug> nbdkit.FLAG=N
Set the nbdkit server Debug Flag called C<FLAG> to the integer value
-C<N>.
+C<N>. See L</SERVER DEBUG FLAGS> below.
=item B<--dump-config>
@@ -527,6 +527,39 @@ languages. The file should be executable. For example:
(see L<nbdkit-perl-plugin(3)> for a full example).
+=head1 SERVER DEBUG FLAGS
+
+As well as enabling or disabling debugging in the server using
+I<--verbose> you can control extra debugging in the server using the
+C<-D nbdkit.*> flags listed in this section. Note these flags are an
+internal implementation detail of the server and may be changed or
+removed at any time in the future.
+
+=over 4
+
+=item B<-D nbdkit.backend.controlpath=0>
+
+=item B<-D nbdkit.backend.controlpath=1>
+
+=item B<-D nbdkit.backend.datapath=0>
+
+=item B<-D nbdkit.backend.datapath=1>
+
+These flags control the verbosity of nbdkit backend debugging messages
+(the ones which show every request processed by the server). The
+default for both settings is C<1> (normal debugging) but you can set
+them to C<0> to suppress these messages.
+
+C<-D nbdkit.backend.datapath=0> is the more useful setting which lets you
+suppress messages about pread, pwrite, zero, trim, etc. commands.
+When transferring large amounts of data these messages are numerous
+and not usually very interesting.
+
+C<-D nbdkit.backend.controlpath=0> suppresses the non-datapath
+commands (config, open, close, can_write, etc.)
+
+=back
+
=head1 SIGNALS
nbdkit responds to the following signals:
diff --git a/server/backend.c b/server/backend.c
index b9fe2a21..208c07b1 100644
--- a/server/backend.c
+++ b/server/backend.c
@@ -46,6 +46,22 @@
/* Helpers for registering a new backend. */
+/* Use:
+ * -D nbdkit.backend.controlpath=0 to suppress control path debugging.
+ * -D nbdkit.backend.datapath=0 to suppress data path debugging.
+ */
+int nbdkit_debug_backend_controlpath = 1;
+int nbdkit_debug_backend_datapath = 1;
+
+#define controlpath_debug(fs, ...) \
+ do { \
+ if (nbdkit_debug_backend_controlpath) debug ((fs), ##__VA_ARGS__); \
+ } while (0)
+#define datapath_debug(fs, ...) \
+ do { \
+ if (nbdkit_debug_backend_datapath) debug ((fs), ##__VA_ARGS__); \
+ } while (0)
+
void
backend_init (struct backend *b, struct backend *next, size_t index,
const char *filename, void *dl, const char *type)
@@ -108,7 +124,7 @@ backend_load (struct backend *b, const char *name, void (*load) (void))
apply_debug_flags (b->dl, name);
/* Call the on-load callback if it exists. */
- debug ("%s: load", name);
+ controlpath_debug ("%s: load", name);
if (load)
load ();
}
@@ -121,7 +137,7 @@ backend_unload (struct backend *b, void (*unload) (void))
*/
lock_unload ();
- debug ("%s: unload %s", b->name, b->type);
+ controlpath_debug ("%s: unload %s", b->name, b->type);
if (unload)
unload ();
@@ -139,7 +155,7 @@ backend_open (struct backend *b, struct connection *conn, int readonly)
{
struct b_conn_handle *h = &conn->handles[b->i];
- debug ("%s: open readonly=%d", b->name, readonly);
+ controlpath_debug ("%s: open readonly=%d", b->name, readonly);
assert (h->handle == NULL);
assert ((h->state & HANDLE_OPEN) == 0);
@@ -151,7 +167,7 @@ backend_open (struct backend *b, struct connection *conn, int readonly)
* inner-to-outer ordering.
*/
h->handle = b->open (b, conn, readonly);
- debug ("%s: open returned handle %p", b->name, h->handle);
+ controlpath_debug ("%s: open returned handle %p", b->name, h->handle);
if (h->handle == NULL) {
if (b->i) /* Do not strand backend if this layer failed */
@@ -179,7 +195,7 @@ backend_prepare (struct backend *b, struct connection *conn)
if (b->i && backend_prepare (b->next, conn) == -1)
return -1;
- debug ("%s: prepare readonly=%d", b->name, h->can_write == 0);
+ controlpath_debug ("%s: prepare readonly=%d", b->name, h->can_write == 0);
if (b->prepare (b, conn, h->handle, h->can_write == 0) == -1)
return -1;
@@ -196,7 +212,7 @@ backend_finalize (struct backend *b, struct connection *conn)
* filter furthest away from the plugin, and matching .close order.
*/
- debug ("%s: finalize", b->name);
+ controlpath_debug ("%s: finalize", b->name);
/* Once finalize fails, we can do nothing further on this connection */
if (h->state & HANDLE_FAILED)
@@ -223,7 +239,7 @@ backend_close (struct backend *b, struct connection *conn)
struct b_conn_handle *h = &conn->handles[b->i];
/* outer-to-inner order, opposite .open */
- debug ("%s: close", b->name);
+ controlpath_debug ("%s: close", b->name);
if (h->handle) {
assert (h->state & HANDLE_OPEN);
@@ -252,7 +268,7 @@ backend_valid_range (struct backend *b, struct connection *conn,
int
backend_reopen (struct backend *b, struct connection *conn, int readonly)
{
- debug ("%s: reopen readonly=%d", b->name, readonly);
+ controlpath_debug ("%s: reopen readonly=%d", b->name, readonly);
if (backend_finalize (b, conn) == -1)
return -1;
@@ -274,7 +290,7 @@ backend_get_size (struct backend *b, struct connection *conn)
{
struct b_conn_handle *h = &conn->handles[b->i];
- debug ("%s: get_size", b->name);
+ controlpath_debug ("%s: get_size", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->exportsize == -1)
@@ -287,7 +303,7 @@ backend_can_write (struct backend *b, struct connection *conn)
{
struct b_conn_handle *h = &conn->handles[b->i];
- debug ("%s: can_write", b->name);
+ controlpath_debug ("%s: can_write", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->can_write == -1)
@@ -300,7 +316,7 @@ backend_can_flush (struct backend *b, struct connection *conn)
{
struct b_conn_handle *h = &conn->handles[b->i];
- debug ("%s: can_flush", b->name);
+ controlpath_debug ("%s: can_flush", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->can_flush == -1)
@@ -313,7 +329,7 @@ backend_is_rotational (struct backend *b, struct connection *conn)
{
struct b_conn_handle *h = &conn->handles[b->i];
- debug ("%s: is_rotational", b->name);
+ controlpath_debug ("%s: is_rotational", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->is_rotational == -1)
@@ -327,7 +343,7 @@ backend_can_trim (struct backend *b, struct connection *conn)
struct b_conn_handle *h = &conn->handles[b->i];
int r;
- debug ("%s: can_trim", b->name);
+ controlpath_debug ("%s: can_trim", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->can_trim == -1) {
@@ -347,7 +363,7 @@ backend_can_zero (struct backend *b, struct connection *conn)
struct b_conn_handle *h = &conn->handles[b->i];
int r;
- debug ("%s: can_zero", b->name);
+ controlpath_debug ("%s: can_zero", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->can_zero == -1) {
@@ -367,7 +383,7 @@ backend_can_fast_zero (struct backend *b, struct connection *conn)
struct b_conn_handle *h = &conn->handles[b->i];
int r;
- debug ("%s: can_fast_zero", b->name);
+ controlpath_debug ("%s: can_fast_zero", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->can_fast_zero == -1) {
@@ -386,7 +402,7 @@ backend_can_extents (struct backend *b, struct connection *conn)
{
struct b_conn_handle *h = &conn->handles[b->i];
- debug ("%s: can_extents", b->name);
+ controlpath_debug ("%s: can_extents", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->can_extents == -1)
@@ -400,7 +416,7 @@ backend_can_fua (struct backend *b, struct connection *conn)
struct b_conn_handle *h = &conn->handles[b->i];
int r;
- debug ("%s: can_fua", b->name);
+ controlpath_debug ("%s: can_fua", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->can_fua == -1) {
@@ -420,7 +436,7 @@ backend_can_multi_conn (struct backend *b, struct connection *conn)
struct b_conn_handle *h = &conn->handles[b->i];
assert (h->handle && (h->state & HANDLE_CONNECTED));
- debug ("%s: can_multi_conn", b->name);
+ controlpath_debug ("%s: can_multi_conn", b->name);
if (h->can_multi_conn == -1)
h->can_multi_conn = b->can_multi_conn (b, conn, h->handle);
@@ -432,7 +448,7 @@ backend_can_cache (struct backend *b, struct connection *conn)
{
struct b_conn_handle *h = &conn->handles[b->i];
- debug ("%s: can_cache", b->name);
+ controlpath_debug ("%s: can_cache", b->name);
assert (h->handle && (h->state & HANDLE_CONNECTED));
if (h->can_cache == -1)
@@ -451,8 +467,8 @@ backend_pread (struct backend *b, struct connection *conn,
assert (h->handle && (h->state & HANDLE_CONNECTED));
assert (backend_valid_range (b, conn, offset, count));
assert (flags == 0);
- debug ("%s: pread count=%" PRIu32 " offset=%" PRIu64,
- b->name, count, offset);
+ datapath_debug ("%s: pread count=%" PRIu32 " offset=%" PRIu64,
+ b->name, count, offset);
r = b->pread (b, conn, h->handle, buf, count, offset, flags, err);
if (r == -1)
@@ -475,8 +491,8 @@ backend_pwrite (struct backend *b, struct connection *conn,
assert (!(flags & ~NBDKIT_FLAG_FUA));
if (fua)
assert (h->can_fua > NBDKIT_FUA_NONE);
- debug ("%s: pwrite count=%" PRIu32 " offset=%" PRIu64 " fua=%d",
- b->name, count, offset, fua);
+ datapath_debug ("%s: pwrite count=%" PRIu32 " offset=%" PRIu64 " fua=%d",
+ b->name, count, offset, fua);
r = b->pwrite (b, conn, h->handle, buf, count, offset, flags, err);
if (r == -1)
@@ -494,7 +510,7 @@ backend_flush (struct backend *b, struct connection *conn,
assert (h->handle && (h->state & HANDLE_CONNECTED));
assert (h->can_flush == 1);
assert (flags == 0);
- debug ("%s: flush", b->name);
+ datapath_debug ("%s: flush", b->name);
r = b->flush (b, conn, h->handle, flags, err);
if (r == -1)
@@ -518,8 +534,8 @@ backend_trim (struct backend *b, struct connection *conn,
assert (!(flags & ~NBDKIT_FLAG_FUA));
if (fua)
assert (h->can_fua > NBDKIT_FUA_NONE);
- debug ("%s: trim count=%" PRIu32 " offset=%" PRIu64 " fua=%d",
- b->name, count, offset, fua);
+ datapath_debug ("%s: trim count=%" PRIu32 " offset=%" PRIu64 " fua=%d",
+ b->name, count, offset, fua);
r = b->trim (b, conn, h->handle, count, offset, flags, err);
if (r == -1)
@@ -547,9 +563,10 @@ backend_zero (struct backend *b, struct connection *conn,
assert (h->can_fua > NBDKIT_FUA_NONE);
if (fast)
assert (h->can_fast_zero == 1);
- debug ("%s: zero count=%" PRIu32 " offset=%" PRIu64
- " may_trim=%d fua=%d fast=%d",
- b->name, count, offset, !!(flags & NBDKIT_FLAG_MAY_TRIM), fua, fast);
+ datapath_debug ("%s: zero count=%" PRIu32 " offset=%" PRIu64
+ " may_trim=%d fua=%d fast=%d",
+ b->name, count, offset,
+ !!(flags & NBDKIT_FLAG_MAY_TRIM), fua, fast);
r = b->zero (b, conn, h->handle, count, offset, flags, err);
if (r == -1) {
@@ -572,8 +589,8 @@ backend_extents (struct backend *b, struct connection *conn,
assert (h->can_extents >= 0);
assert (backend_valid_range (b, conn, offset, count));
assert (!(flags & ~NBDKIT_FLAG_REQ_ONE));
- debug ("%s: extents count=%" PRIu32 " offset=%" PRIu64 " req_one=%d",
- b->name, count, offset, !!(flags & NBDKIT_FLAG_REQ_ONE));
+ datapath_debug ("%s: extents count=%" PRIu32 " offset=%" PRIu64 " req_one=%d",
+ b->name, count, offset, !!(flags & NBDKIT_FLAG_REQ_ONE));
if (h->can_extents == 0) {
/* By default it is safe assume that everything in the range is
@@ -602,8 +619,8 @@ backend_cache (struct backend *b, struct connection *conn,
assert (h->can_cache > NBDKIT_CACHE_NONE);
assert (backend_valid_range (b, conn, offset, count));
assert (flags == 0);
- debug ("%s: cache count=%" PRIu32 " offset=%" PRIu64,
- b->name, count, offset);
+ datapath_debug ("%s: cache count=%" PRIu32 " offset=%" PRIu64,
+ b->name, count, offset);
if (h->can_cache == NBDKIT_CACHE_EMULATE) {
static char buf[MAX_REQUEST_SIZE]; /* data sink, never read */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 01341973..d225cc63 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -135,6 +135,7 @@ EXTRA_DIST = \
test-nbd-extents.sh \
test-nbd-tls.sh \
test-nbd-tls-psk.sh \
+ test-nbdkit-backend-debug.sh \
test-nozero.sh \
test-null-extents.sh \
test_ocaml_plugin.ml \
@@ -746,6 +747,9 @@ endif HAVE_VDDK
# zero plugin test.
TESTS += test-zero.sh
+# -D nbdkit.backend.* settings.
+TESTS += test-nbdkit-backend-debug.sh
+
#----------------------------------------------------------------------
# Tests of language plugins.
diff --git a/tests/test-nbdkit-backend-debug.sh b/tests/test-nbdkit-backend-debug.sh
new file mode 100755
index 00000000..69a69a7c
--- /dev/null
+++ b/tests/test-nbdkit-backend-debug.sh
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+# nbdkit
+# Copyright (C) 2019 Red Hat Inc.
+#
+# 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.
+
+source ./functions.sh
+set -x
+set -e
+
+requires qemu-img --version
+
+out="test-nbdkit-backend-debug.out"
+debug="test-nbdkit-backend-debug.debug"
+files="$out $debug"
+rm -f $files
+cleanup_fn rm -f $files
+
+nbdkit -U - \
+ -v \
+ memory 10M \
+ --run "qemu-img convert \$nbd $out" |& tee $debug
+
+# Should contain all debugging messages.
+grep '^nbdkit:.*debug: memory: open' $debug
+grep '^nbdkit:.*debug: memory: pread' $debug
+
+nbdkit -U - \
+ -v -D nbdkit.backend.controlpath=0 \
+ memory 10M \
+ --run "qemu-img convert \$nbd $out" |& tee $debug
+
+# Should contain only datapath messages.
+grep -v '^nbdkit:.*debug: memory: open' $debug
+grep '^nbdkit:.*debug: memory: pread' $debug
+
+nbdkit -U - \
+ -v -D nbdkit.backend.datapath=0 \
+ memory 10M \
+ --run "qemu-img convert \$nbd $out" |& tee $debug
+
+# Should contain only controlpath messages.
+grep '^nbdkit:.*debug: memory: open' $debug
+grep -v '^nbdkit:.*debug: memory: pread' $debug
--
2.18.2

@ -1,29 +0,0 @@
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,65 @@
From b646050b8da51c39cf21f95fa847c12784a1169c Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 21 Nov 2019 15:02:44 +0000
Subject: [PATCH 04/19] python: Add various constants to the API.
These are accessible from the plugin by:
import nbdkit
if flags & nbdkit.FLAG_MAY_TRIM:
&c.
Many (all?) of these are not yet useful for plugins, some will never
be useful, but they only consume a tiny bit of memory and it's nice to
have the complete set available for future use.
(cherry picked from commit 14b7fe2e0de881e3dfc8803484ade29a61e323c9)
---
plugins/python/python.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/plugins/python/python.c b/plugins/python/python.c
index 7052aac0..47da0838 100644
--- a/plugins/python/python.c
+++ b/plugins/python/python.c
@@ -231,6 +231,36 @@ create_nbdkit_module (void)
nbdkit_error ("could not create the nbdkit API module");
exit (EXIT_FAILURE);
}
+
+ /* Constants corresponding to various flags. */
+#define ADD_INT_CONSTANT(name) \
+ if (PyModule_AddIntConstant (m, #name, NBDKIT_##name) == -1) { \
+ nbdkit_error ("could not add constant %s to nbdkit API module", \
+ #name); \
+ exit (EXIT_FAILURE); \
+ }
+ ADD_INT_CONSTANT (THREAD_MODEL_SERIALIZE_CONNECTIONS);
+ ADD_INT_CONSTANT (THREAD_MODEL_SERIALIZE_ALL_REQUESTS);
+ ADD_INT_CONSTANT (THREAD_MODEL_SERIALIZE_REQUESTS);
+ ADD_INT_CONSTANT (THREAD_MODEL_PARALLEL);
+
+ ADD_INT_CONSTANT (FLAG_MAY_TRIM);
+ ADD_INT_CONSTANT (FLAG_FUA);
+ ADD_INT_CONSTANT (FLAG_REQ_ONE);
+ ADD_INT_CONSTANT (FLAG_FAST_ZERO);
+
+ ADD_INT_CONSTANT (FUA_NONE);
+ ADD_INT_CONSTANT (FUA_EMULATE);
+ ADD_INT_CONSTANT (FUA_NATIVE);
+
+ ADD_INT_CONSTANT (CACHE_NONE);
+ ADD_INT_CONSTANT (CACHE_EMULATE);
+ ADD_INT_CONSTANT (CACHE_NATIVE);
+
+ ADD_INT_CONSTANT (EXTENT_HOLE);
+ ADD_INT_CONSTANT (EXTENT_ZERO);
+#undef ADD_INT_CONSTANT
+
return m;
}
--
2.18.2

@ -1,50 +0,0 @@
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,558 @@
From 49ef7e7d7c3602cc8e53d2052fce9d3a12840ea2 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 21 Nov 2019 15:44:39 +0000
Subject: [PATCH 05/19] python: Implement nbdkit API version 2.
To avoid breaking existing plugins, Python plugins wishing to use
version 2 of the API must opt in by declaring:
API_VERSION = 2
(Plugins which do not do this are assumed to want API version 1).
For v2 API, we also avoid a copy by passing a buffer into pread.
It's more efficient if we pass the C buffer directly to Python code.
In some cases the Python code will be able to write directly into the
C buffer using functions like file.readinto and socket.recv_into.
This avoids an extra copy.
Thanks: Nir Soffer
https://www.redhat.com/archives/libguestfs/2019-November/thread.html#00220
(cherry picked from commit a9b2637cf4f00fb8a25ffaf31ee83be5fe019ae2)
---
plugins/python/example.py | 20 +++-
plugins/python/nbdkit-python-plugin.pod | 69 +++++++-----
plugins/python/python.c | 139 +++++++++++++++++++-----
tests/python-exception.py | 4 +-
tests/shebang.py | 5 +-
tests/test.py | 28 +++--
6 files changed, 190 insertions(+), 75 deletions(-)
diff --git a/plugins/python/example.py b/plugins/python/example.py
index 60f9d7f0..c04b7e29 100644
--- a/plugins/python/example.py
+++ b/plugins/python/example.py
@@ -34,6 +34,12 @@ import errno
disk = bytearray(1024 * 1024)
+# There are several variants of the API. nbdkit will call this
+# function first to determine which one you want to use. This is the
+# latest version at the time this example was written.
+API_VERSION = 2
+
+
# This just prints the extra command line parameters, but real plugins
# should parse them and reject any unknown parameters.
def config(key, value):
@@ -54,20 +60,22 @@ def get_size(h):
return len(disk)
-def pread(h, count, offset):
+def pread(h, buf, offset, flags):
global disk
- return disk[offset:offset+count]
+ end = offset + len(buf)
+ buf[:] = disk[offset:end]
+ # or if reading from a file you can use:
+ #f.readinto(buf)
-
-def pwrite(h, buf, offset):
+def pwrite(h, buf, offset, flags):
global disk
end = offset + len(buf)
disk[offset:end] = buf
-def zero(h, count, offset, may_trim):
+def zero(h, count, offset, flags):
global disk
- if may_trim:
+ if flags & nbdkit.FLAG_MAY_TRIM:
disk[offset:offset+count] = bytearray(count)
else:
nbdkit.set_error(errno.EOPNOTSUPP)
diff --git a/plugins/python/nbdkit-python-plugin.pod b/plugins/python/nbdkit-python-plugin.pod
index 3680fd65..4923d9da 100644
--- a/plugins/python/nbdkit-python-plugin.pod
+++ b/plugins/python/nbdkit-python-plugin.pod
@@ -33,11 +33,12 @@ To write a Python nbdkit plugin, you create a Python file which
contains at least the following required functions (in the top level
C<__main__> module):
+ API_VERSION = 2
def open(readonly):
# see below
def get_size(h):
# see below
- def pread(h, count, offset):
+ def pread(h, buf, offset, flags):
# see below
Note that the subroutines must have those literal names (like C<open>),
@@ -82,6 +83,18 @@ I<--dump-plugin> option, eg:
python_version=3.7.0
python_pep_384_abi_version=3
+=head2 API versions
+
+The nbdkit API has evolved and new versions are released periodically.
+To ensure backwards compatibility plugins have to opt in to the new
+version. From Python you do this by declaring a constant in your
+module:
+
+ API_VERSION = 2
+
+(where 2 is the latest version at the time this documentation was
+written). All newly written Python modules must have this constant.
+
=head2 Executable script
If you want you can make the script executable and include a "shebang"
@@ -199,16 +212,12 @@ contents will be garbage collected.
(Required)
- def pread(h, count, offset):
- # construct a buffer of length count bytes and return it
+ def pread(h, buf, offset, flags):
+ # read into the buffer
-The body of your C<pread> function should construct a buffer of length
-(at least) C<count> bytes. You should read C<count> bytes from the
-disk starting at C<offset>.
-
-The returned buffer can be any type compatible with the Python 3
-buffer protocol, such as bytearray, bytes or memoryview
-(L<https://docs.python.org/3/c-api/buffer.html>)
+The body of your C<pread> function should read exactly C<len(buf)>
+bytes of data starting at disk C<offset> and write it into the buffer
+C<buf>. C<flags> is always 0.
NBD only supports whole reads, so your function should try to read
the whole region (perhaps requiring a loop). If the read fails or
@@ -219,13 +228,13 @@ C<nbdkit.set_error> first.
(Optional)
- def pwrite(h, buf, offset):
+ def pwrite(h, buf, offset, flags):
length = len (buf)
# no return value
The body of your C<pwrite> function should write the buffer C<buf> to
the disk. You should write C<count> bytes to the disk starting at
-C<offset>.
+C<offset>. C<flags> may contain C<nbdkit.FLAG_FUA>.
NBD only supports whole writes, so your function should try to
write the whole region (perhaps requiring a loop). If the write
@@ -236,11 +245,12 @@ fails or is partial, your function should throw an exception,
(Optional)
- def flush(h):
+ def flush(h, flags):
# no return value
The body of your C<flush> function should do a L<sync(2)> or
L<fdatasync(2)> or equivalent on the backing store.
+C<flags> is always 0.
If the flush fails, your function should throw an exception, optionally
using C<nbdkit.set_error> first.
@@ -249,32 +259,35 @@ using C<nbdkit.set_error> first.
(Optional)
- def trim(h, count, offset):
+ def trim(h, count, offset, flags):
# no return value
-The body of your C<trim> function should "punch a hole" in the
-backing store. If the trim fails, your function should throw an
-exception, optionally using C<nbdkit.set_error> first.
+The body of your C<trim> function should "punch a hole" in the backing
+store. C<flags> may contain C<nbdkit.FLAG_FUA>. If the trim fails,
+your function should throw an exception, optionally using
+C<nbdkit.set_error> first.
=item C<zero>
(Optional)
- def zero(h, count, offset, may_trim):
+ def zero(h, count, offset, flags):
# no return value
-The body of your C<zero> function should ensure that C<count> bytes
-of the disk, starting at C<offset>, will read back as zero. If
-C<may_trim> is true, the operation may be optimized as a trim as long
-as subsequent reads see zeroes.
+The body of your C<zero> function should ensure that C<count> bytes of
+the disk, starting at C<offset>, will read back as zero. C<flags> is
+a bitmask which may include C<nbdkit.FLAG_MAY_TRIM>,
+C<nbdkit.FLAG_FUA>, C<nbdkit.FLAG_FAST_ZERO>.
NBD only supports whole writes, so your function should try to
-write the whole region (perhaps requiring a loop). If the write
-fails or is partial, your function should throw an exception,
-optionally using C<nbdkit.set_error> first. In particular, if
-you would like to automatically fall back to C<pwrite> (perhaps
-because there is nothing to optimize if C<may_trim> is false),
-use C<nbdkit.set_error(errno.EOPNOTSUPP)>.
+write the whole region (perhaps requiring a loop).
+
+If the write fails or is partial, your function should throw an
+exception, optionally using C<nbdkit.set_error> first. In particular,
+if you would like to automatically fall back to C<pwrite> (perhaps
+because there is nothing to optimize if
+S<C<flags & nbdkit.FLAG_MAY_TRIM>> is false), use
+S<C<nbdkit.set_error (errno.EOPNOTSUPP)>>.
=back
diff --git a/plugins/python/python.c b/plugins/python/python.c
index 47da0838..0f28595f 100644
--- a/plugins/python/python.c
+++ b/plugins/python/python.c
@@ -46,6 +46,8 @@
#define PY_SSIZE_T_CLEAN 1
#include <Python.h>
+#define NBDKIT_API_VERSION 2
+
#include <nbdkit-plugin.h>
#include "cleanup.h"
@@ -60,6 +62,7 @@
*/
static const char *script;
static PyObject *module;
+static int py_api_version = 1;
static int last_error;
@@ -285,9 +288,14 @@ py_dump_plugin (void)
PyObject *fn;
PyObject *r;
+ /* Python version and ABI. */
printf ("python_version=%s\n", PY_VERSION);
printf ("python_pep_384_abi_version=%d\n", PYTHON_ABI_VERSION);
+ /* Maximum nbdkit API version supported. */
+ printf ("nbdkit_python_maximum_api_version=%d\n", NBDKIT_API_VERSION);
+
+ /* If the script has a dump_plugin function, call it. */
if (script && callback_defined ("dump_plugin", &fn)) {
PyErr_Clear ();
@@ -297,6 +305,30 @@ py_dump_plugin (void)
}
}
+static int
+get_py_api_version (void)
+{
+ PyObject *obj;
+ long value;
+
+ obj = PyObject_GetAttrString (module, "API_VERSION");
+ if (obj == NULL)
+ return 1; /* Default to API version 1. */
+
+ value = PyLong_AsLong (obj);
+ Py_DECREF (obj);
+
+ if (value < 1 || value > NBDKIT_API_VERSION) {
+ nbdkit_error ("%s: API_VERSION requested unknown version: %ld. "
+ "This plugin supports API versions between 1 and %d.",
+ script, value, NBDKIT_API_VERSION);
+ return -1;
+ }
+
+ nbdkit_debug ("module requested API_VERSION %ld", value);
+ return (int) value;
+}
+
static int
py_config (const char *key, const char *value)
{
@@ -359,6 +391,11 @@ py_config (const char *key, const char *value)
"nbdkit requires these callbacks.", script);
return -1;
}
+
+ /* Get the API version. */
+ py_api_version = get_py_api_version ();
+ if (py_api_version == -1)
+ return -1;
}
else if (callback_defined ("config", &fn)) {
/* Other parameters are passed to the Python .config callback. */
@@ -469,8 +506,8 @@ py_get_size (void *handle)
}
static int
-py_pread (void *handle, void *buf,
- uint32_t count, uint64_t offset)
+py_pread (void *handle, void *buf, uint32_t count, uint64_t offset,