virt-v2v: Virtio-Scsi patch
by Jean-Louis Dupond
Hi,
I was trying to migrate some VM's to Virtio-SCSI block devices, as this
gives some advantages.
While checking the virt-v2v code, I found out that it supported
Virtio-SCSI, but some bits were missing.
In attachment a small patch that adds the missing bits :)
Best regards
Jean-Louis
3 years, 11 months
[PATCH common v2 0/4] Windows BitLocker support.
by Richard W.M. Jones
For links to the original patch series, see:
https://bugzilla.redhat.com/show_bug.cgi?id=1808977#c8
The original feedback was that ignoring errors from guestfs_luks_uuid
would ignore legitimate errors from non-BitLocker disks, so I have
modified this series so that errors are only ignored in the BitLocker
case. As noted in the 4th patch there is no actual error in the
BitLocker case, cryptsetup luksUUID simply exits without printing
anything.
Rich.
4 years, 1 month
[libnbd PATCH 0/3] opt_list_meta_context
by Eric Blake
I'm posting this now, as I'm at the end of a workday and I got things
working for manual experimentation.
Still to do:
- write interop tests for qemu-nbd and nbdkit (including my proposed
patch addition of qemu-nbd -A to show qemu:allocation-depth)
- figure out if we can make 'nbdinfo --map' use the new API to
automatically select all contexts advertised by the server
Eric Blake (3):
api: Add get_nr_meta_contexts, clear_meta_contexts
generator: Rename OPT_SET_META_CONTEXT states
api: Add nbd_opt_list_meta_context
lib/internal.h | 1 +
generator/API.ml | 162 +++++++++++++++++-
generator/Makefile.am | 4 +-
generator/state_machine.ml | 6 +-
...t.c => states-newstyle-opt-meta-context.c} | 106 ++++++++----
.../states-newstyle-opt-structured-reply.c | 4 +-
generator/states-newstyle.c | 5 +-
lib/handle.c | 32 ++++
lib/opt.c | 73 ++++++++
tests/meta-base-allocation.c | 36 +++-
TODO | 11 ++
11 files changed, 394 insertions(+), 46 deletions(-)
rename generator/{states-newstyle-opt-set-meta-context.c => states-newstyle-opt-meta-context.c} (66%)
--
2.28.0
4 years, 1 month
[nbdkit PATCH] server: Adjust limit on max NBD_OPT_* from client
by Eric Blake
Up to nbdkit 1.22, we never advertised large export lists, so a client
had no real reason to give more than 32 NBD_OPT_ commands before
finally selecting an export or quitting, and we were justified in
dropping indecisive chatty clients as being a waste of server
resources. But now that we support .list_exports, it is reasonable
for a client (such as 'qemu-nbd --list' or 'nbdinfo --list') to want
to call NBD_OPT_INFO and several NBD_OPT_LIST_META_CONTEXT commands
for every export returned in NBD_OPT_LIST. We still want to avoid
clients that can tie us up in eternal handshaking, so let's reject a
second call to NBD_OPT_LIST; but once the first call is made, the
client now has a chance to get info on everything listed.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
server/protocol-handshake-newstyle.c | 49 ++++++++++++++++++++--------
1 file changed, 35 insertions(+), 14 deletions(-)
diff --git a/server/protocol-handshake-newstyle.c b/server/protocol-handshake-newstyle.c
index 9c86639b..dedb7f9d 100644
--- a/server/protocol-handshake-newstyle.c
+++ b/server/protocol-handshake-newstyle.c
@@ -44,5 +44,8 @@
#include "nbd-protocol.h"
#include "protostrings.h"
-/* Maximum number of client options we allow before giving up. */
+/* Initial bound of client options we allow before giving up.
+ * However, a client that issues NBD_OPT_LIST is permitted to follow
+ * up with another round of options per export listed.
+ */
#define MAX_NR_OPTIONS 32
/* Receive newstyle options. */
@@ -78,12 +81,13 @@ send_newstyle_option_reply (uint32_t option, uint32_t reply)
/* Reply to NBD_OPT_LIST with the plugin's list of export names.
*/
static int
-send_newstyle_option_reply_exportnames (uint32_t option)
+send_newstyle_option_reply_exportnames (uint32_t option, size_t *nr_options)
{
GET_CONN;
struct nbd_fixed_new_option_reply fixed_new_option_reply;
- size_t i;
+ size_t i, list_len;
CLEANUP_EXPORTS_FREE struct nbdkit_exports *exps = NULL;
+ int r;
exps = nbdkit_exports_new ();
if (exps == NULL)
@@ -91,7 +95,8 @@ send_newstyle_option_reply_exportnames (uint32_t option)
if (backend_list_exports (top, read_only, exps) == -1)
return send_newstyle_option_reply (option, NBD_REP_ERR_PLATFORM);
- for (i = 0; i < nbdkit_exports_count (exps); i++) {
+ list_len = nbdkit_exports_count (exps);
+ for (i = 0; i < list_len; i++) {
const struct nbdkit_export export = nbdkit_get_export (exps, i);
size_t name_len = strlen (export.name);
size_t desc_len = export.description ? strlen (export.description) : 0;
@@ -127,7 +132,11 @@ send_newstyle_option_reply_exportnames (uint32_t option)
}
}
- return send_newstyle_option_reply (option, NBD_REP_ACK);
+ r = send_newstyle_option_reply (option, NBD_REP_ACK);
+ /* Allow additional per-export NBD_OPT_INFO and friends. */
+ if (r == 0)
+ *nr_options += MAX_NR_OPTIONS * list_len;
+ return r;
}
static int
@@ -326,6 +335,7 @@ negotiate_handshake_newstyle_options (void)
GET_CONN;
struct nbd_new_option new_option;
size_t nr_options;
+ bool list_seen = false;
uint64_t version;
uint32_t option;
uint32_t optlen;
@@ -334,7 +344,7 @@ negotiate_handshake_newstyle_options (void)
uint64_t exportsize;
struct backend *b;
- for (nr_options = 0; nr_options < MAX_NR_OPTIONS; ++nr_options) {
+ for (nr_options = MAX_NR_OPTIONS; nr_options > 0; --nr_options) {
CLEANUP_FREE char *data = NULL;
if (conn_recv_full (&new_option, sizeof new_option,
@@ -431,11 +441,22 @@ negotiate_handshake_newstyle_options (void)
continue;
}
- /* Send back the exportname list. */
- debug ("newstyle negotiation: %s: advertising exports",
- name_of_nbd_opt (option));
- if (send_newstyle_option_reply_exportnames (option) == -1)
- return -1;
+ if (list_seen) {
+ debug ("newstyle negotiation: %s: export list already advertised",
+ name_of_nbd_opt (option));
+ if (send_newstyle_option_reply (option, NBD_REP_ERR_INVALID)
+ == -1)
+ return -1;
+ continue;
+ }
+ else {
+ /* Send back the exportname list. */
+ debug ("newstyle negotiation: %s: advertising exports",
+ name_of_nbd_opt (option));
+ if (send_newstyle_option_reply_exportnames (option, &nr_options) == -1)
+ return -1;
+ list_seen = true;
+ }
break;
case NBD_OPT_STARTTLS:
@@ -826,8 +847,8 @@ negotiate_handshake_newstyle_options (void)
break;
}
- if (nr_options >= MAX_NR_OPTIONS) {
- nbdkit_error ("client exceeded maximum number of options (%d)",
- MAX_NR_OPTIONS);
+ if (nr_options == 0) {
+ nbdkit_error ("client spent too much time negotiating without selecting "
+ "an export");
return -1;
}
--
2.28.0
4 years, 1 month
[PATCH libnbd] generator: Add SizeT type, maps to C size_t.
by Richard W.M. Jones
---
generator/API.ml | 1 +
generator/API.mli | 1 +
generator/C.ml | 14 ++++++++++----
generator/GoLang.ml | 5 +++++
generator/OCaml.ml | 5 +++++
generator/Python.ml | 11 +++++++++--
6 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/generator/API.ml b/generator/API.ml
index 0a876c4..b93580d 100644
--- a/generator/API.ml
+++ b/generator/API.ml
@@ -47,6 +47,7 @@ and arg =
| Int of string
| Int64 of string
| Path of string
+| SizeT of string
| SockAddrAndLen of string * string
| String of string
| StringList of string
diff --git a/generator/API.mli b/generator/API.mli
index 9d2fdb7..2e7aa78 100644
--- a/generator/API.mli
+++ b/generator/API.mli
@@ -57,6 +57,7 @@ and arg =
| Int of string (** small int *)
| Int64 of string (** 64 bit signed int *)
| Path of string (** filename or path *)
+| SizeT of string (** like size_t, for counting array elements *)
| SockAddrAndLen of string * string (** struct sockaddr * + socklen_t *)
| String of string (** string, cannot be NULL *)
| StringList of string (** argv-style NULL-terminated array of strings *)
diff --git a/generator/C.ml b/generator/C.ml
index 5f68b14..82d5e3d 100644
--- a/generator/C.ml
+++ b/generator/C.ml
@@ -93,6 +93,7 @@ let rec name_of_arg = function
| Int n -> [n]
| Int64 n -> [n]
| Path n -> [n]
+| SizeT n -> [n]
| SockAddrAndLen (n, len) -> [n; len]
| String n -> [n]
| StringList n -> [n]
@@ -157,6 +158,9 @@ and print_arg_list' ?(handle = false) ?(types = true) ?(closure_style = Direct)
| Int64 n ->
if types then pr "int64_t ";
pr "%s" n
+ | SizeT n ->
+ if types then pr "size_t ";
+ pr "%s" n
| Path n
| String n ->
if types then pr "const char *";
@@ -621,7 +625,8 @@ let generate_lib_api_c () =
pr " nbd_internal_printable_string_list (%s);\n" n
| BytesOut _ | BytesPersistOut _
| Bool _ | Closure _ | Enum _ | Flags _ | Fd _ | Int _
- | Int64 _ | SockAddrAndLen _ | UInt _ | UInt32 _ | UInt64 _ -> ()
+ | Int64 _ | SizeT _
+ | SockAddrAndLen _ | UInt _ | UInt32 _ | UInt64 _ -> ()
) args;
pr " debug (h, \"enter:";
List.iter (
@@ -637,6 +642,7 @@ let generate_lib_api_c () =
| Flags (n, _) -> pr " %s=0x%%x" n
| Fd n | Int n -> pr " %s=%%d" n
| Int64 n -> pr " %s=%%\" PRIi64 \"" n
+ | SizeT n -> pr " %s=%%zu" n
| SockAddrAndLen (n, len) -> pr " %s=<sockaddr> %s=%%d" n len
| Path n
| String n -> pr " %s=%%s" n
@@ -662,8 +668,7 @@ let generate_lib_api_c () =
| Closure { cbname } -> ()
| Enum (n, _) -> pr ", %s" n
| Flags (n, _) -> pr ", %s" n
- | Fd n | Int n -> pr ", %s" n
- | Int64 n -> pr ", %s" n
+ | Fd n | Int n | Int64 n | SizeT n -> pr ", %s" n
| SockAddrAndLen (_, len) -> pr ", (int) %s" len
| Path n | String n | StringList n ->
pr ", %s_printable ? %s_printable : \"\"" n n
@@ -686,7 +691,8 @@ let generate_lib_api_c () =
pr " free (%s_printable);\n" n
| BytesOut _ | BytesPersistOut _
| Bool _ | Closure _ | Enum _ | Flags _ | Fd _ | Int _
- | Int64 _ | SockAddrAndLen _ | UInt _ | UInt32 _ | UInt64 _ -> ()
+ | Int64 _ | SizeT _
+ | SockAddrAndLen _ | UInt _ | UInt32 _ | UInt64 _ -> ()
) args;
pr " }\n"
(* Print the trace when we leave a call with debugging enabled. *)
diff --git a/generator/GoLang.ml b/generator/GoLang.ml
index 81446a6..e169173 100644
--- a/generator/GoLang.ml
+++ b/generator/GoLang.ml
@@ -54,6 +54,7 @@ let go_name_of_arg = function
| Int n -> n
| Int64 n -> n
| Path n -> n
+ | SizeT n -> n
| SockAddrAndLen (n, len) -> n
| String n -> n
| StringList n -> n
@@ -74,6 +75,7 @@ let go_arg_type = function
| Int _ -> "int"
| Int64 _ -> "int64"
| Path _ -> "string"
+ | SizeT _ -> "int"
| SockAddrAndLen _ -> "string"
| String _ -> "string"
| StringList _ -> "[]string"
@@ -276,6 +278,8 @@ let print_binding (name, { args; optargs; ret; shortdesc }) =
| Path n ->
pr " c_%s := C.CString (%s)\n" n n;
pr " defer C.free (unsafe.Pointer (c_%s))\n" n
+ | SizeT n ->
+ pr " c_%s := C.size_t (%s)\n" n n
| SockAddrAndLen (n, len) ->
pr " panic (\"SockAddrAndLen not supported\")\n";
pr " var c_%s *C.struct_sockaddr\n" n;
@@ -336,6 +340,7 @@ let print_binding (name, { args; optargs; ret; shortdesc }) =
| Int n -> pr ", c_%s" n
| Int64 n -> pr ", c_%s" n
| Path n -> pr ", c_%s" n
+ | SizeT n -> pr ", c_%s" n
| SockAddrAndLen (n, len) -> pr ", c_%s, c_%s" n len
| String n -> pr ", c_%s" n
| StringList n -> pr ", &c_%s[0]" n
diff --git a/generator/OCaml.ml b/generator/OCaml.ml
index 28acb50..81e5529 100644
--- a/generator/OCaml.ml
+++ b/generator/OCaml.ml
@@ -50,6 +50,7 @@ and ocaml_arg_to_string = function
| Int64 _ -> "int64"
| Path _ -> "string"
| SockAddrAndLen _ -> "string" (* XXX not impl *)
+ | SizeT _ -> "int" (* OCaml int type is always sufficient for counting *)
| String _ -> "string"
| StringList _ -> "string list"
| UInt _ -> "int"
@@ -103,6 +104,7 @@ let ocaml_name_of_arg = function
| Int n -> n
| Int64 n -> n
| Path n -> n
+ | SizeT n -> n
| SockAddrAndLen (n, len) -> n
| String n -> n
| StringList n -> n
@@ -666,6 +668,8 @@ let print_ocaml_binding (name, { args; optargs; ret }) =
pr " int64_t %s = Int64_val (%sv);\n" n n
| Path n | String n ->
pr " const char *%s = String_val (%sv);\n" n n
+ | SizeT n ->
+ pr " size_t %s = Int_val (%sv);\n" n n
| SockAddrAndLen (n, len) ->
pr " const struct sockaddr *%s;\n" n;
pr " socklen_t %s;\n" len;
@@ -738,6 +742,7 @@ let print_ocaml_binding (name, { args; optargs; ret }) =
| Int _
| Int64 _
| Path _
+ | SizeT _
| String _
| SockAddrAndLen _
| UInt _
diff --git a/generator/Python.ml b/generator/Python.ml
index 1705ad9..46b5828 100644
--- a/generator/Python.ml
+++ b/generator/Python.ml
@@ -295,6 +295,8 @@ let print_python_binding name { args; optargs; ret; may_set_error } =
| Path n ->
pr " PyObject *py_%s = NULL;\n" n;
pr " char *%s = NULL;\n" n
+ | SizeT n ->
+ pr " Py_ssize_t %s;\n" n
| SockAddrAndLen (n, _) ->
pr " /* XXX Complicated - Python uses a tuple of different\n";
pr " * lengths for the different socket types.\n";
@@ -341,6 +343,7 @@ let print_python_binding name { args; optargs; ret; may_set_error } =
| Fd n | Int n -> pr " \"i\""
| Int64 n -> pr " \"L\""
| Path n -> pr " \"O&\""
+ | SizeT n -> pr " \"n\""
| SockAddrAndLen (n, _) -> pr " \"O\""
| String n -> pr " \"s\""
| StringList n -> pr " \"O\""
@@ -365,8 +368,7 @@ let print_python_binding name { args; optargs; ret; may_set_error } =
| Closure { cbname } -> pr ", &py_%s_fn" cbname
| Enum (n, _) -> pr ", &%s" n
| Flags (n, _) -> pr ", &%s" n
- | Fd n | Int n -> pr ", &%s" n
- | Int64 n -> pr ", &%s" n
+ | Fd n | Int n | SizeT n | Int64 n -> pr ", &%s" n
| Path n -> pr ", PyUnicode_FSConverter, &py_%s" n
| SockAddrAndLen (n, _) -> pr ", &%s" n
| String n -> pr ", &%s" n
@@ -435,6 +437,7 @@ let print_python_binding name { args; optargs; ret; may_set_error } =
| Path n ->
pr " %s = PyBytes_AS_STRING (py_%s);\n" n n;
pr " assert (%s != NULL);\n" n
+ | SizeT n -> ()
| SockAddrAndLen _ ->
pr " abort (); /* XXX SockAddrAndLen not implemented */\n";
| String _ -> ()
@@ -462,6 +465,7 @@ let print_python_binding name { args; optargs; ret; may_set_error } =
| Fd n | Int n -> pr ", %s" n
| Int64 n -> pr ", %s_i64" n
| Path n -> pr ", %s" n
+ | SizeT n -> pr ", (size_t)%s" n
| SockAddrAndLen (n, _) -> pr ", /* XXX */ (void *) %s, 0" n
| String n -> pr ", %s" n
| StringList n -> pr ", %s" n
@@ -510,6 +514,7 @@ let print_python_binding name { args; optargs; ret; may_set_error } =
| Int64 _
| Path _
| SockAddrAndLen _
+ | SizeT _
| String _
| StringList _
| UInt _
@@ -551,6 +556,7 @@ let print_python_binding name { args; optargs; ret; may_set_error } =
| Int64 _ -> ()
| Path n ->
pr " Py_XDECREF (py_%s);\n" n
+ | SizeT _ -> ()
| SockAddrAndLen _ -> ()
| String n -> ()
| StringList n -> pr " nbd_internal_py_free_string_list (%s);\n" n
@@ -791,6 +797,7 @@ class NBD(object):
| Fd n | Int n -> n, None, None
| Int64 n -> n, None, None
| Path n -> n, None, None
+ | SizeT n -> n, None, None
| SockAddrAndLen (n, _) -> n, None, None
| String n -> n, None, None
| StringList n -> n, None, None
--
2.28.0.rc2
4 years, 1 month
[PATCH libnbd] DO NOT PUSH: Update api: Add get_nr_meta_contexts, clear_meta_contexts
by Richard W.M. Jones
---
generator/API.ml | 2 +-
lib/handle.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/generator/API.ml b/generator/API.ml
index 770f41e..fd6f033 100644
--- a/generator/API.ml
+++ b/generator/API.ml
@@ -1024,7 +1024,7 @@ what it actually supports, see L<nbd_can_meta_context(3)>.";
"get_meta_context", {
default_call with
- args = [ Int "i" ]; ret = RString;
+ args = [ SizeT "i" ]; ret = RString;
shortdesc = "return the i'th meta context request";
longdesc = "\
During connection libnbd can negotiate zero or more metadata
diff --git a/lib/handle.c b/lib/handle.c
index e0047b7..7adc6d1 100644
--- a/lib/handle.c
+++ b/lib/handle.c
@@ -320,12 +320,12 @@ nbd_unlocked_get_nr_meta_contexts (struct nbd_handle *h)
}
char *
-nbd_unlocked_get_meta_context (struct nbd_handle *h, int i)
+nbd_unlocked_get_meta_context (struct nbd_handle *h, size_t i)
{
size_t len = nbd_internal_string_list_length (h->request_meta_contexts);
char *ret;
- if (i < 0 || i >= len) {
+ if (i >= len) {
set_error (EINVAL, "meta context request out of range");
return NULL;
}
--
2.28.0.rc2
4 years, 1 month
[libnbd PATCH] nbdsh: Add --opt-mode command line option
by Eric Blake
Similar to --base-allocation, this is a common enough configuration
that cannot be performed with -c when using --uri, but which makes
life easier in scripting. And like --base-allocation, I'm starting
with only a long option spelling, rather than burning a short option
letter.
---
sh/nbdsh.pod | 21 +++++++++++++++++++--
python/nbdsh.py | 6 ++++++
sh/test-context.sh | 32 +++++++++++++++++++++++++++++++-
3 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/sh/nbdsh.pod b/sh/nbdsh.pod
index 46c0f48..c1f1672 100644
--- a/sh/nbdsh.pod
+++ b/sh/nbdsh.pod
@@ -60,8 +60,10 @@ Display brief command line help and exit.
Request the use of the "base:allocation" meta context, which is the
most common context used with L<nbd_block_status(3)>. This is
-equivalent to calling S<C<h.set_meta_context
-(nbd.CONTEXT_BASE_ALLOCATION)>> in the shell prior to connecting.
+equivalent to calling
+S<C<h.set_meta_context(nbd.CONTEXT_BASE_ALLOCATION)>> in the shell
+prior to connecting, and works even when combined with C<--uri> (while
+attempting the same with C<-c> would be too late).
=item B<-c> 'COMMAND ...'
@@ -70,6 +72,15 @@ equivalent to calling S<C<h.set_meta_context
Instead of starting an interactive shell, run a command. This option
can be specified multiple times in order to run multiple commands.
+=item B<--opt-mode>
+
+Request that option mode be enabled, which gives fine-grained control
+over option negotiation after initially contacting the server but
+prior to actually using the export. This is equivalent to calling
+S<C<h.set_opt_mode(True)>> in the shell prior to connecting, and works
+even when combined with C<--uri> (while attempting the same with C<-c>
+would be too late).
+
=item B<-c ->
=item B<--command ->
@@ -85,6 +96,12 @@ Read standard input and execute it as a command.
Connect to the given L<NBD URI|https://github.com/NetworkBlockDevice/nbd/blob/master/doc/uri.md>.
This is equivalent to the S<C<h.connect_uri(URI)>> command in the shell.
+Note that the connection is created prior to processing any C<-c>
+commands, which prevents the use of configuration commands such as
+S<C<h.add_meta_context(>NAMEC<)>> from the command line when mixed
+with this option. The options C<--opt-mode> and C<--base-allocation>
+can be used to make this situation easier to manage.
+
=item B<-V>
=item B<--version>
diff --git a/python/nbdsh.py b/python/nbdsh.py
index 083dfee..4a1b5f3 100644
--- a/python/nbdsh.py
+++ b/python/nbdsh.py
@@ -38,6 +38,10 @@ def shell():
help='request the "base:allocation" meta context')
long_options.append("--base-allocation")
+ parser.add_argument('--opt-mode', action='store_true',
+ help='request opt mode during connection')
+ long_options.append("--opt-mode")
+
parser.add_argument('-u', '--uri', help="connect to NBD URI")
short_options.append("-u")
long_options.append("--uri")
@@ -89,6 +93,8 @@ help(nbd) # Display documentation
if args.base_allocation:
h.add_meta_context(nbd.CONTEXT_BASE_ALLOCATION)
+ if args.opt_mode:
+ h.set_opt_mode(True)
if args.uri is not None:
try:
h.connect_uri(args.uri)
diff --git a/sh/test-context.sh b/sh/test-context.sh
index fab1aad..5fb5cad 100755
--- a/sh/test-context.sh
+++ b/sh/test-context.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# nbd client library in userspace
-# Copyright (C) 2019 Red Hat Inc.
+# Copyright (C) 2019-2020 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
@@ -31,6 +31,19 @@ if test "x$output" != xFalse; then
fail=1
fi
+# Use of -c to request context is too late with -u
+output=$(nbdkit -U - null --run 'nbdsh -c "
+try:
+ h.add_meta_context(nbd.CONTEXT_BASE_ALLOCATION)
+ assert(False)
+except nbd.Error:
+ print(\"okay\")
+" -u "nbd+unix://?socket=$unixsocket"')
+if test "x$output" != xokay; then
+ echo "$0: unexpected output: $output"
+ fail=1
+fi
+
# With --base-allocation (and a server that supports it), meta context works.
output=$(nbdkit -U - null --run 'nbdsh \
--base-allocation --uri "nbd+unix://?socket=$unixsocket" \
@@ -62,4 +75,21 @@ else
echo "$0: nbdkit lacks --no-sr"
fi
+# Test interaction with opt mode
+output=$(nbdkit -U - null --run 'nbdsh \
+ -u "nbd+unix://?socket=$unixsocket" --opt-mode --base-allocation \
+ -c "
+try:
+ h.can_meta_context(nbd.CONTEXT_BASE_ALLOCATION)
+ assert(False)
+except nbd.Error:
+ pass
+" \
+ -c "h.opt_go()" \
+ -c "print(h.can_meta_context(nbd.CONTEXT_BASE_ALLOCATION))"')
+if test "x$output" != xTrue; then
+ echo "$0: unexpected output: $output"
+ fail=1
+fi
+
exit $fail
--
2.28.0
4 years, 1 month