nbdkit/0005-Add-pattern-plugin.patch

549 lines
18 KiB
Diff

From 0a9205dc8c3b5d5703bd71bc58db503c05b0063b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 7 Jul 2018 13:30:32 +0100
Subject: [PATCH 05/12] Add pattern plugin.
This generates a simple, fixed test pattern which can be used to test
nbdkit filters (especially nbdkit-offset-filter), and also NBD
clients.
---
common-rules.mk | 1 +
configure.ac | 1 +
plugins/null/nbdkit-null-plugin.pod | 1 +
plugins/pattern/Makefile.am | 60 ++++++++++
plugins/pattern/nbdkit-pattern-plugin.pod | 99 ++++++++++++++++
plugins/pattern/pattern.c | 134 ++++++++++++++++++++++
plugins/random/nbdkit-random-plugin.pod | 1 +
plugins/zero/nbdkit-zero-plugin.pod | 1 +
tests/Makefile.am | 4 +
tests/test-pattern.sh | 121 +++++++++++++++++++
10 files changed, 423 insertions(+)
create mode 100644 plugins/pattern/Makefile.am
create mode 100644 plugins/pattern/nbdkit-pattern-plugin.pod
create mode 100644 plugins/pattern/pattern.c
create mode 100755 tests/test-pattern.sh
diff --git a/common-rules.mk b/common-rules.mk
index 5877907..01beff5 100644
--- a/common-rules.mk
+++ b/common-rules.mk
@@ -46,6 +46,7 @@ plugins = \
nbd \
null \
ocaml \
+ pattern \
perl \
python \
random \
diff --git a/configure.ac b/configure.ac
index 6e8d3e2..6304ac8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -610,6 +610,7 @@ AC_CONFIG_FILES([Makefile
plugins/nbd/Makefile
plugins/null/Makefile
plugins/ocaml/Makefile
+ plugins/pattern/Makefile
plugins/perl/Makefile
plugins/python/Makefile
plugins/random/Makefile
diff --git a/plugins/null/nbdkit-null-plugin.pod b/plugins/null/nbdkit-null-plugin.pod
index 7bd7278..55affb8 100644
--- a/plugins/null/nbdkit-null-plugin.pod
+++ b/plugins/null/nbdkit-null-plugin.pod
@@ -33,6 +33,7 @@ This parameter is required.
L<nbdkit(1)>,
L<nbdkit-plugin(3)>,
+L<nbdkit-pattern-plugin(1)>,
L<nbdkit-random-plugin(1)>.
L<nbdkit-zero-plugin(1)>.
diff --git a/plugins/pattern/Makefile.am b/plugins/pattern/Makefile.am
new file mode 100644
index 0000000..da092db
--- /dev/null
+++ b/plugins/pattern/Makefile.am
@@ -0,0 +1,60 @@
+# nbdkit
+# Copyright (C) 2017-2018 Red Hat Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Red Hat nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+include $(top_srcdir)/common-rules.mk
+
+EXTRA_DIST = nbdkit-pattern-plugin.pod
+
+plugin_LTLIBRARIES = nbdkit-pattern-plugin.la
+
+nbdkit_pattern_plugin_la_SOURCES = \
+ pattern.c \
+ $(top_srcdir)/include/nbdkit-plugin.h
+
+nbdkit_pattern_plugin_la_CPPFLAGS = \
+ -I$(top_srcdir)/include
+nbdkit_pattern_plugin_la_CFLAGS = \
+ $(WARNINGS_CFLAGS)
+nbdkit_pattern_plugin_la_LDFLAGS = \
+ -module -avoid-version -shared
+
+if HAVE_POD2MAN
+
+man_MANS = nbdkit-pattern-plugin.1
+CLEANFILES += $(man_MANS)
+
+nbdkit-pattern-plugin.1: nbdkit-pattern-plugin.pod
+ $(POD2MAN) $(POD2MAN_ARGS) --section=1 --name=`basename $@ .1` $< $@.t && \
+ if grep 'POD ERROR' $@.t; then rm $@.t; exit 1; fi && \
+ mv $@.t $@
+
+endif
diff --git a/plugins/pattern/nbdkit-pattern-plugin.pod b/plugins/pattern/nbdkit-pattern-plugin.pod
new file mode 100644
index 0000000..7a6b498
--- /dev/null
+++ b/plugins/pattern/nbdkit-pattern-plugin.pod
@@ -0,0 +1,99 @@
+=encoding utf8
+
+=head1 NAME
+
+nbdkit-pattern-plugin - plugin to serve a fixed pattern of data for testing
+
+=head1 SYNOPSIS
+
+ nbdkit pattern size=SIZE
+
+=head1 DESCRIPTION
+
+C<nbdkit-pattern-plugin> is a plugin for L<nbdkit(1)> which serves a
+fixed pattern of data, read only. This is used for testing nbdkit
+filters and NBD clients.
+
+The fixed pattern is the offset, as a 64 bit big endian integer, every
+8 bytes. In hexadecimal this looks like:
+
+ offset data
+ 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08
+ 0010: 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 18
+ 0020: 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 28
+ └──────────┬──────────┘
+ 64 bit big endian int which encodes the offset of
+ the first byte of this int in the file
+
+The size of the virtual disk must be specified using the C<size>
+parameter. If the size is not a multiple of 8 then the last 8 byte
+offset in the pattern is truncated.
+
+=head1 PARAMETERS
+
+=over 4
+
+=item B<size=SIZE>
+
+Specify the virtual size of the disk image.
+
+This parameter is required.
+
+=back
+
+=head1 SEE ALSO
+
+L<nbdkit(1)>,
+L<nbdkit-plugin(3)>,
+L<nbdkit-null-plugin(1)>,
+L<nbdkit-offset-filter(1)>,
+L<nbdkit-random-plugin(1)>,
+L<nbdkit-zero-plugin(1)>.
+
+=head1 AUTHORS
+
+Richard W.M. Jones
+
+=head1 COPYRIGHT
+
+Copyright (C) 2018 Red Hat Inc.
+
+=head1 LICENSE
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+=over 4
+
+=item *
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+=item *
+
+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.
+
+=item *
+
+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.
+
+=back
+
+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.
diff --git a/plugins/pattern/pattern.c b/plugins/pattern/pattern.c
new file mode 100644
index 0000000..e1dc798
--- /dev/null
+++ b/plugins/pattern/pattern.c
@@ -0,0 +1,134 @@
+/* nbdkit
+ * Copyright (C) 2017-2018 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Red Hat nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#define NBDKIT_API_VERSION 2
+#include <nbdkit-plugin.h>
+
+/* The size of disk in bytes (initialized by size=<SIZE> parameter). */
+static size_t size = 0;
+
+static int
+pattern_config (const char *key, const char *value)
+{
+ int64_t r;
+
+ if (strcmp (key, "size") == 0) {
+ r = nbdkit_parse_size (value);
+ if (r == -1)
+ return -1;
+ if (r > SIZE_MAX) {
+ nbdkit_error ("size > SIZE_MAX");
+ return -1;
+ }
+ size = (ssize_t) r;
+ }
+ else {
+ nbdkit_error ("unknown parameter '%s'", key);
+ return -1;
+ }
+
+ return 0;
+}
+
+#define pattern_config_help \
+ "size=<SIZE> (required) Size of the backing disk"
+
+#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
+
+/* No meaning, just used as the address for the handle. */
+static int ph;
+
+/* Create the per-connection handle. */
+static void *
+pattern_open (int readonly)
+{
+ return &ph;
+}
+
+/* Get the disk size. */
+static int64_t
+pattern_get_size (void *handle)
+{
+ return (int64_t) size;
+}
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/* Read data. */
+static int
+pattern_pread (void *handle, void *buf, uint32_t count, uint64_t offset,
+ uint32_t flags)
+{
+ char *b = buf;
+ uint64_t d;
+ uint64_t o;
+ size_t n;
+
+ while (count > 0) {
+ d = htobe64 (offset & ~7);
+ o = offset & 7;
+ n = MIN (count, 8-o);
+ memcpy (b, (char *)&d + o, n);
+ b += 8-o;
+ offset += 8-o;
+ count -= n;
+ }
+
+ return 0;
+}
+
+static struct nbdkit_plugin plugin = {
+ .name = "pattern",
+ .version = PACKAGE_VERSION,
+ .config = pattern_config,
+ .config_help = pattern_config_help,
+ .open = pattern_open,
+ .get_size = pattern_get_size,
+ .pread = pattern_pread,
+ /* In this plugin, errno is preserved properly along error return
+ * paths from failed system calls.
+ */
+ .errno_is_preserved = 1,
+};
+
+NBDKIT_REGISTER_PLUGIN(plugin)
diff --git a/plugins/random/nbdkit-random-plugin.pod b/plugins/random/nbdkit-random-plugin.pod
index e746699..6539d61 100644
--- a/plugins/random/nbdkit-random-plugin.pod
+++ b/plugins/random/nbdkit-random-plugin.pod
@@ -44,6 +44,7 @@ If not specified then a random seed is chosen.
L<nbdkit(1)>,
L<nbdkit-plugin(3)>,
L<nbdkit-null-plugin(1)>,
+L<nbdkit-pattern-plugin(1)>,
L<nbdkit-zero-plugin(1)>.
=head1 AUTHORS
diff --git a/plugins/zero/nbdkit-zero-plugin.pod b/plugins/zero/nbdkit-zero-plugin.pod
index 67763da..015c70a 100644
--- a/plugins/zero/nbdkit-zero-plugin.pod
+++ b/plugins/zero/nbdkit-zero-plugin.pod
@@ -21,6 +21,7 @@ protocol and NBD clients.
L<nbdkit(1)>,
L<nbdkit-plugin(3)>,
L<nbdkit-null-plugin(1)>,
+L<nbdkit-pattern-plugin(1)>,
L<nbdkit-random-plugin(1)>.
=head1 AUTHORS
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5f21e75..354c12c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -63,6 +63,7 @@ EXTRA_DIST = \
test-ocaml.c \
test-parallel-file.sh \
test-parallel-nbd.sh \
+ test-pattern.sh \
test-python-exception.sh \
test.pl \
test.py \
@@ -315,6 +316,9 @@ test_memory_SOURCES = test-memory.c test.h
test_memory_CFLAGS = $(WARNINGS_CFLAGS) $(LIBGUESTFS_CFLAGS)
test_memory_LDADD = libtest.la $(LIBGUESTFS_LIBS)
+# pattern plugin test.
+TESTS += test-pattern.sh
+
# nbd plugin test.
LIBGUESTFS_TESTS += test-nbd
diff --git a/tests/test-pattern.sh b/tests/test-pattern.sh
new file mode 100755
index 0000000..2db4e0c
--- /dev/null
+++ b/tests/test-pattern.sh
@@ -0,0 +1,121 @@
+#!/bin/bash -
+# nbdkit
+# Copyright (C) 2018 Red Hat Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Red Hat nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+# Test the pattern plugin.
+#
+# Note we don't have any client which can issue misaligned NBD
+# requests. qemu-io will issue 512-byte aligned requests no matter
+# what read parameters we give it. Hence these tests are rather
+# limited. (XXX)
+
+set -e
+
+files="pattern.out pattern.pid pattern.sock"
+rm -f $files
+
+# Test that qemu-io works
+if ! qemu-io --help >/dev/null; then
+ echo "$0: missing or broken qemu-io"
+ exit 77
+fi
+
+# Run nbdkit with pattern plugin.
+nbdkit -P pattern.pid -U pattern.sock pattern size=1G
+
+# We may have to wait a short time for the pid file to appear.
+for i in `seq 1 10`; do
+ if test -f pattern.pid; then
+ break
+ fi
+ sleep 1
+done
+if ! test -f pattern.pid; then
+ echo "$0: PID file was not created"
+ exit 1
+fi
+
+pid="$(cat pattern.pid)"
+
+# Kill the nbdkit process on exit.
+cleanup ()
+{
+ status=$?
+
+ kill $pid
+ rm -f $files
+
+ exit $status
+}
+trap cleanup INT QUIT TERM EXIT ERR
+
+qemu-io -r -f raw 'nbd+unix://?socket=pattern.sock' \
+ -c 'r -v 0 512' | grep -E '^[[:xdigit:]]+:' > pattern.out
+if [ "$(cat pattern.out)" != "00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
+00000010: 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 18 ................
+00000020: 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 28 ................
+00000030: 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 38 .......0.......8
+00000040: 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 48 ...............H
+00000050: 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 58 .......P.......X
+00000060: 00 00 00 00 00 00 00 60 00 00 00 00 00 00 00 68 ...............h
+00000070: 00 00 00 00 00 00 00 70 00 00 00 00 00 00 00 78 .......p.......x
+00000080: 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 88 ................
+00000090: 00 00 00 00 00 00 00 90 00 00 00 00 00 00 00 98 ................
+000000a0: 00 00 00 00 00 00 00 a0 00 00 00 00 00 00 00 a8 ................
+000000b0: 00 00 00 00 00 00 00 b0 00 00 00 00 00 00 00 b8 ................
+000000c0: 00 00 00 00 00 00 00 c0 00 00 00 00 00 00 00 c8 ................
+000000d0: 00 00 00 00 00 00 00 d0 00 00 00 00 00 00 00 d8 ................
+000000e0: 00 00 00 00 00 00 00 e0 00 00 00 00 00 00 00 e8 ................
+000000f0: 00 00 00 00 00 00 00 f0 00 00 00 00 00 00 00 f8 ................
+00000100: 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 08 ................
+00000110: 00 00 00 00 00 00 01 10 00 00 00 00 00 00 01 18 ................
+00000120: 00 00 00 00 00 00 01 20 00 00 00 00 00 00 01 28 ................
+00000130: 00 00 00 00 00 00 01 30 00 00 00 00 00 00 01 38 .......0.......8
+00000140: 00 00 00 00 00 00 01 40 00 00 00 00 00 00 01 48 ...............H
+00000150: 00 00 00 00 00 00 01 50 00 00 00 00 00 00 01 58 .......P.......X
+00000160: 00 00 00 00 00 00 01 60 00 00 00 00 00 00 01 68 ...............h
+00000170: 00 00 00 00 00 00 01 70 00 00 00 00 00 00 01 78 .......p.......x
+00000180: 00 00 00 00 00 00 01 80 00 00 00 00 00 00 01 88 ................
+00000190: 00 00 00 00 00 00 01 90 00 00 00 00 00 00 01 98 ................
+000001a0: 00 00 00 00 00 00 01 a0 00 00 00 00 00 00 01 a8 ................
+000001b0: 00 00 00 00 00 00 01 b0 00 00 00 00 00 00 01 b8 ................
+000001c0: 00 00 00 00 00 00 01 c0 00 00 00 00 00 00 01 c8 ................
+000001d0: 00 00 00 00 00 00 01 d0 00 00 00 00 00 00 01 d8 ................
+000001e0: 00 00 00 00 00 00 01 e0 00 00 00 00 00 00 01 e8 ................
+000001f0: 00 00 00 00 00 00 01 f0 00 00 00 00 00 00 01 f8 ................" ]
+then
+ echo "$0: unexpected pattern:"
+ cat pattern.out
+ exit 1
+fi
+
+# The cleanup() function is called implicitly on exit.
--
2.17.1