[Libguestfs] [PATCH nbdkit 1/2] nbd: Implement .block_size callback

Richard W.M. Jones rjones at redhat.com
Thu Feb 17 21:09:32 UTC 2022


---
 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




More information about the Libguestfs mailing list