Richard W.M. Jones
2022-Feb-17 21:09 UTC
[Libguestfs] [PATCH nbdkit 0/2] nbd: Implement .block_size callback
The second patch is an optional tidy-up.
Richard W.M. Jones
2022-Feb-17 21:09 UTC
[Libguestfs] [PATCH nbdkit 1/2] nbd: Implement .block_size callback
---
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
Richard W.M. Jones
2022-Feb-17 21:09 UTC
[Libguestfs] [PATCH nbdkit 2/2] nbd: In error messages, just display nbd_get_error()
The string returned by nbd_get_error() already includes the name of
the call that failed, so we don't really need to see that information
twice. For example:
#include <stdio.h>
#include <libnbd.h>
main () {
nbd_is_read_only (nbd_create ());
fprintf (stderr, "%s\n", nbd_get_error ());
return 0;
}
prints:
nbd_is_read_only: invalid state: START: the handle must be
negotiating, or connected with the server, or shut down: Transport
endpoint is not connected
which is enough information to track down an error to a particular
line in this plugin.
---
plugins/nbd/nbd.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c
index 01a5ce86..92405496 100644
--- a/plugins/nbd/nbd.c
+++ b/plugins/nbd/nbd.c
@@ -269,7 +269,7 @@ nbdplug_config_complete (void)
struct nbd_handle *nbd = nbd_create ();
if (!nbd) {
- nbdkit_error ("unable to query libnbd details: %s",
nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
if (!nbd_supports_uri (nbd)) {
@@ -350,7 +350,7 @@ nbdplug_config_complete (void)
struct nbd_handle *nbd = nbd_create ();
if (!nbd) {
- nbdkit_error ("unable to query libnbd details: %s",
nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
if (!nbd_supports_tls (nbd)) {
@@ -400,7 +400,7 @@ nbdplug_dump_plugin (void)
struct nbd_handle *nbd = nbd_create ();
if (!nbd) {
- nbdkit_error ("unable to query libnbd details: %s", nbd_get_error
());
+ nbdkit_error ("%s", nbd_get_error ());
exit (EXIT_FAILURE);
}
printf ("libnbd_version=%s\n", nbd_get_version (nbd));
@@ -511,7 +511,7 @@ nbdplug_register (struct handle *h, struct transaction
*trans, int64_t cookie)
char c = 0;
if (cookie == -1) {
- nbdkit_error ("command failed: %s", nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
trans->early_err = nbd_get_errno ();
return;
}
@@ -689,7 +689,7 @@ nbdplug_open_handle (int readonly, const char
*client_export)
return h;
errnbd:
- nbdkit_error ("failure while creating nbd handle: %s",
nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
err:
close (h->fds[0]);
close (h->fds[1]);
@@ -732,7 +732,7 @@ nbdplug_list_exports (int readonly, int is_tls, struct
nbdkit_exports *exports)
r = 0;
out:
if (r == -1)
- nbdkit_error ("Unable to get list: %s", nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
if (nbd) {
if (nbd_aio_is_negotiating (nbd))
nbd_opt_abort (nbd);
@@ -802,7 +802,7 @@ static void
nbdplug_close_handle (struct handle *h)
{
if (nbd_aio_disconnect (h->nbd, 0) == -1)
- nbdkit_debug ("failed to clean up handle: %s", nbd_get_error ());
+ nbdkit_debug ("%s", nbd_get_error ());
if ((errno = pthread_join (h->reader, NULL)))
nbdkit_debug ("failed to join reader thread: %m");
close (h->fds[0]);
@@ -842,7 +842,7 @@ nbdplug_get_size (void *handle)
int64_t size = nbd_get_size (h->nbd);
if (size == -1) {
- nbdkit_error ("failure to get size: %s", nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return size;
@@ -919,7 +919,7 @@ nbdplug_can_write (void *handle)
int i = nbd_is_read_only (h->nbd);
if (i == -1) {
- nbdkit_error ("failure to check readonly flag: %s", nbd_get_error
());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return !(i || h->readonly);
@@ -932,7 +932,7 @@ nbdplug_can_flush (void *handle)
int i = nbd_can_flush (h->nbd);
if (i == -1) {
- nbdkit_error ("failure to check flush flag: %s", nbd_get_error
());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return i;
@@ -945,7 +945,7 @@ nbdplug_is_rotational (void *handle)
int i = nbd_is_rotational (h->nbd);
if (i == -1) {
- nbdkit_error ("failure to check rotational flag: %s",
nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return i;
@@ -958,7 +958,7 @@ nbdplug_can_trim (void *handle)
int i = nbd_can_trim (h->nbd);
if (i == -1) {
- nbdkit_error ("failure to check trim flag: %s", nbd_get_error
());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return i;
@@ -971,7 +971,7 @@ nbdplug_can_zero (void *handle)
int i = nbd_can_zero (h->nbd);
if (i == -1) {
- nbdkit_error ("failure to check zero flag: %s", nbd_get_error
());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return i;
@@ -985,7 +985,7 @@ nbdplug_can_fast_zero (void *handle)
int i = nbd_can_fast_zero (h->nbd);
if (i == -1) {
- nbdkit_error ("failure to check fast zero flag: %s",
nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return i;
@@ -1002,7 +1002,7 @@ nbdplug_can_fua (void *handle)
int i = nbd_can_fua (h->nbd);
if (i == -1) {
- nbdkit_error ("failure to check fua flag: %s", nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return i ? NBDKIT_FUA_NATIVE : NBDKIT_FUA_NONE;
@@ -1015,7 +1015,7 @@ nbdplug_can_multi_conn (void *handle)
int i = nbd_can_multi_conn (h->nbd);
if (i == -1) {
- nbdkit_error ("failure to check multi-conn flag: %s",
nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return i;
@@ -1028,7 +1028,7 @@ nbdplug_can_cache (void *handle)
int i = nbd_can_cache (h->nbd);
if (i == -1) {
- nbdkit_error ("failure to check cache flag: %s", nbd_get_error
());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return i ? NBDKIT_CACHE_NATIVE : NBDKIT_CACHE_NONE;
@@ -1041,7 +1041,7 @@ nbdplug_can_extents (void *handle)
int i = nbd_can_meta_context (h->nbd, LIBNBD_CONTEXT_BASE_ALLOCATION);
if (i == -1) {
- nbdkit_error ("failure to check extents ability: %s",
nbd_get_error ());
+ nbdkit_error ("%s", nbd_get_error ());
return -1;
}
return i;
--
2.35.1