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