[PATCH 0/8] v2v: various fixed for -o rhv-upload
by Pino Toscano
This patch series fixes various issues in the rhv-upload output mode:
- properly find and use RHV resources
- cleanup orphan disks, and possibly the current disk transfer on
failure
In reality, the first 4 patches deal with resources, and the other 4
with cleanups. The latter block can be theoretically sent alone --
I just happened to start working on it as part of my "let's fix
rhv-upload oddities" initiative.
Pino Toscano (8):
v2v: -o rhv-upload: split vmcheck out of precheck
v2v: -o rhv-upload: change precheck script to return a JSON
v2v: -o rhv-upload: improve lookup of specified resources
(RHBZ#1612653)
v2v: -o rhv-upload: tell whether a SD actually exists
v2v: add output#disk_copied hook
v2v: -o rhv-upload: collect disks UUIDs right after copy
v2v: -o rhv-upload: remove uploaded disks on failure
v2v: -o rhv-upload: cancel disk transfer on failure
v2v/Makefile.am | 14 ++-
v2v/output_rhv_upload.ml | 106 ++++++++++++++-----
v2v/output_rhv_upload_deletedisks_source.mli | 19 ++++
v2v/output_rhv_upload_vmcheck_source.mli | 19 ++++
v2v/rhv-upload-createvm.py | 11 +-
v2v/rhv-upload-deletedisks.py | 71 +++++++++++++
v2v/rhv-upload-plugin.py | 2 +
v2v/rhv-upload-precheck.py | 55 +++++++---
v2v/rhv-upload-vmcheck.py | 73 +++++++++++++
v2v/types.ml | 1 +
v2v/types.mli | 4 +
v2v/v2v.ml | 9 +-
12 files changed, 331 insertions(+), 53 deletions(-)
create mode 100644 v2v/output_rhv_upload_deletedisks_source.mli
create mode 100644 v2v/output_rhv_upload_vmcheck_source.mli
create mode 100644 v2v/rhv-upload-deletedisks.py
create mode 100644 v2v/rhv-upload-vmcheck.py
--
2.21.0
5 years, 2 months
[libnbd PATCH] api: Add set_handshake_flags for integration
by Eric Blake
Similar to the recent --mask-handshake command line added to nbdkit to
test client fallbacks to crippled servers, it can be worth testing
server fallbacks to crippled clients. And just as we have exposed
whether the client will request structured replies, we can also expose
whether the client will understand various handshake flags from the
NBD protocol.
Of course, we default to supporting all flags that we understand and
which are advertised by the server. But clearing FIXED_NEWSTYLE lets
us test NBD_OPT_EXPORT_NAME handling, and clearing NO_ZEROES lets us
test whether the zero padding in response to NBD_OPT_EXPORT_NAME is
correct.
---
I'm still considering the addition of tests/* against nbd, or interop/*
against qemu, to ensure that we have interoperability between various
degraded connection modes. But that can be a separate patch.
lib/internal.h | 1 +
lib/nbd-protocol.h | 5 +-
generator/generator | 72 ++++++++++++++++++++-
generator/states-newstyle-opt-export-name.c | 2 +-
generator/states-newstyle.c | 14 ++--
generator/states-oldstyle.c | 5 ++
lib/handle.c | 18 ++++++
7 files changed, 107 insertions(+), 10 deletions(-)
diff --git a/lib/internal.h b/lib/internal.h
index ccaca32..998ca3d 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -157,6 +157,7 @@ struct nbd_handle {
} __attribute__((packed)) error;
} payload;
} __attribute__((packed)) sr;
+ uint16_t gflags;
uint32_t cflags;
uint32_t len;
uint16_t nrinfos;
diff --git a/lib/nbd-protocol.h b/lib/nbd-protocol.h
index 04e93d3..699aa22 100644
--- a/lib/nbd-protocol.h
+++ b/lib/nbd-protocol.h
@@ -93,9 +93,10 @@ struct nbd_fixed_new_option_reply {
#define NBD_REP_MAGIC UINT64_C(0x3e889045565a9)
-/* Global flags. */
+/* Global flags. Exposed by the generator as LIBNBD_HANDSHAKE_FLAG_* instead
#define NBD_FLAG_FIXED_NEWSTYLE 1
#define NBD_FLAG_NO_ZEROES 2
+ */
/* Per-export flags. */
#define NBD_FLAG_HAS_FLAGS (1 << 0)
@@ -238,10 +239,12 @@ struct nbd_structured_reply_error {
#define NBD_CMD_WRITE_ZEROES 6
#define NBD_CMD_BLOCK_STATUS 7
+/* Command flags. Exposed by the generator as LIBNBD_CMD_FLAG_* instead
#define NBD_CMD_FLAG_FUA (1<<0)
#define NBD_CMD_FLAG_NO_HOLE (1<<1)
#define NBD_CMD_FLAG_DF (1<<2)
#define NBD_CMD_FLAG_REQ_ONE (1<<3)
+*/
/* NBD error codes. */
#define NBD_SUCCESS 0
diff --git a/generator/generator b/generator/generator
index a72f36c..170121e 100755
--- a/generator/generator
+++ b/generator/generator
@@ -971,7 +971,14 @@ let cmd_flags = {
"FAST_ZERO", 1 lsl 4;
]
}
-let all_flags = [ cmd_flags ]
+let handshake_flags = {
+ flag_prefix = "HANDSHAKE_FLAG";
+ flags = [
+ "FIXED_NEWSTYLE", 1 lsl 0;
+ "NO_ZEROES", 1 lsl 1;
+ ]
+}
+let all_flags = [ cmd_flags; handshake_flags ]
(* Calls.
*
@@ -1261,6 +1268,7 @@ for integration testing, it can be useful to clear this flag
rather than find a way to alter the server to fail the negotiation
request.";
see_also = ["L<nbd_get_request_structured_replies(3)>";
+ "L<nbd_set_handshake_flags(3)>";
"L<nbd_can_meta_context(3)>"; "L<nbd_can_df(3)>"];
};
@@ -1277,6 +1285,66 @@ able to honor that request";
see_also = ["L<nbd_set_request_structured_replies(3)>"];
};
+ "set_handshake_flags", {
+ default_call with
+ args = [ Flags ("flags", handshake_flags) ]; ret = RErr;
+ permitted_states = [ Created ];
+ shortdesc = "control use of handshake flags";
+ longdesc = "\
+By default, libnbd tries to negotiate all possible handshake flags
+that are also supported by the server; since omitting a handshake
+flag can prevent the use of other functionality such as TLS encryption
+or structured replies. However, for integration testing, it can be
+useful to reduce the set of flags supported by the client to test that
+a particular server can handle various clients that were compliant to
+older versions of the NBD specification.
+
+The C<flags> argument is a bitmask, including zero or more of the
+following handshake flags:
+
+=over 4
+
+=item C<LIBNBD_HANDSHAKE_FLAG_FIXED_NEWSTYLE> = 1
+
+The server gracefully handles unknown option requests from the
+client, rather than disconnecting. Without this flag, a client
+cannot safely request to use extensions such as TLS encryption or
+structured replies, as the request may cause an older server to
+drop the connection.
+
+=item C<LIBNBD_HANDSHAKE_FLAG_NO_ZEROES> = 2
+
+If the client is forced to use C<NBD_OPT_EXPORT_NAME> instead of
+the preferred C<NBD_OPT_GO>, this flag allows the server to send
+fewer all-zero padding bytes over the connection.
+
+=back
+
+Future NBD extensions may add further flags.
+";
+ see_also = ["L<nbd_get_handshake_flags(3)>";
+ "L<nbd_set_request_structured_replies(3)>"];
+ };
+
+ "get_handshake_flags", {
+ default_call with
+ args = []; ret = RUInt;
+ may_set_error = false;
+ shortdesc = "see which handshake flags are supported";
+ longdesc = "\
+Return the state of the handshake flags on this handle. When the
+handle has not yet completed a connection (see C<nbd_aio_is_created>),
+this returns the flags that the client is willing to use, provided
+the server also advertises those flags. After the connection is
+ready (see C<nbd_aio_is_ready>), this returns the flags that were
+actually agreed on between the server and client. If the NBD
+protocol defines new handshake flags, then the return value from
+a newer library version may include bits that were undefined at
+the time of compilation.";
+ see_also = ["L<nbd_set_handshake_flags(3)>";
+ "L<nbd_aio_is_created(3)>"; "L<nbd_aio_is_ready(3)>"];
+ };
+
"add_meta_context", {
default_call with
args = [ String "name" ]; ret = RErr;
@@ -2521,6 +2589,8 @@ let first_version = [
"can_fast_zero", (1, 2);
"set_request_structured_replies", (1, 2);
"get_request_structured_replies", (1, 2);
+ "set_handshake_flags", (1, 2);
+ "get_handshake_flags", (1, 2);
(* These calls are proposed for a future version of libnbd, but
* have not been added to any released version so far.
diff --git a/generator/states-newstyle-opt-export-name.c b/generator/states-newstyle-opt-export-name.c
index ec73136..a46d851 100644
--- a/generator/states-newstyle-opt-export-name.c
+++ b/generator/states-newstyle-opt-export-name.c
@@ -45,7 +45,7 @@
case 0:
h->rbuf = &h->sbuf;
h->rlen = sizeof h->sbuf.export_name_reply;
- if ((h->gflags & NBD_FLAG_NO_ZEROES) != 0)
+ if ((h->gflags & LIBNBD_HANDSHAKE_FLAG_NO_ZEROES) != 0)
h->rlen -= sizeof h->sbuf.export_name_reply.zeroes;
SET_NEXT_STATE (%RECV_REPLY);
}
diff --git a/generator/states-newstyle.c b/generator/states-newstyle.c
index b4f2b80..8c3ae8a 100644
--- a/generator/states-newstyle.c
+++ b/generator/states-newstyle.c
@@ -112,8 +112,8 @@ handle_reply_error (struct nbd_handle *h)
/* STATE MACHINE */ {
NEWSTYLE.START:
- h->rbuf = &h->gflags;
- h->rlen = 2;
+ h->rbuf = &h->sbuf;
+ h->rlen = sizeof h->sbuf.gflags;
SET_NEXT_STATE (%RECV_GFLAGS);
return 0;
@@ -127,16 +127,16 @@ handle_reply_error (struct nbd_handle *h)
NEWSTYLE.CHECK_GFLAGS:
uint32_t cflags;
- h->gflags = be16toh (h->gflags);
- if ((h->gflags & NBD_FLAG_FIXED_NEWSTYLE) == 0 &&
+ h->gflags &= be16toh (h->sbuf.gflags);
+ if ((h->gflags & LIBNBD_HANDSHAKE_FLAG_FIXED_NEWSTYLE) == 0 &&
h->tls == LIBNBD_TLS_REQUIRE) {
SET_NEXT_STATE (%.DEAD);
- set_error (ENOTSUP, "handshake: server is not fixed newstyle, "
+ set_error (ENOTSUP, "handshake: server is not using fixed newstyle, "
"but handle TLS setting is 'require' (2)");
return 0;
}
- cflags = h->gflags & (NBD_FLAG_FIXED_NEWSTYLE|NBD_FLAG_NO_ZEROES);
+ cflags = h->gflags;
h->sbuf.cflags = htobe32 (cflags);
h->wbuf = &h->sbuf;
h->wlen = 4;
@@ -148,7 +148,7 @@ handle_reply_error (struct nbd_handle *h)
case -1: SET_NEXT_STATE (%.DEAD); return 0;
case 0:
/* Start sending options. */
- if ((h->gflags & NBD_FLAG_FIXED_NEWSTYLE) == 0)
+ if ((h->gflags & LIBNBD_HANDSHAKE_FLAG_FIXED_NEWSTYLE) == 0)
SET_NEXT_STATE (%OPT_EXPORT_NAME.START);
else
SET_NEXT_STATE (%OPT_STARTTLS.START);
diff --git a/generator/states-oldstyle.c b/generator/states-oldstyle.c
index babefc0..c0d8af8 100644
--- a/generator/states-oldstyle.c
+++ b/generator/states-oldstyle.c
@@ -58,6 +58,11 @@
h->gflags = gflags;
debug (h, "gflags: 0x%" PRIx16, gflags);
+ if (gflags) {
+ set_error (0, "handshake: oldstyle server should not set gflags");
+ SET_NEXT_STATE (%.DEAD);
+ return 0;
+ }
if (nbd_internal_set_size_and_flags (h, exportsize, eflags) == -1) {
SET_NEXT_STATE (%.DEAD);
diff --git a/lib/handle.c b/lib/handle.c
index bc4206c..8ca2e5a 100644
--- a/lib/handle.c
+++ b/lib/handle.c
@@ -64,6 +64,8 @@ nbd_create (void)
h->unique = 1;
h->tls_verify_peer = true;
h->request_sr = true;
+ h->gflags = (LIBNBD_HANDSHAKE_FLAG_FIXED_NEWSTYLE |
+ LIBNBD_HANDSHAKE_FLAG_NO_ZEROES);
s = getenv ("LIBNBD_DEBUG");
h->debug = s && strcmp (s, "1") == 0;
@@ -258,6 +260,22 @@ nbd_unlocked_get_request_structured_replies (struct nbd_handle *h)
return h->request_sr;
}
+int
+nbd_unlocked_set_handshake_flags (struct nbd_handle *h,
+ uint32_t flags)
+{
+ /* The generator already ensured flags was in range. */
+ h->gflags = flags;
+ return 0;
+}
+
+/* NB: may_set_error = false. */
+uint32_t
+nbd_unlocked_get_handshake_flags (struct nbd_handle *h)
+{
+ return h->gflags;
+}
+
const char *
nbd_unlocked_get_package_name (struct nbd_handle *h)
{
--
2.21.0
5 years, 2 months
[libnbd PATCH] states: Avoid magic number for h->tls
by Eric Blake
When we moved to an enum instead of raw int for nbd_set_tls(), we
should have also updated our code to prefer the enum values. While at
it, improve the grammar of error messages (confusing since 632196ec,
and copy-and-pasted into more locations since then).
Fixes: 4488cf2a
Thanks: Rich Jones
---
Rich noticed this while reviewing the patch for today's CVE fix. It's
not a show-stopper if this doesn't get included in today's releases.
generator/states-newstyle-opt-starttls.c | 8 ++++----
generator/states-newstyle.c | 4 ++--
generator/states-oldstyle.c | 6 +++---
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/generator/states-newstyle-opt-starttls.c b/generator/states-newstyle-opt-starttls.c
index 0a18db0..b050ce0 100644
--- a/generator/states-newstyle-opt-starttls.c
+++ b/generator/states-newstyle-opt-starttls.c
@@ -21,7 +21,7 @@
/* STATE MACHINE */ {
NEWSTYLE.OPT_STARTTLS.START:
/* If TLS was not requested we skip this option and go to the next one. */
- if (!h->tls) {
+ if (h->tls == LIBNBD_TLS_DISABLE) {
SET_NEXT_STATE (%^OPT_STRUCTURED_REPLY.START);
return 0;
}
@@ -88,13 +88,13 @@
return 0;
}
- /* Server refused to upgrade to TLS. If h->tls is not require (2)
+ /* Server refused to upgrade to TLS. If h->tls is not 'require' (2)
* then we can continue unencrypted.
*/
- if (h->tls == 2) {
+ if (h->tls == LIBNBD_TLS_REQUIRE) {
SET_NEXT_STATE (%.DEAD);
set_error (ENOTSUP, "handshake: server refused TLS, "
- "but handle TLS setting is require (2)");
+ "but handle TLS setting is 'require' (2)");
return 0;
}
diff --git a/generator/states-newstyle.c b/generator/states-newstyle.c
index c8f817e..b4f2b80 100644
--- a/generator/states-newstyle.c
+++ b/generator/states-newstyle.c
@@ -129,10 +129,10 @@ handle_reply_error (struct nbd_handle *h)
h->gflags = be16toh (h->gflags);
if ((h->gflags & NBD_FLAG_FIXED_NEWSTYLE) == 0 &&
- h->tls == 2) {
+ h->tls == LIBNBD_TLS_REQUIRE) {
SET_NEXT_STATE (%.DEAD);
set_error (ENOTSUP, "handshake: server is not fixed newstyle, "
- "but handle TLS setting is require (2)");
+ "but handle TLS setting is 'require' (2)");
return 0;
}
diff --git a/generator/states-oldstyle.c b/generator/states-oldstyle.c
index 1aff185..babefc0 100644
--- a/generator/states-oldstyle.c
+++ b/generator/states-oldstyle.c
@@ -46,13 +46,13 @@
gflags = be16toh (h->sbuf.old_handshake.gflags);
eflags = be16toh (h->sbuf.old_handshake.eflags);
- /* Server is unable to upgrade to TLS. If h->tls is not require (2)
+ /* Server is unable to upgrade to TLS. If h->tls is not 'require' (2)
* then we can continue unencrypted.
*/
- if (h->tls == 2) {
+ if (h->tls == LIBNBD_TLS_REQUIRE) {
SET_NEXT_STATE (%.DEAD);
set_error (ENOTSUP, "handshake: server is oldstyle, "
- "but handle TLS setting is require (2)");
+ "but handle TLS setting is 'require' (2)");
return 0;
}
--
2.21.0
5 years, 2 months
[LIBNBD SECURITY PATCH 0/1] NBD Protocol Downgrade Attack in libnbd
by Eric Blake
We discovered a possible Downgrade Attack in libnbd.
Lifecycle
---------
Reported: 2019-09-14 Fixed: 2019-09-16 Published: 2019-09-16
There is no CVE number assigned for this issue yet, but the bug is
being categorized and processed by Red Hat's security team which may
result in a CVE being published later.
Description
-----------
Libnbd includes the method nbd_set_tls(h, LIBNBD_TLS_REQUIRE) which is
documented to let a client refuse to connect to a server that is not
using TLS encryption. However, if the server uses the oldstyle
protocol, a flaw in libnbd meant that the client would proceed with an
unencrypted connection without warning.
An attacker, perhaps acting as a man-in-the-middle, can proceed to
offer the oldstyle protocol rather than the newstyle protocol in an
effort to coerce the client to send plaintext data over the network
that the client thought would be secured.
Workarounds
-----------
It is recommended to upgrade to a fixed version of libnbd (see next
section). However if this cannot be done, it is possible for a client
to test after connection whether the server also supports extension
features that require the newstyle protocol, and thus be sure that an
oldstyle server did not thwart encryption. Either of the following
extension tests will prove that a newstyle server is present
(unfortunately, this does not help for a newstyle server that does not
support either extension):
- If nbd_can_df(h) returns true.
- If the client requests nbd_add_meta_context(h, context) prior to
connection, then nbd_can_meta_context(h, context) returns true; the
most commonly supported context is LIBNBD_CONTEXT_BASE_ALLOCATION.
Test if libnbd is vulnerable
----------------------------
Run the following command (tested with nbdkit 1.12 or newer):
$ nbdsh -c 'h.set_tls(nbd.TLS_REQUIRE)' \
-c 'h.connect_command(["nbdkit", "-o", "-s", "null"])' \
-c 'print(h.get_size())'
If the command succeeds and prints 0, then libnbd is vulnerable. The
correct behavior is to fail with an error that the connection was not
possible due to the server lacking encryption support.
Fixes
-----
This affects all stable versions of libnbd. A fix is available for
1.0 and the current development version:
* development branch (1.1)
https://github.com/libguestfs/libnbd/commit/cca3b10fea96a349a9d718cc92f42...
or use libnbdkit >= 1.1.2 from
http://download.libguestfs.org/libnbd/1.1-development/
* stable branch 1.0
https://github.com/libguestfs/libnbd/commit/19217810ce4467cc8b3671a2797e1...
or use nbdkit >= 1.0.2 from
http://download.libguestfs.org/libnbd/1.0-stable/
Credit
------
Discovered by Eric Blake <eblake(a)redhat.com>
Eric Blake (1):
security: states: Fail oldstyle servers when tls==2
generator/states-oldstyle.c | 10 ++++++++++
tests/oldstyle.c | 17 +++++++++++++++++
2 files changed, 27 insertions(+)
--
2.21.0
5 years, 2 months
[PATCH nbdkit] common/bitmap: Don't fail on realloc (ptr, 0)
by Richard W.M. Jones
The following commands:
nbdkit -fv --filter=cow memory size=512 --run 'qemu-img info $nbd'
nbdkit -fv --filter=cache memory size=512 --run 'qemu-img info $nbd'
both fail with:
nbdkit: memory[1]: error: realloc: Success
Initial git bisect pointed to commit 3166d2bcbfd2 (but I don't believe
that commit is the real cause, it merely exposes the bug).
The reason this happens is because the new behaviour after
commit 3166d2bcbfd2 is to round down the size of the underlying disk
to the cow/cache filter block size (4096 bytes).
=> The size of the disk is rounded down to 0.
=> The cow/cache filter requests a bitmap of size 0.
=> We call realloc (ptr, 0).
=> realloc returns NULL + errno == 0 in this case since it is not an
error.
The current commit changes the realloc call so that it does not fail
in this case. There are many other places in nbdkit where we call
realloc, and I did not vet any of them to see if similar bugs could be
present, but it is quite likely.
Note that the correct use of the cow/cache filter in this case is to
combine it with the truncate filter, eg:
nbdkit -fv --filter=cow --filter=truncate memory size=512 round-up=4096
---
common/bitmap/bitmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/bitmap/bitmap.c b/common/bitmap/bitmap.c
index caac916..6bf04dc 100644
--- a/common/bitmap/bitmap.c
+++ b/common/bitmap/bitmap.c
@@ -60,7 +60,7 @@ bitmap_resize (struct bitmap *bm, uint64_t new_size)
new_bm_size = (size_t) new_bm_size_u64;
new_bitmap = realloc (bm->bitmap, new_bm_size);
- if (new_bitmap == NULL) {
+ if (new_bm_size && new_bitmap == NULL) {
nbdkit_error ("realloc: %m");
return -1;
}
--
2.23.0
5 years, 2 months
[libnbd PATCH v2] nbdsh: Prefer --uri over --connect
by Eric Blake
Typing nbdsh --con (the minimum to get an unambiguous prefix for
--connect, different from --command) is annoying compared to having a
short option. Since it takes a URI as an argument, using -u/--uri is
a nicer mnemonic. We still accept --connect for back-compat, and
document it in the man page, but omit it from --help as the new
spelling is nicer all around.
---
Here's what things evolved to after hiding --connect from --help output.
I've gone ahead and pushed this.
sh/nbdsh.pod | 8 ++++++--
python/nbdsh.py | 8 +++++---
sh/test-context.sh | 24 ++++++++++++------------
sh/test-pattern.sh | 2 +-
4 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/sh/nbdsh.pod b/sh/nbdsh.pod
index d44c8d8..41a88a5 100644
--- a/sh/nbdsh.pod
+++ b/sh/nbdsh.pod
@@ -32,11 +32,11 @@ For documentation about the libnbd API please open the shell and type:
=head2 Print the size of an NBD export
-The I<--connect> option connects to an NBD URI. The I<-c> option lets
+The I<-u> option connects to an NBD URI. The I<-c> option lets
you execute single Python statements from the command line. Combining
these two options lets you print the size in bytes of an NBD export:
- $ nbdsh --connect nbd://localhost -c 'print (h.get_size ())'
+ $ nbdsh -u nbd://localhost -c 'print (h.get_size ())'
1073741824
=head2 Hexdump the boot sector of an NBD export
@@ -76,6 +76,10 @@ can be specified multiple times in order to run multiple commands.
Read standard input and execute it as a command.
+=item B<-u> URI
+
+=item B<-uri> URI
+
=item B<--connect> URI
Connect to the given L<NBD URI|https://github.com/NetworkBlockDevice/nbd/blob/master/doc/uri.md>.
diff --git a/python/nbdsh.py b/python/nbdsh.py
index 098cc8a..3b4ad0e 100644
--- a/python/nbdsh.py
+++ b/python/nbdsh.py
@@ -29,8 +29,10 @@ def shell():
epilog=epilog)
parser.add_argument ('--base-allocation', action='store_true',
help='request the "base:allocation" meta context')
- parser.add_argument ('--connect', metavar='URI',
+ parser.add_argument ('-u', '--uri',
help="connect to NBD URI")
+ # For back-compat, provide --connect as an undocumented synonym to --uri
+ parser.add_argument ('--connect', dest='uri', help=argparse.SUPPRESS)
parser.add_argument ('-c', '--command', action='append',
help="run a command")
parser.add_argument ('-V', '--version', action='version',
@@ -56,8 +58,8 @@ help (nbd) # Display documentation
if args.base_allocation:
h.add_meta_context (nbd.CONTEXT_BASE_ALLOCATION)
- if args.connect is not None:
- h.connect_uri (args.connect)
+ if args.uri is not None:
+ h.connect_uri (args.uri)
# If there are no -c or --command parameters, go interactive,
# otherwise we run the commands and exit.
if not args.command:
diff --git a/sh/test-context.sh b/sh/test-context.sh
index 9a7d3ab..ab3ae80 100755
--- a/sh/test-context.sh
+++ b/sh/test-context.sh
@@ -21,7 +21,7 @@ fail=0
# Without --base-allocation, no meta context is requested
output=$(nbdkit -U - null --run 'nbdsh \
- --connect "nbd+unix://?socket=$unixsocket" \
+ -u "nbd+unix://?socket=$unixsocket" \
-c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
if test "x$output" != xFalse; then
echo "$0: unexpected output: $output"
@@ -30,26 +30,26 @@ fi
# With --base-allocation (and a server that supports it), meta context works.
output=$(nbdkit -U - null --run 'nbdsh \
- --base-allocation --connect "nbd+unix://?socket=$unixsocket" \
- -c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
-if test "x$output" != xTrue; then
- echo "$0: unexpected output: $output"
- fail=1
-fi
-
-# Again, but with --b after --connect, and with abbreviated option names
-output=$(nbdkit -U - null --run 'nbdsh \
- --conn "nbd+unix://?socket=$unixsocket" --b \
+ --base-allocation --uri "nbd+unix://?socket=$unixsocket" \
--command "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
if test "x$output" != xTrue; then
echo "$0: unexpected output: $output"
fail=1
fi
+# Again, but with --b after -u, and with abbreviated option names
+output=$(nbdkit -U - null --run 'nbdsh \
+ -u "nbd+unix://?socket=$unixsocket" --b \
+ -c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
+if test "x$output" != xTrue; then
+ echo "$0: unexpected output: $output"
+ fail=1
+fi
+
if [[ $(nbdkit --help) =~ --no-sr ]]; then
# meta context depends on server cooperation
output=$(nbdkit -U - --no-sr null --run 'nbdsh \
- --connect "nbd+unix://?socket=$unixsocket" --base-allocation \
+ -u "nbd+unix://?socket=$unixsocket" --base-allocation \
-c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
if test "x$output" != xFalse; then
echo "$0: unexpected output: $output"
diff --git a/sh/test-pattern.sh b/sh/test-pattern.sh
index 2d4e261..855bec7 100755
--- a/sh/test-pattern.sh
+++ b/sh/test-pattern.sh
@@ -36,7 +36,7 @@ if ! test -f "$pidfile"; then
exit 1
fi
-nbdsh --connect "nbd+unix://?socket=$sock" \
+nbdsh -u "nbd+unix://?socket=$sock" \
-c '
def size():
return h.get_size()
--
2.21.0
5 years, 2 months
[libnbd PATCH] nbdsh: Add -b option to simplify h.block_status
by Eric Blake
We decided to not request the "base:allocation" context by default (if
a client wants to use block_status on a different context, then they'd
have to get any default request out of the way); however, block status
is useless without at least one meta context. This adds a convenience
knob for requesting that, and has the nice benefit of working with the
--connect command line option (previously, if you wanted to use
block_status, you could not use --connect, because requesting the meta
context must happen before the connection).
---
sh/nbdsh.pod | 9 +++++++
python/nbdsh.py | 4 +++
sh/Makefile.am | 4 ++-
sh/test-context.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 78 insertions(+), 1 deletion(-)
create mode 100755 sh/test-context.sh
diff --git a/sh/nbdsh.pod b/sh/nbdsh.pod
index d7fc315..6c540c7 100644
--- a/sh/nbdsh.pod
+++ b/sh/nbdsh.pod
@@ -56,6 +56,15 @@ __EXAMPLES_HEXDUMP__
Display brief command line help and exit.
+=item B<-b>
+
+=item B<--base-allocation>
+
+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.
+
=item B<-c> 'COMMAND ...'
=item B<--command> 'COMMAND ...'
diff --git a/python/nbdsh.py b/python/nbdsh.py
index 319b0f0..00bc6bc 100644
--- a/python/nbdsh.py
+++ b/python/nbdsh.py
@@ -27,6 +27,8 @@ def shell():
epilog = '''Please read the nbdsh(1) manual page for full usage.'''
parser = argparse.ArgumentParser (prog='nbdsh', description=description,
epilog=epilog)
+ parser.add_argument ('-b', '--base-allocation', action='store_true',
+ help='request the "base:allocation" meta context')
parser.add_argument ('--connect', metavar='URI',
help="connect to NBD URI")
parser.add_argument ('-c', '--command', action='append',
@@ -52,6 +54,8 @@ exit() or Ctrl-D # Quit the shell
help (nbd) # Display documentation
'''
+ if args.base_allocation:
+ h.add_meta_context (nbd.CONTEXT_BASE_ALLOCATION)
if args.connect is not None:
h.connect_uri (args.connect)
# If there are no -c or --command parameters, go interactive,
diff --git a/sh/Makefile.am b/sh/Makefile.am
index 8f70e69..415e241 100644
--- a/sh/Makefile.am
+++ b/sh/Makefile.am
@@ -21,6 +21,7 @@ EXTRA_DIST = \
nbdsh.pod \
examples/LICENSE-FOR-EXAMPLES \
examples/hexdump.sh \
+ test-context.sh \
test-help.sh \
test-pattern.sh \
test-version.sh \
@@ -43,7 +44,7 @@ nbdsh.1: nbdsh.pod $(top_builddir)/podwrapper.pl
endif HAVE_POD
-TESTS_ENVIRONMENT = LIBNBD_DEBUG=1 EXP_VERSION=$(VERSION)
+TESTS_ENVIRONMENT = LIBNBD_DEBUG=1 NBDKIT_DEBUG=1 EXP_VERSION=$(VERSION)
LOG_COMPILER = $(top_builddir)/run
TESTS = \
test-help.sh \
@@ -53,6 +54,7 @@ TESTS = \
if HAVE_NBDKIT
TESTS += \
+ test-context.sh \
test-pattern.sh \
$(NULL)
diff --git a/sh/test-context.sh b/sh/test-context.sh
new file mode 100755
index 0000000..55f9b53
--- /dev/null
+++ b/sh/test-context.sh
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+# nbd client library in userspace
+# Copyright (C) 2019 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
+# 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 effects of nbdsh -b
+fail=0
+
+# Without -b, no meta context is requested
+output=$(nbdkit -U - null --run 'nbdsh \
+ --connect "nbd+unix://?socket=$unixsocket" \
+ -c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))" </dev/null')
+if test "x$output" != xFalse; then
+ echo "$0: unexpected output: $output"
+ fail=1
+fi
+
+# With -b (and a server that supports it), meta context works.
+output=$(nbdkit -U - null --run 'nbdsh \
+ -b --connect "nbd+unix://?socket=$unixsocket" \
+ -c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))" </dev/null')
+if test "x$output" != xTrue; then
+ echo "$0: unexpected output: $output"
+ fail=1
+fi
+
+# Again, but with -b after --connect
+output=$(nbdkit -U - null --run 'nbdsh \
+ --connect "nbd+unix://?socket=$unixsocket" --base-allocation \
+ -c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))" </dev/null')
+if test "x$output" != xTrue; then
+ echo "$0: unexpected output: $output"
+ fail=1
+fi
+
+if [[ $(nbdkit --help) =~ --no-sr ]]; then
+ # meta context depends on server cooperation
+ output=$(nbdkit -U - --no-sr null --run 'nbdsh \
+ --connect "nbd+unix://?socket=$unixsocket" --base-allocation \
+ -c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))" </dev/null')
+ if test "x$output" != xFalse; then
+ echo "$0: unexpected output: $output"
+ fail=1
+ fi
+else
+ echo "$0: nbdkit lacks --no-sr"
+fi
+
+exit $fail
--
2.21.0
5 years, 2 months
[libnbd PATCH] nbdsh: Support -u as synonym for --connect
by Eric Blake
Typing nbdsh --con (the minimum to get an unambiguous prefix for
--connect, different from --command) is annoying compared to having a
short option. Since it takes a URI as an argument, using -u seems
like a reasonable mnemonic.
---
sh/nbdsh.pod | 6 ++++--
python/nbdsh.py | 2 +-
sh/test-context.sh | 8 ++++----
sh/test-pattern.sh | 2 +-
4 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/sh/nbdsh.pod b/sh/nbdsh.pod
index 6c540c7..b1a3552 100644
--- a/sh/nbdsh.pod
+++ b/sh/nbdsh.pod
@@ -32,11 +32,11 @@ For documentation about the libnbd API please open the shell and type:
=head2 Print the size of an NBD export
-The I<--connect> option connects to an NBD URI. The I<-c> option lets
+The I<-u> option connects to an NBD URI. The I<-c> option lets
you execute single Python statements from the command line. Combining
these two options lets you print the size in bytes of an NBD export:
- $ nbdsh --connect nbd://localhost -c 'print (h.get_size ())'
+ $ nbdsh -u nbd://localhost -c 'print (h.get_size ())'
1073741824
=head2 Hexdump the boot sector of an NBD export
@@ -78,6 +78,8 @@ can be specified multiple times in order to run multiple commands.
Read standard input and execute it as a command.
+=item B<-u> URI
+
=item B<--connect> URI
Connect to the given L<NBD URI|https://github.com/NetworkBlockDevice/nbd/blob/master/doc/uri.md>.
diff --git a/python/nbdsh.py b/python/nbdsh.py
index 00bc6bc..b15702c 100644
--- a/python/nbdsh.py
+++ b/python/nbdsh.py
@@ -29,7 +29,7 @@ def shell():
epilog=epilog)
parser.add_argument ('-b', '--base-allocation', action='store_true',
help='request the "base:allocation" meta context')
- parser.add_argument ('--connect', metavar='URI',
+ parser.add_argument ('-u', '--connect', metavar='URI',
help="connect to NBD URI")
parser.add_argument ('-c', '--command', action='append',
help="run a command")
diff --git a/sh/test-context.sh b/sh/test-context.sh
index 3b32ba9..f2c3ba5 100755
--- a/sh/test-context.sh
+++ b/sh/test-context.sh
@@ -21,7 +21,7 @@ fail=0
# Without -b, no meta context is requested
output=$(nbdkit -U - null --run 'nbdsh \
- --connect "nbd+unix://?socket=$unixsocket" \
+ -u "nbd+unix://?socket=$unixsocket" \
-c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
if test "x$output" != xFalse; then
echo "$0: unexpected output: $output"
@@ -30,7 +30,7 @@ fi
# With -b (and a server that supports it), meta context works.
output=$(nbdkit -U - null --run 'nbdsh \
- -b --connect "nbd+unix://?socket=$unixsocket" \
+ -b -u "nbd+unix://?socket=$unixsocket" \
-c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
if test "x$output" != xTrue; then
echo "$0: unexpected output: $output"
@@ -40,7 +40,7 @@ fi
# Again, but with -b after -u, and with long option names
output=$(nbdkit -U - null --run 'nbdsh \
--connect "nbd+unix://?socket=$unixsocket" --base-allocation \
- --command "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
+ -command "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
if test "x$output" != xTrue; then
echo "$0: unexpected output: $output"
fail=1
@@ -49,7 +49,7 @@ fi
if [[ $(nbdkit --help) =~ --no-sr ]]; then
# meta context depends on server cooperation
output=$(nbdkit -U - --no-sr null --run 'nbdsh \
- --connect "nbd+unix://?socket=$unixsocket" --base-allocation \
+ -u "nbd+unix://?socket=$unixsocket" --base-allocation \
-c "print (h.can_meta_context (nbd.CONTEXT_BASE_ALLOCATION))"')
if test "x$output" != xFalse; then
echo "$0: unexpected output: $output"
diff --git a/sh/test-pattern.sh b/sh/test-pattern.sh
index 2d4e261..855bec7 100755
--- a/sh/test-pattern.sh
+++ b/sh/test-pattern.sh
@@ -36,7 +36,7 @@ if ! test -f "$pidfile"; then
exit 1
fi
-nbdsh --connect "nbd+unix://?socket=$sock" \
+nbdsh -u "nbd+unix://?socket=$sock" \
-c '
def size():
return h.get_size()
--
2.21.0
5 years, 2 months