[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Libguestfs] [libnbd PATCH v3 20/22] interop: Add test of 64-bit blo
From: |
Richard W.M. Jones |
Subject: |
Re: [Libguestfs] [libnbd PATCH v3 20/22] interop: Add test of 64-bit block status |
Date: |
Thu, 8 Jun 2023 10:46:15 +0100 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Thu, May 25, 2023 at 08:01:06AM -0500, Eric Blake wrote:
> Prove that we can round-trip a block status request larger than 4G
> through a new-enough qemu-nbd. Also serves as a unit test of our shim
> for converting internal 64-bit representation back to the older 32-bit
> nbd_block_status callback interface.
I think it would be best to call this test "large-block-status.{c,sh}"
as "large-status" is ambiguous. (Or even "block-status-64"?)
The test itself is fine, so if renamed:
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
> Signed-off-by: Eric Blake <eblake@redhat.com>
> ---
> interop/Makefile.am | 6 ++
> interop/large-status.c | 186 ++++++++++++++++++++++++++++++++++++++++
> interop/large-status.sh | 49 +++++++++++
> .gitignore | 1 +
> 4 files changed, 242 insertions(+)
> create mode 100644 interop/large-status.c
> create mode 100755 interop/large-status.sh
>
> diff --git a/interop/Makefile.am b/interop/Makefile.am
> index 3f81df0c..9a7a5967 100644
> --- a/interop/Makefile.am
> +++ b/interop/Makefile.am
> @@ -21,6 +21,7 @@ EXTRA_DIST = \
> dirty-bitmap.sh \
> interop-qemu-storage-daemon.sh \
> interop-qemu-block-size.sh \
> + large-status.sh \
> list-exports-nbd-config \
> list-exports-test-dir/disk1 \
> list-exports-test-dir/disk2 \
> @@ -134,6 +135,7 @@ check_PROGRAMS += \
> list-exports-qemu-nbd \
> socket-activation-qemu-nbd \
> dirty-bitmap \
> + large-status \
> structured-read \
> opt-extended-headers \
> $(NULL)
> @@ -144,6 +146,7 @@ TESTS += \
> list-exports-qemu-nbd \
> socket-activation-qemu-nbd \
> dirty-bitmap.sh \
> + large-status.sh \
> structured-read.sh \
> interop-qemu-block-size.sh \
> opt-extended-headers.sh \
> @@ -235,6 +238,9 @@ socket_activation_qemu_nbd_LDADD =
> $(top_builddir)/lib/libnbd.la
> dirty_bitmap_SOURCES = dirty-bitmap.c
> dirty_bitmap_LDADD = $(top_builddir)/lib/libnbd.la
>
> +large_status_SOURCES = large-status.c
> +large_status_LDADD = $(top_builddir)/lib/libnbd.la
> +
> structured_read_SOURCES = structured-read.c
> structured_read_LDADD = $(top_builddir)/lib/libnbd.la
>
> diff --git a/interop/large-status.c b/interop/large-status.c
> new file mode 100644
> index 00000000..36415653
> --- /dev/null
> +++ b/interop/large-status.c
> @@ -0,0 +1,186 @@
> +/* NBD client library in userspace
> + * Copyright Red Hat
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA
> + */
> +
> +/* Test 64-bit block status with qemu. */
> +
> +#include <config.h>
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <assert.h>
> +#include <stdbool.h>
> +#include <errno.h>
> +
> +#include <libnbd.h>
> +
> +static const char *bitmap;
> +
> +struct data {
> + bool req_one; /* input: true if req_one was passed to request */
> + int count; /* input: count of expected remaining calls */
> + bool seen_base; /* output: true if base:allocation encountered */
> + bool seen_dirty; /* output: true if qemu:dirty-bitmap encountered */
> +};
> +
> +static int
> +cb32 (void *opaque, const char *metacontext, uint64_t offset,
> + uint32_t *entries, size_t len, int *error)
> +{
> + struct data *data = opaque;
> +
> + assert (offset == 0);
> + assert (data->count-- > 0);
> +
> + if (strcmp (metacontext, LIBNBD_CONTEXT_BASE_ALLOCATION) == 0) {
> + assert (!data->seen_base);
> + data->seen_base = true;
> +
> + /* Data block offset 0 size 64k, remainder is hole */
> + assert (len == 4);
> + assert (entries[0] == 65536);
> + assert (entries[1] == 0);
> + /* libnbd had to truncate qemu's >4G answer */
> + assert (entries[2] == 4227858432);
> + assert (entries[3] == (LIBNBD_STATE_HOLE|LIBNBD_STATE_ZERO));
> + }
> + else if (strcmp (metacontext, bitmap) == 0) {
> + assert (!data->seen_dirty);
> + data->seen_dirty = true;
> +
> + /* Dirty block at offset 5G-64k, remainder is clean */
> + /* libnbd had to truncate qemu's >4G answer */
> + assert (len == 2);
> + assert (entries[0] == 4227858432);
> + assert (entries[1] == 0);
> + }
> + else {
> + fprintf (stderr, "unexpected context %s\n", metacontext);
> + exit (EXIT_FAILURE);
> + }
> + return 0;
> +}
> +
> +static int
> +cb64 (void *opaque, const char *metacontext, uint64_t offset,
> + nbd_extent *entries, size_t len, int *error)
> +{
> + struct data *data = opaque;
> +
> + assert (offset == 0);
> + assert (data->count-- > 0);
> +
> + if (strcmp (metacontext, LIBNBD_CONTEXT_BASE_ALLOCATION) == 0) {
> + assert (!data->seen_base);
> + data->seen_base = true;
> +
> + /* Data block offset 0 size 64k, remainder is hole */
> + assert (len == 2);
> + assert (entries[0].length == 65536);
> + assert (entries[0].flags == 0);
> + assert (entries[1].length == 5368643584ULL);
> + assert (entries[1].flags == (LIBNBD_STATE_HOLE|LIBNBD_STATE_ZERO));
> + }
> + else if (strcmp (metacontext, bitmap) == 0) {
> + assert (!data->seen_dirty);
> + data->seen_dirty = true;
> +
> + /* Dirty block at offset 5G-64k, remainder is clean */
> + assert (len == 2);
> + assert (entries[0].length == 5368643584ULL);
> + assert (entries[0].flags == 0);
> + assert (entries[1].length == 65536);
> + assert (entries[1].flags == 1);
> + }
> + else {
> + fprintf (stderr, "unexpected context %s\n", metacontext);
> + exit (EXIT_FAILURE);
> + }
> + return 0;
> +}
> +
> +int
> +main (int argc, char *argv[])
> +{
> + struct nbd_handle *nbd;
> + int64_t exportsize;
> + struct data data;
> +
> + if (argc < 3) {
> + fprintf (stderr, "%s bitmap qemu-nbd [args ...]\n", argv[0]);
> + exit (EXIT_FAILURE);
> + }
> + bitmap = argv[1];
> +
> + nbd = nbd_create ();
> + if (nbd == NULL) {
> + fprintf (stderr, "%s\n", nbd_get_error ());
> + exit (EXIT_FAILURE);
> + }
> +
> + nbd_add_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION);
> + nbd_add_meta_context (nbd, bitmap);
> +
> + if (nbd_connect_systemd_socket_activation (nbd, &argv[2]) == -1) {
> + fprintf (stderr, "%s\n", nbd_get_error ());
> + exit (EXIT_FAILURE);
> + }
> +
> + exportsize = nbd_get_size (nbd);
> + if (exportsize == -1) {
> + fprintf (stderr, "%s\n", nbd_get_error ());
> + exit (EXIT_FAILURE);
> + }
> +
> + if (nbd_get_extended_headers_negotiated (nbd) != 1) {
> + fprintf (stderr, "skipping: qemu-nbd lacks extended headers\n");
> + exit (77);
> + }
> +
> + /* Prove that we can round-trip a >4G block status request */
> + data = (struct data) { .count = 2, };
> + if (nbd_block_status_64 (nbd, exportsize, 0,
> + (nbd_extent64_callback) { .callback = cb64,
> + .user_data = &data },
> + 0) == -1) {
> + fprintf (stderr, "%s\n", nbd_get_error ());
> + exit (EXIT_FAILURE);
> + }
> + assert (data.seen_base && data.seen_dirty);
> +
> + /* Check libnbd's handling of a >4G response through older interface */
> + data = (struct data) { .count = 2, };
> + if (nbd_block_status (nbd, exportsize, 0,
> + (nbd_extent_callback) { .callback = cb32,
> + .user_data = &data },
> + 0) == -1) {
> + fprintf (stderr, "%s\n", nbd_get_error ());
> + exit (EXIT_FAILURE);
> + }
> + assert (data.seen_base && data.seen_dirty);
> +
> + if (nbd_shutdown (nbd, 0) == -1) {
> + fprintf (stderr, "%s\n", nbd_get_error ());
> + exit (EXIT_FAILURE);
> + }
> +
> + nbd_close (nbd);
> +
> + exit (EXIT_SUCCESS);
> +}
> diff --git a/interop/large-status.sh b/interop/large-status.sh
> new file mode 100755
> index 00000000..46810dc3
> --- /dev/null
> +++ b/interop/large-status.sh
> @@ -0,0 +1,49 @@
> +#!/usr/bin/env bash
> +# nbd client library in userspace
> +# Copyright Red Hat
> +#
> +# This library is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU Lesser General Public
> +# License as published by the Free Software Foundation; either
> +# version 2 of the License, or (at your option) any later version.
> +#
> +# This library is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +# Lesser General Public License for more details.
> +#
> +# You should have received a copy of the GNU Lesser General Public
> +# License along with this library; if not, write to the Free Software
> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA
> +
> +# Test reading qemu dirty-bitmap.
> +
> +source ../tests/functions.sh
> +set -e
> +set -x
> +
> +requires qemu-img bitmap --help
> +requires qemu-nbd --version
> +
> +# This test uses the qemu-nbd -B option.
> +if ! qemu-nbd --help | grep -sq -- -B; then
> + echo "$0: skipping because qemu-nbd does not support the -B option"
> + exit 77
> +fi
> +
> +files="large-status.qcow2"
> +rm -f $files
> +cleanup_fn rm -f $files
> +
> +# Create mostly-sparse file with intentionally different data vs. dirty areas
> +# (64k data, 5G-64k hole,zero; 5G-64k clean, 64k dirty)
> +qemu-img create -f qcow2 large-status.qcow2 5G
> +qemu-img bitmap --add --enable -f qcow2 large-status.qcow2 bitmap0
> +qemu-io -f qcow2 -c "w -z $((5*1024*1024*1024 - 64*1024)) 64k" \
> + large-status.qcow2
> +qemu-img bitmap --disable -f qcow2 large-status.qcow2 bitmap0
> +qemu-io -f qcow2 -c 'w 0 64k' large-status.qcow2
> +
> +# Run the test.
> +$VG ./large-status qemu:dirty-bitmap:bitmap0 \
> + qemu-nbd -f qcow2 -B bitmap0 large-status.qcow2
> diff --git a/.gitignore b/.gitignore
> index 24642748..fd81357b 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -114,6 +114,7 @@ Makefile.in
> /interop/interop-qemu-nbd
> /interop/interop-qemu-nbd-tls-certs
> /interop/interop-qemu-nbd-tls-psk
> +/interop/large-status
> /interop/list-exports-nbd-server
> /interop/list-exports-nbdkit
> /interop/list-exports-qemu-nbd
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Libguestfs] [libnbd PATCH v3 20/22] interop: Add test of 64-bit block status,
Richard W.M. Jones <=