From 56cf9d0471c6481adcada2b6afbaf6c7af9e76c7 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Mon, 25 Sep 2023 14:22:39 -0500 Subject: [PATCH] nbd/client: Request extended headers during negotiation All the pieces are in place for a client to finally request extended headers. Note that we must not request extended headers when qemu-nbd is used to connect to the kernel module (as nbd.ko does not expect them, but expects us to do the negotiation in userspace before handing the socket over to the kernel), but there is no harm in all other clients requesting them. Extended headers are not essential to the information collected during 'qemu-nbd --list', but probing for it gives us one more piece of information in that output. Update the iotests affected by the new line of output. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy Message-ID: <20230925192229.3186470-23-eblake@redhat.com> --- nbd/client-connection.c | 2 +- nbd/client.c | 20 ++++++++++++++----- qemu-nbd.c | 3 +++ tests/qemu-iotests/223.out | 6 ++++++ tests/qemu-iotests/233.out | 4 ++++ tests/qemu-iotests/241.out | 3 +++ tests/qemu-iotests/307.out | 5 +++++ .../tests/nbd-qemu-allocation.out | 1 + 8 files changed, 38 insertions(+), 6 deletions(-) diff --git a/nbd/client-connection.c b/nbd/client-connection.c index aa0201b710..f9da67c87e 100644 --- a/nbd/client-connection.c +++ b/nbd/client-connection.c @@ -93,7 +93,7 @@ NBDClientConnection *nbd_client_connection_new(const SocketAddress *saddr, .do_negotiation = do_negotiation, .initial_info.request_sizes = true, - .initial_info.mode = NBD_MODE_STRUCTURED, + .initial_info.mode = NBD_MODE_EXTENDED, .initial_info.base_allocation = true, .initial_info.x_dirty_bitmap = g_strdup(x_dirty_bitmap), .initial_info.name = g_strdup(export_name ?: "") diff --git a/nbd/client.c b/nbd/client.c index a2f253062a..29ffc609a4 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -953,15 +953,23 @@ static int nbd_start_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, if (fixedNewStyle) { int result = 0; + if (max_mode >= NBD_MODE_EXTENDED) { + result = nbd_request_simple_option(ioc, + NBD_OPT_EXTENDED_HEADERS, + false, errp); + if (result) { + return result < 0 ? -EINVAL : NBD_MODE_EXTENDED; + } + } if (max_mode >= NBD_MODE_STRUCTURED) { result = nbd_request_simple_option(ioc, NBD_OPT_STRUCTURED_REPLY, false, errp); - if (result < 0) { - return -EINVAL; + if (result) { + return result < 0 ? -EINVAL : NBD_MODE_STRUCTURED; } } - return result ? NBD_MODE_STRUCTURED : NBD_MODE_SIMPLE; + return NBD_MODE_SIMPLE; } else { return NBD_MODE_EXPORT_NAME; } @@ -1034,6 +1042,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, } switch (info->mode) { + case NBD_MODE_EXTENDED: case NBD_MODE_STRUCTURED: if (base_allocation) { result = nbd_negotiate_simple_meta_context(ioc, info, errp); @@ -1144,7 +1153,7 @@ int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, *info = NULL; result = nbd_start_negotiate(ioc, tlscreds, hostname, &sioc, - NBD_MODE_STRUCTURED, NULL, errp); + NBD_MODE_EXTENDED, NULL, errp); if (tlscreds && sioc) { ioc = sioc; } @@ -1155,6 +1164,7 @@ int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, switch ((NBDMode)result) { case NBD_MODE_SIMPLE: case NBD_MODE_STRUCTURED: + case NBD_MODE_EXTENDED: /* newstyle - use NBD_OPT_LIST to populate array, then try * NBD_OPT_INFO on each array member. If structured replies * are enabled, also try NBD_OPT_LIST_META_CONTEXT. */ @@ -1191,7 +1201,7 @@ int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, break; } - if (result == NBD_MODE_STRUCTURED && + if (result >= NBD_MODE_STRUCTURED && nbd_list_meta_contexts(ioc, &array[i], errp) < 0) { goto out; } diff --git a/qemu-nbd.c b/qemu-nbd.c index 54faa87a0c..1a39bb8fac 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -235,6 +235,9 @@ static int qemu_nbd_client_list(SocketAddress *saddr, QCryptoTLSCreds *tls, printf(" opt block: %u\n", list[i].opt_block); printf(" max block: %u\n", list[i].max_block); } + printf(" transaction size: %s\n", + list[i].mode >= NBD_MODE_EXTENDED ? + "64-bit" : "32-bit"); if (list[i].n_contexts) { printf(" available meta contexts: %d\n", list[i].n_contexts); for (j = 0; j < list[i].n_contexts; j++) { diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out index 86a37014d0..32f05f1c9a 100644 --- a/tests/qemu-iotests/223.out +++ b/tests/qemu-iotests/223.out @@ -87,6 +87,7 @@ exports available: 3 min block: 1 opt block: 4096 max block: 33554432 + transaction size: 64-bit available meta contexts: 2 base:allocation qemu:dirty-bitmap:b @@ -97,6 +98,7 @@ exports available: 3 min block: 1 opt block: 4096 max block: 33554432 + transaction size: 64-bit available meta contexts: 2 base:allocation qemu:dirty-bitmap:b2 @@ -106,6 +108,7 @@ exports available: 3 min block: 1 opt block: 4096 max block: 33554432 + transaction size: 64-bit available meta contexts: 2 base:allocation qemu:dirty-bitmap:b3 @@ -206,6 +209,7 @@ exports available: 3 min block: 1 opt block: 4096 max block: 33554432 + transaction size: 64-bit available meta contexts: 2 base:allocation qemu:dirty-bitmap:b @@ -216,6 +220,7 @@ exports available: 3 min block: 1 opt block: 4096 max block: 33554432 + transaction size: 64-bit available meta contexts: 2 base:allocation qemu:dirty-bitmap:b2 @@ -225,6 +230,7 @@ exports available: 3 min block: 1 opt block: 4096 max block: 33554432 + transaction size: 64-bit available meta contexts: 2 base:allocation qemu:dirty-bitmap:b3 diff --git a/tests/qemu-iotests/233.out b/tests/qemu-iotests/233.out index 237c82767e..1910f7df20 100644 --- a/tests/qemu-iotests/233.out +++ b/tests/qemu-iotests/233.out @@ -39,6 +39,7 @@ exports available: 1 export: '' size: 67108864 min block: 1 + transaction size: 64-bit == check TLS fail over TCP with mismatched hostname == qemu-img: Could not open 'driver=nbd,host=localhost,port=PORT,tls-creds=tls0': Certificate does not match the hostname localhost @@ -53,6 +54,7 @@ exports available: 1 export: '' size: 67108864 min block: 1 + transaction size: 64-bit == check TLS with different CA fails == qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': The certificate hasn't got a known issuer @@ -83,6 +85,7 @@ exports available: 1 export: '' size: 67108864 min block: 1 + transaction size: 64-bit == check TLS works over UNIX with PSK == image: nbd+unix://?socket=SOCK_DIR/qemu-nbd.sock @@ -93,6 +96,7 @@ exports available: 1 export: '' size: 67108864 min block: 1 + transaction size: 64-bit == check TLS fails over UNIX with mismatch PSK == qemu-img: Could not open 'driver=nbd,path=SOCK_DIR/qemu-nbd.sock,tls-creds=tls0': TLS handshake failed: The TLS connection was non-properly terminated. diff --git a/tests/qemu-iotests/241.out b/tests/qemu-iotests/241.out index 7946c286d5..7267cd2997 100644 --- a/tests/qemu-iotests/241.out +++ b/tests/qemu-iotests/241.out @@ -6,6 +6,7 @@ exports available: 1 export: '' size: 1024 min block: 1 + transaction size: 64-bit [{ "start": 0, "length": 1000, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}, { "start": 1000, "length": 24, "depth": 0, "present": true, "zero": true, "data": false, "compressed": false, "offset": OFFSET}] 1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) @@ -16,6 +17,7 @@ exports available: 1 export: '' size: 1024 min block: 512 + transaction size: 64-bit [{ "start": 0, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}] 1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. @@ -28,6 +30,7 @@ exports available: 1 export: '' size: 1024 min block: 1 + transaction size: 64-bit [{ "start": 0, "length": 1000, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}, { "start": 1000, "length": 24, "depth": 0, "present": true, "zero": true, "data": false, "compressed": false, "offset": OFFSET}] 1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) diff --git a/tests/qemu-iotests/307.out b/tests/qemu-iotests/307.out index 390f05d1b7..2b9a6a67a1 100644 --- a/tests/qemu-iotests/307.out +++ b/tests/qemu-iotests/307.out @@ -19,6 +19,7 @@ exports available: 1 min block: XXX opt block: XXX max block: XXX + transaction size: 64-bit available meta contexts: 1 base:allocation @@ -47,6 +48,7 @@ exports available: 1 min block: XXX opt block: XXX max block: XXX + transaction size: 64-bit available meta contexts: 1 base:allocation @@ -78,6 +80,7 @@ exports available: 2 min block: XXX opt block: XXX max block: XXX + transaction size: 64-bit available meta contexts: 1 base:allocation export: 'export1' @@ -87,6 +90,7 @@ exports available: 2 min block: XXX opt block: XXX max block: XXX + transaction size: 64-bit available meta contexts: 1 base:allocation @@ -113,6 +117,7 @@ exports available: 1 min block: XXX opt block: XXX max block: XXX + transaction size: 64-bit available meta contexts: 1 base:allocation diff --git a/tests/qemu-iotests/tests/nbd-qemu-allocation.out b/tests/qemu-iotests/tests/nbd-qemu-allocation.out index 138eb09c6d..1db16926ed 100644 --- a/tests/qemu-iotests/tests/nbd-qemu-allocation.out +++ b/tests/qemu-iotests/tests/nbd-qemu-allocation.out @@ -21,6 +21,7 @@ exports available: 1 min block: 1 opt block: 4096 max block: 33554432 + transaction size: 64-bit available meta contexts: 2 base:allocation qemu:allocation-depth