import nbdkit-1.16.2-4.module+el8.3.0+6922+fd575af8
parent
63ffbeb99a
commit
003a44a973
@ -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
|
||||
|
@ -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,
|
||||