Richard W.M. Jones
2022-Sep-01 16:29 UTC
[Libguestfs] [libnbd PATCH v2 04/12] api: Add nbd_set_request_meta_context()
On Wed, Aug 31, 2022 at 09:39:20AM -0500, Eric Blake wrote:> Add a new control knob nbd_set_request_meta_context(), modeled after > the existing nbd_set_request_structured_replies(), to make it possible > to skip the NBD_OPT_SET_META_CONTEXT half of the two-command sequence > currently performed in nbd_opt_go() and nbd_opt_info(). Also add a > counterpart nbd_get_request_meta_context() for symmetry. > > A later patch will then add the ability for the user to manually > invoke nbd_opt_set_meta_context() at a time of their choosing during > option negotiation; but even without that patch, this new API has some > demonstrable effects by itself: > > - skipping meta contexts but not structured replies lets us test > additional corner cases of servers (for example, while trying to > write my unit tests, I quickly found out that with structured > replies negotiated, current nbdkit ALWAYS emulates and advertises > the base:allocation context rather than consulting .can_extents as a > way to suppress it on a per-export basis, even when a corresponding > .open would fail. A future nbdkit may make .can_extents tri-state to > make it possible to do structured reads but not extents; however, > the current nbdkit behavior appears to comply with the NBD spec, > which allows but does not require NBD_OPT_SET_META_CONTEXT to pay > attention to the export name) > > - back-to-back nbd_opt_info() and nbd_opt_go() was performing a > redundant SET_META_CONTEXT; with this new API, we can get by with > less network traffic during negotiation > > - nbd_opt_info() has to be client-side stateful (you check things like > nbd_get_size after the fact), but based on the name, the fact that > it was also server-side stateful was surprising. Skipping > SET_META_CONTEXT during nbd_opt_info(), and instead using > stateless[1] nbd_opt_list_meta_context(), avoids messing with server > state and can also be more convenient in getting supported context > names by callback instead of lots of post-process > nbd_can_meta_context() calls > > Things to note in the patch: the choice of when to change h->meta_valid > is moved around. Marking contexts invalid is no longer a side effect > of clearing h->exportsize (that is, once set_request_meta_context is > false, nbd_opt_go() and nbd_opt_info() should inherit what contexts > are previously negotiated); it is now an explicit action when changing > the export name[2], starting an actual NBD_OPT_SET_META_CONTEXT > request, or upon failure of NBD_OPT_GO/INFO. > > The testsuite changes added here depend on the new API; therefore, > there is no benefit to separating the C change to a separate patch (if > split and you rearranged the series, it would fail to compile). > However, for ease of review, porting the test to its counterparts in > other languages is split out. > > [1] nbd_opt_list_meta_context() is slightly improved here, but has > other client-side state effects that are left for a later patch to > minimize the size of this one > [2] nbd_set_export_name() should also reset size, but I'm leaving that > for a later patch to minimize this oneThis really needs an example.> lib/internal.h | 1 + > generator/API.ml | 71 ++++++- > generator/states-newstyle-opt-go.c | 1 + > generator/states-newstyle-opt-meta-context.c | 19 +- > lib/flags.c | 4 +- > lib/handle.c | 17 ++ > tests/opt-info.c | 67 +++++- > tests/opt-set-meta | 210 +++++++++++++++++++ > 8 files changed, 369 insertions(+), 21 deletions(-) > create mode 100755 tests/opt-set-meta > > diff --git a/lib/internal.h b/lib/internal.h > index 8aaff15..9d329f0 100644 > --- a/lib/internal.h > +++ b/lib/internal.h > @@ -111,6 +111,7 @@ struct nbd_handle { > > /* Desired metadata contexts. */ > bool request_sr; > + bool request_meta; > string_vector request_meta_contexts; > > /* Allowed in URIs, see lib/uri.c. */ > diff --git a/generator/API.ml b/generator/API.ml > index 62e2d54..adafac6 100644 > --- a/generator/API.ml > +++ b/generator/API.ml > @@ -747,6 +747,46 @@ "get_structured_replies_negotiated", { > Link "get_protocol"]; > }; > > + "set_request_meta_context", { > + default_call with > + args = [Bool "request"]; ret = RErr; > + permitted_states = [ Created; Negotiating ]; > + shortdesc = "control whether connect automatically requests meta contexts"; > + longdesc = "\ > +This function controls whether the act of connecting to an export > +(all C<nbd_connect_*> calls when L<nbd_set_opt_mode(3)> is false, > +or L<nbd_opt_go(3)> and L<nbd_opt_info(3)> when option mode is > +enabled) will also try to issue NBD_OPT_SET_META_CONTEXT when > +the server supports structured replies and any contexts were > +registered by L<nbd_add_meta_context(3)>. The default setting > +is true; however the extra step of negotiating meta contexts is > +not always desirable: performing both info and go on the same > +export works without needing to re-negotiate contexts on the > +second call; and even when using just L<nbd_opt_info(3)>, it > +can be faster to collect the server's results by relying on the > +callback function passed to L<nbd_opt_list_meta_context(3)> than > +a series of post-process calls to L<nbd_can_meta_context(3)>. > + > +Note that this control has no effect if the server does not > +negotiate structured replies, or if the client did not request > +any contexts via L<nbd_add_meta_context(3)>. Setting this > +control to false may cause L<nbd_block_status(3)> to fail."; > + see_also = [Link "set_opt_mode"; Link "opt_go"; Link "opt_info"; > + Link "opt_list_meta_context"; > + Link "get_structured_replies_negotiated"; > + Link "get_request_meta_context"; Link "can_meta_context"]; > + }; > + > + "get_request_meta_context", { > + default_call with > + args = []; ret = RBool; > + permitted_states = []; > + shortdesc = "see if connect automatically requests meta contexts"; > + longdesc = "\ > +Return the state of the automatic meta context request flag on this handle."; > + see_also = [Link "set_request_meta_context"]; > + }; > + > "set_handshake_flags", { > default_call with > args = [ Flags ("flags", handshake_flags) ]; ret = RErr; > @@ -994,12 +1034,17 @@ "opt_go", { > or L<nbd_connect_uri(3)>. This can only be used if > L<nbd_set_opt_mode(3)> enabled option mode. > > +By default, libnbd will automatically request all meta contexts > +registered by L<nbd_add_meta_context(3)> as part of this call; but > +this can be suppressed with L<nbd_set_request_meta_context(3)>. > + > If this fails, the server may still be in negotiation, where it is > possible to attempt another option such as a different export name; > although older servers will instead have killed the connection."; > example = Some "examples/list-exports.c"; > see_also = [Link "set_opt_mode"; Link "aio_opt_go"; Link "opt_abort"; > - Link "set_export_name"; Link "connect_uri"; Link "opt_info"]; > + Link "set_export_name"; Link "connect_uri"; Link "opt_info"; > + Link "add_meta_context"; Link "set_request_meta_context"]; > }; > > "opt_abort", { > @@ -1068,16 +1113,23 @@ "opt_info", { > L<nbd_set_opt_mode(3)> enabled option mode. > > If successful, functions like L<nbd_is_read_only(3)> and > -L<nbd_get_size(3)> will report details about that export. In > -general, if L<nbd_opt_go(3)> is called next, that call will > -likely succeed with the details remaining the same, although this > -is not guaranteed by all servers. > +L<nbd_get_size(3)> will report details about that export. If > +L<nbd_set_request_meta_context(3)> is set (the default) and > +structured replies were negotiated, it is also valid to use > +L<nbd_can_meta_context(3)> after this call. However, it may be > +more efficient to clear that setting and manually utilize > +L<nbd_opt_list_meta_context(3)> with its callback approach, for > +learning which contexts an export supports. In general, if > +L<nbd_opt_go(3)> is called next, that call will likely succeed > +with the details remaining the same, although this is not > +guaranteed by all servers. > > Not all servers understand this request, and even when it is > understood, the server might fail the request even when a > corresponding L<nbd_opt_go(3)> would succeed."; > see_also = [Link "set_opt_mode"; Link "aio_opt_info"; Link "opt_go"; > - Link "set_export_name"]; > + Link "set_export_name"; Link "set_request_meta_context"; > + Link "opt_list_meta_context"]; > }; > > "opt_list_meta_context", { > @@ -1797,7 +1849,8 @@ "can_meta_context", { > ^ non_blocking_test_call_description; > see_also = [SectionLink "Flag calls"; Link "opt_info"; > Link "add_meta_context"; > - Link "block_status"; Link "aio_block_status"]; > + Link "block_status"; Link "aio_block_status"; > + Link "set_request_meta_context"]; > }; > > "get_protocol", { > @@ -3246,6 +3299,10 @@ let first_version > "set_request_block_size", (1, 12); > "get_request_block_size", (1, 12); > > + (* Added in 1.13.x development cycle, will be stable and supported in 1.14. *) > + "set_request_meta_context", (1, 14); > + "get_request_meta_context", (1, 14);I think this should be 1.15.x .. 1.16, since 1.14 is already out. Rich.> (* These calls are proposed for a future version of libnbd, but > * have not been added to any released version so far. > "get_tls_certificates", (1, ??); > diff --git a/generator/states-newstyle-opt-go.c b/generator/states-newstyle-opt-go.c > index b7354ae..1ca5f09 100644 > --- a/generator/states-newstyle-opt-go.c > +++ b/generator/states-newstyle-opt-go.c > @@ -269,6 +269,7 @@ STATE_MACHINE { > reply); > } > nbd_internal_reset_size_and_flags (h); > + h->meta_valid = false; > err = nbd_get_errno () ? : ENOTSUP; > break; > case NBD_REP_ACK: > diff --git a/generator/states-newstyle-opt-meta-context.c b/generator/states-newstyle-opt-meta-context.c > index 5c65454..35d3cbc 100644 > --- a/generator/states-newstyle-opt-meta-context.c > +++ b/generator/states-newstyle-opt-meta-context.c > @@ -29,9 +29,6 @@ STATE_MACHINE { > */ > assert (h->gflags & LIBNBD_HANDSHAKE_FLAG_FIXED_NEWSTYLE); > nbd_internal_reset_size_and_flags (h); > - for (i = 0; i < h->meta_contexts.len; ++i) > - free (h->meta_contexts.ptr[i].name); > - meta_vector_reset (&h->meta_contexts); > if (h->opt_current == NBD_OPT_LIST_META_CONTEXT) { > assert (h->opt_mode); > assert (CALLBACK_IS_NOT_NULL (h->opt_cb.fn.context)); > @@ -40,13 +37,19 @@ STATE_MACHINE { > else { > assert (CALLBACK_IS_NULL (h->opt_cb.fn.context)); > opt = NBD_OPT_SET_META_CONTEXT; > - if (!h->structured_replies || h->request_meta_contexts.len == 0) { > - SET_NEXT_STATE (%^OPT_GO.START); > - return 0; > + if (h->request_meta) { > + for (i = 0; i < h->meta_contexts.len; ++i) > + free (h->meta_contexts.ptr[i].name); > + meta_vector_reset (&h->meta_contexts); > + h->meta_valid = false; > } > } > - > - assert (!h->meta_valid); > + if (opt != h->opt_current && > + (!h->request_meta || !h->structured_replies || > + h->request_meta_contexts.len == 0)) { > + SET_NEXT_STATE (%^OPT_GO.START); > + return 0; > + } > > /* Calculate the length of the option request data. */ > len = 4 /* exportname len */ + strlen (h->export_name) + 4 /* nr queries */; > diff --git a/lib/flags.c b/lib/flags.c > index 91efc1a..c8c68ea 100644 > --- a/lib/flags.c > +++ b/lib/flags.c > @@ -37,7 +37,6 @@ nbd_internal_reset_size_and_flags (struct nbd_handle *h) > > h->exportsize = 0; > h->eflags = 0; > - h->meta_valid = false; > h->block_minimum = 0; > h->block_preferred = 0; > h->block_maximum = 0; > @@ -73,7 +72,8 @@ nbd_internal_set_size_and_flags (struct nbd_handle *h, > eflags &= ~NBD_FLAG_SEND_FAST_ZERO; > } > > - if (!h->structured_replies || h->request_meta_contexts.len == 0) { > + if (h->request_meta && > + (!h->structured_replies || h->request_meta_contexts.len == 0)) { > assert (h->meta_contexts.len == 0); > h->meta_valid = true; > } > diff --git a/lib/handle.c b/lib/handle.c > index 03f45a4..4b373f5 100644 > --- a/lib/handle.c > +++ b/lib/handle.c > @@ -64,6 +64,7 @@ nbd_create (void) > h->unique = 1; > h->tls_verify_peer = true; > h->request_sr = true; > + h->request_meta = true; > h->request_block_size = true; > h->pread_initialize = true; > > @@ -232,6 +233,7 @@ nbd_unlocked_set_export_name (struct nbd_handle *h, const char *export_name) > > free (h->export_name); > h->export_name = new_name; > + h->meta_valid = false; > return 0; > } > > @@ -391,6 +393,21 @@ nbd_unlocked_get_request_structured_replies (struct nbd_handle *h) > return h->request_sr; > } > > +int > +nbd_unlocked_set_request_meta_context (struct nbd_handle *h, > + bool request) > +{ > + h->request_meta = request; > + return 0; > +} > + > +/* NB: may_set_error = false. */ > +int > +nbd_unlocked_get_request_meta_context (struct nbd_handle *h) > +{ > + return h->request_meta; > +} > + > int > nbd_unlocked_get_structured_replies_negotiated (struct nbd_handle *h) > { > diff --git a/tests/opt-info.c b/tests/opt-info.c > index b9739a5..26de0ee 100644 > --- a/tests/opt-info.c > +++ b/tests/opt-info.c > @@ -1,5 +1,5 @@ > /* NBD client library in userspace > - * Copyright (C) 2013-2020 Red Hat Inc. > + * Copyright (C) 2013-2022 Red Hat Inc. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public > @@ -102,11 +102,15 @@ main (int argc, char *argv[]) > exit (EXIT_FAILURE); > } > > - /* info for a different export */ > + /* info for a different export, with automatic meta_context disabled */ > if (nbd_set_export_name (nbd, "b") == -1) { > fprintf (stderr, "%s\n", nbd_get_error ()); > exit (EXIT_FAILURE); > } > + if (nbd_set_request_meta_context (nbd, 0) == -1) { > + fprintf (stderr, "%s\n", nbd_get_error ()); > + exit (EXIT_FAILURE); > + } > if (nbd_opt_info (nbd) == -1) { > fprintf (stderr, "%s\n", nbd_get_error ()); > exit (EXIT_FAILURE); > @@ -119,8 +123,12 @@ main (int argc, char *argv[]) > fprintf (stderr, "expecting read-write export, got %" PRId64 "\n", r); > exit (EXIT_FAILURE); > } > - if ((r = nbd_can_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION)) != 1) { > - fprintf (stderr, "expecting can_meta_context true, got %" PRId64 "\n", r); > + if (nbd_can_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION) != -1) { > + fprintf (stderr, "expecting error for can_meta_context\n"); > + exit (EXIT_FAILURE); > + } > + if (nbd_set_request_meta_context (nbd, 1) == -1) { > + fprintf (stderr, "%s\n", nbd_get_error ()); > exit (EXIT_FAILURE); > } > > @@ -189,8 +197,59 @@ main (int argc, char *argv[]) > fprintf (stderr, "expecting size of 4, got %" PRId64 "\n", r); > exit (EXIT_FAILURE); > } > + if ((r = nbd_can_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION)) != 1) { > + fprintf (stderr, "expecting can_meta_context true, got %" PRId64 "\n", r); > + exit (EXIT_FAILURE); > + } > > nbd_shutdown (nbd, 0); > nbd_close (nbd); > + > + /* Another connection. This time, check that SET_META triggered by opt_info > + * persists through nbd_opt_go with set_request_meta_context disabled. */ > + nbd = nbd_create (); > + if (nbd == NULL || > + nbd_set_opt_mode (nbd, true) == -1 || > + nbd_connect_command (nbd, args) == -1 || > + nbd_add_meta_context (nbd, "x-unexpected:bogus") == -1) { > + fprintf (stderr, "%s\n", nbd_get_error ()); > + exit (EXIT_FAILURE); > + } > + > + if (nbd_can_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION) != -1) { > + fprintf (stderr, "expecting error for can_meta_context\n"); > + exit (EXIT_FAILURE); > + } > + if (nbd_opt_info (nbd) == -1) { > + fprintf (stderr, "%s\n", nbd_get_error ()); > + exit (EXIT_FAILURE); > + } > + if ((r = nbd_can_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION)) != 0) { > + fprintf (stderr, "expecting can_meta_context false, got %" PRId64 "\n", r); > + > + exit (EXIT_FAILURE); > + } > + if (nbd_set_request_meta_context (nbd, 0) == -1) { > + fprintf (stderr, "%s\n", nbd_get_error ()); > + exit (EXIT_FAILURE); > + } > + /* Adding to the request list now won't matter */ > + if (nbd_add_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION) != 0) { > + fprintf (stderr, "%s\n", nbd_get_error ()); > + exit (EXIT_FAILURE); > + } > + if (nbd_opt_go (nbd) == -1) { > + fprintf (stderr, "%s\n", nbd_get_error ()); > + exit (EXIT_FAILURE); > + } > + if ((r = nbd_can_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION)) != 0) { > + fprintf (stderr, "expecting can_meta_context false, got %" PRId64 "\n", r); > + > + exit (EXIT_FAILURE); > + } > + > + nbd_shutdown (nbd, 0); > + nbd_close (nbd); > + > exit (EXIT_SUCCESS); > } > diff --git a/tests/opt-set-meta b/tests/opt-set-meta > new file mode 100755 > index 0000000..6c7b044 > --- /dev/null > +++ b/tests/opt-set-meta > @@ -0,0 +1,210 @@ > +#! /bin/sh > + > +# opt-set-meta - temporary wrapper script for .libs/opt-set-meta > +# Generated by libtool (GNU libtool) 2.4.6 > +# > +# The opt-set-meta program cannot be directly executed until all the libtool > +# libraries that it depends on are installed. > +# > +# This wrapper script should never be moved out of the build directory. > +# If it is, it will not operate correctly. > + > +# Sed substitution that helps us do robust quoting. It backslashifies > +# metacharacters that are still active within double-quoted strings. > +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' > + > +# Be Bourne compatible > +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then > + emulate sh > + NULLCMD=: > + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which > + # is contrary to our usage. Disable this feature. > + alias -g '${1+"$@"}'='"$@"' > + setopt NO_GLOB_SUBST > +else > + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac > +fi > +BIN_SH=xpg4; export BIN_SH # for Tru64 > +DUALCASE=1; export DUALCASE # for MKS sh > + > +# The HP-UX ksh and POSIX shell print the target directory to stdout > +# if CDPATH is set. > +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH > + > +relink_command="" > + > +# This environment variable determines our operation mode. > +if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then > + # install mode needs the following variables: > + generated_by_libtool_version='2.4.6' > + notinst_deplibs=' ../lib/libnbd.la' > +else > + # When we are sourced in execute mode, $file and $ECHO are already set. > + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then > + file="$0" > + > +# A function that is used when there is no print builtin or printf. > +func_fallback_echo () > +{ > + eval 'cat <<_LTECHO_EOF > +$1 > +_LTECHO_EOF' > +} > + ECHO="printf %s\\n" > + fi > + > +# Very basic option parsing. These options are (a) specific to > +# the libtool wrapper, (b) are identical between the wrapper > +# /script/ and the wrapper /executable/ that is used only on > +# windows platforms, and (c) all begin with the string --lt- > +# (application programs are unlikely to have options that match > +# this pattern). > +# > +# There are only two supported options: --lt-debug and > +# --lt-dump-script. There is, deliberately, no --lt-help. > +# > +# The first argument to this parsing function should be the > +# script's ../libtool value, followed by no. > +lt_option_debug> +func_parse_lt_options () > +{ > + lt_script_arg0=$0 > + shift > + for lt_opt > + do > + case "$lt_opt" in > + --lt-debug) lt_option_debug=1 ;; > + --lt-dump-script) > + lt_dump_D=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%/[^/]*$%%'` > + test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=. > + lt_dump_F=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%^.*/%%'` > + cat "$lt_dump_D/$lt_dump_F" > + exit 0 > + ;; > + --lt-*) > + $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2 > + exit 1 > + ;; > + esac > + done > + > + # Print the debug banner immediately: > + if test -n "$lt_option_debug"; then > + echo "opt-set-meta:opt-set-meta:$LINENO: libtool wrapper (GNU libtool) 2.4.6" 1>&2 > + fi > +} > + > +# Used when --lt-debug. Prints its arguments to stdout > +# (redirection is the responsibility of the caller) > +func_lt_dump_args () > +{ > + lt_dump_args_N=1; > + for lt_arg > + do > + $ECHO "opt-set-meta:opt-set-meta:$LINENO: newargv[$lt_dump_args_N]: $lt_arg" > + lt_dump_args_N=`expr $lt_dump_args_N + 1` > + done > +} > + > +# Core function for launching the target application > +func_exec_program_core () > +{ > + > + if test -n "$lt_option_debug"; then > + $ECHO "opt-set-meta:opt-set-meta:$LINENO: newargv[0]: $progdir/$program" 1>&2 > + func_lt_dump_args ${1+"$@"} 1>&2 > + fi > + exec "$progdir/$program" ${1+"$@"} > + > + $ECHO "$0: cannot exec $program $*" 1>&2 > + exit 1 > +} > + > +# A function to encapsulate launching the target application > +# Strips options in the --lt-* namespace from $@ and > +# launches target application with the remaining arguments. > +func_exec_program () > +{ > + case " $* " in > + *\ --lt-*) > + for lt_wr_arg > + do > + case $lt_wr_arg in > + --lt-*) ;; > + *) set x "$@" "$lt_wr_arg"; shift;; > + esac > + shift > + done ;; > + esac > + func_exec_program_core ${1+"$@"} > +} > + > + # Parse options > + func_parse_lt_options "$0" ${1+"$@"} > + > + # Find the directory that this script lives in. > + thisdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'` > + test "x$thisdir" = "x$file" && thisdir=. > + > + # Follow symbolic links until we get to the real thisdir. > + file=`ls -ld "$file" | /usr/bin/sed -n 's/.*-> //p'` > + while test -n "$file"; do > + destdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'` > + > + # If there was a directory component, then change thisdir. > + if test "x$destdir" != "x$file"; then > + case "$destdir" in > + [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;; > + *) thisdir="$thisdir/$destdir" ;; > + esac > + fi > + > + file=`$ECHO "$file" | /usr/bin/sed 's%^.*/%%'` > + file=`ls -ld "$thisdir/$file" | /usr/bin/sed -n 's/.*-> //p'` > + done > + > + # Usually 'no', except on cygwin/mingw when embedded into > + # the cwrapper. > + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no > + if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then > + # special case for '.' > + if test "$thisdir" = "."; then > + thisdir=`pwd` > + fi > + # remove .libs from thisdir > + case "$thisdir" in > + *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /usr/bin/sed 's%[\\/][^\\/]*$%%'` ;; > + .libs ) thisdir=. ;; > + esac > + fi > + > + # Try to get the absolute directory name. > + absdir=`cd "$thisdir" && pwd` > + test -n "$absdir" && thisdir="$absdir" > + > + program='opt-set-meta' > + progdir="$thisdir/.libs" > + > + > + if test -f "$progdir/$program"; then > + # Add our own library path to LD_LIBRARY_PATH > + LD_LIBRARY_PATH="/home/eblake/libnbd/lib/.libs:$LD_LIBRARY_PATH" > + > + # Some systems cannot cope with colon-terminated LD_LIBRARY_PATH > + # The second colon is a workaround for a bug in BeOS R4 sed > + LD_LIBRARY_PATH=`$ECHO "$LD_LIBRARY_PATH" | /usr/bin/sed 's/::*$//'` > + > + export LD_LIBRARY_PATH > + > + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then > + # Run the actual program with our arguments. > + func_exec_program ${1+"$@"} > + fi > + else > + # The program doesn't exist. > + $ECHO "$0: error: '$progdir/$program' does not exist" 1>&2 > + $ECHO "This script is just a wrapper for $program." 1>&2 > + $ECHO "See the libtool documentation for more information." 1>&2 > + exit 1 > + fi > +fi > -- > 2.37.2 > > _______________________________________________ > Libguestfs mailing list > Libguestfs at redhat.com > https://listman.redhat.com/mailman/listinfo/libguestfs-- 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
Eric Blake
2022-Sep-01 20:38 UTC
[Libguestfs] [libnbd PATCH v2 04/12] api: Add nbd_set_request_meta_context()
On Thu, Sep 01, 2022 at 05:29:21PM +0100, Richard W.M. Jones wrote:> On Wed, Aug 31, 2022 at 09:39:20AM -0500, Eric Blake wrote: > > Add a new control knob nbd_set_request_meta_context(), modeled after > > the existing nbd_set_request_structured_replies(), to make it possible > > to skip the NBD_OPT_SET_META_CONTEXT half of the two-command sequence > > currently performed in nbd_opt_go() and nbd_opt_info(). Also add a > > counterpart nbd_get_request_meta_context() for symmetry. > > > > This really needs an example.Will do. Sounds like I have enough incremental things to improve that it will be worth a v3 series, although I'll continue to let more reviews come on in the rest of the series before I post that. I'm wondering whether it is easier to modify the existing examples/list-exports.c, or to write a second example. Over the course of this series, as more and more APIs are added, the example can cover more steps. By the end of the series, it would look something like: // error checking omitted here for brevity, but I'll probably add it in the example nbd = nbd_create (); nbd_set_tls (nbd, LIBNBD_TLS_DISABLE); // we'll manually enable tls later nbd_set_request_structured_reply (nbd, false); // we'll manually request SR later nbd_set_request_meta_context (nbd, false); // we'll do this ourselves nbd_set_opt_mode (nbd, true); nbd_connect_...(); if (!nbd_aio_is_negotiating (nbd)) fatal ("server does not support listing"); // Determine which exports (if any) are exposed without TLS printf ("unencrypted exports:\n"); nbd_opt_list (nbd, callback_exports); // Now enable TLS, and try again if (nbd_opt_starttls (nbd) != 0) fatal ("server does not support TLS"); printf ("encrypted exports:\n"); nbd_opt_list (nbd, callback_exports); printf ("which export to learn more about?"); get user's choice... nbd_set_export_name (nbd, name); if (nbd_opt_structured_reply (nbd) == 1) { printf ("metacontexts available:"); nbd_opt_list_meta_context (nbd, callback_contexts); while (1) { printf ("which context to request, or -1 to finish connecting"); get user's choice if (choice == -1) break; nbd_add_meta_context (nbd, choice); } nbd_opt_set_meta_context (nbd, callback_silent); } else printf ("metacontexts not available\n"); nbd_opt_go (nbd);> > @@ -3246,6 +3299,10 @@ let first_version > > "set_request_block_size", (1, 12); > > "get_request_block_size", (1, 12); > > > > + (* Added in 1.13.x development cycle, will be stable and supported in 1.14. *) > > + "set_request_meta_context", (1, 14); > > + "get_request_meta_context", (1, 14); > > I think this should be 1.15.x .. 1.16, since 1.14 is already out.You're right. Fixed for the nbd_supports_vsock() patch, since that one will beat this series in. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org