import nbdkit-1.16.2-2.module+el8.3.0+6423+e4cb6418
This commit is contained in:
commit
fa44cefe07
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
SOURCES/libguestfs.keyring
|
||||
SOURCES/nbdkit-1.16.2.tar.gz
|
2
.nbdkit.metadata
Normal file
2
.nbdkit.metadata
Normal file
@ -0,0 +1,2 @@
|
||||
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
|
||||
42a5761cd3403c02c43cdf7d541ff3faaf8b4769 SOURCES/nbdkit-1.16.2.tar.gz
|
@ -0,0 +1,74 @@
|
||||
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] 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 a2e72b1..346d833 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 3c23937..c367542 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 d39941b..11ba1e6 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 390972e..96c22c0 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
|
||||
|
@ -0,0 +1,66 @@
|
||||
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] 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 b69cb82..879ddf0 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 9344d85..5e06f5e 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] 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 346d833..38e6bfc 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 b9fe2a2..208c07b 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 0134197..d225cc6 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 0000000..69a69a7
|
||||
--- /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
|
||||
|
65
SOURCES/0004-python-Add-various-constants-to-the-API.patch
Normal file
65
SOURCES/0004-python-Add-various-constants-to-the-API.patch
Normal file
@ -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] 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 7052aac..47da083 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
|
||||
|
558
SOURCES/0005-python-Implement-nbdkit-API-version-2.patch
Normal file
558
SOURCES/0005-python-Implement-nbdkit-API-version-2.patch
Normal file
@ -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] 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 60f9d7f..c04b7e2 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 3680fd6..4923d9d 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 47da083..0f28595 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,
|
||||
+ uint32_t flags)
|
||||
{
|
||||
PyObject *obj = handle;
|
||||
PyObject *fn;
|
||||
@@ -485,24 +522,40 @@ py_pread (void *handle, void *buf,
|
||||
|
||||
PyErr_Clear ();
|
||||
|
||||
- r = PyObject_CallFunction (fn, "OiL", obj, count, offset);
|
||||
+ switch (py_api_version) {
|
||||
+ case 1:
|
||||
+ r = PyObject_CallFunction (fn, "OiL", obj, count, offset);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ r = PyObject_CallFunction (fn, "ONLI", obj,
|
||||
+ PyMemoryView_FromMemory ((char *)buf, count, PyBUF_WRITE),
|
||||
+ offset, flags);
|
||||
+ break;
|
||||
+ default: abort ();
|
||||
+ }
|
||||
Py_DECREF (fn);
|
||||
if (check_python_failure ("pread") == -1)
|
||||
return ret;
|
||||
|
||||
- if (PyObject_GetBuffer (r, &view, PyBUF_SIMPLE) == -1) {
|
||||
- nbdkit_error ("%s: value returned from pread does not support the "
|
||||
- "buffer protocol",
|
||||
- script);
|
||||
- goto out;
|
||||
- }
|
||||
+ if (py_api_version == 1) {
|
||||
+ /* In API v1 the Python pread function had to return a buffer
|
||||
+ * protocol compatible function. In API v2+ it writes directly to
|
||||
+ * the C buffer so this code is not used.
|
||||
+ */
|
||||
+ if (PyObject_GetBuffer (r, &view, PyBUF_SIMPLE) == -1) {
|
||||
+ nbdkit_error ("%s: value returned from pread does not support the "
|
||||
+ "buffer protocol",
|
||||
+ script);
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
- if (view.len < count) {
|
||||
- nbdkit_error ("%s: buffer returned from pread is too small", script);
|
||||
- goto out;
|
||||
- }
|
||||
+ if (view.len < count) {
|
||||
+ nbdkit_error ("%s: buffer returned from pread is too small", script);
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
- memcpy (buf, view.buf, count);
|
||||
+ memcpy (buf, view.buf, count);
|
||||
+ }
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
@@ -515,8 +568,8 @@ out:
|
||||
}
|
||||
|
||||
static int
|
||||
-py_pwrite (void *handle, const void *buf,
|
||||
- uint32_t count, uint64_t offset)
|
||||
+py_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset,
|
||||
+ uint32_t flags)
|
||||
{
|
||||
PyObject *obj = handle;
|
||||
PyObject *fn;
|
||||
@@ -525,9 +578,19 @@ py_pwrite (void *handle, const void *buf,
|
||||
if (callback_defined ("pwrite", &fn)) {
|
||||
PyErr_Clear ();
|
||||
|
||||
- r = PyObject_CallFunction (fn, "ONL", obj,
|
||||
+ switch (py_api_version) {
|
||||
+ case 1:
|
||||
+ r = PyObject_CallFunction (fn, "ONL", obj,
|
||||
PyMemoryView_FromMemory ((char *)buf, count, PyBUF_READ),
|
||||
offset);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ r = PyObject_CallFunction (fn, "ONLI", obj,
|
||||
+ PyMemoryView_FromMemory ((char *)buf, count, PyBUF_READ),
|
||||
+ offset, flags);
|
||||
+ break;
|
||||
+ default: abort ();
|
||||
+ }
|
||||
Py_DECREF (fn);
|
||||
if (check_python_failure ("pwrite") == -1)
|
||||
return -1;
|
||||
@@ -542,7 +605,7 @@ py_pwrite (void *handle, const void *buf,
|
||||
}
|
||||
|
||||
static int
|
||||
-py_flush (void *handle)
|
||||
+py_flush (void *handle, uint32_t flags)
|
||||
{
|
||||
PyObject *obj = handle;
|
||||
PyObject *fn;
|
||||
@@ -551,7 +614,15 @@ py_flush (void *handle)
|
||||
if (callback_defined ("flush", &fn)) {
|
||||
PyErr_Clear ();
|
||||
|
||||
- r = PyObject_CallFunctionObjArgs (fn, obj, NULL);
|
||||
+ switch (py_api_version) {
|
||||
+ case 1:
|
||||
+ r = PyObject_CallFunctionObjArgs (fn, obj, NULL);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ r = PyObject_CallFunction (fn, "OI", obj, flags);
|
||||
+ break;
|
||||
+ default: abort ();
|
||||
+ }
|
||||
Py_DECREF (fn);
|
||||
if (check_python_failure ("flush") == -1)
|
||||
return -1;
|
||||
@@ -566,7 +637,7 @@ py_flush (void *handle)
|
||||
}
|
||||
|
||||
static int
|
||||
-py_trim (void *handle, uint32_t count, uint64_t offset)
|
||||
+py_trim (void *handle, uint32_t count, uint64_t offset, uint32_t flags)
|
||||
{
|
||||
PyObject *obj = handle;
|
||||
PyObject *fn;
|
||||
@@ -575,7 +646,15 @@ py_trim (void *handle, uint32_t count, uint64_t offset)
|
||||
if (callback_defined ("trim", &fn)) {
|
||||
PyErr_Clear ();
|
||||
|
||||
- r = PyObject_CallFunction (fn, "OiL", obj, count, offset);
|
||||
+ switch (py_api_version) {
|
||||
+ case 1:
|
||||
+ r = PyObject_CallFunction (fn, "OiL", obj, count, offset);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ r = PyObject_CallFunction (fn, "OiLI", obj, count, offset, flags);
|
||||
+ break;
|
||||
+ default: abort ();
|
||||
+ }
|
||||
Py_DECREF (fn);
|
||||
if (check_python_failure ("trim") == -1)
|
||||
return -1;
|
||||
@@ -590,7 +669,7 @@ py_trim (void *handle, uint32_t count, uint64_t offset)
|
||||
}
|
||||
|
||||
static int
|
||||
-py_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)
|
||||
+py_zero (void *handle, uint32_t count, uint64_t offset, uint32_t flags)
|
||||
{
|
||||
PyObject *obj = handle;
|
||||
PyObject *fn;
|
||||
@@ -600,9 +679,19 @@ py_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)
|
||||
PyErr_Clear ();
|
||||
|
||||
last_error = 0;
|
||||
- r = PyObject_CallFunction (fn, "OiLO",
|
||||
- obj, count, offset,
|
||||
- may_trim ? Py_True : Py_False);
|
||||
+ switch (py_api_version) {
|
||||
+ case 1: {
|
||||
+ int may_trim = flags & NBDKIT_FLAG_MAY_TRIM;
|
||||
+ r = PyObject_CallFunction (fn, "OiLO",
|
||||
+ obj, count, offset,
|
||||
+ may_trim ? Py_True : Py_False);
|
||||
+ break;
|
||||
+ }
|
||||
+ case 2:
|
||||
+ r = PyObject_CallFunction (fn, "OiLI", obj, count, offset, flags);
|
||||
+ break;
|
||||
+ default: abort ();
|
||||
+ }
|
||||
Py_DECREF (fn);
|
||||
if (last_error == EOPNOTSUPP || last_error == ENOTSUP) {
|
||||
/* When user requests this particular error, we want to
|
||||
diff --git a/tests/python-exception.py b/tests/python-exception.py
|
||||
index d0c79bb..ee4a3f3 100644
|
||||
--- a/tests/python-exception.py
|
||||
+++ b/tests/python-exception.py
|
||||
@@ -62,5 +62,5 @@ def get_size(h):
|
||||
return 0
|
||||
|
||||
|
||||
-def pread(h, count, offset):
|
||||
- return ""
|
||||
+def pread(h, buf, offset):
|
||||
+ buf[:] = bytearray(len(buf))
|
||||
diff --git a/tests/shebang.py b/tests/shebang.py
|
||||
index 6f33623..0634589 100755
|
||||
--- a/tests/shebang.py
|
||||
+++ b/tests/shebang.py
|
||||
@@ -13,6 +13,7 @@ def get_size(h):
|
||||
return len(disk)
|
||||
|
||||
|
||||
-def pread(h, count, offset):
|
||||
+def pread(h, buf, offset):
|
||||
global disk
|
||||
- return disk[offset:offset+count]
|
||||
+ end = offset + len(buf)
|
||||
+ buf[:] = disk[offset:end]
|
||||
diff --git a/tests/test.py b/tests/test.py
|
||||
index 9a2e947..4db5662 100644
|
||||
--- a/tests/test.py
|
||||
+++ b/tests/test.py
|
||||
@@ -3,6 +3,9 @@ import nbdkit
|
||||
disk = bytearray(1024*1024)
|
||||
|
||||
|
||||
+API_VERSION = 2
|
||||
+
|
||||
+
|
||||
def config_complete():
|
||||
print ("set_error = %r" % nbdkit.set_error)
|
||||
|
||||
@@ -32,25 +35,26 @@ def can_trim(h):
|
||||
return True
|
||||
|
||||
|
||||
-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]
|
||||
|
||||
|
||||
-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=False):
|
||||
+def flush(h, flags):
|
||||
+ pass
|
||||
+
|
||||
+
|
||||
+def trim(h, count, offset, flags):
|
||||
+ pass
|
||||
+
|
||||
+
|
||||
+def zero(h, count, offset, flags):
|
||||
global disk
|
||||
disk[offset:offset+count] = bytearray(count)
|
||||
-
|
||||
-
|
||||
-def flush(h):
|
||||
- pass
|
||||
-
|
||||
-
|
||||
-def trim(h, count, offset):
|
||||
- pass
|
||||
--
|
||||
2.18.2
|
||||
|
98
SOURCES/0006-python-Implement-cache.patch
Normal file
98
SOURCES/0006-python-Implement-cache.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From c5b1fac4c67078f0164bd23eab6d4d2b8c9830b0 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 21 Nov 2019 16:42:02 +0000
|
||||
Subject: [PATCH] python: Implement cache.
|
||||
|
||||
However this does not implement can_cache, since that is not a simple
|
||||
boolean.
|
||||
|
||||
(cherry picked from commit e61ffb73c7a0af0c383184fdb8f08d30784a195e)
|
||||
---
|
||||
plugins/python/nbdkit-python-plugin.pod | 14 ++++++++++-
|
||||
plugins/python/python.c | 31 +++++++++++++++++++++++++
|
||||
2 files changed, 44 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/plugins/python/nbdkit-python-plugin.pod b/plugins/python/nbdkit-python-plugin.pod
|
||||
index 4923d9d..0ea8dee 100644
|
||||
--- a/plugins/python/nbdkit-python-plugin.pod
|
||||
+++ b/plugins/python/nbdkit-python-plugin.pod
|
||||
@@ -289,6 +289,19 @@ because there is nothing to optimize if
|
||||
S<C<flags & nbdkit.FLAG_MAY_TRIM>> is false), use
|
||||
S<C<nbdkit.set_error (errno.EOPNOTSUPP)>>.
|
||||
|
||||
+=item C<cache>
|
||||
+
|
||||
+(Optional)
|
||||
+
|
||||
+ def cache(h, count, offset, flags):
|
||||
+ # no return value
|
||||
+
|
||||
+The body of your C<cache> function should prefetch data in the
|
||||
+indicated range.
|
||||
+
|
||||
+If the cache operation fails, your function should throw an exception,
|
||||
+optionally using C<nbdkit.set_error> first.
|
||||
+
|
||||
=back
|
||||
|
||||
=head2 Missing callbacks
|
||||
@@ -317,7 +330,6 @@ C<can_zero>,
|
||||
C<can_fast_zero>,
|
||||
C<can_extents>,
|
||||
C<can_multi_conn>,
|
||||
-C<cache>,
|
||||
C<extents>.
|
||||
|
||||
These are not yet supported.
|
||||
diff --git a/plugins/python/python.c b/plugins/python/python.c
|
||||
index 0f28595..c5cf38e 100644
|
||||
--- a/plugins/python/python.c
|
||||
+++ b/plugins/python/python.c
|
||||
@@ -714,6 +714,36 @@ py_zero (void *handle, uint32_t count, uint64_t offset, uint32_t flags)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+static int
|
||||
+py_cache (void *handle, uint32_t count, uint64_t offset, uint32_t flags)
|
||||
+{
|
||||
+ PyObject *obj = handle;
|
||||
+ PyObject *fn;
|
||||
+ PyObject *r;
|
||||
+
|
||||
+ if (callback_defined ("cache", &fn)) {
|
||||
+ PyErr_Clear ();
|
||||
+
|
||||
+ switch (py_api_version) {
|
||||
+ case 1:
|
||||
+ case 2:
|
||||
+ r = PyObject_CallFunction (fn, "OiLI", obj, count, offset, flags, NULL);
|
||||
+ break;
|
||||
+ default: abort ();
|
||||
+ }
|
||||
+ Py_DECREF (fn);
|
||||
+ if (check_python_failure ("cache") == -1)
|
||||
+ return -1;
|
||||
+ Py_DECREF (r);
|
||||
+ }
|
||||
+ else {
|
||||
+ nbdkit_error ("%s not implemented", "cache");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
boolean_callback (void *handle, const char *can_fn, const char *plain_fn)
|
||||
{
|
||||
@@ -799,6 +829,7 @@ static struct nbdkit_plugin plugin = {
|
||||
.flush = py_flush,
|
||||
.trim = py_trim,
|
||||
.zero = py_zero,
|
||||
+ .cache = py_cache,
|
||||
};
|
||||
|
||||
NBDKIT_REGISTER_PLUGIN (plugin)
|
||||
--
|
||||
2.18.2
|
||||
|
80
SOURCES/0007-python-Implement-can_zero-can_fast_zero.patch
Normal file
80
SOURCES/0007-python-Implement-can_zero-can_fast_zero.patch
Normal file
@ -0,0 +1,80 @@
|
||||
From 17721b316dd66b0a1ed792eeccd2489fb97828df Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 21 Nov 2019 16:42:59 +0000
|
||||
Subject: [PATCH] python: Implement can_zero, can_fast_zero.
|
||||
|
||||
(cherry picked from commit 039f600d2ad7a9ff04523a165eb2fe41b9c87c01)
|
||||
---
|
||||
plugins/python/nbdkit-python-plugin.pod | 16 ++++++++++++++--
|
||||
plugins/python/python.c | 14 ++++++++++++++
|
||||
2 files changed, 28 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/python/nbdkit-python-plugin.pod b/plugins/python/nbdkit-python-plugin.pod
|
||||
index 0ea8dee..1f1c30f 100644
|
||||
--- a/plugins/python/nbdkit-python-plugin.pod
|
||||
+++ b/plugins/python/nbdkit-python-plugin.pod
|
||||
@@ -208,6 +208,20 @@ contents will be garbage collected.
|
||||
def can_trim(h):
|
||||
# return a boolean
|
||||
|
||||
+=item C<can_zero>
|
||||
+
|
||||
+(Optional)
|
||||
+
|
||||
+ def can_zero(h):
|
||||
+ # return a boolean
|
||||
+
|
||||
+=item C<can_fast_zero>
|
||||
+
|
||||
+(Optional)
|
||||
+
|
||||
+ def can_fast_zero(h):
|
||||
+ # return a boolean
|
||||
+
|
||||
=item C<pread>
|
||||
|
||||
(Required)
|
||||
@@ -326,8 +340,6 @@ C<config_help>,
|
||||
C<magic_config_key>,
|
||||
C<can_fua>,
|
||||
C<can_cache>,
|
||||
-C<can_zero>,
|
||||
-C<can_fast_zero>,
|
||||
C<can_extents>,
|
||||
C<can_multi_conn>,
|
||||
C<extents>.
|
||||
diff --git a/plugins/python/python.c b/plugins/python/python.c
|
||||
index c5cf38e..38fc119 100644
|
||||
--- a/plugins/python/python.c
|
||||
+++ b/plugins/python/python.c
|
||||
@@ -797,6 +797,18 @@ py_can_trim (void *handle)
|
||||
return boolean_callback (handle, "can_trim", "trim");
|
||||
}
|
||||
|
||||
+static int
|
||||
+py_can_zero (void *handle)
|
||||
+{
|
||||
+ return boolean_callback (handle, "can_zero", "zero");
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+py_can_fast_zero (void *handle)
|
||||
+{
|
||||
+ return boolean_callback (handle, "can_fast_zero", NULL);
|
||||
+}
|
||||
+
|
||||
#define py_config_help \
|
||||
"script=<FILENAME> (required) The Python plugin to run.\n" \
|
||||
"[other arguments may be used by the plugin that you load]"
|
||||
@@ -823,6 +835,8 @@ static struct nbdkit_plugin plugin = {
|
||||
.can_write = py_can_write,
|
||||
.can_flush = py_can_flush,
|
||||
.can_trim = py_can_trim,
|
||||
+ .can_zero = py_can_zero,
|
||||
+ .can_fast_zero = py_can_fast_zero,
|
||||
|
||||
.pread = py_pread,
|
||||
.pwrite = py_pwrite,
|
||||
--
|
||||
2.18.2
|
||||
|
65
SOURCES/0008-python-Implement-can_multi_conn.patch
Normal file
65
SOURCES/0008-python-Implement-can_multi_conn.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 2a85ce81ad95eb2f9b2f29666480b814ea0f80d9 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 21 Nov 2019 16:46:11 +0000
|
||||
Subject: [PATCH] python: Implement can_multi_conn.
|
||||
|
||||
(cherry picked from commit 21dd7bf49d3238c7e75918d4bf324b617f458d83)
|
||||
---
|
||||
plugins/python/nbdkit-python-plugin.pod | 8 +++++++-
|
||||
plugins/python/python.c | 7 +++++++
|
||||
2 files changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/plugins/python/nbdkit-python-plugin.pod b/plugins/python/nbdkit-python-plugin.pod
|
||||
index 1f1c30f..b92bb56 100644
|
||||
--- a/plugins/python/nbdkit-python-plugin.pod
|
||||
+++ b/plugins/python/nbdkit-python-plugin.pod
|
||||
@@ -187,6 +187,13 @@ contents will be garbage collected.
|
||||
def is_rotational(h):
|
||||
# return a boolean
|
||||
|
||||
+=item C<can_multi_conn>
|
||||
+
|
||||
+(Optional)
|
||||
+
|
||||
+ def can_multi_conn(h):
|
||||
+ # return a boolean
|
||||
+
|
||||
=item C<can_write>
|
||||
|
||||
(Optional)
|
||||
@@ -341,7 +348,6 @@ C<magic_config_key>,
|
||||
C<can_fua>,
|
||||
C<can_cache>,
|
||||
C<can_extents>,
|
||||
-C<can_multi_conn>,
|
||||
C<extents>.
|
||||
|
||||
These are not yet supported.
|
||||
diff --git a/plugins/python/python.c b/plugins/python/python.c
|
||||
index 38fc119..b186b99 100644
|
||||
--- a/plugins/python/python.c
|
||||
+++ b/plugins/python/python.c
|
||||
@@ -779,6 +779,12 @@ py_is_rotational (void *handle)
|
||||
return boolean_callback (handle, "is_rotational", NULL);
|
||||
}
|
||||
|
||||
+static int
|
||||
+py_can_multi_conn (void *handle)
|
||||
+{
|
||||
+ return boolean_callback (handle, "can_multi_conn", NULL);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
py_can_write (void *handle)
|
||||
{
|
||||
@@ -832,6 +838,7 @@ static struct nbdkit_plugin plugin = {
|
||||
|
||||
.get_size = py_get_size,
|
||||
.is_rotational = py_is_rotational,
|
||||
+ .can_multi_conn = py_can_multi_conn,
|
||||
.can_write = py_can_write,
|
||||
.can_flush = py_can_flush,
|
||||
.can_trim = py_can_trim,
|
||||
--
|
||||
2.18.2
|
||||
|
126
SOURCES/0009-python-Implement-can_fua-and-can_cache.patch
Normal file
126
SOURCES/0009-python-Implement-can_fua-and-can_cache.patch
Normal file
@ -0,0 +1,126 @@
|
||||
From 38124a137974e1433d68732640ca7f88664557da Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 22 Nov 2019 19:25:53 +0000
|
||||
Subject: [PATCH] python: Implement can_fua and can_cache.
|
||||
|
||||
(cherry picked from commit 97c46f885edec5a61a96ac86eccb9d8c874c602e)
|
||||
---
|
||||
plugins/python/nbdkit-python-plugin.pod | 18 +++++++-
|
||||
plugins/python/python.c | 58 +++++++++++++++++++++++++
|
||||
2 files changed, 74 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/python/nbdkit-python-plugin.pod b/plugins/python/nbdkit-python-plugin.pod
|
||||
index b92bb56..4065ec7 100644
|
||||
--- a/plugins/python/nbdkit-python-plugin.pod
|
||||
+++ b/plugins/python/nbdkit-python-plugin.pod
|
||||
@@ -229,6 +229,22 @@ contents will be garbage collected.
|
||||
def can_fast_zero(h):
|
||||
# return a boolean
|
||||
|
||||
+=item C<can_fua>
|
||||
+
|
||||
+(Optional)
|
||||
+
|
||||
+ def can_fua(h):
|
||||
+ # return nbdkit.FUA_NONE or nbdkit.FUA_EMULATE
|
||||
+ # or nbdkit.FUA_NATIVE
|
||||
+
|
||||
+=item C<can_cache>
|
||||
+
|
||||
+(Optional)
|
||||
+
|
||||
+ def can_cache(h):
|
||||
+ # return nbdkit.CACHE_NONE or nbdkit.CACHE_EMULATE
|
||||
+ # or nbdkit.CACHE_NATIVE
|
||||
+
|
||||
=item C<pread>
|
||||
|
||||
(Required)
|
||||
@@ -345,8 +361,6 @@ C<longname>,
|
||||
C<description>,
|
||||
C<config_help>,
|
||||
C<magic_config_key>,
|
||||
-C<can_fua>,
|
||||
-C<can_cache>,
|
||||
C<can_extents>,
|
||||
C<extents>.
|
||||
|
||||
diff --git a/plugins/python/python.c b/plugins/python/python.c
|
||||
index b186b99..5e2e526 100644
|
||||
--- a/plugins/python/python.c
|
||||
+++ b/plugins/python/python.c
|
||||
@@ -815,6 +815,62 @@ py_can_fast_zero (void *handle)
|
||||
return boolean_callback (handle, "can_fast_zero", NULL);
|
||||
}
|
||||
|
||||
+static int
|
||||
+py_can_fua (void *handle)
|
||||
+{
|
||||
+ PyObject *obj = handle;
|
||||
+ PyObject *fn;
|
||||
+ PyObject *r;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (callback_defined ("can_fua", &fn)) {
|
||||
+ PyErr_Clear ();
|
||||
+
|
||||
+ r = PyObject_CallFunctionObjArgs (fn, obj, NULL);
|
||||
+ Py_DECREF (fn);
|
||||
+ if (check_python_failure ("can_fua") == -1)
|
||||
+ return -1;
|
||||
+ ret = PyLong_AsLong (r);
|
||||
+ Py_DECREF (r);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ /* No Python ‘can_fua’, but check if there's a Python ‘flush’
|
||||
+ * callback defined. (In C modules, nbdkit would do this).
|
||||
+ */
|
||||
+ else if (callback_defined ("flush", NULL))
|
||||
+ return NBDKIT_FUA_EMULATE;
|
||||
+ else
|
||||
+ return NBDKIT_FUA_NONE;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+py_can_cache (void *handle)
|
||||
+{
|
||||
+ PyObject *obj = handle;
|
||||
+ PyObject *fn;
|
||||
+ PyObject *r;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (callback_defined ("can_cache", &fn)) {
|
||||
+ PyErr_Clear ();
|
||||
+
|
||||
+ r = PyObject_CallFunctionObjArgs (fn, obj, NULL);
|
||||
+ Py_DECREF (fn);
|
||||
+ if (check_python_failure ("can_cache") == -1)
|
||||
+ return -1;
|
||||
+ ret = PyLong_AsLong (r);
|
||||
+ Py_DECREF (r);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ /* No Python ‘can_cache’, but check if there's a Python ‘cache’
|
||||
+ * callback defined. (In C modules, nbdkit would do this).
|
||||
+ */
|
||||
+ else if (callback_defined ("cache", NULL))
|
||||
+ return NBDKIT_CACHE_NATIVE;
|
||||
+ else
|
||||
+ return NBDKIT_CACHE_NONE;
|
||||
+}
|
||||
+
|
||||
#define py_config_help \
|
||||
"script=<FILENAME> (required) The Python plugin to run.\n" \
|
||||
"[other arguments may be used by the plugin that you load]"
|
||||
@@ -844,6 +900,8 @@ static struct nbdkit_plugin plugin = {
|
||||
.can_trim = py_can_trim,
|
||||
.can_zero = py_can_zero,
|
||||
.can_fast_zero = py_can_fast_zero,
|
||||
+ .can_fua = py_can_fua,
|
||||
+ .can_cache = py_can_cache,
|
||||
|
||||
.pread = py_pread,
|
||||
.pwrite = py_pwrite,
|
||||
--
|
||||
2.18.2
|
||||
|
597
SOURCES/0010-tests-Test-the-Python-plugin-thoroughly.patch
Normal file
597
SOURCES/0010-tests-Test-the-Python-plugin-thoroughly.patch
Normal file
@ -0,0 +1,597 @@
|
||||
From 7cb79aef2a12f29f1286caf3858001e47214f871 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 21 Nov 2019 20:54:41 +0000
|
||||
Subject: [PATCH] tests: Test the Python plugin thoroughly.
|
||||
|
||||
This tests the Python plugin thoroughly by issuing client commands
|
||||
through libnbd and checking we get the expected results.
|
||||
|
||||
(cherry picked from commit 8ead4a82ec3227dbecb6cbfc419f1a18f2817d62)
|
||||
---
|
||||
.gitignore | 1 +
|
||||
README | 2 +
|
||||
tests/Makefile.am | 15 +--
|
||||
tests/test-lang-plugins.c | 3 +-
|
||||
tests/test-python-plugin.py | 133 +++++++++++++++++++++
|
||||
tests/test-python.sh | 49 ++++++++
|
||||
tests/test.py | 60 ----------
|
||||
tests/test_python.py | 222 ++++++++++++++++++++++++++++++++++++
|
||||
8 files changed, 413 insertions(+), 72 deletions(-)
|
||||
create mode 100644 tests/test-python-plugin.py
|
||||
create mode 100755 tests/test-python.sh
|
||||
delete mode 100644 tests/test.py
|
||||
create mode 100755 tests/test_python.py
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index b25ac7f..e25bd99 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -71,6 +71,7 @@ Makefile.in
|
||||
/server/synopsis.c
|
||||
/server/test-public
|
||||
/stamp-h1
|
||||
+/tests/__pycache__/
|
||||
/tests/disk
|
||||
/tests/disk.gz
|
||||
/tests/disk.xz
|
||||
diff --git a/README b/README
|
||||
index 40f4cd3..05f1e06 100644
|
||||
--- a/README
|
||||
+++ b/README
|
||||
@@ -130,6 +130,8 @@ For the Python plugin:
|
||||
|
||||
- python development libraries
|
||||
|
||||
+ - python unittest to run the test suite
|
||||
+
|
||||
For the OCaml plugin:
|
||||
|
||||
- OCaml >= 4.02.2
|
||||
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||
index d225cc6..09103fb 100644
|
||||
--- a/tests/Makefile.am
|
||||
+++ b/tests/Makefile.am
|
||||
@@ -67,6 +67,7 @@ EXTRA_PROGRAMS =
|
||||
TESTS_ENVIRONMENT = \
|
||||
PATH=$(abs_top_builddir):$(PATH) \
|
||||
SRCDIR=$(srcdir) \
|
||||
+ PYTHON=$(PYTHON) \
|
||||
LIBGUESTFS_ATTACH_METHOD=appliance \
|
||||
LIBGUESTFS_DEBUG=1 \
|
||||
LIBGUESTFS_TRACE=1 \
|
||||
@@ -160,7 +161,9 @@ EXTRA_DIST = \
|
||||
test-probe-plugin.sh \
|
||||
test-python-exception.sh \
|
||||
test.pl \
|
||||
- test.py \
|
||||
+ test_python.py \
|
||||
+ test-python-plugin.py \
|
||||
+ test-python.sh \
|
||||
test-rate.sh \
|
||||
test-rate-dynamic.sh \
|
||||
test.rb \
|
||||
@@ -801,18 +804,10 @@ endif HAVE_PERL
|
||||
if HAVE_PYTHON
|
||||
|
||||
TESTS += \
|
||||
+ test-python.sh \
|
||||
test-python-exception.sh \
|
||||
test-shebang-python.sh \
|
||||
$(NULL)
|
||||
-LIBGUESTFS_TESTS += test-python
|
||||
-
|
||||
-test_python_SOURCES = test-lang-plugins.c test.h
|
||||
-test_python_CFLAGS = \
|
||||
- -DLANG='"python"' -DSCRIPT='"$(srcdir)/test.py"' \
|
||||
- $(WARNINGS_CFLAGS) \
|
||||
- $(LIBGUESTFS_CFLAGS) \
|
||||
- $(NULL)
|
||||
-test_python_LDADD = libtest.la $(LIBGUESTFS_LIBS)
|
||||
|
||||
endif HAVE_PYTHON
|
||||
|
||||
diff --git a/tests/test-lang-plugins.c b/tests/test-lang-plugins.c
|
||||
index ffb1918..93f9938 100644
|
||||
--- a/tests/test-lang-plugins.c
|
||||
+++ b/tests/test-lang-plugins.c
|
||||
@@ -56,8 +56,7 @@ main (int argc, char *argv[])
|
||||
*/
|
||||
s = getenv ("NBDKIT_VALGRIND");
|
||||
if (s && strcmp (s, "1") == 0 &&
|
||||
- (strcmp (LANG, "python") == 0 ||
|
||||
- strcmp (LANG, "ruby") == 0 ||
|
||||
+ (strcmp (LANG, "ruby") == 0 ||
|
||||
strcmp (LANG, "tcl") == 0)) {
|
||||
fprintf (stderr, "%s test skipped under valgrind.\n", LANG);
|
||||
exit (77); /* Tells automake to skip the test. */
|
||||
diff --git a/tests/test-python-plugin.py b/tests/test-python-plugin.py
|
||||
new file mode 100644
|
||||
index 0000000..8e90bc2
|
||||
--- /dev/null
|
||||
+++ b/tests/test-python-plugin.py
|
||||
@@ -0,0 +1,133 @@
|
||||
+# nbdkit test plugin
|
||||
+# 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.
|
||||
+
|
||||
+"""See test-python.py."""
|
||||
+
|
||||
+import nbdkit
|
||||
+import sys
|
||||
+import pickle
|
||||
+import base64
|
||||
+
|
||||
+API_VERSION = 2
|
||||
+
|
||||
+cfg = {}
|
||||
+
|
||||
+def config (k, v):
|
||||
+ global cfg
|
||||
+ if k == "cfg":
|
||||
+ cfg = pickle.loads (base64.b64decode (v.encode()))
|
||||
+
|
||||
+def config_complete ():
|
||||
+ print ("set_error = %r" % nbdkit.set_error)
|
||||
+
|
||||
+def open (readonly):
|
||||
+ return {
|
||||
+ 'disk': bytearray (cfg.get ('size', 0))
|
||||
+ }
|
||||
+
|
||||
+def get_size (h):
|
||||
+ return len (h['disk'])
|
||||
+
|
||||
+def is_rotational (h):
|
||||
+ return cfg.get ('is_rotational', False)
|
||||
+
|
||||
+def can_multi_conn (h):
|
||||
+ return cfg.get ('can_multi_conn', False)
|
||||
+
|
||||
+def can_write (h):
|
||||
+ return cfg.get ('can_write', True)
|
||||
+
|
||||
+def can_flush (h):
|
||||
+ return cfg.get ('can_flush', False)
|
||||
+
|
||||
+def can_trim (h):
|
||||
+ return cfg.get ('can_trim', False)
|
||||
+
|
||||
+def can_zero (h):
|
||||
+ return cfg.get ('can_zero', False)
|
||||
+
|
||||
+def can_fast_zero (h):
|
||||
+ return cfg.get ('can_fast_zero', False)
|
||||
+
|
||||
+def can_fua (h):
|
||||
+ fua = cfg.get ('can_fua', "none")
|
||||
+ if fua == "none":
|
||||
+ return nbdkit.FUA_NONE
|
||||
+ elif fua == "emulate":
|
||||
+ return nbdkit.FUA_EMULATE
|
||||
+ elif fua == "native":
|
||||
+ return nbdkit.FUA_NATIVE
|
||||
+
|
||||
+def can_cache (h):
|
||||
+ cache = cfg.get ('can_cache', "none")
|
||||
+ if cache == "none":
|
||||
+ return nbdkit.CACHE_NONE
|
||||
+ elif cache == "emulate":
|
||||
+ return nbdkit.CACHE_EMULATE
|
||||
+ elif cache == "native":
|
||||
+ return nbdkit.CACHE_NATIVE
|
||||
+
|
||||
+def pread (h, buf, offset, flags):
|
||||
+ assert flags == 0
|
||||
+ end = offset + len(buf)
|
||||
+ buf[:] = h['disk'][offset:end]
|
||||
+
|
||||
+def pwrite (h, buf, offset, flags):
|
||||
+ expect_fua = cfg.get ('pwrite_expect_fua', False)
|
||||
+ actual_fua = bool (flags & nbdkit.FLAG_FUA)
|
||||
+ assert expect_fua == actual_fua
|
||||
+ end = offset + len(buf)
|
||||
+ h['disk'][offset:end] = buf
|
||||
+
|
||||
+def flush (h, flags):
|
||||
+ assert flags == 0
|
||||
+
|
||||
+def trim (h, count, offset, flags):
|
||||
+ expect_fua = cfg.get ('trim_expect_fua', False)
|
||||
+ actual_fua = bool (flags & nbdkit.FLAG_FUA)
|
||||
+ assert expect_fua == actual_fua
|
||||
+ h['disk'][offset:offset+count] = bytearray(count)
|
||||
+
|
||||
+def zero (h, count, offset, flags):
|
||||
+ expect_fua = cfg.get ('zero_expect_fua', False)
|
||||
+ actual_fua = bool (flags & nbdkit.FLAG_FUA)
|
||||
+ assert expect_fua == actual_fua
|
||||
+ expect_may_trim = cfg.get ('zero_expect_may_trim', False)
|
||||
+ actual_may_trim = bool (flags & nbdkit.FLAG_MAY_TRIM)
|
||||
+ assert expect_may_trim == actual_may_trim
|
||||
+ expect_fast_zero = cfg.get ('zero_expect_fast_zero', False)
|
||||
+ actual_fast_zero = bool (flags & nbdkit.FLAG_FAST_ZERO)
|
||||
+ assert expect_fast_zero == actual_fast_zero
|
||||
+ h['disk'][offset:offset+count] = bytearray(count)
|
||||
+
|
||||
+def cache (h, count, offset, flags):
|
||||
+ assert flags == 0
|
||||
+ # do nothing
|
||||
diff --git a/tests/test-python.sh b/tests/test-python.sh
|
||||
new file mode 100755
|
||||
index 0000000..50324d0
|
||||
--- /dev/null
|
||||
+++ b/tests/test-python.sh
|
||||
@@ -0,0 +1,49 @@
|
||||
+#!/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 -e
|
||||
+set -x
|
||||
+
|
||||
+requires $PYTHON --version
|
||||
+requires $PYTHON -c 'import unittest'
|
||||
+requires $PYTHON -c 'import nbd'
|
||||
+requires test -f test_python.py
|
||||
+requires test -f test-python-plugin.py
|
||||
+
|
||||
+# Python has proven very difficult to valgrind, therefore it is disabled.
|
||||
+if [ "$NBDKIT_VALGRIND" = "1" ]; then
|
||||
+ echo "$0: skipping Python test under valgrind."
|
||||
+ exit 77
|
||||
+fi
|
||||
+
|
||||
+$PYTHON -m unittest test_python
|
||||
diff --git a/tests/test.py b/tests/test.py
|
||||
deleted file mode 100644
|
||||
index 4db5662..0000000
|
||||
--- a/tests/test.py
|
||||
+++ /dev/null
|
||||
@@ -1,60 +0,0 @@
|
||||
-import nbdkit
|
||||
-
|
||||
-disk = bytearray(1024*1024)
|
||||
-
|
||||
-
|
||||
-API_VERSION = 2
|
||||
-
|
||||
-
|
||||
-def config_complete():
|
||||
- print ("set_error = %r" % nbdkit.set_error)
|
||||
-
|
||||
-
|
||||
-def open(readonly):
|
||||
- return 1
|
||||
-
|
||||
-
|
||||
-def get_size(h):
|
||||
- global disk
|
||||
- return len(disk)
|
||||
-
|
||||
-
|
||||
-def can_write(h):
|
||||
- return True
|
||||
-
|
||||
-
|
||||
-def can_flush(h):
|
||||
- return True
|
||||
-
|
||||
-
|
||||
-def is_rotational(h):
|
||||
- return False
|
||||
-
|
||||
-
|
||||
-def can_trim(h):
|
||||
- return True
|
||||
-
|
||||
-
|
||||
-def pread(h, buf, offset, flags):
|
||||
- global disk
|
||||
- end = offset + len(buf)
|
||||
- buf[:] = disk[offset:end]
|
||||
-
|
||||
-
|
||||
-def pwrite(h, buf, offset, flags):
|
||||
- global disk
|
||||
- end = offset + len(buf)
|
||||
- disk[offset:end] = buf
|
||||
-
|
||||
-
|
||||
-def flush(h, flags):
|
||||
- pass
|
||||
-
|
||||
-
|
||||
-def trim(h, count, offset, flags):
|
||||
- pass
|
||||
-
|
||||
-
|
||||
-def zero(h, count, offset, flags):
|
||||
- global disk
|
||||
- disk[offset:offset+count] = bytearray(count)
|
||||
diff --git a/tests/test_python.py b/tests/test_python.py
|
||||
new file mode 100755
|
||||
index 0000000..6b9f297
|
||||
--- /dev/null
|
||||
+++ b/tests/test_python.py
|
||||
@@ -0,0 +1,222 @@
|
||||
+#!/usr/bin/env python3
|
||||
+# 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.
|
||||
+
|
||||
+"""
|
||||
+This tests the Python plugin thoroughly by issuing client commands
|
||||
+through libnbd and checking we get the expected results. It uses an
|
||||
+associated plugin (test-python-plugin.sh).
|
||||
+"""
|
||||
+
|
||||
+import os
|
||||
+import sys
|
||||
+import nbd
|
||||
+import unittest
|
||||
+import pickle
|
||||
+import base64
|
||||
+
|
||||
+class Test (unittest.TestCase):
|
||||
+ def setUp (self):
|
||||
+ self.h = nbd.NBD ()
|
||||
+
|
||||
+ def tearDown (self):
|
||||
+ del self.h
|
||||
+
|
||||
+ def connect (self, cfg):
|
||||
+ cfg = base64.b64encode (pickle.dumps (cfg)).decode()
|
||||
+ cmd = ["nbdkit", "-v", "-s", "--exit-with-parent",
|
||||
+ "python", "test-python-plugin.py", "cfg=" + cfg]
|
||||
+ self.h.connect_command (cmd)
|
||||
+
|
||||
+ def test_none (self):
|
||||
+ """
|
||||
+ Test we can send an empty pickled test configuration and do
|
||||
+ nothing else. This is just to ensure the machinery of the
|
||||
+ test works.
|
||||
+ """
|
||||
+ self.connect ({})
|
||||
+
|
||||
+ def test_size_512 (self):
|
||||
+ """Test the size."""
|
||||
+ self.connect ({"size": 512})
|
||||
+ assert self.h.get_size() == 512
|
||||
+
|
||||
+ def test_size_1m (self):
|
||||
+ """Test the size."""
|
||||
+ self.connect ({"size": 1024*1024})
|
||||
+ assert self.h.get_size() == 1024*1024
|
||||
+
|
||||
+ # Test each flag call.
|
||||
+ def test_is_rotational_true (self):
|
||||
+ self.connect ({"size": 512, "is_rotational": True})
|
||||
+ assert self.h.is_rotational()
|
||||
+
|
||||
+ def test_is_rotational_false (self):
|
||||
+ self.connect ({"size": 512, "is_rotational": False})
|
||||
+ assert not self.h.is_rotational()
|
||||
+
|
||||
+ def test_can_multi_conn_true (self):
|
||||
+ self.connect ({"size": 512, "can_multi_conn": True})
|
||||
+ assert self.h.can_multi_conn()
|
||||
+
|
||||
+ def test_can_multi_conn_false (self):
|
||||
+ self.connect ({"size": 512, "can_multi_conn": False})
|
||||
+ assert not self.h.can_multi_conn()
|
||||
+
|
||||
+ def test_read_write (self):
|
||||
+ self.connect ({"size": 512, "can_write": True})
|
||||
+ assert not self.h.is_read_only()
|
||||
+
|
||||
+ def test_read_only (self):
|
||||
+ self.connect ({"size": 512, "can_write": False})
|
||||
+ assert self.h.is_read_only()
|
||||
+
|
||||
+ def test_can_flush_true (self):
|
||||
+ self.connect ({"size": 512, "can_flush": True})
|
||||
+ assert self.h.can_flush()
|
||||
+
|
||||
+ def test_can_flush_false (self):
|
||||
+ self.connect ({"size": 512, "can_flush": False})
|
||||
+ assert not self.h.can_flush()
|
||||
+
|
||||
+ def test_can_trim_true (self):
|
||||
+ self.connect ({"size": 512, "can_trim": True})
|
||||
+ assert self.h.can_trim()
|
||||
+
|
||||
+ def test_can_trim_false (self):
|
||||
+ self.connect ({"size": 512, "can_trim": False})
|
||||
+ assert not self.h.can_trim()
|
||||
+
|
||||
+ # nbdkit can always zero because it emulates it.
|
||||
+ #self.connect ({"size": 512, "can_zero": True})
|
||||
+ #assert self.h.can_zero()
|
||||
+ #self.connect ({"size": 512, "can_zero": False})
|
||||
+ #assert not self.h.can_zero()
|
||||
+
|
||||
+ def test_can_fast_zero_true (self):
|
||||
+ self.connect ({"size": 512, "can_fast_zero": True})
|
||||
+ assert self.h.can_fast_zero()
|
||||
+
|
||||
+ def test_can_fast_zero_false (self):
|
||||
+ self.connect ({"size": 512, "can_fast_zero": False})
|
||||
+ assert not self.h.can_fast_zero()
|
||||
+
|
||||
+ def test_can_fua_none (self):
|
||||
+ self.connect ({"size": 512, "can_fua": "none"})
|
||||
+ assert not self.h.can_fua()
|
||||
+
|
||||
+ def test_can_fua_emulate (self):
|
||||
+ self.connect ({"size": 512, "can_fua": "emulate"})
|
||||
+ assert self.h.can_fua()
|
||||
+
|
||||
+ def test_can_fua_native (self):
|
||||
+ self.connect ({"size": 512, "can_fua": "native"})
|
||||
+ assert self.h.can_fua()
|
||||
+
|
||||
+ def test_can_cache_none (self):
|
||||
+ self.connect ({"size": 512, "can_cache": "none"})
|
||||
+ assert not self.h.can_cache()
|
||||
+
|
||||
+ def test_can_cache_emulate (self):
|
||||
+ self.connect ({"size": 512, "can_cache": "emulate"})
|
||||
+ assert self.h.can_cache()
|
||||
+
|
||||
+ def test_can_cache_native (self):
|
||||
+ self.connect ({"size": 512, "can_cache": "native"})
|
||||
+ assert self.h.can_cache()
|
||||
+
|
||||
+ # Not yet implemented: can_extents.
|
||||
+
|
||||
+ def test_pread (self):
|
||||
+ """Test pread."""
|
||||
+ self.connect ({"size": 512})
|
||||
+ buf = self.h.pread (512, 0)
|
||||
+ assert buf == bytearray (512)
|
||||
+
|
||||
+ # Test pwrite + flags.
|
||||
+ def test_pwrite (self):
|
||||
+ self.connect ({"size": 512})
|
||||
+ buf = bytearray (512)
|
||||
+ self.h.pwrite (buf, 0)
|
||||
+
|
||||
+ def test_pwrite_fua (self):
|
||||
+ self.connect ({"size": 512,
|
||||
+ "can_fua": "native",
|
||||
+ "pwrite_expect_fua": True})
|
||||
+ buf = bytearray (512)
|
||||
+ self.h.pwrite (buf, 0, nbd.CMD_FLAG_FUA)
|
||||
+
|
||||
+ def test_flush (self):
|
||||
+ """Test flush."""
|
||||
+ self.connect ({"size": 512, "can_flush": True})
|
||||
+ self.h.flush ()
|
||||
+
|
||||
+ # Test trim + flags.
|
||||
+ def test_trim (self):
|
||||
+ self.connect ({"size": 512, "can_trim": True})
|
||||
+ self.h.trim (512, 0)
|
||||
+
|
||||
+ def test_trim_fua (self):
|
||||
+ self.connect ({"size": 512,
|
||||
+ "can_trim": True,
|
||||
+ "can_fua": "native",
|
||||
+ "trim_expect_fua": True})
|
||||
+ self.h.trim (512, 0, nbd.CMD_FLAG_FUA)
|
||||
+
|
||||
+ # Test zero + flags.
|
||||
+ def test_zero (self):
|
||||
+ self.connect ({"size": 512, "can_zero": True})
|
||||
+ self.h.zero (512, 0, nbd.CMD_FLAG_NO_HOLE)
|
||||
+
|
||||
+ def test_zero_fua (self):
|
||||
+ self.connect ({"size": 512,
|
||||
+ "can_zero": True,
|
||||
+ "can_fua": "native",
|
||||
+ "zero_expect_fua": True})
|
||||
+ self.h.zero (512, 0, nbd.CMD_FLAG_NO_HOLE | nbd.CMD_FLAG_FUA)
|
||||
+
|
||||
+ def test_zero_may_trim (self):
|
||||
+ self.connect ({"size": 512,
|
||||
+ "can_zero": True,
|
||||
+ "zero_expect_may_trim": True})
|
||||
+ self.h.zero (512, 0, 0) # absence of nbd.CMD_FLAG_NO_HOLE
|
||||
+
|
||||
+ def test_zero_fast_zero (self):
|
||||
+ self.connect ({"size": 512,
|
||||
+ "can_zero": True,
|
||||
+ "can_fast_zero": True,
|
||||
+ "zero_expect_fast_zero": True})
|
||||
+ self.h.zero (512, 0, nbd.CMD_FLAG_NO_HOLE | nbd.CMD_FLAG_FAST_ZERO)
|
||||
+
|
||||
+ def test_cache (self):
|
||||
+ """Test cache."""
|
||||
+ self.connect ({"size": 512, "can_cache": "native"})
|
||||
+ self.h.cache (512, 0)
|
||||
--
|
||||
2.18.2
|
||||
|
790
SOURCES/0011-New-filter-extentlist.patch
Normal file
790
SOURCES/0011-New-filter-extentlist.patch
Normal file
@ -0,0 +1,790 @@
|
||||
From e744dcb38cc52cbe64977efcdd4bc60e802d1b17 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 23 Jan 2020 19:52:00 +0000
|
||||
Subject: [PATCH] New filter: extentlist.
|
||||
|
||||
Allows a list of extents to be placed on top of an existing plugin.
|
||||
|
||||
(cherry picked from commit 3e770b6d6620a62546849a2863638041c0b00640)
|
||||
---
|
||||
TODO | 4 +
|
||||
configure.ac | 2 +
|
||||
.../nbdkit-cacheextents-filter.pod | 1 +
|
||||
filters/extentlist/Makefile.am | 67 ++++
|
||||
filters/extentlist/extentlist.c | 326 ++++++++++++++++++
|
||||
.../extentlist/nbdkit-extentlist-filter.pod | 90 +++++
|
||||
filters/noextents/nbdkit-noextents-filter.pod | 1 +
|
||||
tests/Makefile.am | 4 +
|
||||
tests/test-extentlist.sh | 175 ++++++++++
|
||||
9 files changed, 670 insertions(+)
|
||||
create mode 100644 filters/extentlist/Makefile.am
|
||||
create mode 100644 filters/extentlist/extentlist.c
|
||||
create mode 100644 filters/extentlist/nbdkit-extentlist-filter.pod
|
||||
create mode 100755 tests/test-extentlist.sh
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index d2aca44..2a3e89d 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -187,6 +187,10 @@ Suggestions for filters
|
||||
MBs of extra data)
|
||||
https://github.com/facebook/zstd/issues/395#issuecomment-535875379
|
||||
|
||||
+* nbdkit-extentlist-filter could read the extents generated by
|
||||
+ qemu-img map, allowing extents to be ported from a qemu block
|
||||
+ device.
|
||||
+
|
||||
nbdkit-rate-filter:
|
||||
|
||||
* allow other kinds of traffic shaping such as VBR
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index fde498b..41e68de 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -896,6 +896,7 @@ filters="\
|
||||
cow \
|
||||
delay \
|
||||
error \
|
||||
+ extentlist \
|
||||
fua \
|
||||
log \
|
||||
nocache \
|
||||
@@ -979,6 +980,7 @@ AC_CONFIG_FILES([Makefile
|
||||
filters/cow/Makefile
|
||||
filters/delay/Makefile
|
||||
filters/error/Makefile
|
||||
+ filters/extentlist/Makefile
|
||||
filters/fua/Makefile
|
||||
filters/log/Makefile
|
||||
filters/nocache/Makefile
|
||||
diff --git a/filters/cacheextents/nbdkit-cacheextents-filter.pod b/filters/cacheextents/nbdkit-cacheextents-filter.pod
|
||||
index fdd2285..bb2514a 100644
|
||||
--- a/filters/cacheextents/nbdkit-cacheextents-filter.pod
|
||||
+++ b/filters/cacheextents/nbdkit-cacheextents-filter.pod
|
||||
@@ -52,6 +52,7 @@ C<nbdkit-cacheextents-filter> first appeared in nbdkit 1.14.
|
||||
|
||||
L<nbdkit(1)>,
|
||||
L<nbdkit-cache-filter(1)>,
|
||||
+L<nbdkit-extentlist-filter(1)>,
|
||||
L<nbdkit-readahead-filter(1)>,
|
||||
L<nbdkit-vddk-plugin(1)>,
|
||||
L<nbdkit-filter(3)>,
|
||||
diff --git a/filters/extentlist/Makefile.am b/filters/extentlist/Makefile.am
|
||||
new file mode 100644
|
||||
index 0000000..88a9afe
|
||||
--- /dev/null
|
||||
+++ b/filters/extentlist/Makefile.am
|
||||
@@ -0,0 +1,67 @@
|
||||
+# nbdkit
|
||||
+# Copyright (C) 2019-2020 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.
|
||||
+
|
||||
+include $(top_srcdir)/common-rules.mk
|
||||
+
|
||||
+EXTRA_DIST = nbdkit-extentlist-filter.pod
|
||||
+
|
||||
+filter_LTLIBRARIES = nbdkit-extentlist-filter.la
|
||||
+
|
||||
+nbdkit_extentlist_filter_la_SOURCES = \
|
||||
+ extentlist.c \
|
||||
+ $(top_srcdir)/include/nbdkit-filter.h \
|
||||
+ $(NULL)
|
||||
+
|
||||
+nbdkit_extentlist_filter_la_CPPFLAGS = \
|
||||
+ -I$(top_srcdir)/include \
|
||||
+ -I$(top_srcdir)/common/include \
|
||||
+ -I$(top_srcdir)/common/utils \
|
||||
+ $(NULL)
|
||||
+nbdkit_extentlist_filter_la_CFLAGS = $(WARNINGS_CFLAGS)
|
||||
+nbdkit_extentlist_filter_la_LDFLAGS = \
|
||||
+ -module -avoid-version -shared \
|
||||
+ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \
|
||||
+ $(NULL)
|
||||
+nbdkit_extentlist_filter_la_LIBADD = \
|
||||
+ $(top_builddir)/common/utils/libutils.la \
|
||||
+ $(NULL)
|
||||
+
|
||||
+if HAVE_POD
|
||||
+
|
||||
+man_MANS = nbdkit-extentlist-filter.1
|
||||
+CLEANFILES += $(man_MANS)
|
||||
+
|
||||
+nbdkit-extentlist-filter.1: nbdkit-extentlist-filter.pod
|
||||
+ $(PODWRAPPER) --section=1 --man $@ \
|
||||
+ --html $(top_builddir)/html/$@.html \
|
||||
+ $<
|
||||
+
|
||||
+endif HAVE_POD
|
||||
diff --git a/filters/extentlist/extentlist.c b/filters/extentlist/extentlist.c
|
||||
new file mode 100644
|
||||
index 0000000..5f4990b
|
||||
--- /dev/null
|
||||
+++ b/filters/extentlist/extentlist.c
|
||||
@@ -0,0 +1,326 @@
|
||||
+/* nbdkit
|
||||
+ * Copyright (C) 2019-2020 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.
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdint.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <string.h>
|
||||
+#include <errno.h>
|
||||
+#include <assert.h>
|
||||
+
|
||||
+#include <nbdkit-filter.h>
|
||||
+
|
||||
+#include "cleanup.h"
|
||||
+#include "minmax.h"
|
||||
+
|
||||
+#define HOLE (NBDKIT_EXTENT_HOLE|NBDKIT_EXTENT_ZERO)
|
||||
+
|
||||
+static const char *extentlist;
|
||||
+
|
||||
+/* List of extents. Once we've finally parsed them this will be
|
||||
+ * ordered, non-overlapping and have no gaps.
|
||||
+ */
|
||||
+struct extent {
|
||||
+ uint64_t offset, length;
|
||||
+ uint32_t type;
|
||||
+};
|
||||
+static struct extent *extents;
|
||||
+static size_t nr_extents, allocated;
|
||||
+
|
||||
+/* Insert an extent before i. If i = nr_extents, inserts at the end. */
|
||||
+static void
|
||||
+insert_extent (size_t i, struct extent new_extent)
|
||||
+{
|
||||
+ if (nr_extents >= allocated) {
|
||||
+ allocated = allocated == 0 ? 1 : allocated * 2;
|
||||
+ extents = realloc (extents, (sizeof (struct extent) * allocated));
|
||||
+ if (extents == NULL) {
|
||||
+ nbdkit_error ("realloc: %m");
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ }
|
||||
+ memmove (&extents[i+1], &extents[i],
|
||||
+ sizeof (struct extent) * (nr_extents-i));
|
||||
+ extents[i] = new_extent;
|
||||
+ nr_extents++;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+extentlist_unload (void)
|
||||
+{
|
||||
+ free (extents);
|
||||
+}
|
||||
+
|
||||
+/* Called for each key=value passed on the command line. */
|
||||
+static int
|
||||
+extentlist_config (nbdkit_next_config *next, void *nxdata,
|
||||
+ const char *key, const char *value)
|
||||
+{
|
||||
+ if (strcmp (key, "extentlist") == 0) {
|
||||
+ if (extentlist != NULL) {
|
||||
+ nbdkit_error ("extentlist cannot appear twice");
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ extentlist = value;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ return next (nxdata, key, value);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+compare_offsets (const void *ev1, const void *ev2)
|
||||
+{
|
||||
+ const struct extent *e1 = ev1;
|
||||
+ const struct extent *e2 = ev2;
|
||||
+
|
||||
+ if (e1->offset < e2->offset)
|
||||
+ return -1;
|
||||
+ else if (e1->offset > e2->offset)
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+compare_ranges (const void *ev1, const void *ev2)
|
||||
+{
|
||||
+ const struct extent *e1 = ev1;
|
||||
+ const struct extent *e2 = ev2;
|
||||
+
|
||||
+ if (e1->offset < e2->offset)
|
||||
+ return -1;
|
||||
+ else if (e1->offset >= e2->offset + e2->length)
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Similar to parse_extents in plugins/sh/methods.c */
|
||||
+static void
|
||||
+parse_extentlist (void)
|
||||
+{
|
||||
+ FILE *fp;
|
||||
+ CLEANUP_FREE char *line = NULL;
|
||||
+ size_t linelen = 0;
|
||||
+ ssize_t len;
|
||||
+ size_t i;
|
||||
+ uint64_t end;
|
||||
+
|
||||
+ assert (extentlist != NULL);
|
||||
+ assert (extents == NULL);
|
||||
+ assert (nr_extents == 0);
|
||||
+
|
||||
+ fp = fopen (extentlist, "r");
|
||||
+ if (!fp) {
|
||||
+ nbdkit_error ("open: %s: %m", extentlist);
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ while ((len = getline (&line, &linelen, fp)) != -1) {
|
||||
+ const char *delim = " \t";
|
||||
+ char *sp, *p;
|
||||
+ int64_t offset, length;
|
||||
+ uint32_t type;
|
||||
+
|
||||
+ if (len > 0 && line[len-1] == '\n') {
|
||||
+ line[len-1] = '\0';
|
||||
+ len--;
|
||||
+ }
|
||||
+
|
||||
+ if ((p = strtok_r (line, delim, &sp)) == NULL) {
|
||||
+ parse_error:
|
||||
+ nbdkit_error ("%s: cannot parse %s", extentlist, line);
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ offset = nbdkit_parse_size (p);
|
||||
+ if (offset == -1)
|
||||
+ exit (EXIT_FAILURE);
|
||||
+
|
||||
+ if ((p = strtok_r (NULL, delim, &sp)) == NULL)
|
||||
+ goto parse_error;
|
||||
+ length = nbdkit_parse_size (p);
|
||||
+ if (length == -1)
|
||||
+ exit (EXIT_FAILURE);
|
||||
+
|
||||
+ /* Skip zero length extents. Makes the rest of the code easier. */
|
||||
+ if (length == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ if ((p = strtok_r (NULL, delim, &sp)) == NULL)
|
||||
+ /* empty type field means allocated data (0) */
|
||||
+ type = 0;
|
||||
+ else if (sscanf (p, "%" SCNu32, &type) == 1)
|
||||
+ ;
|
||||
+ else {
|
||||
+ type = 0;
|
||||
+ if (strstr (p, "hole") != NULL)
|
||||
+ type |= NBDKIT_EXTENT_HOLE;
|
||||
+ if (strstr (p, "zero") != NULL)
|
||||
+ type |= NBDKIT_EXTENT_ZERO;
|
||||
+ }
|
||||
+
|
||||
+ insert_extent (nr_extents,
|
||||
+ (struct extent){.offset = offset, .length=length,
|
||||
+ .type=type});
|
||||
+ }
|
||||
+
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ /* Sort the extents by offset. */
|
||||
+ qsort (extents, nr_extents, sizeof (struct extent), compare_offsets);
|
||||
+
|
||||
+ /* There must not be overlaps at this point. */
|
||||
+ end = 0;
|
||||
+ for (i = 0; i < nr_extents; ++i) {
|
||||
+ if (extents[i].offset < end ||
|
||||
+ extents[i].offset + extents[i].length < extents[i].offset) {
|
||||
+ nbdkit_error ("extents in the extent list are overlapping");
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ end = extents[i].offset + extents[i].length;
|
||||
+ }
|
||||
+
|
||||
+ /* If there's a gap at the beginning, insert a hole|zero extent. */
|
||||
+ if (nr_extents == 0 || extents[0].offset > 0) {
|
||||
+ end = nr_extents == 0 ? UINT64_MAX : extents[0].offset;
|
||||
+ insert_extent (0, (struct extent){.offset = 0, .length = end,
|
||||
+ .type = HOLE});
|
||||
+ }
|
||||
+
|
||||
+ /* Now insert hole|zero extents after every extent where there
|
||||
+ * is a gap between that extent and the next one.
|
||||
+ */
|
||||
+ for (i = 0; i < nr_extents-1; ++i) {
|
||||
+ end = extents[i].offset + extents[i].length;
|
||||
+ if (end < extents[i+1].offset)
|
||||
+ insert_extent (i+1, (struct extent){.offset = end,
|
||||
+ .length = extents[i+1].offset - end,
|
||||
+ .type = HOLE});
|
||||
+ }
|
||||
+
|
||||
+ /* If there's a gap at the end, insert a hole|zero extent. */
|
||||
+ end = extents[nr_extents-1].offset + extents[nr_extents-1].length;
|
||||
+ if (end < UINT64_MAX)
|
||||
+ insert_extent (nr_extents, (struct extent){.offset = end,
|
||||
+ .length = UINT64_MAX-end,
|
||||
+ .type = HOLE});
|
||||
+
|
||||
+ /* Debug the final list. */
|
||||
+ for (i = 0; i < nr_extents; ++i) {
|
||||
+ nbdkit_debug ("extentlist: "
|
||||
+ "extent[%zu] = %" PRIu64 "-%" PRIu64 " (length %" PRIu64 ")"
|
||||
+ " type %" PRIu32,
|
||||
+ i, extents[i].offset,
|
||||
+ extents[i].offset + extents[i].length - 1,
|
||||
+ extents[i].length,
|
||||
+ extents[i].type);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+extentlist_config_complete (nbdkit_next_config_complete *next, void *nxdata)
|
||||
+{
|
||||
+ if (extentlist == NULL) {
|
||||
+ nbdkit_error ("you must supply the extentlist parameter "
|
||||
+ "on the command line");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ parse_extentlist ();
|
||||
+
|
||||
+ return next (nxdata);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+extentlist_can_extents (struct nbdkit_next_ops *next_ops, void *nxdata,
|
||||
+ void *handle)
|
||||
+{
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+/* Use ‘-D extentlist.lookup=1’ to debug the function below. */
|
||||
+int extentlist_debug_lookup = 0;
|
||||
+
|
||||
+/* Read extents. */
|
||||
+static int
|
||||
+extentlist_extents (struct nbdkit_next_ops *next_ops, void *nxdata,
|
||||
+ void *handle, uint32_t count, uint64_t offset,
|
||||
+ uint32_t flags,
|
||||
+ struct nbdkit_extents *ret_extents,
|
||||
+ int *err)
|
||||
+{
|
||||
+ const struct extent eoffset = { .offset = offset };
|
||||
+ struct extent *p;
|
||||
+ ssize_t i;
|
||||
+ uint64_t end;
|
||||
+
|
||||
+ /* Find the starting point in the extents list. */
|
||||
+ p = bsearch (&eoffset, extents,
|
||||
+ nr_extents, sizeof (struct extent), compare_ranges);
|
||||
+ assert (p != NULL);
|
||||
+ i = p - extents;
|
||||
+
|
||||
+ /* Add extents to the output. */
|
||||
+ while (count > 0) {
|
||||
+ if (extentlist_debug_lookup)
|
||||
+ nbdkit_debug ("extentlist lookup: "
|
||||
+ "loop i=%zd count=%" PRIu32 " offset=%" PRIu64,
|
||||
+ i, count, offset);
|
||||
+
|
||||
+ end = extents[i].offset + extents[i].length;
|
||||
+ if (nbdkit_add_extent (ret_extents, offset, end - offset,
|
||||
+ extents[i].type) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ count -= MIN (count, end-offset);
|
||||
+ offset = end;
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct nbdkit_filter filter = {
|
||||
+ .name = "extentlist",
|
||||
+ .longname = "nbdkit extentlist filter",
|
||||
+ .unload = extentlist_unload,
|
||||
+ .config = extentlist_config,
|
||||
+ .config_complete = extentlist_config_complete,
|
||||
+ .can_extents = extentlist_can_extents,
|
||||
+ .extents = extentlist_extents,
|
||||
+};
|
||||
+
|
||||
+NBDKIT_REGISTER_FILTER(filter)
|
||||
diff --git a/filters/extentlist/nbdkit-extentlist-filter.pod b/filters/extentlist/nbdkit-extentlist-filter.pod
|
||||
new file mode 100644
|
||||
index 0000000..adfb4ad
|
||||
--- /dev/null
|
||||
+++ b/filters/extentlist/nbdkit-extentlist-filter.pod
|
||||
@@ -0,0 +1,90 @@
|
||||
+=head1 NAME
|
||||
+
|
||||
+nbdkit-extentlist-filter - place extent list over a plugin
|
||||
+
|
||||
+=head1 SYNOPSIS
|
||||
+
|
||||
+ nbdkit --filter=extentlist plugin extentlist=FILENAME
|
||||
+
|
||||
+=head1 DESCRIPTION
|
||||
+
|
||||
+C<nbdkit-extentlist-filter> is an nbdkit filter lets you place a
|
||||
+static list of extents on top of an existing plugin. Extents record
|
||||
+whether or not specific parts of the disk are allocated or sparse.
|
||||
+
|
||||
+You can use this with plugins which cannot get extent information
|
||||
+themselves, but you can get this information from another source. One
|
||||
+place where it is useful is with L<nbdkit-ssh-plugin(1)> because the
|
||||
+sftp protocol does not support reading sparseness information, but you
|
||||
+may be able to get this information directly from the source disk on
|
||||
+the remote server.
|
||||
+
|
||||
+=head1 FILE FORMAT
|
||||
+
|
||||
+The list of extents is specified in a text file. There is one extent
|
||||
+specified per line. Each line has the format:
|
||||
+
|
||||
+ offset length type
|
||||
+
|
||||
+The C<offset> and C<length> fields may use any format understood by
|
||||
+C<nbdkit_parse_size>. The optional C<type> field may be an integer,
|
||||
+missing (same as 0), or a comma-separated list of the words C<hole>
|
||||
+and C<zero>. (The fields correspond to the inputs of the
|
||||
+C<nbdkit_add_extent> function, see L<nbdkit-plugin(3)>).
|
||||
+
|
||||
+An example of a valid set of extents covering a C<10M> disk where the
|
||||
+first megabyte only is allocated data:
|
||||
+
|
||||
+ 0 1M
|
||||
+ 1M 9M hole,zero
|
||||
+
|
||||
+Or you could omit the C<hole,zero> extent since any gaps are assumed
|
||||
+to be holes with that type:
|
||||
+
|
||||
+ 0 1M
|
||||
+
|
||||
+The extent list need not cover the whole disk, and does not need to be
|
||||
+in ascending order, but it must I<not> contain overlapping extents.
|
||||
+
|
||||
+=head1 PARAMETERS
|
||||
+
|
||||
+=over 4
|
||||
+
|
||||
+=item B<extentlist=>FILENAME
|
||||
+
|
||||
+Specify the file containing the extent list, in the format described
|
||||
+in L</FILE FORMAT> above.
|
||||
+
|
||||
+=back
|
||||
+
|
||||
+=head1 FILES
|
||||
+
|
||||
+=over 4
|
||||
+
|
||||
+=item F<$filterdir/nbdkit-extentlist-filter.so>
|
||||
+
|
||||
+The filter.
|
||||
+
|
||||
+Use C<nbdkit --dump-config> to find the location of C<$filterdir>.
|
||||
+
|
||||
+=back
|
||||
+
|
||||
+=head1 VERSION
|
||||
+
|
||||
+C<nbdkit-extentlist-filter> first appeared in nbdkit 1.18.
|
||||
+
|
||||
+=head1 SEE ALSO
|
||||
+
|
||||
+L<nbdkit(1)>,
|
||||
+L<nbdkit-cacheextents-filter(1)>,
|
||||
+L<nbdkit-noextents-filter(1)>,
|
||||
+L<nbdkit-filter(3)>,
|
||||
+L<nbdkit-plugin(3)>.
|
||||
+
|
||||
+=head1 AUTHORS
|
||||
+
|
||||
+Richard W.M. Jones
|
||||
+
|
||||
+=head1 COPYRIGHT
|
||||
+
|
||||
+Copyright (C) 2020 Red Hat Inc.
|
||||
diff --git a/filters/noextents/nbdkit-noextents-filter.pod b/filters/noextents/nbdkit-noextents-filter.pod
|
||||
index 991ecfe..0260a5c 100644
|
||||
--- a/filters/noextents/nbdkit-noextents-filter.pod
|
||||
+++ b/filters/noextents/nbdkit-noextents-filter.pod
|
||||
@@ -47,6 +47,7 @@ C<nbdkit-noextents-filter> first appeared in nbdkit 1.14.
|
||||
|
||||
L<nbdkit(1)>,
|
||||
L<nbdkit-filter(3)>,
|
||||
+L<nbdkit-extentlist-filter(1)>,
|
||||
L<nbdkit-fua-filter(1)>,
|
||||
L<nbdkit-nocache-filter(1)>,
|
||||
L<nbdkit-noparallel-filter(1)>,
|
||||
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||
index 09103fb..b99952f 100644
|
||||
--- a/tests/Makefile.am
|
||||
+++ b/tests/Makefile.am
|
||||
@@ -110,6 +110,7 @@ EXTRA_DIST = \
|
||||
test-error100.sh \
|
||||
test-error-triggered.sh \
|
||||
test-export-name.sh \
|
||||
+ test-extentlist.sh \
|
||||
test-file-extents.sh \
|
||||
test-floppy.sh \
|
||||
test-foreground.sh \
|
||||
@@ -1009,6 +1010,9 @@ TESTS += \
|
||||
test-error-triggered.sh \
|
||||
$(NULL)
|
||||
|
||||
+# extentlist filter test.
|
||||
+TESTS += test-extentlist.sh
|
||||
+
|
||||
# fua filter test.
|
||||
TESTS += test-fua.sh
|
||||
|
||||
diff --git a/tests/test-extentlist.sh b/tests/test-extentlist.sh
|
||||
new file mode 100755
|
||||
index 0000000..7d05de4
|
||||
--- /dev/null
|
||||
+++ b/tests/test-extentlist.sh
|
||||
@@ -0,0 +1,175 @@
|
||||
+#!/usr/bin/env bash
|
||||
+# nbdkit
|
||||
+# Copyright (C) 2016-2020 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.
|
||||
+
|
||||
+# Test the extentlist filter.
|
||||
+
|
||||
+source ./functions.sh
|
||||
+set -e
|
||||
+set -x
|
||||
+
|
||||
+requires jq --version
|
||||
+requires qemu-img --version
|
||||
+requires qemu-img map --help
|
||||
+
|
||||
+out=test-extentlist.out
|
||||
+input=test-extentlist.in
|
||||
+expected=test-extentlist.expected
|
||||
+files="$out $input $expected"
|
||||
+rm -f $files
|
||||
+cleanup_fn rm $files
|
||||
+
|
||||
+test ()
|
||||
+{
|
||||
+ nbdkit -v -D extentlist.lookup=1 \
|
||||
+ -U - \
|
||||
+ --filter=extentlist \
|
||||
+ null size=$1 extentlist=$input \
|
||||
+ --run 'qemu-img map -f raw --output=json $nbd' |
|
||||
+ jq -c '.[] | {start:.start, length:.length, data:.data, zero:.zero}' \
|
||||
+ > $out
|
||||
+ diff -u $out $expected
|
||||
+}
|
||||
+
|
||||
+# Empty extent list.
|
||||
+cat > $input <<'EOF'
|
||||
+EOF
|
||||
+
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":0,"data":false,"zero":false}
|
||||
+EOF
|
||||
+test 0
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":false,"zero":true}
|
||||
+EOF
|
||||
+test 1M
|
||||
+
|
||||
+# Extent list covering 0-1M with data.
|
||||
+cat > $input <<'EOF'
|
||||
+0 1M
|
||||
+EOF
|
||||
+
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":0,"data":false,"zero":false}
|
||||
+EOF
|
||||
+test 0
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":true,"zero":false}
|
||||
+EOF
|
||||
+test 1M
|
||||
+
|
||||
+# Extent list covering 1-2M with data.
|
||||
+cat > $input <<'EOF'
|
||||
+1M 1M
|
||||
+EOF
|
||||
+
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":0,"data":false,"zero":false}
|
||||
+EOF
|
||||
+test 0
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":false,"zero":true}
|
||||
+EOF
|
||||
+test 1M
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":false,"zero":true}
|
||||
+{"start":1048576,"length":1048576,"data":true,"zero":false}
|
||||
+EOF
|
||||
+test 2M
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":false,"zero":true}
|
||||
+{"start":1048576,"length":1048576,"data":true,"zero":false}
|
||||
+{"start":2097152,"length":1048576,"data":false,"zero":true}
|
||||
+EOF
|
||||
+test 3M
|
||||
+
|
||||
+# Extent list covering 1-2M with data, but in a more fragmented
|
||||
+# way than the above.
|
||||
+cat > $input <<'EOF'
|
||||
+1024K 512K
|
||||
+1536K 512K
|
||||
+EOF
|
||||
+
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":0,"data":false,"zero":false}
|
||||
+EOF
|
||||
+test 0
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":false,"zero":true}
|
||||
+EOF
|
||||
+test 1M
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":false,"zero":true}
|
||||
+{"start":1048576,"length":1048576,"data":true,"zero":false}
|
||||
+EOF
|
||||
+test 2M
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":false,"zero":true}
|
||||
+{"start":1048576,"length":1048576,"data":true,"zero":false}
|
||||
+{"start":2097152,"length":1048576,"data":false,"zero":true}
|
||||
+EOF
|
||||
+test 3M
|
||||
+
|
||||
+# Adjacent data and holes.
|
||||
+cat > $input <<'EOF'
|
||||
+0 1M
|
||||
+2M 1M
|
||||
+4M 1M
|
||||
+EOF
|
||||
+
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":0,"data":false,"zero":false}
|
||||
+EOF
|
||||
+test 0
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":true,"zero":false}
|
||||
+EOF
|
||||
+test 1M
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":true,"zero":false}
|
||||
+{"start":1048576,"length":1048576,"data":false,"zero":true}
|
||||
+EOF
|
||||
+test 2M
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":true,"zero":false}
|
||||
+{"start":1048576,"length":1048576,"data":false,"zero":true}
|
||||
+{"start":2097152,"length":1048576,"data":true,"zero":false}
|
||||
+EOF
|
||||
+test 3M
|
||||
+cat > $expected <<'EOF'
|
||||
+{"start":0,"length":1048576,"data":true,"zero":false}
|
||||
+{"start":1048576,"length":1048576,"data":false,"zero":true}
|
||||
+{"start":2097152,"length":1048576,"data":true,"zero":false}
|
||||
+{"start":3145728,"length":1048576,"data":false,"zero":true}
|
||||
+{"start":4194304,"length":1048576,"data":true,"zero":false}
|
||||
+{"start":5242880,"length":1048576,"data":false,"zero":true}
|
||||
+EOF
|
||||
+test 6M
|
||||
--
|
||||
2.18.2
|
||||
|
125
SOURCES/0012-extentlist-Documentation-and-test-fixes.patch
Normal file
125
SOURCES/0012-extentlist-Documentation-and-test-fixes.patch
Normal file
@ -0,0 +1,125 @@
|
||||
From 2a3e909e9e1ccb608bde75b76524acd753b33889 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Sat, 25 Jan 2020 11:38:14 +0000
|
||||
Subject: [PATCH] extentlist: Documentation and test fixes.
|
||||
|
||||
Updates commit 3e770b6d6620a62546849a2863638041c0b00640.
|
||||
|
||||
(cherry picked from commit c16709ef663a5ed9fd9ddef4e379f316d84c9a07)
|
||||
---
|
||||
TODO | 12 +++++++----
|
||||
.../extentlist/nbdkit-extentlist-filter.pod | 21 +++++++++++++------
|
||||
plugins/curl/nbdkit-curl-plugin.pod | 1 +
|
||||
plugins/ssh/nbdkit-ssh-plugin.pod | 1 +
|
||||
tests/test-extentlist.sh | 2 +-
|
||||
5 files changed, 26 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index 2a3e89d..e1ac71c 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -187,10 +187,6 @@ Suggestions for filters
|
||||
MBs of extra data)
|
||||
https://github.com/facebook/zstd/issues/395#issuecomment-535875379
|
||||
|
||||
-* nbdkit-extentlist-filter could read the extents generated by
|
||||
- qemu-img map, allowing extents to be ported from a qemu block
|
||||
- device.
|
||||
-
|
||||
nbdkit-rate-filter:
|
||||
|
||||
* allow other kinds of traffic shaping such as VBR
|
||||
@@ -216,6 +212,14 @@ nbdkit-retry-filter:
|
||||
|
||||
* subsecond times
|
||||
|
||||
+nbdkit-extentlist-filter:
|
||||
+
|
||||
+* read the extents generated by qemu-img map, allowing extents to be
|
||||
+ ported from a qemu block device
|
||||
+
|
||||
+* make non-read-only access safe by updating the extent list when the
|
||||
+ filter sees writes and trims
|
||||
+
|
||||
Filters for security
|
||||
--------------------
|
||||
|
||||
diff --git a/filters/extentlist/nbdkit-extentlist-filter.pod b/filters/extentlist/nbdkit-extentlist-filter.pod
|
||||
index adfb4ad..5d1a38a 100644
|
||||
--- a/filters/extentlist/nbdkit-extentlist-filter.pod
|
||||
+++ b/filters/extentlist/nbdkit-extentlist-filter.pod
|
||||
@@ -4,7 +4,7 @@ nbdkit-extentlist-filter - place extent list over a plugin
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
- nbdkit --filter=extentlist plugin extentlist=FILENAME
|
||||
+ nbdkit -r --filter=extentlist plugin extentlist=FILENAME
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@@ -13,11 +13,20 @@ static list of extents on top of an existing plugin. Extents record
|
||||
whether or not specific parts of the disk are allocated or sparse.
|
||||
|
||||
You can use this with plugins which cannot get extent information
|
||||
-themselves, but you can get this information from another source. One
|
||||
-place where it is useful is with L<nbdkit-ssh-plugin(1)> because the
|
||||
-sftp protocol does not support reading sparseness information, but you
|
||||
-may be able to get this information directly from the source disk on
|
||||
-the remote server.
|
||||
+themselves, but where you can get this information from another
|
||||
+source. One place where it is useful is with L<nbdkit-ssh-plugin(1)>
|
||||
+because the sftp protocol does not support reading sparseness
|
||||
+information, but you may be able to get this information directly from
|
||||
+the source disk on the remote server using commands such as
|
||||
+L<xfs_bmap(8)>. A similar situation applies to
|
||||
+L<nbdkit-curl-plugin(1)>.
|
||||
+
|
||||
+Note that the extent list is read-only. This filter does not monitor
|
||||
+writes and trims in order to update the extent list. What can happen
|
||||
+is that you would write to a “hole” in the disk, but would not be able
|
||||
+to read it back because the NBD client would still think that part of
|
||||
+the disk is a hole. So it is generally only safe to use this filter
|
||||
+in read-only mode (I<-r> option).
|
||||
|
||||
=head1 FILE FORMAT
|
||||
|
||||
diff --git a/plugins/curl/nbdkit-curl-plugin.pod b/plugins/curl/nbdkit-curl-plugin.pod
|
||||
index 827e0bd..d3c8524 100644
|
||||
--- a/plugins/curl/nbdkit-curl-plugin.pod
|
||||
+++ b/plugins/curl/nbdkit-curl-plugin.pod
|
||||
@@ -182,6 +182,7 @@ L<libcurl(3)>,
|
||||
L<CURLOPT_COOKIE(3)>
|
||||
L<CURLOPT_VERBOSE(3)>,
|
||||
L<nbdkit(1)>,
|
||||
+L<nbdkit-extentlist-filter(1)>,
|
||||
L<nbdkit-readahead-filter(1)>,
|
||||
L<nbdkit-retry-filter(1)>,
|
||||
L<nbdkit-ssh-plugin(1)>,
|
||||
diff --git a/plugins/ssh/nbdkit-ssh-plugin.pod b/plugins/ssh/nbdkit-ssh-plugin.pod
|
||||
index 0a0421d..3fc3146 100644
|
||||
--- a/plugins/ssh/nbdkit-ssh-plugin.pod
|
||||
+++ b/plugins/ssh/nbdkit-ssh-plugin.pod
|
||||
@@ -316,6 +316,7 @@ C<nbdkit-ssh-plugin> first appeared in nbdkit 1.12.
|
||||
|
||||
L<nbdkit(1)>,
|
||||
L<nbdkit-curl-plugin(1)>,
|
||||
+L<nbdkit-extentlist-filter(1)>,
|
||||
L<nbdkit-readahead-filter(1)>,
|
||||
L<nbdkit-retry-filter(1)>,
|
||||
L<nbdkit-plugin(3)>,
|
||||
diff --git a/tests/test-extentlist.sh b/tests/test-extentlist.sh
|
||||
index 7d05de4..73ce3ca 100755
|
||||
--- a/tests/test-extentlist.sh
|
||||
+++ b/tests/test-extentlist.sh
|
||||
@@ -50,7 +50,7 @@ cleanup_fn rm $files
|
||||
test ()
|
||||
{
|
||||
nbdkit -v -D extentlist.lookup=1 \
|
||||
- -U - \
|
||||
+ -r -U - \
|
||||
--filter=extentlist \
|
||||
null size=$1 extentlist=$input \
|
||||
--run 'qemu-img map -f raw --output=json $nbd' |
|
||||
--
|
||||
2.18.2
|
||||
|
17
SOURCES/nbdkit-1.16.2.tar.gz.sig
Normal file
17
SOURCES/nbdkit-1.16.2.tar.gz.sig
Normal file
@ -0,0 +1,17 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAl4wFvoRHHJpY2hAYW5u
|
||||
ZXhpYS5vcmcACgkQkXOPc+G3aKASexAAmpZw61rCI7SY8zm4O0gb+pIx7oLYx0Lq
|
||||
2puIftzxUUw9Q6pFJJyXSvlsvHy3qUF7HiMVdpW61ItIChV1xBDVKEPAacNzsZh4
|
||||
30CI7kfJMfj6u+hpOCVlLk4uJFjZkmIpEKkDpEBemxLMME4JsLJdawKzKhjT2PI7
|
||||
dWMjYkOeD4NkAzQLQGskEswoIgZQ0twuyPUErjEL9fcXw4OjxFvQJG85FsIF2lR6
|
||||
FUDQg5y9YLzeMJMsjW4rO+LAz2c1mJwYR1EgYP43avm/pJfd1mVQLGRoLb7NwMSw
|
||||
6mkwhJ4Kvq6BN0PSqpKqQtXZrDoElWN8cVJVf+dAjONcvzYi0gsHWDL+FZ731Q2M
|
||||
s4nq0aRscBTL2DOaE9DzBY2AO1jKUB/+02qRpidWTYBmsmL2QQI8n33Q7JuDuEXX
|
||||
bVm1RDA4ike4PUXXY5KJ6MZhKID5453SVFausFse+u4MCQHQPFYspkXmaNWRhjgs
|
||||
yu2zPc9jHdBkpzNov/CCZoFketFRz/BKexBeH2vcfTYfREVf9lEZi7qEa0kQHDn9
|
||||
EMTFsCqmGat9TEVbt9t8c/tODTeRE00MFx4gPspzy+m4YP+Gl3ySHsAbPQ90uBGX
|
||||
c8xggwqWXr1GAP5HbAhs/Bs7USrWMMgqii1ppnzoAkHh+j4rsdL4dS2dmhxX756u
|
||||
IKP/JC2oA8U=
|
||||
=mV8z
|
||||
-----END PGP SIGNATURE-----
|
993
SPECS/nbdkit.spec
Normal file
993
SPECS/nbdkit.spec
Normal file
@ -0,0 +1,993 @@
|
||||
%global _hardened_build 1
|
||||
|
||||
%ifarch aarch64 %{arm} x86_64 ppc %{power64}
|
||||
%global have_libguestfs 1
|
||||
%endif
|
||||
|
||||
# Architectures where the complete test suite must pass.
|
||||
#
|
||||
# On all other architectures, a simpler test suite must pass. This
|
||||
# omits any tests that run full qemu, since running qemu under TCG is
|
||||
# often broken on non-x86_64 arches.
|
||||
%global complete_test_arches x86_64
|
||||
|
||||
# Disable libvirt on riscv64 for now.
|
||||
%ifnarch riscv64
|
||||
%global have_libvirt 1
|
||||
%endif
|
||||
|
||||
# If we should verify tarball signature with GPGv2.
|
||||
%global verify_tarball_signature 1
|
||||
|
||||
# If there are patches which touch autotools files, set this to 1.
|
||||
%global patches_touch_autotools 1
|
||||
|
||||
# The source directory.
|
||||
%global source_directory 1.16-stable
|
||||
|
||||
Name: nbdkit
|
||||
Version: 1.16.2
|
||||
Release: 2%{?dist}
|
||||
Summary: NBD server
|
||||
|
||||
License: BSD
|
||||
URL: https://github.com/libguestfs/nbdkit
|
||||
|
||||
Source0: http://libguestfs.org/download/nbdkit/%{source_directory}/%{name}-%{version}.tar.gz
|
||||
%if 0%{verify_tarball_signature}
|
||||
Source1: http://libguestfs.org/download/nbdkit/%{source_directory}/%{name}-%{version}.tar.gz.sig
|
||||
# Keyring used to verify tarball signature.
|
||||
Source2: libguestfs.keyring
|
||||
%endif
|
||||
|
||||
# Patches come from this upstream branch:
|
||||
# https://github.com/libguestfs/nbdkit/tree/rhel-8.2
|
||||
|
||||
# Patches.
|
||||
Patch0001: 0001-server-Allow-D-nbdkit.-debug-flags-for-the-core-serv.patch
|
||||
Patch0002: 0002-server-Allow-D-debug-flags-to-contain-dots-for-names.patch
|
||||
Patch0003: 0003-server-Add-D-nbdkit.backend.controlpath-and-D-nbdkit.patch
|
||||
Patch0004: 0004-python-Add-various-constants-to-the-API.patch
|
||||
Patch0005: 0005-python-Implement-nbdkit-API-version-2.patch
|
||||
Patch0006: 0006-python-Implement-cache.patch
|
||||
Patch0007: 0007-python-Implement-can_zero-can_fast_zero.patch
|
||||
Patch0008: 0008-python-Implement-can_multi_conn.patch
|
||||
Patch0009: 0009-python-Implement-can_fua-and-can_cache.patch
|
||||
Patch0010: 0010-tests-Test-the-Python-plugin-thoroughly.patch
|
||||
Patch0011: 0011-New-filter-extentlist.patch
|
||||
Patch0012: 0012-extentlist-Documentation-and-test-fixes.patch
|
||||
|
||||
%if 0%{patches_touch_autotools}
|
||||
BuildRequires: autoconf, automake, libtool
|
||||
%endif
|
||||
|
||||
%if 0%{patches_touch_autotools}
|
||||
BuildRequires: autoconf, automake, libtool
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel} == 8
|
||||
# On RHEL 8, we cannot build the package on i686 (no virt stack).
|
||||
ExcludeArch: i686
|
||||
%endif
|
||||
|
||||
%ifnarch %{complete_test_arches}
|
||||
BuildRequires: autoconf, automake, libtool
|
||||
%endif
|
||||
BuildRequires: /usr/bin/pod2man
|
||||
BuildRequires: gnutls-devel
|
||||
BuildRequires: libselinux-devel
|
||||
%if 0%{?have_libguestfs}
|
||||
BuildRequires: libguestfs-devel
|
||||
%endif
|
||||
%if 0%{?have_libvirt}
|
||||
BuildRequires: libvirt-devel
|
||||
%endif
|
||||
BuildRequires: xz-devel
|
||||
BuildRequires: zlib-devel
|
||||
BuildRequires: libcurl-devel
|
||||
BuildRequires: libssh-devel
|
||||
BuildRequires: e2fsprogs, e2fsprogs-devel
|
||||
BuildRequires: bash-completion
|
||||
BuildRequires: perl-devel
|
||||
BuildRequires: perl(ExtUtils::Embed)
|
||||
BuildRequires: python3-devel
|
||||
%if 0%{verify_tarball_signature}
|
||||
BuildRequires: gnupg2
|
||||
%endif
|
||||
|
||||
# Only for running the test suite:
|
||||
BuildRequires: /usr/bin/certtool
|
||||
BuildRequires: jq
|
||||
BuildRequires: /usr/bin/nbdsh
|
||||
BuildRequires: /usr/bin/qemu-img
|
||||
BuildRequires: /usr/bin/socat
|
||||
BuildRequires: /usr/sbin/ss
|
||||
BuildRequires: /usr/bin/ssh-keygen
|
||||
|
||||
# nbdkit is a metapackage pulling the server and a useful subset
|
||||
# of the plugins and filters.
|
||||
Requires: nbdkit-server%{?_isa} = %{version}-%{release}
|
||||
Requires: nbdkit-basic-plugins%{?_isa} = %{version}-%{release}
|
||||
Requires: nbdkit-basic-filters%{?_isa} = %{version}-%{release}
|
||||
|
||||
|
||||
%description
|
||||
NBD is a protocol for accessing block devices (hard disks and
|
||||
disk-like things) over the network.
|
||||
|
||||
nbdkit is a toolkit for creating NBD servers.
|
||||
|
||||
The key features are:
|
||||
|
||||
* Multithreaded NBD server written in C with good performance.
|
||||
|
||||
* Minimal dependencies for the basic server.
|
||||
|
||||
* Liberal license (BSD) allows nbdkit to be linked to proprietary
|
||||
libraries or included in proprietary code.
|
||||
|
||||
* Well-documented, simple plugin API with a stable ABI guarantee.
|
||||
Lets you to export "unconventional" block devices easily.
|
||||
|
||||
* You can write plugins in C or many other languages.
|
||||
|
||||
* Filters can be stacked in front of plugins to transform the output.
|
||||
|
||||
In Red Hat Enterprise Linux, '%{name}' is a meta-package which pulls
|
||||
in the core server and a useful subset of plugins and filters.
|
||||
|
||||
If you want just the server, install '%{name}-server'.
|
||||
|
||||
To develop plugins, install the '%{name}-devel' package and start by
|
||||
reading the nbdkit(1) and nbdkit-plugin(3) manual pages.
|
||||
|
||||
|
||||
%package server
|
||||
Summary: The %{name} server
|
||||
License: BSD
|
||||
|
||||
Conflicts: nbdkit < 1.12
|
||||
|
||||
|
||||
%description server
|
||||
This package contains the %{name} server with no plugins or filters.
|
||||
|
||||
|
||||
%package basic-plugins
|
||||
Summary: Basic plugins for %{name}
|
||||
License: BSD
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
Provides: %{name}-data-plugin = %{version}-%{release}
|
||||
Provides: %{name}-file-plugin = %{version}-%{release}
|
||||
Provides: %{name}-floppy-plugin = %{version}-%{release}
|
||||
Provides: %{name}-full-plugin = %{version}-%{release}
|
||||
Provides: %{name}-info-plugin = %{version}-%{release}
|
||||
Provides: %{name}-memory-plugin = %{version}-%{release}
|
||||
Provides: %{name}-null-plugin = %{version}-%{release}
|
||||
Provides: %{name}-pattern-plugin = %{version}-%{release}
|
||||
Provides: %{name}-partitioning-plugin = %{version}-%{release}
|
||||
Provides: %{name}-random-plugin = %{version}-%{release}
|
||||
Provides: %{name}-sh-plugin = %{version}-%{release}
|
||||
Provides: %{name}-split-plugin = %{version}-%{release}
|
||||
Provides: %{name}-streaming-plugin = %{version}-%{release}
|
||||
Provides: %{name}-zero-plugin = %{version}-%{release}
|
||||
|
||||
|
||||
%description basic-plugins
|
||||
This package contains some basic plugins for %{name} which have only
|
||||
trivial dependencies.
|
||||
|
||||
nbdkit-data-plugin Serve small amounts of data from the command line.
|
||||
|
||||
nbdkit-file-plugin The normal file plugin for serving files.
|
||||
|
||||
nbdkit-floppy-plugin Create a virtual floppy disk from a directory.
|
||||
|
||||
nbdkit-full-plugin A virtual disk that returns ENOSPC errors.
|
||||
|
||||
nbdkit-info-plugin Serve client and server information.
|
||||
|
||||
nbdkit-memory-plugin A virtual memory plugin.
|
||||
|
||||
nbdkit-null-plugin A null (bitbucket) plugin.
|
||||
|
||||
nbdkit-pattern-plugin Fixed test pattern.
|
||||
|
||||
nbdkit-partitioning-plugin Create virtual disks from partitions.
|
||||
|
||||
nbdkit-random-plugin Random content plugin for testing.
|
||||
|
||||
nbdkit-sh-plugin Write plugins as shell scripts or executables.
|
||||
|
||||
nbdkit-split-plugin Concatenate one or more files.
|
||||
|
||||
nbdkit-streaming-plugin A streaming file serving plugin.
|
||||
|
||||
nbdkit-zero-plugin Zero-length plugin for testing.
|
||||
|
||||
|
||||
%package example-plugins
|
||||
Summary: Example plugins for %{name}
|
||||
License: BSD
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
|
||||
|
||||
%description example-plugins
|
||||
This package contains example plugins for %{name}.
|
||||
|
||||
|
||||
# The plugins below have non-trivial dependencies are so are
|
||||
# packaged separately.
|
||||
|
||||
%package curl-plugin
|
||||
Summary: HTTP/FTP (cURL) plugin for %{name}
|
||||
License: BSD
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
|
||||
|
||||
%description curl-plugin
|
||||
This package contains cURL (HTTP/FTP) support for %{name}.
|
||||
|
||||
|
||||
%package gzip-plugin
|
||||
Summary: GZip file serving plugin for %{name}
|
||||
License: BSD
|
||||
|
||||
# Upgrade path from RHEL 8.0
|
||||
Provides: %{name}-plugin-gzip = %{version}-%{release}
|
||||
Obsoletes: %{name}-plugin-gzip <= %{version}-%{release}
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
|
||||
|
||||
%description gzip-plugin
|
||||
This package is a gzip file serving plugin for %{name}.
|
||||
|
||||
|
||||
%package linuxdisk-plugin
|
||||
Summary: Virtual Linux disk plugin for %{name}
|
||||
License: BSD
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
# for mke2fs
|
||||
Requires: e2fsprogs
|
||||
|
||||
|
||||
%description linuxdisk-plugin
|
||||
This package is a virtual Linux disk plugin for %{name}.
|
||||
|
||||
|
||||
%package python-plugin
|
||||
Summary: Python 3 plugin for %{name}
|
||||
License: BSD
|
||||
|
||||
# Upgrade path from RHEL 8.0
|
||||
Provides: %{name}-plugin-python-common = %{version}-%{release}
|
||||
Obsoletes: %{name}-plugin-python-common <= %{version}-%{release}
|
||||
Provides: %{name}-plugin-python3 = %{version}-%{release}
|
||||
Obsoletes: %{name}-plugin-python3 <= %{version}-%{release}
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
|
||||
|
||||
%description python-plugin
|
||||
This package lets you write Python 3 plugins for %{name}.
|
||||
|
||||
|
||||
%package ssh-plugin
|
||||
Summary: SSH plugin for %{name}
|
||||
License: BSD
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
|
||||
|
||||
%description ssh-plugin
|
||||
This package contains SSH support for %{name}.
|
||||
|
||||
|
||||
%ifarch %{ix86} x86_64
|
||||
%package vddk-plugin
|
||||
Summary: VMware VDDK plugin for %{name}
|
||||
License: BSD
|
||||
|
||||
# Upgrade path from RHEL 8.0
|
||||
Provides: %{name}-plugin-vddk = %{version}-%{release}
|
||||
Obsoletes: %{name}-plugin-vddk <= %{version}-%{release}
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
|
||||
|
||||
%description vddk-plugin
|
||||
This package is a plugin for %{name} which connects to
|
||||
VMware VDDK for accessing VMware disks and servers.
|
||||
%endif
|
||||
|
||||
|
||||
%package basic-filters
|
||||
Summary: Basic filters for %{name}
|
||||
License: BSD
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
Provides: %{name}-blocksize-filter = %{version}-%{release}
|
||||
Provides: %{name}-cache-filter = %{version}-%{release}
|
||||
Provides: %{name}-cacheextents-filter = %{version}-%{release}
|
||||
Provides: %{name}-cow-filter = %{version}-%{release}
|
||||
Provides: %{name}-delay-filter = %{version}-%{release}
|
||||
Provides: %{name}-error-filter = %{version}-%{release}
|
||||
Provides: %{name}-extentlist-filter = %{version}-%{release}
|
||||
Provides: %{name}-fua-filter = %{version}-%{release}
|
||||
Provides: %{name}-log-filter = %{version}-%{release}
|
||||
Provides: %{name}-nocache-filter = %{version}-%{release}
|
||||
Provides: %{name}-noextents-filter = %{version}-%{release}
|
||||
Provides: %{name}-noparallel-filter = %{version}-%{release}
|
||||
Provides: %{name}-nozero-filter = %{version}-%{release}
|
||||
Provides: %{name}-offset-filter = %{version}-%{release}
|
||||
Provides: %{name}-partition-filter = %{version}-%{release}
|
||||
Provides: %{name}-rate-filter = %{version}-%{release}
|
||||
Provides: %{name}-readahead-filter = %{version}-%{release}
|
||||
Provides: %{name}-retry-filter = %{version}-%{release}
|
||||
Provides: %{name}-stats-filter = %{version}-%{release}
|
||||
Provides: %{name}-truncate-filter = %{version}-%{release}
|
||||
|
||||
%description basic-filters
|
||||
This package contains some basic filters for %{name} which have only
|
||||
trivial dependencies.
|
||||
|
||||
nbdkit-blocksize-filter Adjust block size of requests sent to plugins.
|
||||
|
||||
nbdkit-cache-filter Server-side cache.
|
||||
|
||||
nbdkit-cacheextents-filter Cache extents.
|
||||
|
||||
nbdkit-cow-filter Copy-on-write overlay for read-only plugins.
|
||||
|
||||
nbdkit-delay-filter Inject read and write delays.
|
||||
|
||||
nbdkit-error-filter Inject errors.
|
||||
|
||||
nbdkit-extentlist-filter Place extent list over a plugin.
|
||||
|
||||
nbdkit-fua-filter Modify flush behaviour in plugins.
|
||||
|
||||
nbdkit-log-filter Log all transactions to a file.
|
||||
|
||||
nbdkit-nocache-filter Disable cache requests in the underlying plugin.
|
||||
|
||||
nbdkit-noextents-filter Disable extents in the underlying plugin.
|
||||
|
||||
nbdkit-noparallel-filter Serialize requests to the underlying plugin.
|
||||
|
||||
nbdkit-nozero-filter Adjust handling of zero requests by plugins.
|
||||
|
||||
nbdkit-offset-filter Serve an offset and range.
|
||||
|
||||
nbdkit-partition-filter Serve a single partition.
|
||||
|
||||
nbdkit-rate-filter Limit bandwidth by connection or server.
|
||||
|
||||
nbdkit-readahead-filter Prefetch data when reading sequentially.
|
||||
|
||||
nbdkit-retry-filter Reopen connection on error.
|
||||
|
||||
nbdkit-stats-filter Display statistics about operations.
|
||||
|
||||
nbdkit-truncate-filter Truncate, expand, round up or round down size.
|
||||
|
||||
|
||||
%package xz-filter
|
||||
Summary: XZ filter for %{name}
|
||||
License: BSD
|
||||
|
||||
# Upgrade path from RHEL 8.0
|
||||
Provides: %{name}-plugin-xz = %{version}-%{release}
|
||||
Obsoletes: %{name}-plugin-xz <= %{version}-%{release}
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
|
||||
|
||||
%description xz-filter
|
||||
This package is the xz filter for %{name}.
|
||||
|
||||
|
||||
%package devel
|
||||
Summary: Development files and documentation for %{name}
|
||||
License: BSD
|
||||
|
||||
Requires: %{name}-server%{?_isa} = %{version}-%{release}
|
||||
Requires: pkgconfig
|
||||
|
||||
|
||||
%description devel
|
||||
This package contains development files and documentation
|
||||
for %{name}. Install this package if you want to develop
|
||||
plugins for %{name}.
|
||||
|
||||
|
||||
%package bash-completion
|
||||
Summary: Bash tab-completion for %{name}
|
||||
BuildArch: noarch
|
||||
Requires: bash-completion >= 2.0
|
||||
Requires: %{name}-server = %{version}-%{release}
|
||||
|
||||
|
||||
%description bash-completion
|
||||
Install this package if you want intelligent bash tab-completion
|
||||
for %{name}.
|
||||
|
||||
|
||||
%prep
|
||||
%if 0%{verify_tarball_signature}
|
||||
tmphome="$(mktemp -d)"
|
||||
gpgv2 --homedir "$tmphome" --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0}
|
||||
%endif
|
||||
%autosetup -p1
|
||||
%if 0%{patches_touch_autotools}
|
||||
autoreconf -i
|
||||
%endif
|
||||
|
||||
%ifnarch %{complete_test_arches}
|
||||
# Simplify the test suite so it doesn't require qemu.
|
||||
sed -i -e '/^if HAVE_LIBGUESTFS/,/^endif HAVE_LIBGUESTFS/d' tests/Makefile.am
|
||||
sed -i -e '/^if HAVE_GUESTFISH/,/^endif HAVE_GUESTFISH/d' tests/Makefile.am
|
||||
autoreconf -i
|
||||
%endif
|
||||
|
||||
|
||||
%build
|
||||
%configure \
|
||||
PYTHON=%{_bindir}/python3 \
|
||||
--disable-static \
|
||||
--disable-lua \
|
||||
--disable-perl \
|
||||
--disable-nbd-plugin \
|
||||
--disable-ocaml \
|
||||
--disable-ruby \
|
||||
--disable-rust \
|
||||
--disable-ruby \
|
||||
--disable-tcl \
|
||||
--without-ext2 \
|
||||
--without-iso \
|
||||
--without-libguestfs \
|
||||
--without-libvirt \
|
||||
--with-tls-priority=@NBDKIT,SYSTEM
|
||||
|
||||
# Verify that it picked the correct version of Python
|
||||
# to avoid RHBZ#1404631 happening again silently.
|
||||
grep '^PYTHON_VERSION = 3' Makefile
|
||||
|
||||
make %{?_smp_mflags}
|
||||
|
||||
|
||||
%install
|
||||
%make_install
|
||||
|
||||
# Delete libtool crap.
|
||||
find $RPM_BUILD_ROOT -name '*.la' -delete
|
||||
|
||||
# If cargo happens to be installed on the machine then the
|
||||
# rust plugin is built. Delete it if this happens.
|
||||
rm -f $RPM_BUILD_ROOT%{_mandir}/man3/nbdkit-rust-plugin.3*
|
||||
|
||||
|
||||
%check
|
||||
# Workaround for broken libvirt (RHBZ#1138604).
|
||||
mkdir -p $HOME/.cache/libvirt
|
||||
|
||||
# tests/test-captive.sh is racy especially on s390x. We need to
|
||||
# rethink this test upstream.
|
||||
truncate -s 0 tests/test-captive.sh
|
||||
|
||||
# Temporarily kill tests/test-shutdown.sh because this test is racy on
|
||||
# slow hardware.
|
||||
truncate -s 0 tests/test-shutdown.sh
|
||||
|
||||
%ifarch s390x
|
||||
# Temporarily kill tests/test-cache-max-size.sh since it fails
|
||||
# sometimes on s390x for unclear reasons.
|
||||
truncate -s 0 tests/test-cache-max-size.sh
|
||||
%endif
|
||||
|
||||
# Make sure we can see the debug messages (RHBZ#1230160).
|
||||
export LIBGUESTFS_DEBUG=1
|
||||
export LIBGUESTFS_TRACE=1
|
||||
|
||||
make %{?_smp_mflags} check || {
|
||||
cat tests/test-suite.log
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
%files
|
||||
# metapackage so empty
|
||||
|
||||
|
||||
%files server
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_sbindir}/nbdkit
|
||||
%dir %{_libdir}/%{name}
|
||||
%dir %{_libdir}/%{name}/plugins
|
||||
%dir %{_libdir}/%{name}/filters
|
||||
%{_mandir}/man1/nbdkit.1*
|
||||
%{_mandir}/man1/nbdkit-captive.1*
|
||||
%{_mandir}/man1/nbdkit-loop.1*
|
||||
%{_mandir}/man1/nbdkit-probing.1*
|
||||
%{_mandir}/man1/nbdkit-protocol.1*
|
||||
%{_mandir}/man1/nbdkit-service.1*
|
||||
%{_mandir}/man1/nbdkit-security.1*
|
||||
%{_mandir}/man1/nbdkit-tls.1*
|
||||
|
||||
|
||||
%files basic-plugins
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/plugins/nbdkit-data-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-file-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-floppy-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-full-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-info-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-memory-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-null-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-partitioning-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-pattern-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-random-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-sh-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-split-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-streaming-plugin.so
|
||||
%{_libdir}/%{name}/plugins/nbdkit-zero-plugin.so
|
||||
%{_mandir}/man1/nbdkit-data-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-file-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-floppy-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-full-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-info-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-memory-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-null-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-partitioning-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-pattern-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-random-plugin.1*
|
||||
%{_mandir}/man3/nbdkit-sh-plugin.3*
|
||||
%{_mandir}/man1/nbdkit-split-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-streaming-plugin.1*
|
||||
%{_mandir}/man1/nbdkit-zero-plugin.1*
|
||||
|
||||
|
||||
%files example-plugins
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/plugins/nbdkit-example*-plugin.so
|
||||
%{_mandir}/man1/nbdkit-example*-plugin.1*
|
||||
|
||||
|
||||
%files curl-plugin
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/plugins/nbdkit-curl-plugin.so
|
||||
%{_mandir}/man1/nbdkit-curl-plugin.1*
|
||||
|
||||
|
||||
%files gzip-plugin
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/plugins/nbdkit-gzip-plugin.so
|
||||
%{_mandir}/man1/nbdkit-gzip-plugin.1*
|
||||
|
||||
|
||||
%files linuxdisk-plugin
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/plugins/nbdkit-linuxdisk-plugin.so
|
||||
%{_mandir}/man1/nbdkit-linuxdisk-plugin.1*
|
||||
|
||||
|
||||
%files python-plugin
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/plugins/nbdkit-python-plugin.so
|
||||
%{_mandir}/man3/nbdkit-python-plugin.3*
|
||||
|
||||
|
||||
%files ssh-plugin
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/plugins/nbdkit-ssh-plugin.so
|
||||
%{_mandir}/man1/nbdkit-ssh-plugin.1*
|
||||
|
||||
|
||||
%ifarch %{ix86} x86_64
|
||||
%files vddk-plugin
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/plugins/nbdkit-vddk-plugin.so
|
||||
%{_mandir}/man1/nbdkit-vddk-plugin.1*
|
||||
%endif
|
||||
|
||||
|
||||
%files basic-filters
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/filters/nbdkit-blocksize-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-cache-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-cacheextents-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-cow-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-delay-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-error-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-extentlist-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-fua-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-log-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-nocache-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-noextents-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-noparallel-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-nozero-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-offset-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-partition-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-rate-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-readahead-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-retry-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-stats-filter.so
|
||||
%{_libdir}/%{name}/filters/nbdkit-truncate-filter.so
|
||||
%{_mandir}/man1/nbdkit-blocksize-filter.1*
|
||||
%{_mandir}/man1/nbdkit-cache-filter.1*
|
||||
%{_mandir}/man1/nbdkit-cacheextents-filter.1*
|
||||
%{_mandir}/man1/nbdkit-cow-filter.1*
|
||||
%{_mandir}/man1/nbdkit-delay-filter.1*
|
||||
%{_mandir}/man1/nbdkit-error-filter.1*
|
||||
%{_mandir}/man1/nbdkit-extentlist-filter.1*
|
||||
%{_mandir}/man1/nbdkit-fua-filter.1*
|
||||
%{_mandir}/man1/nbdkit-log-filter.1*
|
||||
%{_mandir}/man1/nbdkit-nocache-filter.1*
|
||||
%{_mandir}/man1/nbdkit-noextents-filter.1*
|
||||
%{_mandir}/man1/nbdkit-noparallel-filter.1*
|
||||
%{_mandir}/man1/nbdkit-nozero-filter.1*
|
||||
%{_mandir}/man1/nbdkit-offset-filter.1*
|
||||
%{_mandir}/man1/nbdkit-partition-filter.1*
|
||||
%{_mandir}/man1/nbdkit-rate-filter.1*
|
||||
%{_mandir}/man1/nbdkit-readahead-filter.1*
|
||||
%{_mandir}/man1/nbdkit-retry-filter.1*
|
||||
%{_mandir}/man1/nbdkit-stats-filter.1*
|
||||
%{_mandir}/man1/nbdkit-truncate-filter.1*
|
||||
|
||||
|
||||
%files xz-filter
|
||||
%doc README
|
||||
%license LICENSE
|
||||
%{_libdir}/%{name}/filters/nbdkit-xz-filter.so
|
||||
%{_mandir}/man1/nbdkit-xz-filter.1*
|
||||
|
||||
|
||||
%files devel
|
||||
%doc BENCHMARKING OTHER_PLUGINS README SECURITY TODO
|
||||
%license LICENSE
|
||||
# Include the source of the example plugins in the documentation.
|
||||
%doc plugins/example*/*.c
|
||||
%doc plugins/python/example.py
|
||||
%doc plugins/sh/example.sh
|
||||
%{_includedir}/nbdkit-common.h
|
||||
%{_includedir}/nbdkit-filter.h
|
||||
%{_includedir}/nbdkit-plugin.h
|
||||
%{_includedir}/nbdkit-version.h
|
||||
%{_includedir}/nbd-protocol.h
|
||||
%{_mandir}/man3/nbdkit-filter.3*
|
||||
%{_mandir}/man3/nbdkit-plugin.3*
|
||||
%{_mandir}/man1/nbdkit-release-notes-1.*.1*
|
||||
%{_libdir}/pkgconfig/nbdkit.pc
|
||||
|
||||
|
||||
%files bash-completion
|
||||
%license LICENSE
|
||||
%dir %{_datadir}/bash-completion/completions
|
||||
%{_datadir}/bash-completion/completions/nbdkit
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Apr 27 2020 Danilo C. L. de Paula <ddepaula@redhat.com> - 1.16.2
|
||||
- Resolves: bz#1810193
|
||||
(Upgrade components in virt:rhel module:stream for RHEL-8.3 release)
|
||||
|
||||
* Fri Jun 28 2019 Danilo de Paula <ddepaula@redhat.com> - 1.4.2-5
|
||||
- Rebuild all virt packages to fix RHEL's upgrade path
|
||||
- Resolves: rhbz#1695587
|
||||
(Ensure modular RPM upgrade path)
|
||||
|
||||
* Mon Dec 17 2018 Richard W.M. Jones <rjones@redhat.com> - 1.4.2-4
|
||||
- Remove misguided LDFLAGS hack which removed server hardening.
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1624149#c6
|
||||
resolves: rhbz#1624149
|
||||
|
||||
* Fri Dec 14 2018 Richard W.M. Jones <rjones@redhat.com> - 1.4.2-3
|
||||
- Use platform-python
|
||||
resolves: rhbz#1659159
|
||||
|
||||
* Fri Aug 10 2018 Richard W.M. Jones <rjones@redhat.com> - 1.4.2-2
|
||||
- Add Enhanced Python error reporting
|
||||
resolves: rhbz#1614750.
|
||||
- Use copy-patches.sh script.
|
||||
|
||||
* Wed Aug 1 2018 Richard W.M. Jones <rjones@redhat.com> - 1.4.2-1
|
||||
- New stable version 1.4.2.
|
||||
|
||||
* Wed Jul 25 2018 Richard W.M. Jones <rjones@redhat.com> - 1.4.1-3
|
||||
- Enable VDDK plugin on x86-64 only.
|
||||
|
||||
* Fri Jul 20 2018 Richard W.M. Jones <rjones@redhat.com> - 1.4.1-1
|
||||
- New upstream version 1.4.1.
|
||||
- Small refactorings in the spec file.
|
||||
|
||||
* Fri Jul 6 2018 Richard W.M. Jones <rjones@redhat.com> - 1.4.0-1
|
||||
- New upstream version 1.4.0.
|
||||
- New plugins: random, zero.
|
||||
- New bash tab completion subpackage.
|
||||
- Remove unused build dependencies.
|
||||
|
||||
* Sun Jul 1 2018 Richard W.M. Jones <rjones@redhat.com> - 1.2.4-3
|
||||
- Add all upstream patches since 1.2.4 was released.
|
||||
|
||||
* Tue Jun 12 2018 Richard W.M. Jones <rjones@redhat.com> - 1.2.4-2
|
||||
- Add all upstream patches since 1.2.4 was released.
|
||||
|
||||
* Mon Jun 11 2018 Richard W.M. Jones <rjones@redhat.com> - 1.2.4-2
|
||||
- Disable plugins and filters that we do not want to ship in RHEL 8.
|
||||
|
||||
* Sat Jun 9 2018 Richard W.M. Jones <rjones@redhat.com> - 1.2.4-1
|
||||
- New stable version 1.2.4.
|
||||
- Remove upstream patches.
|
||||
- Enable tarball signatures.
|
||||
- Add upstream patch to fix tests when guestfish not available.
|
||||
|
||||
* Wed Jun 6 2018 Richard W.M. Jones <rjones@redhat.com> - 1.2.3-1
|
||||
- New stable version 1.2.3.
|
||||
- Add patch to work around libvirt problem with relative socket paths.
|
||||
- Add patch to fix the xz plugin test with recent guestfish.
|
||||
|
||||
* Sat Apr 21 2018 Richard W.M. Jones <rjones@redhat.com> - 1.2.2-1
|
||||
- New stable version 1.2.2.
|
||||
|
||||
* Mon Apr 9 2018 Richard W.M. Jones <rjones@redhat.com> - 1.2.1-1
|
||||
- New stable version 1.2.1.
|
||||
|
||||
* Fri Apr 6 2018 Richard W.M. Jones <rjones@redhat.com> - 1.2.0-1
|
||||
- Move to stable branch version 1.2.0.
|
||||
|
||||
* Fri Feb 09 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.1.28-5
|
||||
- Escape macros in %%changelog
|
||||
|
||||
* Thu Feb 08 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.1.28-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||
|
||||
* Wed Jan 31 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.1.28-3
|
||||
- Switch to %%ldconfig_scriptlets
|
||||
|
||||
* Fri Jan 26 2018 Richard W.M. Jones <rjones@redhat.com> - 1.1.28-2
|
||||
- Run a simplified test suite on all arches.
|
||||
|
||||
* Mon Jan 22 2018 Richard W.M. Jones <rjones@redhat.com> - 1.1.28-1
|
||||
- New upstream version 1.1.28.
|
||||
- Add two new filters to nbdkit-basic-filters.
|
||||
|
||||
* Sat Jan 20 2018 Björn Esser <besser82@fedoraproject.org> - 1.1.27-2
|
||||
- Rebuilt for switch to libxcrypt
|
||||
|
||||
* Sat Jan 20 2018 Richard W.M. Jones <rjones@redhat.com> - 1.1.27-1
|
||||
- New upstream version 1.1.27.
|
||||
- Add new subpackage nbdkit-basic-filters containing new filters.
|
||||
|
||||
* Thu Jan 11 2018 Richard W.M. Jones <rjones@redhat.com> - 1.1.26-2
|
||||
- Rebuild against updated Ruby.
|
||||
|
||||
* Sat Dec 23 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.26-1
|
||||
- New upstream version 1.1.26.
|
||||
- Add new pkg-config file and dependency.
|
||||
|
||||
* Wed Dec 06 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.25-1
|
||||
- New upstream version 1.1.25.
|
||||
|
||||
* Tue Dec 05 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.24-1
|
||||
- New upstream version 1.1.24.
|
||||
- Add tar plugin (new subpackage nbdkit-plugin-tar).
|
||||
|
||||
* Tue Dec 05 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.23-1
|
||||
- New upstream version 1.1.23.
|
||||
- Add example4 plugin.
|
||||
- Python3 tests require libguestfs so disable on s390x.
|
||||
|
||||
* Sun Dec 03 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.22-1
|
||||
- New upstream version 1.1.22.
|
||||
- Enable tests on Fedora.
|
||||
|
||||
* Sat Dec 02 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.20-1
|
||||
- New upstream version 1.1.20.
|
||||
- Add nbdkit-split-plugin to basic plugins.
|
||||
|
||||
* Sat Dec 02 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.19-2
|
||||
- OCaml 4.06.0 rebuild.
|
||||
|
||||
* Thu Nov 30 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.19-1
|
||||
- New upstream version 1.1.19.
|
||||
- Combine all the simple plugins in %%{name}-basic-plugins.
|
||||
- Add memory and null plugins.
|
||||
- Rename the example plugins subpackage.
|
||||
- Use %%license instead of %%doc for license file.
|
||||
- Remove patches now upstream.
|
||||
|
||||
* Wed Nov 29 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.18-4
|
||||
- Fix Python 3 builds / RHEL macros (RHBZ#1404631).
|
||||
|
||||
* Tue Nov 21 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.18-3
|
||||
- New upstream version 1.1.18.
|
||||
- Add NBD forwarding plugin.
|
||||
- Add libselinux-devel so that SELinux support is enabled in the daemon.
|
||||
- Apply all patches from upstream since 1.1.18.
|
||||
|
||||
* Fri Oct 20 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.16-2
|
||||
- New upstream version 1.1.16.
|
||||
- Disable python3 plugin on RHEL/EPEL <= 7.
|
||||
- Only ship on x86_64 in RHEL/EPEL <= 7.
|
||||
|
||||
* Wed Sep 27 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.15-1
|
||||
- New upstream version 1.1.15.
|
||||
- Enable TLS support.
|
||||
|
||||
* Fri Sep 01 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.14-1
|
||||
- New upstream version 1.1.14.
|
||||
|
||||
* Fri Aug 25 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.13-1
|
||||
- New upstream version 1.1.13.
|
||||
- Remove patches which are all upstream.
|
||||
- Remove grubby hack, should not be needed with modern supermin.
|
||||
|
||||
* Sat Aug 19 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.12-13
|
||||
- Rebuild for OCaml 4.05.0.
|
||||
|
||||
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.1.12-12
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
|
||||
|
||||
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.1.12-11
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
|
||||
|
||||
* Tue Jun 27 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.12-10
|
||||
- Rebuild for OCaml 4.04.2.
|
||||
|
||||
* Sun Jun 04 2017 Jitka Plesnikova <jplesnik@redhat.com> - 1.1.12-9
|
||||
- Perl 5.26 rebuild
|
||||
|
||||
* Mon May 15 2017 Richard W.M. Jones <rjones@redhat.com> - 1.1.12-8
|
||||
- Rebuild for OCaml 4.04.1.
|
||||
|
||||
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.1.12-7
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
|
||||
|
||||
* Thu Jan 12 2017 Vít Ondruch <vondruch@redhat.com> - 1.1.12-6
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Changes/Ruby_2.4
|
||||
|
||||
* Fri Dec 23 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.12-5
|
||||
- Rebuild for Python 3.6 update.
|
||||
|
||||
* Wed Dec 14 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.12-4
|
||||
- Fix python3 subpackage so it really uses python3 (RHBZ#1404631).
|
||||
|
||||
* Sat Nov 05 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.12-3
|
||||
- Rebuild for OCaml 4.04.0.
|
||||
|
||||
* Mon Oct 03 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.12-2
|
||||
- Compile Python 2 and Python 3 versions of the plugin.
|
||||
|
||||
* Wed Jun 08 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.12-1
|
||||
- New upstream version 1.1.12
|
||||
- Enable Ruby plugin.
|
||||
- Disable tests on Rawhide because libvirt is broken again (RHBZ#1344016).
|
||||
|
||||
* Wed May 25 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.11-10
|
||||
- Add another upstream patch since 1.1.11.
|
||||
|
||||
* Mon May 23 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.11-9
|
||||
- Add all patches upstream since 1.1.11 (fixes RHBZ#1336758).
|
||||
|
||||
* Tue May 17 2016 Jitka Plesnikova <jplesnik@redhat.com> - 1.1.11-7
|
||||
- Perl 5.24 rebuild
|
||||
|
||||
* Wed Mar 09 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.11-6
|
||||
- When tests fail, dump out test-suite.log so we can debug it.
|
||||
|
||||
* Fri Feb 05 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.11-5
|
||||
- Don't run tests on x86, because kernel is broken there
|
||||
(https://bugzilla.redhat.com/show_bug.cgi?id=1302071)
|
||||
|
||||
* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.1.11-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
|
||||
|
||||
* Mon Jan 11 2016 Richard W.M. Jones <rjones@redhat.com> - 1.1.11-3
|
||||
- Add support for newstyle NBD protocol (RHBZ#1297100).
|
||||
|
||||
* Sat Oct 31 2015 Richard W.M. Jones <rjones@redhat.com> - 1.1.11-1
|
||||
- New upstream version 1.1.11.
|
||||
|
||||
* Thu Jul 30 2015 Richard W.M. Jones <rjones@redhat.com> - 1.1.10-3
|
||||
- OCaml 4.02.3 rebuild.
|
||||
|
||||
* Sat Jun 20 2015 Richard W.M. Jones <rjones@redhat.com> - 1.1.10-2
|
||||
- Enable libguestfs plugin on aarch64.
|
||||
|
||||
* Fri Jun 19 2015 Richard W.M. Jones <rjones@redhat.com> - 1.1.10-1
|
||||
- New upstream version.
|
||||
- Enable now working OCaml plugin (requires OCaml >= 4.02.2).
|
||||
|
||||
* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.9-6
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
|
||||
|
||||
* Thu Jun 11 2015 Jitka Plesnikova <jplesnik@redhat.com> - 1.1.9-5
|
||||
- Perl 5.22 rebuild
|
||||
|
||||
* Wed Jun 10 2015 Richard W.M. Jones <rjones@redhat.com> - 1.1.9-4
|
||||
- Enable debugging messages when running make check.
|
||||
|
||||
* Sat Jun 06 2015 Jitka Plesnikova <jplesnik@redhat.com> - 1.1.9-3
|
||||
- Perl 5.22 rebuild
|
||||
|
||||
* Tue Oct 14 2014 Richard W.M. Jones <rjones@redhat.com> - 1.1.9-2
|
||||
- New upstream version 1.1.9.
|
||||
- Add the streaming plugin.
|
||||
- Include fix for streaming plugin in 1.1.9.
|
||||
|
||||
* Wed Sep 10 2014 Richard W.M. Jones <rjones@redhat.com> - 1.1.8-4
|
||||
- Rebuild for updated Perl in Rawhide.
|
||||
- Workaround for broken libvirt (RHBZ#1138604).
|
||||
|
||||
* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.8-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
|
||||
|
||||
* Sat Jun 21 2014 Richard W.M. Jones <rjones@redhat.com> - 1.1.8-1
|
||||
- New upstream version 1.1.8.
|
||||
- Add support for cURL, and new nbdkit-plugin-curl package.
|
||||
|
||||
* Fri Jun 20 2014 Richard W.M. Jones <rjones@redhat.com> - 1.1.7-1
|
||||
- New upstream version 1.1.7.
|
||||
- Remove patches which are now all upstream.
|
||||
|
||||
* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.6-5
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
|
||||
|
||||
* Thu Mar 06 2014 Dan Horák <dan[at]danny.cz> - 1.1.6-4
|
||||
- libguestfs is available only on selected arches
|
||||
|
||||
* Fri Feb 21 2014 Richard W.M. Jones <rjones@redhat.com> - 1.1.6-3
|
||||
- Backport some upstream patches, fixing a minor bug and adding more tests.
|
||||
- Enable the tests since kernel bug is fixed.
|
||||
|
||||
* Sun Feb 16 2014 Richard W.M. Jones <rjones@redhat.com> - 1.1.6-1
|
||||
- New upstream version 1.1.6.
|
||||
|
||||
* Sat Feb 15 2014 Richard W.M. Jones <rjones@redhat.com> - 1.1.5-2
|
||||
- New upstream version 1.1.5.
|
||||
- Enable the new Python plugin.
|
||||
- Perl plugin man page moved to section 3.
|
||||
- Perl now requires ExtUtils::Embed.
|
||||
|
||||
* Mon Feb 10 2014 Richard W.M. Jones <rjones@redhat.com> - 1.1.4-1
|
||||
- New upstream version 1.1.4.
|
||||
- Enable the new Perl plugin.
|
||||
|
||||
* Sun Aug 4 2013 Richard W.M. Jones <rjones@redhat.com> - 1.1.3-1
|
||||
- New upstream version 1.1.3 which fixes some test problems.
|
||||
- Disable tests because Rawhide kernel is broken (RHBZ#991808).
|
||||
- Remove a single quote from description which confused emacs.
|
||||
- Remove patch, now upstream.
|
||||
|
||||
* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.2-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
|
||||
|
||||
* Sun Jul 21 2013 Richard W.M. Jones <rjones@redhat.com> - 1.1.2-3
|
||||
- Fix segfault when IPv6 client is used (RHBZ#986601).
|
||||
|
||||
* Tue Jul 16 2013 Richard W.M. Jones <rjones@redhat.com> - 1.1.2-2
|
||||
- New development version 1.1.2.
|
||||
- Disable the tests on Fedora <= 18.
|
||||
|
||||
* Tue Jun 25 2013 Richard W.M. Jones <rjones@redhat.com> - 1.1.1-1
|
||||
- New development version 1.1.1.
|
||||
- Add libguestfs plugin.
|
||||
- Run the test suite.
|
||||
|
||||
* Mon Jun 24 2013 Richard W.M. Jones <rjones@redhat.com> - 1.0.0-4
|
||||
- Initial release.
|
Loading…
Reference in New Issue
Block a user