---
tests/Makefile.am | 2 ++
plugins/nbd/nbd.c | 65 ++++++++++++++++++++++++++++++++++++
tests/test-nbd-block-size.sh | 54 ++++++++++++++++++++++++++++++
3 files changed, 121 insertions(+)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 66156a3b..dd3b4ded 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -814,6 +814,7 @@ if HAVE_LIBNBD
# nbd plugin test.
LIBGUESTFS_TESTS += test-nbd
TESTS += \
+ test-nbd-block-size.sh \
test-nbd-dynamic-content.sh \
test-nbd-dynamic-list.sh \
test-nbd-extents.sh \
@@ -823,6 +824,7 @@ TESTS += \
test-nbd-vsock.sh \
$(NULL)
EXTRA_DIST += \
+ test-nbd-block-size.sh \
test-nbd-dynamic-content.sh \
test-nbd-dynamic-list.sh \
test-nbd-extents.sh \
diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c
index ab516967..01a5ce86 100644
--- a/plugins/nbd/nbd.c
+++ b/plugins/nbd/nbd.c
@@ -848,6 +848,70 @@ nbdplug_get_size (void *handle)
return size;
}
+static int
+nbdplug_block_size (void *handle,
+ uint32_t *minimum, uint32_t *preferred, uint32_t *maximum)
+{
+#ifdef LIBNBD_HAVE_NBD_GET_BLOCK_SIZE
+ struct handle *h = handle;
+ int64_t r;
+
+ r = nbd_get_block_size (h->nbd, LIBNBD_SIZE_MINIMUM);
+ if (r == -1) {
+ nbdkit_error ("%s", nbd_get_error ());
+ return -1;
+ }
+ if (r == 0)
+ goto no_information;
+ if (r > UINT32_MAX) {
+ nbdkit_error ("nbd_get_block_size: LIBNBD_SIZE_MINIMUM: "
+ "value out of range");
+ return -1;
+ }
+ *minimum = r;
+
+ r = nbd_get_block_size (h->nbd, LIBNBD_SIZE_PREFERRED);
+ if (r == -1) {
+ nbdkit_error ("%s", nbd_get_error ());
+ return -1;
+ }
+ if (r == 0)
+ goto no_information;
+ if (r > UINT32_MAX) {
+ nbdkit_error ("nbd_get_block_size: LIBNBD_SIZE_PREFERRED: "
+ "value out of range");
+ return -1;
+ }
+ *preferred = r;
+
+ r = nbd_get_block_size (h->nbd, LIBNBD_SIZE_MAXIMUM);
+ if (r == -1) {
+ nbdkit_error ("%s", nbd_get_error ());
+ return -1;
+ }
+ if (r == 0)
+ goto no_information;
+ if (r > UINT32_MAX) {
+ nbdkit_error ("nbd_get_block_size: LIBNBD_SIZE_MAXIMUM: "
+ "value out of range");
+ return -1;
+ }
+ *maximum = r;
+
+ return 0;
+
+#else /* !LIBNBD_HAVE_NBD_GET_BLOCK_SIZE */
+ goto no_information;
+#endif
+
+ no_information:
+ /* We reach here if there was no error, but there was insufficient
+ * information about block size constraints.
+ */
+ *minimum = *preferred = *maximum = 0;
+ return 0;
+}
+
static int
nbdplug_can_write (void *handle)
{
@@ -1135,6 +1199,7 @@ static struct nbdkit_plugin plugin = {
.close = nbdplug_close,
.export_description = nbdplug_export_description,
.get_size = nbdplug_get_size,
+ .block_size = nbdplug_block_size,
.can_write = nbdplug_can_write,
.can_flush = nbdplug_can_flush,
.is_rotational = nbdplug_is_rotational,
diff --git a/tests/test-nbd-block-size.sh b/tests/test-nbd-block-size.sh
new file mode 100755
index 00000000..0ddd2052
--- /dev/null
+++ b/tests/test-nbd-block-size.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+# nbdkit
+# Copyright (C) 2019-2022 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_plugin eval
+requires_plugin nbd
+requires nbdsh -c 'print(h.get_block_size)'
+
+# Create an nbdkit eval plugin which presents block size constraints.
+# Check the advertised block size constraints can be read.
+nbdkit -U - eval \
+ block_size="echo 64K 128K 32M" \
+ get_size="echo 0" \
+ --run '
+ nbdkit -U - nbd $uri --run "
+ nbdsh \
+ -u \$uri \
+ -c \"assert h.get_block_size(nbd.SIZE_MINIMUM) == 64 * 1024\" \
+ -c \"assert h.get_block_size(nbd.SIZE_PREFERRED) == 128 * 1024\" \
+ -c \"assert h.get_block_size(nbd.SIZE_MAXIMUM) == 32 * 1024 * 1024\"
\
+ "
+'
--
2.35.1