From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543615621136285.32260046015233; Fri, 30 Nov 2018 14:07:01 -0800 (PST) Received: from localhost ([::1]:34823 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqw8-0006Gj-1F for importer@patchew.org; Fri, 30 Nov 2018 17:07:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55926) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtH-0004Mv-6i for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtG-0004AA-3g for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39636) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqt9-0003JU-65; Fri, 30 Nov 2018 17:03:55 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 70BD3C05D3F3; Fri, 30 Nov 2018 22:03:54 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id B1F1F1057072; Fri, 30 Nov 2018 22:03:53 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:30 -0600 Message-Id: <20181130220344.3350618-2-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 30 Nov 2018 22:03:54 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 01/14] qemu-nbd: Use program name in error messages X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, qemu-block@nongnu.org, rjones@redhat.com, Max Reitz , nsoffer@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This changes output from: $ qemu-nbd nosuch Failed to blk_new_open 'nosuch': Could not open 'nosuch': No such file or d= irectory to something more consistent with qemu-img and qemu: $ qemu-nbd nosuch qemu-nbd: Failed to blk_new_open 'nosuch': Could not open 'nosuch': No such= file or directory Update the lone affected test to match. (Hmm - is it sad that we don't do much testing of expected failures?) Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones Reviewed-by: Vladimir Sementsov-Ogievskiy --- qemu-nbd.c | 1 + tests/qemu-iotests/233.out | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/qemu-nbd.c b/qemu-nbd.c index ca7109652e5..e169b839ece 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -571,6 +571,7 @@ int main(int argc, char **argv) #endif module_call_init(MODULE_INIT_TRACE); + error_set_progname(argv[0]); qcrypto_init(&error_fatal); module_call_init(MODULE_INIT_QOM); diff --git a/tests/qemu-iotests/233.out b/tests/qemu-iotests/233.out index 94acd9b9479..5f416721b03 100644 --- a/tests/qemu-iotests/233.out +++ b/tests/qemu-iotests/233.out @@ -27,7 +27,7 @@ virtual size: 64M (67108864 bytes) disk size: unavailable =3D=3D check TLS with different CA fails =3D=3D -option negotiation failed: Verify failed: No certificate was found. +qemu-nbd: option negotiation failed: Verify failed: No certificate was fou= nd. qemu-img: Could not open 'driver=3Dnbd,host=3D127.0.0.1,port=3DPORT,tls-cr= eds=3Dtls0': The certificate hasn't got a known issuer =3D=3D perform I/O over TLS =3D=3D --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543615725908115.10021712130765; Fri, 30 Nov 2018 14:08:45 -0800 (PST) Received: from localhost ([::1]:34832 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqxf-0008Tp-WD for importer@patchew.org; Fri, 30 Nov 2018 17:08:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55929) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtH-0004N0-8n for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtG-0004AG-4O for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40290) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqt9-0003Mc-Pa; Fri, 30 Nov 2018 17:03:55 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2356B3082DDB; Fri, 30 Nov 2018 22:03:55 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8CFE21057072; Fri, 30 Nov 2018 22:03:54 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:31 -0600 Message-Id: <20181130220344.3350618-3-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 30 Nov 2018 22:03:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 02/14] nbd/client: More consistent error messages X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Consolidate on using decimal (not hex) and on outputting the option reply name (not just value) when the client reports protocol discrepancies from the server. While it won't affect normal operation, it makes debugging additions easier. Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones Reviewed-by: Vladimir Sementsov-Ogievskiy --- nbd/client.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index b4d457a19ad..b667a1b56fd 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -132,8 +132,9 @@ static int nbd_receive_option_reply(QIOChannel *ioc, ui= nt32_t opt, return -1; } if (reply->option !=3D opt) { - error_setg(errp, "Unexpected option type %x expected %x", - reply->option, opt); + error_setg(errp, "Unexpected option type %u (%s) expected %u (%s)", + reply->option, nbd_opt_lookup(reply->option), + opt, nbd_opt_lookup(opt)); nbd_send_opt_abort(ioc); return -1; } @@ -265,8 +266,9 @@ static int nbd_receive_list(QIOChannel *ioc, const char= *want, bool *match, } return 0; } else if (reply.type !=3D NBD_REP_SERVER) { - error_setg(errp, "Unexpected reply type %" PRIx32 " expected %x", - reply.type, NBD_REP_SERVER); + error_setg(errp, "Unexpected reply type %u (%s) expected %u (%s)", + reply.type, nbd_rep_lookup(reply.type), + NBD_REP_SERVER, nbd_rep_lookup(NBD_REP_SERVER)); nbd_send_opt_abort(ioc); return -1; } @@ -378,9 +380,9 @@ static int nbd_opt_go(QIOChannel *ioc, const char *want= name, return 1; } if (reply.type !=3D NBD_REP_INFO) { - error_setg(errp, "unexpected reply type %" PRIu32 - " (%s), expected %u", - reply.type, nbd_rep_lookup(reply.type), NBD_REP_INF= O); + error_setg(errp, "unexpected reply type %u (%s), expected %u (= %s)", + reply.type, nbd_rep_lookup(reply.type), + NBD_REP_INFO, nbd_rep_lookup(NBD_REP_INFO)); nbd_send_opt_abort(ioc); return -1; } @@ -704,8 +706,9 @@ static int nbd_negotiate_simple_meta_context(QIOChannel= *ioc, } if (reply.type !=3D NBD_REP_ACK) { - error_setg(errp, "Unexpected reply type %" PRIx32 " expected %x", - reply.type, NBD_REP_ACK); + error_setg(errp, "Unexpected reply type %u (%s) expected %u (%s)", + reply.type, nbd_rep_lookup(reply.type), + NBD_REP_ACK, nbd_rep_lookup(NBD_REP_ACK)); nbd_send_opt_abort(ioc); return -1; } --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543615914515484.5763985201572; Fri, 30 Nov 2018 14:11:54 -0800 (PST) Received: from localhost ([::1]:34861 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr0r-0003Ee-BA for importer@patchew.org; Fri, 30 Nov 2018 17:11:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55955) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtI-0004Nw-15 for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtG-0004BH-8d for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50468) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtA-0003T2-Fl; Fri, 30 Nov 2018 17:03:56 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D1CD3307D84D; Fri, 30 Nov 2018 22:03:55 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4607B1057072; Fri, 30 Nov 2018 22:03:55 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:32 -0600 Message-Id: <20181130220344.3350618-4-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 30 Nov 2018 22:03:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 03/14] qemu-nbd: Fail earlier for -c/-d on non-linux X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Connecting to a /dev/nbdN device is a Linux-specific action. We were already masking -c and -d from 'qemu-nbd --help' on non-linux. However, while -d fails with a sensible error message, it took hunting through a couple of files to prove that. What's more, the code for -c doesn't fail until after it has created a pthread and tried to open a device - possibly even printing an error message with %m on a non-Linux platform in spite of the comment that %m is glibc-specific. Make the failure happen sooner, then get rid of stubs that are no longer needed because of the early exits. While at it: tweak the blank newlines in --help output to be consistent, whether or not built on Linux. Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones --- nbd/client.c | 18 +----------------- qemu-nbd.c | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index b667a1b56fd..0be89f9e641 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -1029,23 +1029,7 @@ int nbd_disconnect(int fd) return 0; } -#else -int nbd_init(int fd, QIOChannelSocket *ioc, NBDExportInfo *info, - Error **errp) -{ - error_setg(errp, "nbd_init is only supported on Linux"); - return -ENOTSUP; -} - -int nbd_client(int fd) -{ - return -ENOTSUP; -} -int nbd_disconnect(int fd) -{ - return -ENOTSUP; -} -#endif +#endif /* __linux__ */ int nbd_send_request(QIOChannel *ioc, NBDRequest *request) { diff --git a/qemu-nbd.c b/qemu-nbd.c index e169b839ece..55e29bd9a7e 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -43,6 +43,12 @@ #include "trace/control.h" #include "qemu-version.h" +#ifdef __linux__ +#define HAVE_NBD_DEVICE 1 +#else +#define HAVE_NBD_DEVICE 0 +#endif + #define SOCKET_PATH "/var/lock/qemu-nbd-%s" #define QEMU_NBD_OPT_CACHE 256 #define QEMU_NBD_OPT_AIO 257 @@ -98,11 +104,11 @@ static void usage(const char *name) " specify tracing options\n" " --fork fork off the server process and exit the pare= nt\n" " once the server is running\n" -#ifdef __linux__ +#if HAVE_NBD_DEVICE +"\n" "Kernel NBD client support:\n" " -c, --connect=3DDEV connect FILE to the local NBD device DEV\n" " -d, --disconnect disconnect the specified device\n" -"\n" #endif "\n" "Block device options:\n" @@ -236,6 +242,7 @@ static void termsig_handler(int signum) } +#if HAVE_NBD_DEVICE static void *show_parts(void *arg) { char *device =3D arg; @@ -321,6 +328,7 @@ out: kill(getpid(), SIGTERM); return (void *) EXIT_FAILURE; } +#endif /* HAVE_NBD_DEVICE */ static int nbd_can_accept(void) { @@ -815,6 +823,7 @@ int main(int argc, char **argv) } if (disconnect) { +#if HAVE_NBD_DEVICE int nbdfd =3D open(argv[optind], O_RDWR); if (nbdfd < 0) { error_report("Cannot open %s: %s", argv[optind], @@ -828,6 +837,10 @@ int main(int argc, char **argv) printf("%s disconnected\n", argv[optind]); return 0; +#else + error_report("Kernel /dev/nbdN support not available"); + exit(EXIT_FAILURE); +#endif } if ((device && !verbose) || fork_process) { @@ -1006,6 +1019,7 @@ int main(int argc, char **argv) nbd_export_set_description(exp, export_description); if (device) { +#if HAVE_NBD_DEVICE int ret; ret =3D pthread_create(&client_thread, NULL, nbd_client_thread, de= vice); @@ -1013,6 +1027,10 @@ int main(int argc, char **argv) error_report("Failed to create client thread: %s", strerror(re= t)); exit(EXIT_FAILURE); } +#else + error_report("Kernel /dev/nbdN support not available"); + exit(EXIT_FAILURE); +#endif } else { /* Shut up GCC warnings. */ memset(&client_thread, 0, sizeof(client_thread)); --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543615598140482.7596951777592; Fri, 30 Nov 2018 14:06:38 -0800 (PST) Received: from localhost ([::1]:34814 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqvl-0005yt-0Y for importer@patchew.org; Fri, 30 Nov 2018 17:06:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55947) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtH-0004Nq-UA for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtG-0004C5-D8 for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:49866) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtB-0003XV-6w; Fri, 30 Nov 2018 17:03:57 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8925C3091D5C; Fri, 30 Nov 2018 22:03:56 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id F17E91057072; Fri, 30 Nov 2018 22:03:55 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:33 -0600 Message-Id: <20181130220344.3350618-5-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 30 Nov 2018 22:03:56 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 04/14] qemu-nbd: Simplify --partition handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Our open-coding of strtol handling forgot to handle overflow conditions. What's more, since we insiste on a user-supplied partition to be non-zero, we can use 0 rather than -1 for our initial value to distinguish when a partition is not being served, for slightly more optimal code. Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones Reviewed-by: Vladimir Sementsov-Ogievskiy --- qemu-nbd.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/qemu-nbd.c b/qemu-nbd.c index 55e29bd9a7e..866e64779f1 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -546,7 +546,7 @@ int main(int argc, char **argv) int opt_ind =3D 0; char *end; int flags =3D BDRV_O_RDWR; - int partition =3D -1; + int partition =3D 0; int ret =3D 0; bool seen_cache =3D false; bool seen_discard =3D false; @@ -685,13 +685,9 @@ int main(int argc, char **argv) flags &=3D ~BDRV_O_RDWR; break; case 'P': - partition =3D strtol(optarg, &end, 0); - if (*end) { - error_report("Invalid partition `%s'", optarg); - exit(EXIT_FAILURE); - } - if (partition < 1 || partition > 8) { - error_report("Invalid partition %d", partition); + if (qemu_strtoi(optarg, NULL, 0, &partition) < 0 || + partition < 1 || partition > 8) { + error_report("Invalid partition %s", optarg); exit(EXIT_FAILURE); } break; @@ -1004,7 +1000,7 @@ int main(int argc, char **argv) } fd_size -=3D dev_offset; - if (partition !=3D -1) { + if (partition) { ret =3D find_partition(blk, partition, &dev_offset, &fd_size); if (ret < 0) { error_report("Could not find partition %d: %s", partition, --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543616064505305.21805375986446; Fri, 30 Nov 2018 14:14:24 -0800 (PST) Received: from localhost ([::1]:34877 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr3H-0006iJ-Dy for importer@patchew.org; Fri, 30 Nov 2018 17:14:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55956) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtI-0004Nx-1C for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtG-0004CB-F6 for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38174) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtB-0003bJ-U0; Fri, 30 Nov 2018 17:03:58 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 45C083002887; Fri, 30 Nov 2018 22:03:57 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id AD7951057072; Fri, 30 Nov 2018 22:03:56 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:34 -0600 Message-Id: <20181130220344.3350618-6-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 30 Nov 2018 22:03:57 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 05/14] nbd/client: Drop pointless buf variable X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" There's no need to read into a temporary buffer (oversized since commit 7d3123e1) followed by a byteswap into a uint64_t to check for a magic number via memcmp(), when the code immediately below demonstrates reading into the uint64_t then byteswapping in place and checking for a magic number via integer math. What's more, having a different error message when the server's first reply byte is 0 is unusual - it's no different from any other wrong magic number, and we already detected short reads. Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones Reviewed-by: Vladimir Sementsov-Ogievskiy --- nbd/nbd-internal.h | 1 + nbd/client.c | 14 +++----------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h index eeff78d3c98..306a533dcd1 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -46,6 +46,7 @@ /* Size of oldstyle negotiation */ #define NBD_OLDSTYLE_NEGOTIATE_SIZE (8 + 8 + 8 + 4 + 124) +#define NBD_INIT_MAGIC 0x4e42444d41474943LL #define NBD_REQUEST_MAGIC 0x25609513 #define NBD_OPTS_MAGIC 0x49484156454F5054LL #define NBD_CLIENT_MAGIC 0x0000420281861253LL diff --git a/nbd/client.c b/nbd/client.c index 0be89f9e641..17ee24492a4 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -731,7 +731,6 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *= name, QIOChannel **outioc, NBDExportInfo *info, Error **errp) { - char buf[256]; uint64_t magic; int rc; bool zeroes =3D true; @@ -752,21 +751,14 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char= *name, goto fail; } - if (nbd_read(ioc, buf, 8, errp) < 0) { + if (nbd_read(ioc, &magic, sizeof(magic), errp) < 0) { error_prepend(errp, "Failed to read data: "); goto fail; } - - buf[8] =3D '\0'; - if (strlen(buf) =3D=3D 0) { - error_setg(errp, "Server connection closed unexpectedly"); - goto fail; - } - - magic =3D ldq_be_p(buf); + magic =3D be64_to_cpu(magic); trace_nbd_receive_negotiate_magic(magic); - if (memcmp(buf, "NBDMAGIC", 8) !=3D 0) { + if (magic !=3D NBD_INIT_MAGIC) { error_setg(errp, "Invalid magic received"); goto fail; } --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543615993672279.9796284883723; Fri, 30 Nov 2018 14:13:13 -0800 (PST) Received: from localhost ([::1]:34863 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr28-0004K4-CZ for importer@patchew.org; Fri, 30 Nov 2018 17:13:12 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56018) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtJ-0004Pn-Gp for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtH-0004Fa-7K for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34668) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtC-0003fn-Ph; Fri, 30 Nov 2018 17:03:58 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 238243154865; Fri, 30 Nov 2018 22:03:58 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6BF211057072; Fri, 30 Nov 2018 22:03:57 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:35 -0600 Message-Id: <20181130220344.3350618-7-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 30 Nov 2018 22:03:58 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 06/14] nbd/client: Move export name into NBDExportInfo X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, qemu-block@nongnu.org, rjones@redhat.com, Max Reitz , nsoffer@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Refactor the 'name' parameter of nbd_receive_negotiate() from being a separate parameter into being part of the in-out 'info'. This also spills over to a simplification of nbd_opt_go(). The main driver for this refactoring is that an upcoming patch would like to add support to qemu-nbd to list information about all exports available on a server, where the name(s) will be provided by the server instead of the client. But another benefit is that we can now allow the client to explicitly specify the empty export name "" even when connecting to an oldstyle server (even if qemu is no longer such a server after commit 7f7dfe2a). Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/nbd.h | 8 ++++---- block/nbd-client.c | 5 +++-- nbd/client.c | 39 ++++++++++++++++++--------------------- qemu-nbd.c | 6 ++++-- nbd/trace-events | 2 +- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 6a5bfe5d559..65feff8ba96 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -262,6 +262,7 @@ struct NBDExportInfo { /* Set by client before nbd_receive_negotiate() */ bool request_sizes; char *x_dirty_bitmap; + char *name; /* must be non-NULL */ /* In-out fields, set by client before nbd_receive_negotiate() and * updated by server results during nbd_receive_negotiate() */ @@ -279,10 +280,9 @@ struct NBDExportInfo { }; typedef struct NBDExportInfo NBDExportInfo; -int nbd_receive_negotiate(QIOChannel *ioc, const char *name, - QCryptoTLSCreds *tlscreds, const char *hostname, - QIOChannel **outioc, NBDExportInfo *info, - Error **errp); +int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, + const char *hostname, QIOChannel **outioc, + NBDExportInfo *info, Error **errp); int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info, Error **errp); int nbd_send_request(QIOChannel *ioc, NBDRequest *request); diff --git a/block/nbd-client.c b/block/nbd-client.c index fc5b7eda8ee..417971d8b05 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -984,10 +984,11 @@ int nbd_client_init(BlockDriverState *bs, client->info.structured_reply =3D true; client->info.base_allocation =3D true; client->info.x_dirty_bitmap =3D g_strdup(x_dirty_bitmap); - ret =3D nbd_receive_negotiate(QIO_CHANNEL(sioc), export, - tlscreds, hostname, + client->info.name =3D g_strdup(export ?: ""); + ret =3D nbd_receive_negotiate(QIO_CHANNEL(sioc), tlscreds, hostname, &client->ioc, &client->info, errp); g_free(client->info.x_dirty_bitmap); + g_free(client->info.name); if (ret < 0) { logout("Failed to negotiate with the NBD server\n"); return ret; diff --git a/nbd/client.c b/nbd/client.c index 17ee24492a4..b5818a99d21 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -320,15 +320,14 @@ static int nbd_receive_list(QIOChannel *ioc, const ch= ar *want, bool *match, } -/* Returns -1 if NBD_OPT_GO proves the export @wantname cannot be +/* Returns -1 if NBD_OPT_GO proves the export @info->name cannot be * used, 0 if NBD_OPT_GO is unsupported (fall back to NBD_OPT_LIST and * NBD_OPT_EXPORT_NAME in that case), and > 0 if the export is good to - * go (with @info populated). */ -static int nbd_opt_go(QIOChannel *ioc, const char *wantname, - NBDExportInfo *info, Error **errp) + * go (with the rest of @info populated). */ +static int nbd_opt_go(QIOChannel *ioc, NBDExportInfo *info, Error **errp) { NBDOptionReply reply; - uint32_t len =3D strlen(wantname); + uint32_t len =3D strlen(info->name); uint16_t type; int error; char *buf; @@ -338,10 +337,10 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wa= ntname, * flags still 0 is a witness of a broken server. */ info->flags =3D 0; - trace_nbd_opt_go_start(wantname); + trace_nbd_opt_go_start(info->name); buf =3D g_malloc(4 + len + 2 + 2 * info->request_sizes + 1); stl_be_p(buf, len); - memcpy(buf + 4, wantname, len); + memcpy(buf + 4, info->name, len); /* At most one request, everything else up to server */ stw_be_p(buf + 4 + len, info->request_sizes); if (info->request_sizes) { @@ -726,10 +725,9 @@ static int nbd_negotiate_simple_meta_context(QIOChanne= l *ioc, return 0; } -int nbd_receive_negotiate(QIOChannel *ioc, const char *name, - QCryptoTLSCreds *tlscreds, const char *hostname, - QIOChannel **outioc, NBDExportInfo *info, - Error **errp) +int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, + const char *hostname, QIOChannel **outioc, + NBDExportInfo *info, Error **errp) { uint64_t magic; int rc; @@ -739,6 +737,8 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *= name, trace_nbd_receive_negotiate(tlscreds, hostname ? hostname : ""); + assert(info->name); + trace_nbd_receive_negotiate_name(info->name); info->structured_reply =3D false; info->base_allocation =3D false; rc =3D -EINVAL; @@ -807,10 +807,6 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char = *name, goto fail; } } - if (!name) { - trace_nbd_receive_negotiate_default_name(); - name =3D ""; - } if (fixedNewStyle) { int result; @@ -826,7 +822,8 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *= name, if (info->structured_reply && base_allocation) { result =3D nbd_negotiate_simple_meta_context( - ioc, name, info->x_dirty_bitmap ?: "base:allocatio= n", + ioc, info->name, + info->x_dirty_bitmap ?: "base:allocation", &info->meta_base_allocation_id, errp); if (result < 0) { goto fail; @@ -839,7 +836,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *= name, * TLS). If it is not available, fall back to * NBD_OPT_LIST for nicer error messages about a missing * export, then use NBD_OPT_EXPORT_NAME. */ - result =3D nbd_opt_go(ioc, name, info, errp); + result =3D nbd_opt_go(ioc, info, errp); if (result < 0) { goto fail; } @@ -852,12 +849,12 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char= *name, * query gives us better error reporting if the * export name is not available. */ - if (nbd_receive_query_exports(ioc, name, errp) < 0) { + if (nbd_receive_query_exports(ioc, info->name, errp) < 0) { goto fail; } } /* write the export name request */ - if (nbd_send_option_request(ioc, NBD_OPT_EXPORT_NAME, -1, name, + if (nbd_send_option_request(ioc, NBD_OPT_EXPORT_NAME, -1, info->na= me, errp) < 0) { goto fail; } @@ -877,8 +874,8 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *= name, } else if (magic =3D=3D NBD_CLIENT_MAGIC) { uint32_t oldflags; - if (name) { - error_setg(errp, "Server does not support export names"); + if (*info->name) { + error_setg(errp, "Server does not support non-empty export nam= es"); goto fail; } if (tlscreds) { diff --git a/qemu-nbd.c b/qemu-nbd.c index 866e64779f1..c57053a0795 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -263,7 +263,7 @@ static void *show_parts(void *arg) static void *nbd_client_thread(void *arg) { char *device =3D arg; - NBDExportInfo info =3D { .request_sizes =3D false, }; + NBDExportInfo info =3D { .request_sizes =3D false, .name =3D g_strdup(= "") }; QIOChannelSocket *sioc; int fd; int ret; @@ -278,7 +278,7 @@ static void *nbd_client_thread(void *arg) goto out; } - ret =3D nbd_receive_negotiate(QIO_CHANNEL(sioc), NULL, + ret =3D nbd_receive_negotiate(QIO_CHANNEL(sioc), NULL, NULL, NULL, &info, &local_error); if (ret < 0) { if (local_error) { @@ -317,6 +317,7 @@ static void *nbd_client_thread(void *arg) } close(fd); object_unref(OBJECT(sioc)); + free(info.name); kill(getpid(), SIGTERM); return (void *) EXIT_SUCCESS; @@ -325,6 +326,7 @@ out_fd: out_socket: object_unref(OBJECT(sioc)); out: + free(info.name); kill(getpid(), SIGTERM); return (void *) EXIT_FAILURE; } diff --git a/nbd/trace-events b/nbd/trace-events index 5e1d4afe8e6..289337d0dc3 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -15,7 +15,7 @@ nbd_opt_meta_reply(const char *context, uint32_t id) "Rec= eived mapping of contex nbd_receive_negotiate(void *tlscreds, const char *hostname) "Receiving neg= otiation tlscreds=3D%p hostname=3D%s" nbd_receive_negotiate_magic(uint64_t magic) "Magic is 0x%" PRIx64 nbd_receive_negotiate_server_flags(uint32_t globalflags) "Global flags are= 0x%" PRIx32 -nbd_receive_negotiate_default_name(void) "Using default NBD export name \"= \"" +nbd_receive_negotiate_name(const char *name) "Requesting NBD export name \= "%s\"" nbd_receive_negotiate_size_flags(uint64_t size, uint16_t flags) "Size is %= " PRIu64 ", export flags 0x%" PRIx16 nbd_init_set_socket(void) "Setting NBD socket" nbd_init_set_block_size(unsigned long block_size) "Setting block size to %= lu" --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543616214299704.4879015677304; Fri, 30 Nov 2018 14:16:54 -0800 (PST) Received: from localhost ([::1]:34891 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr5a-0008VC-0r for importer@patchew.org; Fri, 30 Nov 2018 17:16:46 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56006) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtJ-0004PG-4V for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtH-0004FP-5x for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55212) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtD-0003jJ-Hj; Fri, 30 Nov 2018 17:03:59 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D42349D781; Fri, 30 Nov 2018 22:03:58 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 45A221057072; Fri, 30 Nov 2018 22:03:58 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:36 -0600 Message-Id: <20181130220344.3350618-8-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Fri, 30 Nov 2018 22:03:58 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 07/14] nbd/client: Refactor nbd_negotiate_simple_meta_context() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Change the signature to make it easier for a future patch to reuse this function for calling NBD_OPT_LIST_META_CONTEXT with 0 or 1 queries. Also, always allocate space for the received name, even if it doesn't match expected lengths (no point trying to optimize the unlikely error case, and tracing the received rather than expected name can help debug a server implementation). While there are now slightly different traces, and the error message for a server replying with too many contexts is different, there are no runtime-observable changes in behavior for the more common case of the lone caller interacting with a compliant server. Signed-off-by: Eric Blake Tested-by: Richard W.M. Jones --- nbd/client.c | 105 +++++++++++++++++++++++++++-------------------- nbd/trace-events | 2 +- 2 files changed, 61 insertions(+), 46 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index b5818a99d21..1dc8f83e19a 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -603,49 +603,57 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *i= oc, } /* nbd_negotiate_simple_meta_context: - * Set one meta context. Simple means that reply must contain zero (not - * negotiated) or one (negotiated) contexts. More contexts would be consid= ered - * as a protocol error. It's also implied that meta-data query equals quer= ied - * context name, so, if server replies with something different than @cont= ext, - * it is considered an error too. - * return 1 for successful negotiation, context_id is set - * 0 if operation is unsupported, + * List or set meta context data for export @info->name, based on @opt. + * For list, leave @context NULL for 0 queries, or supplied for a single + * query; all replies are ignored, and the call merely traces server behav= ior. + * For set, @context must result in at most one matching server reply, in + * which case @info->meta_base_allocation_id is set to the resulting id. + * return 1 for successful negotiation, + * 0 if operation is unsupported or context unavailable, * -1 with errp set for any other error */ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc, - const char *export, + int32_t opt, const char *context, - uint32_t *context_id, + NBDExportInfo *info, Error **errp) { int ret; NBDOptionReply reply; uint32_t received_id =3D 0; bool received =3D false; - uint32_t export_len =3D strlen(export); - uint32_t context_len =3D strlen(context); - uint32_t data_len =3D sizeof(export_len) + export_len + - sizeof(uint32_t) + /* number of queries */ - sizeof(context_len) + context_len; - char *data =3D g_malloc(data_len); - char *p =3D data; + uint32_t export_len =3D strlen(info->name); + uint32_t context_len; + uint32_t data_len =3D sizeof(export_len) + export_len + sizeof(uint32_= t); + char *data; + char *p; - trace_nbd_opt_meta_request(context, export); + if (!context) { + assert(opt =3D=3D NBD_OPT_LIST_META_CONTEXT); + } else { + context_len =3D strlen(context); + data_len +=3D sizeof(context_len) + context_len; + } + data =3D g_malloc(data_len); + p =3D data; + + trace_nbd_opt_meta_request(nbd_opt_lookup(opt), context ?: "(all)", + info->name); stl_be_p(p, export_len); - memcpy(p +=3D sizeof(export_len), export, export_len); - stl_be_p(p +=3D export_len, 1); - stl_be_p(p +=3D sizeof(uint32_t), context_len); - memcpy(p +=3D sizeof(context_len), context, context_len); + memcpy(p +=3D sizeof(export_len), info->name, export_len); + stl_be_p(p +=3D export_len, !!context); + if (context) { + stl_be_p(p +=3D sizeof(uint32_t), context_len); + memcpy(p +=3D sizeof(context_len), context, context_len); + } - ret =3D nbd_send_option_request(ioc, NBD_OPT_SET_META_CONTEXT, data_le= n, data, - errp); + ret =3D nbd_send_option_request(ioc, opt, data_len, data, errp); g_free(data); if (ret < 0) { return ret; } - if (nbd_receive_option_reply(ioc, NBD_OPT_SET_META_CONTEXT, &reply, - errp) < 0) + if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) { return -1; } @@ -655,10 +663,10 @@ static int nbd_negotiate_simple_meta_context(QIOChann= el *ioc, return ret; } - if (reply.type =3D=3D NBD_REP_META_CONTEXT) { + while (reply.type =3D=3D NBD_REP_META_CONTEXT) { char *name; - if (reply.length !=3D sizeof(received_id) + context_len) { + if (reply.length <=3D sizeof(received_id)) { error_setg(errp, "Failed to negotiate meta context '%s', serve= r " "answered with unexpected length %" PRIu32, context, reply.length); @@ -678,23 +686,31 @@ static int nbd_negotiate_simple_meta_context(QIOChann= el *ioc, return -1; } name[reply.length] =3D '\0'; - if (strcmp(context, name)) { - error_setg(errp, "Failed to negotiate meta context '%s', serve= r " - "answered with different context '%s'", context, - name); - g_free(name); - nbd_send_opt_abort(ioc); - return -1; + + trace_nbd_opt_meta_reply(name, received_id); + if (opt =3D=3D NBD_OPT_SET_META_CONTEXT) { + if (received) { + error_setg(errp, "Server replied with more than one contex= t"); + free(name); + nbd_send_opt_abort(ioc); + return -1; + } + + if (strcmp(context, name)) { + error_setg(errp, + "Failed to negotiate meta context '%s', server " + "answered with different context '%s'", context, + name); + g_free(name); + nbd_send_opt_abort(ioc); + return -1; + } } g_free(name); - - trace_nbd_opt_meta_reply(context, received_id); received =3D true; /* receive NBD_REP_ACK */ - if (nbd_receive_option_reply(ioc, NBD_OPT_SET_META_CONTEXT, &reply, - errp) < 0) - { + if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) { return -1; } @@ -717,12 +733,11 @@ static int nbd_negotiate_simple_meta_context(QIOChann= el *ioc, return -1; } - if (received) { - *context_id =3D received_id; - return 1; + if (received && opt =3D=3D NBD_OPT_SET_META_CONTEXT) { + info->meta_base_allocation_id =3D received_id; } - return 0; + return received || opt =3D=3D NBD_OPT_LIST_META_CONTEXT; } int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, @@ -822,9 +837,9 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, if (info->structured_reply && base_allocation) { result =3D nbd_negotiate_simple_meta_context( - ioc, info->name, + ioc, NBD_OPT_SET_META_CONTEXT, info->x_dirty_bitmap ?: "base:allocation", - &info->meta_base_allocation_id, errp); + info, errp); if (result < 0) { goto fail; } diff --git a/nbd/trace-events b/nbd/trace-events index 289337d0dc3..5d0d202fad2 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -10,7 +10,7 @@ nbd_receive_query_exports_start(const char *wantname) "Qu= erying export list for nbd_receive_query_exports_success(const char *wantname) "Found desired exp= ort name '%s'" nbd_receive_starttls_new_client(void) "Setting up TLS" nbd_receive_starttls_tls_handshake(void) "Starting TLS handshake" -nbd_opt_meta_request(const char *context, const char *export) "Requesting = to set meta context %s for export %s" +nbd_opt_meta_request(const char *opt, const char *context, const char *exp= ort) "Requesting to %s %s for export %s" nbd_opt_meta_reply(const char *context, uint32_t id) "Received mapping of = context %s to id %" PRIu32 nbd_receive_negotiate(void *tlscreds, const char *hostname) "Receiving neg= otiation tlscreds=3D%p hostname=3D%s" nbd_receive_negotiate_magic(uint64_t magic) "Magic is 0x%" PRIx64 --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543615823047354.9779950285225; Fri, 30 Nov 2018 14:10:23 -0800 (PST) Received: from localhost ([::1]:34848 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqzM-0001yb-V1 for importer@patchew.org; Fri, 30 Nov 2018 17:10:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55995) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtI-0004P0-To for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtH-0004Ff-7a for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:04 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52186) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtE-0003px-7x; Fri, 30 Nov 2018 17:04:00 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8FE2B3DE0D; Fri, 30 Nov 2018 22:03:59 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id F2DF81057072; Fri, 30 Nov 2018 22:03:58 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:37 -0600 Message-Id: <20181130220344.3350618-9-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 30 Nov 2018 22:03:59 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 08/14] nbd/client: Refactor nbd_receive_list() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add some parameters to make this function reusable in upcoming export listing, where we will want to capture the name and description rather than compare against a user-supplied name. No change in semantics to the existing caller. Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones --- nbd/client.c | 66 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index 1dc8f83e19a..27785c55d0a 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -232,18 +232,21 @@ static int nbd_handle_reply_err(QIOChannel *ioc, NBDO= ptionReply *reply, return result; } -/* Process another portion of the NBD_OPT_LIST reply. Set *@match if - * the current reply matches @want or if the server does not support - * NBD_OPT_LIST, otherwise leave @match alone. Return 0 if iteration - * is complete, positive if more replies are expected, or negative - * with @errp set if an unrecoverable error occurred. */ +/* Process another portion of the NBD_OPT_LIST reply. If @want, then + * set *@match if the current reply matches @want or if the server + * does not support NBD_OPT_LIST, otherwise leave @match alone. + * Otherwise, @nameout and @description are malloc'd to contain + * NUL-terminated copies of the reply. Return 0 if iteration is + * complete, positive if more replies are expected, or negative with + * @errp set if an unrecoverable error occurred. */ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, - Error **errp) + char **nameout, char **description, Error **er= rp) { NBDOptionReply reply; uint32_t len; uint32_t namelen; - char name[NBD_MAX_NAME_SIZE + 1]; + char array[NBD_MAX_NAME_SIZE + 1]; + char *name =3D array; int error; if (nbd_receive_option_reply(ioc, NBD_OPT_LIST, &reply, errp) < 0) { @@ -253,7 +256,12 @@ static int nbd_receive_list(QIOChannel *ioc, const cha= r *want, bool *match, if (error <=3D 0) { /* The server did not support NBD_OPT_LIST, so set *match on * the assumption that any name will be accepted. */ - *match =3D true; + if (want) { + *match =3D true; + } else if (!error) { + error_setg(errp, "Server does not support export lists"); + error =3D -1; + } return error; } len =3D reply.length; @@ -290,30 +298,49 @@ static int nbd_receive_list(QIOChannel *ioc, const ch= ar *want, bool *match, nbd_send_opt_abort(ioc); return -1; } - if (namelen !=3D strlen(want)) { - if (nbd_drop(ioc, len, errp) < 0) { - error_prepend(errp, - "failed to skip export name with wrong length: "= ); - nbd_send_opt_abort(ioc); - return -1; + if (want) { + if (namelen !=3D strlen(want)) { + if (nbd_drop(ioc, len, errp) < 0) { + error_prepend(errp, + "failed to skip export name with wrong lengt= h: "); + nbd_send_opt_abort(ioc); + return -1; + } + return 1; } - return 1; + assert(namelen < sizeof(array)); + } else { + assert(nameout); + *nameout =3D name =3D g_new(char, namelen + 1); } - assert(namelen < sizeof(name)); if (nbd_read(ioc, name, namelen, errp) < 0) { error_prepend(errp, "failed to read export name: "); nbd_send_opt_abort(ioc); + if (!want) { + free(name); + } return -1; } name[namelen] =3D '\0'; len -=3D namelen; - if (nbd_drop(ioc, len, errp) < 0) { + if (!want) { + assert(description); + *description =3D g_new(char, len + 1); + if (nbd_read(ioc, *description, len, errp) < 0) { + error_prepend(errp, "failed to read export description: "); + nbd_send_opt_abort(ioc); + free(name); + free(*description); + return -1; + } + (*description)[len] =3D '\0'; + } else if (nbd_drop(ioc, len, errp) < 0) { error_prepend(errp, "failed to read export description: "); nbd_send_opt_abort(ioc); return -1; } - if (!strcmp(name, want)) { + if (want && !strcmp(name, want)) { *match =3D true; } return 1; @@ -498,7 +525,8 @@ static int nbd_receive_query_exports(QIOChannel *ioc, } while (1) { - int ret =3D nbd_receive_list(ioc, wantname, &foundExport, errp); + int ret =3D nbd_receive_list(ioc, wantname, &foundExport, + NULL, NULL, errp); if (ret < 0) { /* Server gave unexpected reply */ --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543616130612848.5841290146149; Fri, 30 Nov 2018 14:15:30 -0800 (PST) Received: from localhost ([::1]:34881 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr4L-0007XT-Aj for importer@patchew.org; Fri, 30 Nov 2018 17:15:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56074) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtO-0004Ru-2G for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtJ-0004TZ-FL for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:09 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34674) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtE-0003xC-UH; Fri, 30 Nov 2018 17:04:01 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 45DAE3154849; Fri, 30 Nov 2018 22:04:00 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id AED811057073; Fri, 30 Nov 2018 22:03:59 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:38 -0600 Message-Id: <20181130220344.3350618-10-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 30 Nov 2018 22:04:00 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 09/14] nbd/client: Refactor return of nbd_receive_negotiate() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The function could only ever return 0 or -EINVAL; make this clearer by dropping a useless 'fail:' label. Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones Reviewed-by: Vladimir Sementsov-Ogievskiy --- nbd/client.c | 51 +++++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index 27785c55d0a..1ed5009642e 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -773,7 +773,6 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, NBDExportInfo *info, Error **errp) { uint64_t magic; - int rc; bool zeroes =3D true; bool structured_reply =3D info->structured_reply; bool base_allocation =3D info->base_allocation; @@ -784,31 +783,30 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLS= Creds *tlscreds, trace_nbd_receive_negotiate_name(info->name); info->structured_reply =3D false; info->base_allocation =3D false; - rc =3D -EINVAL; if (outioc) { *outioc =3D NULL; } if (tlscreds && !outioc) { error_setg(errp, "Output I/O channel required for TLS"); - goto fail; + return -EINVAL; } if (nbd_read(ioc, &magic, sizeof(magic), errp) < 0) { error_prepend(errp, "Failed to read data: "); - goto fail; + return -EINVAL; } magic =3D be64_to_cpu(magic); trace_nbd_receive_negotiate_magic(magic); if (magic !=3D NBD_INIT_MAGIC) { error_setg(errp, "Invalid magic received"); - goto fail; + return -EINVAL; } if (nbd_read(ioc, &magic, sizeof(magic), errp) < 0) { error_prepend(errp, "Failed to read magic: "); - goto fail; + return -EINVAL; } magic =3D be64_to_cpu(magic); trace_nbd_receive_negotiate_magic(magic); @@ -820,7 +818,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, if (nbd_read(ioc, &globalflags, sizeof(globalflags), errp) < 0) { error_prepend(errp, "Failed to read server flags: "); - goto fail; + return -EINVAL; } globalflags =3D be16_to_cpu(globalflags); trace_nbd_receive_negotiate_server_flags(globalflags); @@ -836,18 +834,18 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLS= Creds *tlscreds, clientflags =3D cpu_to_be32(clientflags); if (nbd_write(ioc, &clientflags, sizeof(clientflags), errp) < 0) { error_prepend(errp, "Failed to send clientflags field: "); - goto fail; + return -EINVAL; } if (tlscreds) { if (fixedNewStyle) { *outioc =3D nbd_receive_starttls(ioc, tlscreds, hostname, = errp); if (!*outioc) { - goto fail; + return -EINVAL; } ioc =3D *outioc; } else { error_setg(errp, "Server does not support STARTTLS"); - goto fail; + return -EINVAL; } } if (fixedNewStyle) { @@ -858,7 +856,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, NBD_OPT_STRUCTURED_REPL= Y, errp); if (result < 0) { - goto fail; + return -EINVAL; } info->structured_reply =3D result =3D=3D 1; } @@ -869,7 +867,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, info->x_dirty_bitmap ?: "base:allocation", info, errp); if (result < 0) { - goto fail; + return -EINVAL; } info->base_allocation =3D result =3D=3D 1; } @@ -881,7 +879,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, * export, then use NBD_OPT_EXPORT_NAME. */ result =3D nbd_opt_go(ioc, info, errp); if (result < 0) { - goto fail; + return -EINVAL; } if (result > 0) { return 0; @@ -893,25 +891,25 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLS= Creds *tlscreds, * export name is not available. */ if (nbd_receive_query_exports(ioc, info->name, errp) < 0) { - goto fail; + return -EINVAL; } } /* write the export name request */ if (nbd_send_option_request(ioc, NBD_OPT_EXPORT_NAME, -1, info->na= me, errp) < 0) { - goto fail; + return -EINVAL; } /* Read the response */ if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) { error_prepend(errp, "Failed to read export length: "); - goto fail; + return -EINVAL; } info->size =3D be64_to_cpu(info->size); if (nbd_read(ioc, &info->flags, sizeof(info->flags), errp) < 0) { error_prepend(errp, "Failed to read export flags: "); - goto fail; + return -EINVAL; } info->flags =3D be16_to_cpu(info->flags); } else if (magic =3D=3D NBD_CLIENT_MAGIC) { @@ -919,43 +917,40 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLS= Creds *tlscreds, if (*info->name) { error_setg(errp, "Server does not support non-empty export nam= es"); - goto fail; + return -EINVAL; } if (tlscreds) { error_setg(errp, "Server does not support STARTTLS"); - goto fail; + return -EINVAL; } if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) { error_prepend(errp, "Failed to read export length: "); - goto fail; + return -EINVAL; } info->size =3D be64_to_cpu(info->size); if (nbd_read(ioc, &oldflags, sizeof(oldflags), errp) < 0) { error_prepend(errp, "Failed to read export flags: "); - goto fail; + return -EINVAL; } oldflags =3D be32_to_cpu(oldflags); if (oldflags & ~0xffff) { error_setg(errp, "Unexpected export flags %0x" PRIx32, oldflag= s); - goto fail; + return -EINVAL; } info->flags =3D oldflags; } else { error_setg(errp, "Bad magic received"); - goto fail; + return -EINVAL; } trace_nbd_receive_negotiate_size_flags(info->size, info->flags); if (zeroes && nbd_drop(ioc, 124, errp) < 0) { error_prepend(errp, "Failed to read reserved block: "); - goto fail; + return -EINVAL; } - rc =3D 0; - -fail: - return rc; + return 0; } #ifdef __linux__ --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543615947336549.4619439980382; Fri, 30 Nov 2018 14:12:27 -0800 (PST) Received: from localhost ([::1]:34862 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr1O-0003f0-3W for importer@patchew.org; Fri, 30 Nov 2018 17:12:26 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56072) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtO-0004Rs-1x for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtK-0004cM-PL for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:09 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55228) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtF-00045I-QP; Fri, 30 Nov 2018 17:04:02 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0D0D91F8C5; Fri, 30 Nov 2018 22:04:01 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 699B51057073; Fri, 30 Nov 2018 22:04:00 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:39 -0600 Message-Id: <20181130220344.3350618-11-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Fri, 30 Nov 2018 22:04:01 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 10/14] nbd/client: Split handshake into two functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" An upcoming patch will add the ability for qemu-nbd to list the services provided by an NBD server. Share the common code of the TLS handshake by splitting the initial exchange into a separate function, leaving only the export handling in the original function. Functionally, there should be no change in behavior in this patch, although some of the code motion may be difficult to follow due to indentation changes (view with 'git diff -w' for a smaller changeset). Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones Reviewed-by: Vladimir Sementsov-Ogievskiy --- nbd/client.c | 142 ++++++++++++++++++++++++++++++----------------- nbd/trace-events | 2 +- 2 files changed, 92 insertions(+), 52 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index 1ed5009642e..a282712724d 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -768,21 +768,22 @@ static int nbd_negotiate_simple_meta_context(QIOChann= el *ioc, return received || opt =3D=3D NBD_OPT_LIST_META_CONTEXT; } -int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, - const char *hostname, QIOChannel **outioc, - NBDExportInfo *info, Error **errp) +/* Start the handshake to the server. After a positive return, the server + * is ready to accept additional NBD_OPT requests. + * Returns: negative errno: failure talking to server + * 0: server is oldstyle, client must still parse export size + * 1: server is newstyle, but can only accept EXPORT_NAME + * 2: server is newstyle, but lacks structured replies + * 3: server is newstyle and set up for structured replies + */ +static int nbd_start_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, + const char *hostname, QIOChannel **outioc, + bool structured_reply, bool *zeroes, + Error **errp) { uint64_t magic; - bool zeroes =3D true; - bool structured_reply =3D info->structured_reply; - bool base_allocation =3D info->base_allocation; - trace_nbd_receive_negotiate(tlscreds, hostname ? hostname : ""); - - assert(info->name); - trace_nbd_receive_negotiate_name(info->name); - info->structured_reply =3D false; - info->base_allocation =3D false; + trace_nbd_start_negotiate(tlscreds, hostname ? hostname : ""); if (outioc) { *outioc =3D NULL; @@ -827,7 +828,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, clientflags |=3D NBD_FLAG_C_FIXED_NEWSTYLE; } if (globalflags & NBD_FLAG_NO_ZEROES) { - zeroes =3D false; + *zeroes =3D false; clientflags |=3D NBD_FLAG_C_NO_ZEROES; } /* client requested flags */ @@ -849,7 +850,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, } } if (fixedNewStyle) { - int result; + int result =3D 0; if (structured_reply) { result =3D nbd_request_simple_option(ioc, @@ -858,42 +859,86 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLS= Creds *tlscreds, if (result < 0) { return -EINVAL; } - info->structured_reply =3D result =3D=3D 1; } + return 2 + result; + } else { + return 1; + } + } else if (magic =3D=3D NBD_CLIENT_MAGIC) { + if (tlscreds) { + error_setg(errp, "Server does not support STARTTLS"); + return -EINVAL; + } + return 0; + } else { + error_setg(errp, "Bad magic received"); + return -EINVAL; + } +} - if (info->structured_reply && base_allocation) { - result =3D nbd_negotiate_simple_meta_context( +/* Connect to server, complete negotiation, and move into transmission pha= se. + * Returns: negative errno: failure talking to server + * 0: server is connected + */ +int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, + const char *hostname, QIOChannel **outioc, + NBDExportInfo *info, Error **errp) +{ + int result; + bool zeroes =3D true; + bool base_allocation =3D info->base_allocation; + uint32_t oldflags; + + assert(info->name); + trace_nbd_receive_negotiate_name(info->name); + + result =3D nbd_start_negotiate(ioc, tlscreds, hostname, outioc, + info->structured_reply, &zeroes, errp); + + info->structured_reply =3D false; + info->base_allocation =3D false; + if (tlscreds && *outioc) { + ioc =3D *outioc; + } + + switch (result) { + case 3: /* newstyle, with structured replies */ + info->structured_reply =3D true; + if (base_allocation) { + result =3D nbd_negotiate_simple_meta_context( ioc, NBD_OPT_SET_META_CONTEXT, info->x_dirty_bitmap ?: "base:allocation", info, errp); - if (result < 0) { - return -EINVAL; - } - info->base_allocation =3D result =3D=3D 1; - } - - /* Try NBD_OPT_GO first - if it works, we are done (it - * also gives us a good message if the server requires - * TLS). If it is not available, fall back to - * NBD_OPT_LIST for nicer error messages about a missing - * export, then use NBD_OPT_EXPORT_NAME. */ - result =3D nbd_opt_go(ioc, info, errp); if (result < 0) { return -EINVAL; } - if (result > 0) { - return 0; - } - /* Check our desired export is present in the - * server export list. Since NBD_OPT_EXPORT_NAME - * cannot return an error message, running this - * query gives us better error reporting if the - * export name is not available. - */ - if (nbd_receive_query_exports(ioc, info->name, errp) < 0) { - return -EINVAL; - } + info->base_allocation =3D result =3D=3D 1; } + /* fall through */ + case 2: /* newstyle, try OPT_GO */ + /* Try NBD_OPT_GO first - if it works, we are done (it + * also gives us a good message if the server requires + * TLS). If it is not available, fall back to + * NBD_OPT_LIST for nicer error messages about a missing + * export, then use NBD_OPT_EXPORT_NAME. */ + result =3D nbd_opt_go(ioc, info, errp); + if (result < 0) { + return -EINVAL; + } + if (result > 0) { + return 0; + } + /* Check our desired export is present in the + * server export list. Since NBD_OPT_EXPORT_NAME + * cannot return an error message, running this + * query gives us better error reporting if the + * export name is not available. + */ + if (nbd_receive_query_exports(ioc, info->name, errp) < 0) { + return -EINVAL; + } + /* fall through */ + case 1: /* newstyle, but limited to EXPORT_NAME */ /* write the export name request */ if (nbd_send_option_request(ioc, NBD_OPT_EXPORT_NAME, -1, info->na= me, errp) < 0) { @@ -912,17 +957,12 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLS= Creds *tlscreds, return -EINVAL; } info->flags =3D be16_to_cpu(info->flags); - } else if (magic =3D=3D NBD_CLIENT_MAGIC) { - uint32_t oldflags; - + break; + case 0: /* oldstyle, parse length and flags */ if (*info->name) { error_setg(errp, "Server does not support non-empty export nam= es"); return -EINVAL; } - if (tlscreds) { - error_setg(errp, "Server does not support STARTTLS"); - return -EINVAL; - } if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) { error_prepend(errp, "Failed to read export length: "); @@ -940,9 +980,9 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, return -EINVAL; } info->flags =3D oldflags; - } else { - error_setg(errp, "Bad magic received"); - return -EINVAL; + break; + default: + return result; } trace_nbd_receive_negotiate_size_flags(info->size, info->flags); diff --git a/nbd/trace-events b/nbd/trace-events index 5d0d202fad2..570b04997ff 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -12,7 +12,7 @@ nbd_receive_starttls_new_client(void) "Setting up TLS" nbd_receive_starttls_tls_handshake(void) "Starting TLS handshake" nbd_opt_meta_request(const char *opt, const char *context, const char *exp= ort) "Requesting to %s %s for export %s" nbd_opt_meta_reply(const char *context, uint32_t id) "Received mapping of = context %s to id %" PRIu32 -nbd_receive_negotiate(void *tlscreds, const char *hostname) "Receiving neg= otiation tlscreds=3D%p hostname=3D%s" +nbd_start_negotiate(void *tlscreds, const char *hostname) "Receiving negot= iation tlscreds=3D%p hostname=3D%s" nbd_receive_negotiate_magic(uint64_t magic) "Magic is 0x%" PRIx64 nbd_receive_negotiate_server_flags(uint32_t globalflags) "Global flags are= 0x%" PRIx32 nbd_receive_negotiate_name(const char *name) "Requesting NBD export name \= "%s\"" --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543616322423770.0679686836328; Fri, 30 Nov 2018 14:18:42 -0800 (PST) Received: from localhost ([::1]:34897 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr7Q-0001gT-Vo for importer@patchew.org; Fri, 30 Nov 2018 17:18:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56147) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtR-0004W6-Ec for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtP-00058u-QW for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42662) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtJ-0004PH-6S; Fri, 30 Nov 2018 17:04:05 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5F73B3001FD2; Fri, 30 Nov 2018 22:04:04 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 290AE1057073; Fri, 30 Nov 2018 22:04:01 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:40 -0600 Message-Id: <20181130220344.3350618-12-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 30 Nov 2018 22:04:04 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 11/14] nbd/client: Add nbd_receive_export_list() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, qemu-block@nongnu.org, rjones@redhat.com, Max Reitz , nsoffer@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We want to be able to detect whether a given qemu NBD server is exposing the right export(s) and dirty bitmaps, at least for regression testing. We could use 'nbd-client -l' from the upstream NBD project to list exports, but it's annoying to rely on out-of-tree binaries; furthermore, nbd-client doesn't necessarily know about all of the qemu NBD extensions. Thus, we plan on adding a new mode to qemu-nbd that merely sniffs all possible information from the server during handshake phase, then disconnects and dumps the information. This patch adds the low-level client code for grabbing the list of exports. It benefits from the recent refactoring patches, as well as a minor tweak of changing nbd_opt_go() to nbd_opt_info_go(), in order to share as much code as possible when it comes to doing validation of server replies. The resulting information is stored in an array of NBDExportInfo which has been expanded to hold more members, along with a convenience function for freeing the list. Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones --- include/block/nbd.h | 15 +++- nbd/client.c | 166 ++++++++++++++++++++++++++++++++++++++++++-- nbd/trace-events | 2 +- 3 files changed, 174 insertions(+), 9 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 65feff8ba96..74d006b8d62 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -262,6 +262,9 @@ struct NBDExportInfo { /* Set by client before nbd_receive_negotiate() */ bool request_sizes; char *x_dirty_bitmap; + + /* Set by client before nbd_receive_negotiate(), or by server results + * during nbd_receive_export_list() */ char *name; /* must be non-NULL */ /* In-out fields, set by client before nbd_receive_negotiate() and @@ -269,7 +272,8 @@ struct NBDExportInfo { bool structured_reply; bool base_allocation; /* base:allocation context for NBD_CMD_BLOCK_STA= TUS */ - /* Set by server results during nbd_receive_negotiate() */ + /* Set by server results during nbd_receive_negotiate() and + * nbd_receive_export_list() */ uint64_t size; uint16_t flags; uint32_t min_block; @@ -277,12 +281,21 @@ struct NBDExportInfo { uint32_t max_block; uint32_t meta_base_allocation_id; + + /* Set by server results during nbd_receive_export_list() */ + char *description; + int n_contexts; + char **contexts; }; typedef struct NBDExportInfo NBDExportInfo; int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, const char *hostname, QIOChannel **outioc, NBDExportInfo *info, Error **errp); +void nbd_free_export_list(NBDExportInfo *info, int count); +int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, + const char *hostname, NBDExportInfo **info, + Error **errp); int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info, Error **errp); int nbd_send_request(QIOChannel *ioc, NBDRequest *request); diff --git a/nbd/client.c b/nbd/client.c index a282712724d..6292de560ee 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -351,7 +351,8 @@ static int nbd_receive_list(QIOChannel *ioc, const char= *want, bool *match, * used, 0 if NBD_OPT_GO is unsupported (fall back to NBD_OPT_LIST and * NBD_OPT_EXPORT_NAME in that case), and > 0 if the export is good to * go (with the rest of @info populated). */ -static int nbd_opt_go(QIOChannel *ioc, NBDExportInfo *info, Error **errp) +static int nbd_opt_info_go(QIOChannel *ioc, uint32_t opt, + NBDExportInfo *info, Error **errp) { NBDOptionReply reply; uint32_t len =3D strlen(info->name); @@ -364,7 +365,8 @@ static int nbd_opt_go(QIOChannel *ioc, NBDExportInfo *i= nfo, Error **errp) * flags still 0 is a witness of a broken server. */ info->flags =3D 0; - trace_nbd_opt_go_start(info->name); + assert(opt =3D=3D NBD_OPT_GO || opt =3D=3D NBD_OPT_INFO); + trace_nbd_opt_go_start(nbd_opt_lookup(opt), info->name); buf =3D g_malloc(4 + len + 2 + 2 * info->request_sizes + 1); stl_be_p(buf, len); memcpy(buf + 4, info->name, len); @@ -373,7 +375,7 @@ static int nbd_opt_go(QIOChannel *ioc, NBDExportInfo *i= nfo, Error **errp) if (info->request_sizes) { stw_be_p(buf + 4 + len + 2, NBD_INFO_BLOCK_SIZE); } - error =3D nbd_send_option_request(ioc, NBD_OPT_GO, + error =3D nbd_send_option_request(ioc, opt, 4 + len + 2 + 2 * info->request_sizes, buf, errp); g_free(buf); @@ -382,7 +384,7 @@ static int nbd_opt_go(QIOChannel *ioc, NBDExportInfo *i= nfo, Error **errp) } while (1) { - if (nbd_receive_option_reply(ioc, NBD_OPT_GO, &reply, errp) < 0) { + if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) { return -1; } error =3D nbd_handle_reply_err(ioc, &reply, errp); @@ -733,8 +735,12 @@ static int nbd_negotiate_simple_meta_context(QIOChanne= l *ioc, nbd_send_opt_abort(ioc); return -1; } + g_free(name); + } else { + info->contexts =3D g_renew(char *, info->contexts, + ++info->n_contexts); + info->contexts[info->n_contexts - 1] =3D name; } - g_free(name); received =3D true; /* receive NBD_REP_ACK */ @@ -828,7 +834,9 @@ static int nbd_start_negotiate(QIOChannel *ioc, QCrypto= TLSCreds *tlscreds, clientflags |=3D NBD_FLAG_C_FIXED_NEWSTYLE; } if (globalflags & NBD_FLAG_NO_ZEROES) { - *zeroes =3D false; + if (zeroes) { + *zeroes =3D false; + } clientflags |=3D NBD_FLAG_C_NO_ZEROES; } /* client requested flags */ @@ -921,7 +929,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCr= eds *tlscreds, * TLS). If it is not available, fall back to * NBD_OPT_LIST for nicer error messages about a missing * export, then use NBD_OPT_EXPORT_NAME. */ - result =3D nbd_opt_go(ioc, info, errp); + result =3D nbd_opt_info_go(ioc, NBD_OPT_GO, info, errp); if (result < 0) { return -EINVAL; } @@ -993,6 +1001,150 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTL= SCreds *tlscreds, return 0; } +/* Clean up result of nbd_receive_export_list */ +void nbd_free_export_list(NBDExportInfo *info, int count) +{ + int i, j; + + for (i =3D 0; info && i < count; i++) { + free(info[i].name); + free(info[i].description); + for (j =3D 0; j < info[i].n_contexts; j++) { + free(info[i].contexts[j]); + } + free(info[i].contexts); + } + free(info); +} + +/* Query details about a server's exports, then disconnect without + * going into transmission phase. Return a count of the exports listed + * in @info by the server, or -1 on error. Caller must free @info. */ +int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, + const char *hostname, NBDExportInfo **info, + Error **errp) +{ + int result; + int count =3D 0; + int i; + int rc; + int ret =3D -1; + NBDExportInfo *array =3D NULL; + uint32_t oldflags; + QIOChannel *sioc =3D NULL; + bool try_context =3D true; + + *info =3D NULL; + result =3D nbd_start_negotiate(ioc, tlscreds, hostname, &sioc, true, N= ULL, + errp); + if (tlscreds && sioc) { + ioc =3D sioc; + } + + switch (result) { + case 2: + /* meta contexts are only useful with structured reply */ + try_context =3D false; + /* fall through */ + case 3: + /* 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. */ + if (nbd_send_option_request(ioc, NBD_OPT_LIST, 0, NULL, errp) < 0)= { + goto out; + } + while (1) { + char *name; + char *desc; + + rc =3D nbd_receive_list(ioc, NULL, NULL, &name, &desc, errp); + if (rc < 0) { + goto out; + } else if (rc =3D=3D 0) { + break; + } + array =3D g_renew(NBDExportInfo, array, ++count); + memset(&array[count - 1], 0, sizeof(*array)); + array[count - 1].name =3D name; + array[count - 1].description =3D desc; + array[count - 1].structured_reply =3D result =3D=3D 3; + } + + for (i =3D 0; i < count; i++) { + array[i].request_sizes =3D true; + rc =3D nbd_opt_info_go(ioc, NBD_OPT_INFO, &array[i], errp); + if (rc < 0) { + goto out; + } else if (rc =3D=3D 0) { + /* Pointless to try rest of loop. If OPT_INFO doesn't work, + * it's unlikely that meta contexts work either */ + break; + } + + if (try_context) { + rc =3D nbd_negotiate_simple_meta_context( + ioc, NBD_OPT_LIST_META_CONTEXT, NULL, &array[i], errp); + if (rc < 0) { + goto out; + } else if (rc =3D=3D 0) { + try_context =3D false; + } + } + } + + /* Send NBD_OPT_ABORT as a courtesy before hanging up */ + nbd_send_opt_abort(ioc); + break; + case 1: /* newstyle, but limited to EXPORT_NAME */ + error_setg(errp, "Server does not support export lists"); + /* We can't even send NBD_OPT_ABORT, so merely hang up */ + goto out; + case 0: /* oldstyle, parse length and flags */ + array =3D g_new0(NBDExportInfo, 1); + array->name =3D g_strdup(""); + count =3D 1; + + if (nbd_read(ioc, &array->size, sizeof(array->size), errp) < 0) { + error_prepend(errp, "Failed to read export length: "); + goto out; + } + array->size =3D be64_to_cpu(array->size); + + if (nbd_read(ioc, &oldflags, sizeof(oldflags), errp) < 0) { + error_prepend(errp, "Failed to read export flags: "); + goto out; + } + oldflags =3D be32_to_cpu(oldflags); + if (oldflags & ~0xffff) { + error_setg(errp, "Unexpected export flags %0x" PRIx32, oldflag= s); + goto out; + } + array->flags =3D oldflags; + + /* Send NBD_CMD_DISC as a courtesy to the server, but ignore all + * errors now that we have the information we wanted. */ + if (nbd_drop(ioc, 124, NULL) =3D=3D 0) { + NBDRequest request =3D { .type =3D NBD_CMD_DISC }; + + nbd_send_request(ioc, &request); + } + break; + default: + goto out; + } + + *info =3D array; + array =3D NULL; + ret =3D count; + + out: + qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL); + qio_channel_close(ioc, NULL); + object_unref(OBJECT(sioc)); + nbd_free_export_list(array, count); + return ret; +} + #ifdef __linux__ int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info, Error **errp) diff --git a/nbd/trace-events b/nbd/trace-events index 570b04997ff..2cf83ebed15 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -2,7 +2,7 @@ nbd_send_option_request(uint32_t opt, const char *name, uint32_t len) "Sen= ding option request %" PRIu32" (%s), len %" PRIu32 nbd_receive_option_reply(uint32_t option, const char *optname, uint32_t ty= pe, const char *typename, uint32_t length) "Received option reply %" PRIu32= " (%s), type %" PRIu32" (%s), len %" PRIu32 nbd_reply_err_unsup(uint32_t option, const char *name) "server doesn't und= erstand request %" PRIu32 " (%s), attempting fallback" -nbd_opt_go_start(const char *name) "Attempting NBD_OPT_GO for export '%s'" +nbd_opt_go_start(const char *opt, const char *name) "Attempting %s for exp= ort '%s'" nbd_opt_go_success(void) "Export is good to go" nbd_opt_go_info_unknown(int info, const char *name) "Ignoring unknown info= %d (%s)" nbd_opt_go_info_block_size(uint32_t minimum, uint32_t preferred, uint32_t = maximum) "Block sizes are 0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32 --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543615918306100.88512175447545; Fri, 30 Nov 2018 14:11:58 -0800 (PST) Received: from localhost ([::1]:34860 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr0r-0003Dn-62 for importer@patchew.org; Fri, 30 Nov 2018 17:11:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56121) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtQ-0004Um-5a for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtP-00053y-9N for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:58950) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtJ-0004SK-Sk; Fri, 30 Nov 2018 17:04:06 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 16C5699D2D; Fri, 30 Nov 2018 22:04:05 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7D34C105B1FA; Fri, 30 Nov 2018 22:04:04 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:41 -0600 Message-Id: <20181130220344.3350618-13-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 30 Nov 2018 22:04:05 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 12/14] nbd/client: Work around 3.0 bug for listing meta contexts X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Commit 3d068aff forgot to advertise available qemu: contexts when the client requests a list with 0 queries. Furthermore, 3.0 shipped with a qemu-img hack of x-dirty-bitmap (commit 216ee365) that _silently_ acts as though the entire image is clean if a requested bitmap is not present. Both bugs have been recently fixed to give full output from the start, and to refuse a connection if a requested x-dirty-bitmap was not found. Still, it is likely that there will be users that have to work with a mix of old and new qemu versions, depending on which features get backported where, at which point being able to rely on 'qemu-img --list' output to know for sure whether a given NBD export has the desired dirty bitmap is much nicer than blindly connecting and risking that the entire image may appear clean. We can make our --list code smart enough to work around buggy servers by tracking whether we've seen any qemu: replies in the original 0-query list; if not, recurse to a single query on "qemu:" (which may still have no replies, but then we know for sure we didn't trip up on the server bug). Signed-off-by: Eric Blake --- Done as a separate patch to make it easier to revert when we no longer care about 3.0 servers --- nbd/client.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/nbd/client.c b/nbd/client.c index 6292de560ee..928ecabd420 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -21,6 +21,7 @@ #include "qapi/error.h" #include "trace.h" #include "nbd-internal.h" +#include "qemu/cutils.h" /* Definitions for opaque data types */ @@ -736,12 +737,13 @@ static int nbd_negotiate_simple_meta_context(QIOChann= el *ioc, return -1; } g_free(name); + received =3D true; } else { info->contexts =3D g_renew(char *, info->contexts, ++info->n_contexts); info->contexts[info->n_contexts - 1] =3D name; + received |=3D strstart(name, "qemu:", NULL); } - received =3D true; /* receive NBD_REP_ACK */ if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) { @@ -771,6 +773,13 @@ static int nbd_negotiate_simple_meta_context(QIOChanne= l *ioc, info->meta_base_allocation_id =3D received_id; } + /* Recurse to work around qemu 3.0 bug - the server forgot to send + * "qemu:" replies to 0 queries. */ + if (!context && !received) { + return nbd_negotiate_simple_meta_context(ioc, opt, "qemu:", info, + errp); + } + return received || opt =3D=3D NBD_OPT_LIST_META_CONTEXT; } --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543616372918288.6192651437625; Fri, 30 Nov 2018 14:19:32 -0800 (PST) Received: from localhost ([::1]:34901 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr8F-0002Zn-HS for importer@patchew.org; Fri, 30 Nov 2018 17:19:31 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56152) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtR-0004WL-OJ for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtQ-0005CW-5h for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40508) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtK-0004Xc-Fw; Fri, 30 Nov 2018 17:04:06 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C20C630842AB; Fri, 30 Nov 2018 22:04:05 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 345F11057075; Fri, 30 Nov 2018 22:04:05 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:42 -0600 Message-Id: <20181130220344.3350618-14-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Fri, 30 Nov 2018 22:04:05 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 13/14] qemu-nbd: Add --list option X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nsoffer@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We want to be able to detect whether a given qemu NBD server is exposing the right export(s) and dirty bitmaps, at least for regression testing. We could use 'nbd-client -l' from the upstream NBD project to list exports, but it's annoying to rely on out-of-tree binaries; furthermore, nbd-client doesn't necessarily know about all of the qemu NBD extensions. Thus, we plan on adding a new mode to qemu-nbd that merely sniffs all possible information from the server during handshake phase, then disconnects and dumps the information. This patch actually implements --list/-L, while reusing other options such as --tls-creds for now designating how to connect as the client (rather than their non-list usage of how to operate as the server). I debated about adding this functionality to something akin to 'qemu-img info' - but that tool does not readily lend itself to connecting to an arbitrary NBD server without also tying to a specific export (I may, however, still add ImageInfoSpecificNBD for reporting the bitmaps available when connecting to a single export). And, while it may feel a bit odd that normally qemu-nbd is a server but 'qemu-nbd -L' is a client, we are not really making the qemu-nbd binary that much larger, because 'qemu-nbd -c' has to operate as both server and client simultaneously across two threads when feeding the kernel module for /dev/nbdN access. Sample output: $ qemu-nbd -L exports available: 1 export: '' size: 65536 flags: 0x4ed ( flush fua trim zeroes df cache ) min block: 512 opt block: 4096 max block: 33554432 available meta contexts: 1 base:allocation Signed-off-by: Eric Blake --- qemu-nbd.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 141 insertions(+), 12 deletions(-) diff --git a/qemu-nbd.c b/qemu-nbd.c index c57053a0795..e19a841b869 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -76,6 +76,7 @@ static void usage(const char *name) { (printf) ( "Usage: %s [OPTIONS] FILE\n" +" or: %s -L [OPTIONS]\n" "QEMU Disk Network Block Device Server\n" "\n" " -h, --help display this help and exit\n" @@ -97,6 +98,7 @@ static void usage(const char *name) " -P, --partition=3DNUM only expose partition NUM\n" "\n" "General purpose options:\n" +" -L, --list list NBD exports visible to client\n" " --object type,id=3DID,... define an object such as 'secret' for provi= ding\n" " passwords and/or encryption keys\n" " --tls-creds=3DID use id of an earlier --object to provide TL= S\n" @@ -130,7 +132,7 @@ static void usage(const char *name) " --image-opts treat FILE as a full set of image options\n" "\n" QEMU_HELP_BOTTOM "\n" - , name, NBD_DEFAULT_PORT, "DEVICE"); + , name, name, NBD_DEFAULT_PORT, "DEVICE"); } static void version(const char *name) @@ -242,6 +244,92 @@ static void termsig_handler(int signum) } +static int qemu_nbd_client_list(SocketAddress *saddr, QCryptoTLSCreds *tls, + const char *hostname) +{ + int ret =3D EXIT_FAILURE; + int rc; + Error *err =3D NULL; + QIOChannelSocket *sioc; + NBDExportInfo *list; + int i, j; + + sioc =3D qio_channel_socket_new(); + if (qio_channel_socket_connect_sync(sioc, saddr, &err) < 0) { + error_report_err(err); + goto out; + } + rc =3D nbd_receive_export_list(QIO_CHANNEL(sioc), tls, hostname, &list, + &err); + if (rc < 0) { + if (err) { + error_report_err(err); + } + goto out_socket; + } + printf("exports available: %d\n", rc); + for (i =3D 0; i < rc; i++) { + printf(" export: '%s'\n", list[i].name); + if (list[i].description && *list[i].description) { + printf(" description: %s\n", list[i].description); + } + if (list[i].flags & NBD_FLAG_HAS_FLAGS) { + printf(" size: %" PRIu64 "\n", list[i].size); + printf(" flags: 0x%x (", list[i].flags); + if (list[i].flags & NBD_FLAG_READ_ONLY) { + printf(" readonly"); + } + if (list[i].flags & NBD_FLAG_SEND_FLUSH) { + printf(" flush"); + } + if (list[i].flags & NBD_FLAG_SEND_FUA) { + printf(" fua"); + } + if (list[i].flags & NBD_FLAG_ROTATIONAL) { + printf(" rotational"); + } + if (list[i].flags & NBD_FLAG_SEND_TRIM) { + printf(" trim"); + } + if (list[i].flags & NBD_FLAG_SEND_WRITE_ZEROES) { + printf(" zeroes"); + } + if (list[i].flags & NBD_FLAG_SEND_DF) { + printf(" df"); + } + if (list[i].flags & NBD_FLAG_CAN_MULTI_CONN) { + printf(" multi"); + } + if (list[i].flags & NBD_FLAG_SEND_RESIZE) { + printf(" resize"); + } + if (list[i].flags & NBD_FLAG_SEND_CACHE) { + printf(" cache"); + } + printf(" )\n"); + } + if (list[i].min_block) { + printf(" min block: %u\n", list[i].min_block); + printf(" opt block: %u\n", list[i].opt_block); + printf(" max block: %u\n", list[i].max_block); + } + if (list[i].n_contexts) { + printf(" available meta contexts: %d\n", list[i].n_contexts); + for (j =3D 0; j < list[i].n_contexts; j++) { + printf(" %s\n", list[i].contexts[j]); + } + } + } + nbd_free_export_list(list, rc); + + ret =3D EXIT_SUCCESS; + out_socket: + object_unref(OBJECT(sioc)); + out: + return ret; +} + + #if HAVE_NBD_DEVICE static void *show_parts(void *arg) { @@ -424,7 +512,8 @@ static QemuOptsList qemu_object_opts =3D { -static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, Error **errp) +static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, bool list, + Error **errp) { Object *obj; QCryptoTLSCreds *creds; @@ -444,10 +533,18 @@ static QCryptoTLSCreds *nbd_get_tls_creds(const char = *id, Error **errp) return NULL; } - if (creds->endpoint !=3D QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - error_setg(errp, - "Expecting TLS credentials with a server endpoint"); - return NULL; + if (list) { + if (creds->endpoint !=3D QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) { + error_setg(errp, + "Expecting TLS credentials with a client endpoint"); + return NULL; + } + } else { + if (creds->endpoint !=3D QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { + error_setg(errp, + "Expecting TLS credentials with a server endpoint"); + return NULL; + } } object_ref(obj); return creds; @@ -470,7 +567,8 @@ static void setup_address_and_port(const char **address= , const char **port) static const char *socket_activation_validate_opts(const char *device, const char *sockpath, const char *address, - const char *port) + const char *port, + bool list) { if (device !=3D NULL) { return "NBD device can't be set when using socket activation"; @@ -488,6 +586,10 @@ static const char *socket_activation_validate_opts(con= st char *device, return "TCP port number can't be set when using socket activation"; } + if (list) { + return "List mode is incompatible with socket activation"; + } + return NULL; } @@ -511,7 +613,7 @@ int main(int argc, char **argv) off_t fd_size; QemuOpts *sn_opts =3D NULL; const char *sn_id_or_name =3D NULL; - const char *sopt =3D "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:D:"; + const char *sopt =3D "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:D:L"; struct option lopt[] =3D { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, @@ -523,6 +625,7 @@ int main(int argc, char **argv) { "partition", required_argument, NULL, 'P' }, { "connect", required_argument, NULL, 'c' }, { "disconnect", no_argument, NULL, 'd' }, + { "list", no_argument, NULL, 'L' }, { "snapshot", no_argument, NULL, 's' }, { "load-snapshot", required_argument, NULL, 'l' }, { "nocache", no_argument, NULL, 'n' }, @@ -558,13 +661,14 @@ int main(int argc, char **argv) Error *local_err =3D NULL; BlockdevDetectZeroesOptions detect_zeroes =3D BLOCKDEV_DETECT_ZEROES_O= PTIONS_OFF; QDict *options =3D NULL; - const char *export_name =3D ""; /* Default export name */ + const char *export_name =3D NULL; const char *export_description =3D NULL; const char *tlscredsid =3D NULL; bool imageOpts =3D false; bool writethrough =3D true; char *trace_file =3D NULL; bool fork_process =3D false; + bool list =3D false; int old_stderr =3D -1; unsigned socket_activation; @@ -764,13 +868,32 @@ int main(int argc, char **argv) case QEMU_NBD_OPT_FORK: fork_process =3D true; break; + case 'L': + list =3D true; + break; } } - if ((argc - optind) !=3D 1) { + if (list) { + if (argc !=3D optind) { + error_report("List mode is incompatible with a file name"); + exit(EXIT_FAILURE); + } + if (export_name || export_description || dev_offset || partition || + device || disconnect || fmt || sn_id_or_name) { + error_report("List mode is incompatible with per-device settin= gs"); + exit(EXIT_FAILURE); + } + if (fork_process) { + error_report("List mode is incompatible with forking"); + exit(EXIT_FAILURE); + } + } else if ((argc - optind) !=3D 1) { error_report("Invalid number of arguments"); error_printf("Try `%s --help' for more information.\n", argv[0]); exit(EXIT_FAILURE); + } else if (!export_name) { + export_name =3D ""; } qemu_opts_foreach(&qemu_object_opts, @@ -789,7 +912,8 @@ int main(int argc, char **argv) } else { /* Using socket activation - check user didn't use -p etc. */ const char *err_msg =3D socket_activation_validate_opts(device, so= ckpath, - bindto, port= ); + bindto, port, + list); if (err_msg !=3D NULL) { error_report("%s", err_msg); exit(EXIT_FAILURE); @@ -812,7 +936,7 @@ int main(int argc, char **argv) error_report("TLS is not supported with a host device"); exit(EXIT_FAILURE); } - tlscreds =3D nbd_get_tls_creds(tlscredsid, &local_err); + tlscreds =3D nbd_get_tls_creds(tlscredsid, list, &local_err); if (local_err) { error_report("Failed to get TLS creds %s", error_get_pretty(local_err)); @@ -820,6 +944,11 @@ int main(int argc, char **argv) } } + if (list) { + saddr =3D nbd_build_socket_address(sockpath, bindto, port); + return qemu_nbd_client_list(saddr, tlscreds, bindto); + } + if (disconnect) { #if HAVE_NBD_DEVICE int nbdfd =3D open(argv[optind], O_RDWR); --=20 2.17.2 From nobody Sun Oct 5 17:23:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 154361616266551.79114221596535; Fri, 30 Nov 2018 14:16:02 -0800 (PST) Received: from localhost ([::1]:34888 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSr4r-0007xb-Di for importer@patchew.org; Fri, 30 Nov 2018 17:16:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56127) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gSqtQ-0004VK-Kt for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gSqtP-00056H-GL for qemu-devel@nongnu.org; Fri, 30 Nov 2018 17:04:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40346) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gSqtL-0004cX-AT; Fri, 30 Nov 2018 17:04:07 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A6A0C3082E51; Fri, 30 Nov 2018 22:04:06 +0000 (UTC) Received: from red.redhat.com (ovpn-117-105.phx2.redhat.com [10.3.117.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id EC93E1057073; Fri, 30 Nov 2018 22:04:05 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 30 Nov 2018 16:03:43 -0600 Message-Id: <20181130220344.3350618-15-eblake@redhat.com> In-Reply-To: <20181130220344.3350618-1-eblake@redhat.com> References: <20181130220344.3350618-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 30 Nov 2018 22:04:06 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 14/14] iotests: Enhance 223, 233 to cover 'qemu-nbd --list' X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, qemu-block@nongnu.org, rjones@redhat.com, Max Reitz , nsoffer@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Any good new feature deserves some regression testing :) Coverage includes: - 223: what happens when there are 0 or more than 1 export, proof that we can see multiple contexts including qemu:dirty-bitmap - 233: proof that we can list over TLS, and that mix-and-match of plain/TLS listings sanely Signed-off-by: Eric Blake Reviewed-by: Richard W.M. Jones Reviewed-by: Vladimir Sementsov-Ogievskiy Tested-by: Richard W.M. Jones --- tests/qemu-iotests/223 | 2 ++ tests/qemu-iotests/223.out | 20 ++++++++++++++++++++ tests/qemu-iotests/233 | 10 ++++++++++ tests/qemu-iotests/233.out | 15 +++++++++++++++ 4 files changed, 47 insertions(+) diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223 index 397b865d347..e64747a9a61 100755 --- a/tests/qemu-iotests/223 +++ b/tests/qemu-iotests/223 @@ -119,6 +119,7 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"x-block-dirty-= bitmap-disable", _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"'"$TEST_DIR/nbd"'"}}}}' "return" +$QEMU_NBD_PROG -L -k "$TEST_DIR/nbd" _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", "arguments":{"device":"n"}}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", @@ -127,6 +128,7 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add= ", "arguments":{"device":"n", "name":"n2"}}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", "arguments":{"name":"n2", "bitmap":"b2"}}' "return" +$QEMU_NBD_PROG -L -k "$TEST_DIR/nbd" echo echo "=3D=3D=3D Contrast normal status to large granularity dirty-bitmap = =3D=3D=3D" diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out index de417477de0..3342bff3447 100644 --- a/tests/qemu-iotests/223.out +++ b/tests/qemu-iotests/223.out @@ -29,10 +29,30 @@ wrote 2097152/2097152 bytes at offset 2097152 {"return": {}} {"return": {}} {"return": {}} +exports available: 0 {"return": {}} {"return": {}} {"return": {}} {"return": {}} +exports available: 2 + export: 'n' + size: 4194304 + flags: 0x4ef ( readonly flush fua trim zeroes df cache ) + min block: 512 + opt block: 4096 + max block: 33554432 + available meta contexts: 2 + base:allocation + qemu:dirty-bitmap:b + export: 'n2' + size: 4194304 + flags: 0x4ef ( readonly flush fua trim zeroes df cache ) + min block: 512 + opt block: 4096 + max block: 33554432 + available meta contexts: 2 + base:allocation + qemu:dirty-bitmap:b2 =3D=3D=3D Contrast normal status to large granularity dirty-bitmap =3D=3D= =3D diff --git a/tests/qemu-iotests/233 b/tests/qemu-iotests/233 index 1814efe3333..5d694d9d242 100755 --- a/tests/qemu-iotests/233 +++ b/tests/qemu-iotests/233 @@ -72,6 +72,9 @@ $QEMU_IMG info --image-opts \ --object tls-creds-x509,dir=3D${tls_dir}/client1,endpoint=3Dclient,id= =3Dtls0 \ driver=3Dnbd,host=3D$nbd_tcp_addr,port=3D$nbd_tcp_port,tls-creds=3Dtls= 0 \ 2>&1 | sed "s/$nbd_tcp_port/PORT/g" +$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port \ + --object tls-creds-x509,dir=3D${tls_dir}/client1,endpoint=3Dclient,id= =3Dtls0 \ + --tls-creds=3Dtls0 nbd_server_stop @@ -84,6 +87,7 @@ nbd_server_start_tcp_socket \ -f $IMGFMT "$TEST_IMG" $QEMU_IMG info nbd://localhost:$nbd_tcp_port 2>&1 | sed "s/$nbd_tcp_port/P= ORT/g" +$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port echo echo "=3D=3D check TLS works =3D=3D" @@ -91,6 +95,9 @@ $QEMU_IMG info --image-opts \ --object tls-creds-x509,dir=3D${tls_dir}/client1,endpoint=3Dclient,id= =3Dtls0 \ driver=3Dnbd,host=3D$nbd_tcp_addr,port=3D$nbd_tcp_port,tls-creds=3Dtls= 0 \ 2>&1 | sed "s/$nbd_tcp_port/PORT/g" +$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port \ + --object tls-creds-x509,dir=3D${tls_dir}/client1,endpoint=3Dclient,id= =3Dtls0 \ + --tls-creds=3Dtls0 echo echo "=3D=3D check TLS with different CA fails =3D=3D" @@ -98,6 +105,9 @@ $QEMU_IMG info --image-opts \ --object tls-creds-x509,dir=3D${tls_dir}/client2,endpoint=3Dclient,id= =3Dtls0 \ driver=3Dnbd,host=3D$nbd_tcp_addr,port=3D$nbd_tcp_port,tls-creds=3Dtls= 0 \ 2>&1 | sed "s/$nbd_tcp_port/PORT/g" +$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port \ + --object tls-creds-x509,dir=3D${tls_dir}/client2,endpoint=3Dclient,id= =3Dtls0 \ + --tls-creds=3Dtls0 echo echo "=3D=3D perform I/O over TLS =3D=3D" diff --git a/tests/qemu-iotests/233.out b/tests/qemu-iotests/233.out index 5f416721b03..ab669488669 100644 --- a/tests/qemu-iotests/233.out +++ b/tests/qemu-iotests/233.out @@ -15,20 +15,35 @@ wrote 1048576/1048576 bytes at offset 1048576 =3D=3D check TLS client to plain server fails =3D=3D qemu-img: Could not open 'driver=3Dnbd,host=3D127.0.0.1,port=3DPORT,tls-cr= eds=3Dtls0': Denied by server for option 5 (starttls) server reported: TLS not configured +qemu-nbd: Denied by server for option 5 (starttls) +server reported: TLS not configured =3D=3D check plain client to TLS server fails =3D=3D qemu-img: Could not open 'nbd://localhost:PORT': TLS negotiation required = before option 8 (structured reply) server reported: Option 0x8 not permitted before TLS +qemu-nbd: TLS negotiation required before option 8 (structured reply) +server reported: Option 0x8 not permitted before TLS =3D=3D check TLS works =3D=3D image: nbd://127.0.0.1:PORT file format: nbd virtual size: 64M (67108864 bytes) disk size: unavailable +exports available: 1 + export: '' + size: 67108864 + flags: 0x4ed ( flush fua trim zeroes df cache ) + min block: 512 + opt block: 4096 + max block: 33554432 + available meta contexts: 1 + base:allocation =3D=3D check TLS with different CA fails =3D=3D qemu-nbd: option negotiation failed: Verify failed: No certificate was fou= nd. qemu-img: Could not open 'driver=3Dnbd,host=3D127.0.0.1,port=3DPORT,tls-cr= eds=3Dtls0': The certificate hasn't got a known issuer +qemu-nbd: option negotiation failed: Verify failed: No certificate was fou= nd. +qemu-nbd: The certificate hasn't got a known issuer =3D=3D perform I/O over TLS =3D=3D read 1048576/1048576 bytes at offset 1048576 --=20 2.17.2