From nobody Fri Apr 19 13:13:18 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) 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=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802451117509.63244904247824; Thu, 12 Oct 2017 03:00:51 -0700 (PDT) Received: from localhost ([::1]:44545 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aIJ-00074a-BR for importer@patchew.org; Thu, 12 Oct 2017 06:00:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35446) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001FZ-5k for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBE-0000Gw-W7 for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:35715 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBE-0000Da-Jy for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:28 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVh025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:07 +0300 Message-Id: <20171012095319.136610-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 01/13] block/nbd-client: assert qiov len once in nbd_co_request 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Also improve the assertion: check that qiov is NULL for other commands than CMD_READ and CMD_WRITE. Signed-off-by: Vladimir Sementsov-Ogievskiy --- block/nbd-client.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/block/nbd-client.c b/block/nbd-client.c index 72651dcdb1..ddf273a6a4 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -156,7 +156,6 @@ static int nbd_co_send_request(BlockDriverState *bs, qio_channel_set_cork(s->ioc, true); rc =3D nbd_send_request(s->ioc, request); if (rc >=3D 0 && !s->quit) { - assert(request->len =3D=3D iov_size(qiov->iov, qiov->niov)); if (qio_channel_writev_all(s->ioc, qiov->iov, qiov->niov, NULL) < 0) { rc =3D -EIO; @@ -197,7 +196,6 @@ static int nbd_co_receive_reply(NBDClientSession *s, assert(s->reply.handle =3D=3D request->handle); ret =3D -s->reply.error; if (qiov && s->reply.error =3D=3D 0) { - assert(request->len =3D=3D iov_size(qiov->iov, qiov->niov)); if (qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov, NULL) < 0) { ret =3D -EIO; @@ -231,8 +229,12 @@ static int nbd_co_request(BlockDriverState *bs, NBDClientSession *client =3D nbd_get_client_session(bs); int ret; =20 - assert(!qiov || request->type =3D=3D NBD_CMD_WRITE || - request->type =3D=3D NBD_CMD_READ); + if (qiov) { + assert(request->type =3D=3D NBD_CMD_WRITE || request->type =3D=3D = NBD_CMD_READ); + assert(request->len =3D=3D iov_size(qiov->iov, qiov->niov)); + } else { + assert(request->type !=3D NBD_CMD_WRITE && request->type !=3D NBD_= CMD_READ); + } ret =3D nbd_co_send_request(bs, request, request->type =3D=3D NBD_CMD_WRITE ? qiov : = NULL); if (ret < 0) { --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802295335117.61052314161168; Thu, 12 Oct 2017 02:58:15 -0700 (PDT) Received: from localhost ([::1]:44531 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aFq-0004rP-JK for importer@patchew.org; Thu, 12 Oct 2017 05:58:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35436) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001FR-3O for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBE-0000Gq-Vz for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:30970 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBE-0000DT-Jl for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:28 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVi025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:08 +0300 Message-Id: <20171012095319.136610-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 02/13] block/nbd-client: refactor nbd_co_receive_reply 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Pass handle parameter directly, as the whole request isn't needed. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- block/nbd-client.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/nbd-client.c b/block/nbd-client.c index ddf273a6a4..c0683c3c83 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -180,11 +180,11 @@ err: } =20 static int nbd_co_receive_reply(NBDClientSession *s, - NBDRequest *request, + uint64_t handle, QEMUIOVector *qiov) { int ret; - int i =3D HANDLE_TO_INDEX(s, request->handle); + int i =3D HANDLE_TO_INDEX(s, handle); =20 /* Wait until we're woken up by nbd_read_reply_entry. */ s->requests[i].receiving =3D true; @@ -193,7 +193,7 @@ static int nbd_co_receive_reply(NBDClientSession *s, if (!s->ioc || s->quit) { ret =3D -EIO; } else { - assert(s->reply.handle =3D=3D request->handle); + assert(s->reply.handle =3D=3D handle); ret =3D -s->reply.error; if (qiov && s->reply.error =3D=3D 0) { if (qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov, @@ -241,7 +241,7 @@ static int nbd_co_request(BlockDriverState *bs, return ret; } =20 - return nbd_co_receive_reply(client, request, + return nbd_co_receive_reply(client, request->handle, request->type =3D=3D NBD_CMD_READ ? qiov := NULL); } =20 --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802384085285.8027145491751; Thu, 12 Oct 2017 02:59:44 -0700 (PDT) Received: from localhost ([::1]:44537 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aHC-00062Y-B8 for importer@patchew.org; Thu, 12 Oct 2017 05:59:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35444) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001FY-5j for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000HH-2f for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:34797 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBE-0000DZ-JT for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:29 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVj025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:09 +0300 Message-Id: <20171012095319.136610-4-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 03/13] nbd: rename some simple-request related objects to be _simple_ 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" To be consistent when their _structured_analogs will be introduced. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- nbd/nbd-internal.h | 2 +- nbd/client.c | 4 ++-- nbd/server.c | 12 ++++++------ nbd/trace-events | 2 +- tests/qemu-iotests/nbd-fault-injector.py | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h index 8a609a227f..2d6663de23 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -47,7 +47,7 @@ #define NBD_OLDSTYLE_NEGOTIATE_SIZE (8 + 8 + 8 + 4 + 124) =20 #define NBD_REQUEST_MAGIC 0x25609513 -#define NBD_REPLY_MAGIC 0x67446698 +#define NBD_SIMPLE_REPLY_MAGIC 0x67446698 #define NBD_OPTS_MAGIC 0x49484156454F5054LL #define NBD_CLIENT_MAGIC 0x0000420281861253LL #define NBD_REP_MAGIC 0x0003e889045565a9LL diff --git a/nbd/client.c b/nbd/client.c index 68a0bc1ffc..cd5a2c80ac 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -931,7 +931,7 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply,= Error **errp) } =20 /* Reply - [ 0 .. 3] magic (NBD_REPLY_MAGIC) + [ 0 .. 3] magic (NBD_SIMPLE_REPLY_MAGIC) [ 4 .. 7] error (0 =3D=3D no error) [ 7 .. 15] handle */ @@ -949,7 +949,7 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply,= Error **errp) } trace_nbd_receive_reply(magic, reply->error, reply->handle); =20 - if (magic !=3D NBD_REPLY_MAGIC) { + if (magic !=3D NBD_SIMPLE_REPLY_MAGIC) { error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic); return -EINVAL; } diff --git a/nbd/server.c b/nbd/server.c index 993ade30bb..bc7f9f0fd6 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -911,11 +911,11 @@ static int nbd_send_reply(QIOChannel *ioc, NBDReply *= reply, Error **errp) trace_nbd_send_reply(reply->error, reply->handle); =20 /* Reply - [ 0 .. 3] magic (NBD_REPLY_MAGIC) + [ 0 .. 3] magic (NBD_SIMPLE_REPLY_MAGIC) [ 4 .. 7] error (0 =3D=3D no error) [ 7 .. 15] handle */ - stl_be_p(buf, NBD_REPLY_MAGIC); + stl_be_p(buf, NBD_SIMPLE_REPLY_MAGIC); stl_be_p(buf + 4, reply->error); stq_be_p(buf + 8, reply->handle); =20 @@ -1208,15 +1208,15 @@ void nbd_export_close_all(void) } } =20 -static int nbd_co_send_reply(NBDRequestData *req, NBDReply *reply, int len, - Error **errp) +static int nbd_co_send_simple_reply(NBDRequestData *req, NBDReply *reply, + int len, Error **errp) { NBDClient *client =3D req->client; int ret; =20 g_assert(qemu_in_coroutine()); =20 - trace_nbd_co_send_reply(reply->handle, reply->error, len); + trace_nbd_co_send_simple_reply(reply->handle, reply->error, len); =20 qemu_co_mutex_lock(&client->send_lock); client->send_coroutine =3D qemu_coroutine_self(); @@ -1465,7 +1465,7 @@ reply: local_err =3D NULL; } =20 - if (nbd_co_send_reply(req, &reply, reply_data_len, &local_err) < 0) { + if (nbd_co_send_simple_reply(req, &reply, reply_data_len, &local_err) = < 0) { error_prepend(&local_err, "Failed to send reply: "); goto disconnect; } diff --git a/nbd/trace-events b/nbd/trace-events index 48a4f27682..c5f2d97be2 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -54,7 +54,7 @@ nbd_receive_request(uint32_t magic, uint16_t flags, uint1= 6_t type, uint64_t from nbd_send_reply(int32_t error, uint64_t handle) "Sending response to client= : { .error =3D %" PRId32 ", handle =3D %" PRIu64 " }" nbd_blk_aio_attached(const char *name, void *ctx) "Export %s: Attaching cl= ients to AIO context %p\n" nbd_blk_aio_detach(const char *name, void *ctx) "Export %s: Detaching clie= nts from AIO context %p\n" -nbd_co_send_reply(uint64_t handle, uint32_t error, int len) "Send reply: h= andle =3D %" PRIu64 ", error =3D %" PRIu32 ", len =3D %d" +nbd_co_send_simple_reply(uint64_t handle, uint32_t error, int len) "Send r= eply: handle =3D %" PRIu64 ", error =3D %" PRIu32 ", len =3D %d" nbd_co_receive_request_decode_type(uint64_t handle, uint16_t type, const c= har *name) "Decoding type: handle =3D %" PRIu64 ", type =3D %" PRIu16 " (%s= )" nbd_co_receive_request_payload_received(uint64_t handle, uint32_t len) "Pa= yload received: handle =3D %" PRIu64 ", len =3D %" PRIu32 nbd_co_receive_request_cmd_write(uint32_t len) "Reading %" PRIu32 " byte(s= )" diff --git a/tests/qemu-iotests/nbd-fault-injector.py b/tests/qemu-iotests/= nbd-fault-injector.py index 1c10dcb51c..8a04d979aa 100755 --- a/tests/qemu-iotests/nbd-fault-injector.py +++ b/tests/qemu-iotests/nbd-fault-injector.py @@ -56,7 +56,7 @@ NBD_CMD_READ =3D 0 NBD_CMD_WRITE =3D 1 NBD_CMD_DISC =3D 2 NBD_REQUEST_MAGIC =3D 0x25609513 -NBD_REPLY_MAGIC =3D 0x67446698 +NBD_SIMPLE_REPLY_MAGIC =3D 0x67446698 NBD_PASSWD =3D 0x4e42444d41474943 NBD_OPTS_MAGIC =3D 0x49484156454F5054 NBD_CLIENT_MAGIC =3D 0x0000420281861253 @@ -166,7 +166,7 @@ def read_request(conn): return req =20 def write_reply(conn, error, handle): - buf =3D reply_struct.pack(NBD_REPLY_MAGIC, error, handle) + buf =3D reply_struct.pack(NBD_SIMPLE_REPLY_MAGIC, error, handle) conn.send(buf, event=3D'reply') =20 def handle_connection(conn, use_export): --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802294509385.2409620593219; Thu, 12 Oct 2017 02:58:14 -0700 (PDT) Received: from localhost ([::1]:44530 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aFm-0004pD-K3 for importer@patchew.org; Thu, 12 Oct 2017 05:58:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35440) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001FV-4b for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBE-0000Gj-V6 for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:26996 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBE-0000DR-Jh for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:28 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVk025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:10 +0300 Message-Id: <20171012095319.136610-5-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 04/13] nbd/server: structurize simple reply header sending 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Use packed structure instead of pointer arithmetics. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- include/block/nbd.h | 6 ++++++ nbd/server.c | 36 ++++++++++++++---------------------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 707fd37575..49008980f4 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -63,6 +63,12 @@ struct NBDReply { }; typedef struct NBDReply NBDReply; =20 +typedef struct NBDSimpleReply { + uint32_t magic; /* NBD_SIMPLE_REPLY_MAGIC */ + uint32_t error; + uint64_t handle; +} QEMU_PACKED NBDSimpleReply; + /* Transmission (export) flags: sent from server to client during handshak= e, but describe what will happen during transmission */ #define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */ diff --git a/nbd/server.c b/nbd/server.c index bc7f9f0fd6..43ade30ba3 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -902,26 +902,6 @@ static int nbd_receive_request(QIOChannel *ioc, NBDReq= uest *request, return 0; } =20 -static int nbd_send_reply(QIOChannel *ioc, NBDReply *reply, Error **errp) -{ - uint8_t buf[NBD_REPLY_SIZE]; - - reply->error =3D system_errno_to_nbd_errno(reply->error); - - trace_nbd_send_reply(reply->error, reply->handle); - - /* Reply - [ 0 .. 3] magic (NBD_SIMPLE_REPLY_MAGIC) - [ 4 .. 7] error (0 =3D=3D no error) - [ 7 .. 15] handle - */ - stl_be_p(buf, NBD_SIMPLE_REPLY_MAGIC); - stl_be_p(buf + 4, reply->error); - stq_be_p(buf + 8, reply->handle); - - return nbd_write(ioc, buf, sizeof(buf), errp); -} - #define MAX_NBD_REQUESTS 16 =20 void nbd_client_get(NBDClient *client) @@ -1208,24 +1188,36 @@ void nbd_export_close_all(void) } } =20 +static inline void set_be_simple_reply(NBDSimpleReply *reply, uint64_t err= or, + uint64_t handle) +{ + stl_be_p(&reply->magic, NBD_SIMPLE_REPLY_MAGIC); + stl_be_p(&reply->error, error); + stq_be_p(&reply->handle, handle); +} + static int nbd_co_send_simple_reply(NBDRequestData *req, NBDReply *reply, int len, Error **errp) { NBDClient *client =3D req->client; + NBDSimpleReply simple_reply; int ret; =20 g_assert(qemu_in_coroutine()); =20 trace_nbd_co_send_simple_reply(reply->handle, reply->error, len); =20 + set_be_simple_reply(&simple_reply, system_errno_to_nbd_errno(reply->er= ror), + reply->handle); + qemu_co_mutex_lock(&client->send_lock); client->send_coroutine =3D qemu_coroutine_self(); =20 if (!len) { - ret =3D nbd_send_reply(client->ioc, reply, errp); + ret =3D nbd_write(client->ioc, &simple_reply, sizeof(simple_reply)= , NULL); } else { qio_channel_set_cork(client->ioc, true); - ret =3D nbd_send_reply(client->ioc, reply, errp); + ret =3D nbd_write(client->ioc, &simple_reply, sizeof(simple_reply)= , NULL); if (ret =3D=3D 0) { ret =3D nbd_write(client->ioc, req->data, len, errp); if (ret < 0) { --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802223346866.295355377391; Thu, 12 Oct 2017 02:57:03 -0700 (PDT) Received: from localhost ([::1]:44528 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aEg-0003lD-Hb for importer@patchew.org; Thu, 12 Oct 2017 05:57:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35437) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001FS-3u for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000HA-1h for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:37412 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBE-0000Dc-Mr for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:28 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVl025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:11 +0300 Message-Id: <20171012095319.136610-6-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 05/13] nbd/server: do not use NBDReply structure 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" NBDReply structure will be upgraded in future patches to handle both simple and structured replies and will be used only in the client Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- nbd/server.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index 43ade30ba3..3878145f63 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1196,7 +1196,9 @@ static inline void set_be_simple_reply(NBDSimpleReply= *reply, uint64_t error, stq_be_p(&reply->handle, handle); } =20 -static int nbd_co_send_simple_reply(NBDRequestData *req, NBDReply *reply, +static int nbd_co_send_simple_reply(NBDRequestData *req, + uint64_t handle, + uint32_t error, int len, Error **errp) { NBDClient *client =3D req->client; @@ -1205,10 +1207,10 @@ static int nbd_co_send_simple_reply(NBDRequestData = *req, NBDReply *reply, =20 g_assert(qemu_in_coroutine()); =20 - trace_nbd_co_send_simple_reply(reply->handle, reply->error, len); + trace_nbd_co_send_simple_reply(handle, error, len); =20 - set_be_simple_reply(&simple_reply, system_errno_to_nbd_errno(reply->er= ror), - reply->handle); + set_be_simple_reply(&simple_reply, system_errno_to_nbd_errno(error), + handle); =20 qemu_co_mutex_lock(&client->send_lock); client->send_coroutine =3D qemu_coroutine_self(); @@ -1323,7 +1325,6 @@ static coroutine_fn void nbd_trip(void *opaque) NBDExport *exp =3D client->exp; NBDRequestData *req; NBDRequest request =3D { 0 }; /* GCC thinks it can be used uninitia= lized */ - NBDReply reply; int ret; int flags; int reply_data_len =3D 0; @@ -1343,11 +1344,7 @@ static coroutine_fn void nbd_trip(void *opaque) goto disconnect; } =20 - reply.handle =3D request.handle; - reply.error =3D 0; - if (ret < 0) { - reply.error =3D -ret; goto reply; } =20 @@ -1366,7 +1363,6 @@ static coroutine_fn void nbd_trip(void *opaque) ret =3D blk_co_flush(exp->blk); if (ret < 0) { error_setg_errno(&local_err, -ret, "flush failed"); - reply.error =3D -ret; break; } } @@ -1375,7 +1371,6 @@ static coroutine_fn void nbd_trip(void *opaque) req->data, request.len); if (ret < 0) { error_setg_errno(&local_err, -ret, "reading from file failed"); - reply.error =3D -ret; break; } =20 @@ -1384,7 +1379,7 @@ static coroutine_fn void nbd_trip(void *opaque) break; case NBD_CMD_WRITE: if (exp->nbdflags & NBD_FLAG_READ_ONLY) { - reply.error =3D EROFS; + ret =3D -EROFS; break; } =20 @@ -1396,14 +1391,13 @@ static coroutine_fn void nbd_trip(void *opaque) req->data, request.len, flags); if (ret < 0) { error_setg_errno(&local_err, -ret, "writing to file failed"); - reply.error =3D -ret; } =20 break; case NBD_CMD_WRITE_ZEROES: if (exp->nbdflags & NBD_FLAG_READ_ONLY) { error_setg(&local_err, "Server is read-only, return error"); - reply.error =3D EROFS; + ret =3D -EROFS; break; } =20 @@ -1418,7 +1412,6 @@ static coroutine_fn void nbd_trip(void *opaque) request.len, flags); if (ret < 0) { error_setg_errno(&local_err, -ret, "writing to file failed"); - reply.error =3D -ret; } =20 break; @@ -1430,7 +1423,6 @@ static coroutine_fn void nbd_trip(void *opaque) ret =3D blk_co_flush(exp->blk); if (ret < 0) { error_setg_errno(&local_err, -ret, "flush failed"); - reply.error =3D -ret; } =20 break; @@ -1439,25 +1431,27 @@ static coroutine_fn void nbd_trip(void *opaque) request.len); if (ret < 0) { error_setg_errno(&local_err, -ret, "discard failed"); - reply.error =3D -ret; } =20 break; default: error_setg(&local_err, "invalid request type (%" PRIu32 ") receive= d", request.type); - reply.error =3D EINVAL; + ret =3D -EINVAL; } =20 reply: if (local_err) { - /* If we are here local_err is not fatal error, already stored in - * reply.error */ + /* If we get here, local_err was not a fatal error, and should be = sent + * to the client. */ error_report_err(local_err); local_err =3D NULL; } =20 - if (nbd_co_send_simple_reply(req, &reply, reply_data_len, &local_err) = < 0) { + if (nbd_co_send_simple_reply(req, request.handle, + ret < 0 ? -ret : 0, + reply_data_len, &local_err) < 0) + { error_prepend(&local_err, "Failed to send reply: "); goto disconnect; } --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802785510285.3667231844463; Thu, 12 Oct 2017 03:06:25 -0700 (PDT) Received: from localhost ([::1]:44584 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aNf-0003BV-Qr for importer@patchew.org; Thu, 12 Oct 2017 06:06:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35449) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001Fb-6K for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000IG-LQ for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:31073 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBF-0000Db-8I for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:29 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVm025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:12 +0300 Message-Id: <20171012095319.136610-7-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 06/13] nbd/server: refactor nbd_co_send_simple_reply parameters 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Pass client and buffer (*data) parameters directly, to make the function consistent with further structured reply sending functions. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- nbd/server.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index 3878145f63..afc127bbd9 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1196,12 +1196,13 @@ static inline void set_be_simple_reply(NBDSimpleRep= ly *reply, uint64_t error, stq_be_p(&reply->handle, handle); } =20 -static int nbd_co_send_simple_reply(NBDRequestData *req, +static int nbd_co_send_simple_reply(NBDClient *client, uint64_t handle, uint32_t error, - int len, Error **errp) + void *data, + size_t len, + Error **errp) { - NBDClient *client =3D req->client; NBDSimpleReply simple_reply; int ret; =20 @@ -1221,7 +1222,7 @@ static int nbd_co_send_simple_reply(NBDRequestData *r= eq, qio_channel_set_cork(client->ioc, true); ret =3D nbd_write(client->ioc, &simple_reply, sizeof(simple_reply)= , NULL); if (ret =3D=3D 0) { - ret =3D nbd_write(client->ioc, req->data, len, errp); + ret =3D nbd_write(client->ioc, data, len, errp); if (ret < 0) { ret =3D -EIO; } @@ -1448,9 +1449,9 @@ reply: local_err =3D NULL; } =20 - if (nbd_co_send_simple_reply(req, request.handle, + if (nbd_co_send_simple_reply(req->client, request.handle, ret < 0 ? -ret : 0, - reply_data_len, &local_err) < 0) + req->data, reply_data_len, &local_err) < = 0) { error_prepend(&local_err, "Failed to send reply: "); goto disconnect; --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802142517762.7384138116824; Thu, 12 Oct 2017 02:55:42 -0700 (PDT) Received: from localhost ([::1]:44518 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aDF-0002WP-Ky for importer@patchew.org; Thu, 12 Oct 2017 05:55:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35439) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001FU-4o for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000HW-Dj for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:15318 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBF-0000DX-1M for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:29 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVn025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:13 +0300 Message-Id: <20171012095319.136610-8-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 07/13] nbd-server: simplify reply transmission 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Send qiov via qio_channel_writev_all instead of calling nbd_write twice with a cork. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- nbd/server.c | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index afc127bbd9..c1bbe8d2d1 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1188,6 +1188,23 @@ void nbd_export_close_all(void) } } =20 +static int coroutine_fn nbd_co_send_iov(NBDClient *client, struct iovec *i= ov, + unsigned niov, Error **errp) +{ + int ret; + + g_assert(qemu_in_coroutine()); + qemu_co_mutex_lock(&client->send_lock); + client->send_coroutine =3D qemu_coroutine_self(); + + ret =3D qio_channel_writev_all(client->ioc, iov, niov, errp) < 0 ? -EI= O : 0; + + client->send_coroutine =3D NULL; + qemu_co_mutex_unlock(&client->send_lock); + + return ret; +} + static inline void set_be_simple_reply(NBDSimpleReply *reply, uint64_t err= or, uint64_t handle) { @@ -1203,36 +1220,17 @@ static int nbd_co_send_simple_reply(NBDClient *clie= nt, size_t len, Error **errp) { - NBDSimpleReply simple_reply; - int ret; - - g_assert(qemu_in_coroutine()); + NBDSimpleReply reply; + struct iovec iov[] =3D { + {.iov_base =3D &reply, .iov_len =3D sizeof(reply)}, + {.iov_base =3D data, .iov_len =3D len} + }; =20 trace_nbd_co_send_simple_reply(handle, error, len); =20 - set_be_simple_reply(&simple_reply, system_errno_to_nbd_errno(error), - handle); - - qemu_co_mutex_lock(&client->send_lock); - client->send_coroutine =3D qemu_coroutine_self(); - - if (!len) { - ret =3D nbd_write(client->ioc, &simple_reply, sizeof(simple_reply)= , NULL); - } else { - qio_channel_set_cork(client->ioc, true); - ret =3D nbd_write(client->ioc, &simple_reply, sizeof(simple_reply)= , NULL); - if (ret =3D=3D 0) { - ret =3D nbd_write(client->ioc, data, len, errp); - if (ret < 0) { - ret =3D -EIO; - } - } - qio_channel_set_cork(client->ioc, false); - } + set_be_simple_reply(&reply, system_errno_to_nbd_errno(error), handle); =20 - client->send_coroutine =3D NULL; - qemu_co_mutex_unlock(&client->send_lock); - return ret; + return nbd_co_send_iov(client, iov, len ? 2 : 1, errp); } =20 /* nbd_co_receive_request --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802547556986.9080922662271; Thu, 12 Oct 2017 03:02:27 -0700 (PDT) Received: from localhost ([::1]:44561 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aJt-0008Rn-NW for importer@patchew.org; Thu, 12 Oct 2017 06:02:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35447) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001Fa-5u for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000Hv-Gi for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:23852 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBF-0000Dd-4F for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:29 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVo025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:14 +0300 Message-Id: <20171012095319.136610-9-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 08/13] nbd: header constants indenting 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Prepare indenting for the following commit. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- include/block/nbd.h | 15 ++++++++------- nbd/nbd-internal.h | 34 +++++++++++++++++----------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 49008980f4..a6df5ce8b5 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -71,13 +71,14 @@ typedef struct NBDSimpleReply { =20 /* Transmission (export) flags: sent from server to client during handshak= e, but describe what will happen during transmission */ -#define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */ -#define NBD_FLAG_READ_ONLY (1 << 1) /* Device is read-only */ -#define NBD_FLAG_SEND_FLUSH (1 << 2) /* Send FLUSH */ -#define NBD_FLAG_SEND_FUA (1 << 3) /* Send FUA (Force Unit Ac= cess) */ -#define NBD_FLAG_ROTATIONAL (1 << 4) /* Use elevator algorithm = - rotational media */ -#define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */ -#define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */ +#define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */ +#define NBD_FLAG_READ_ONLY (1 << 1) /* Device is read-only */ +#define NBD_FLAG_SEND_FLUSH (1 << 2) /* Send FLUSH */ +#define NBD_FLAG_SEND_FUA (1 << 3) /* Send FUA (Force Unit Access= ) */ +#define NBD_FLAG_ROTATIONAL (1 << 4) /* Use elevator algorithm - + rotational media */ +#define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */ +#define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */ =20 /* New-style handshake (global) flags, sent from server to client, and control what will happen during handshake phase. */ diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h index 2d6663de23..11a130d050 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -46,23 +46,23 @@ /* Size of oldstyle negotiation */ #define NBD_OLDSTYLE_NEGOTIATE_SIZE (8 + 8 + 8 + 4 + 124) =20 -#define NBD_REQUEST_MAGIC 0x25609513 -#define NBD_SIMPLE_REPLY_MAGIC 0x67446698 -#define NBD_OPTS_MAGIC 0x49484156454F5054LL -#define NBD_CLIENT_MAGIC 0x0000420281861253LL -#define NBD_REP_MAGIC 0x0003e889045565a9LL - -#define NBD_SET_SOCK _IO(0xab, 0) -#define NBD_SET_BLKSIZE _IO(0xab, 1) -#define NBD_SET_SIZE _IO(0xab, 2) -#define NBD_DO_IT _IO(0xab, 3) -#define NBD_CLEAR_SOCK _IO(0xab, 4) -#define NBD_CLEAR_QUE _IO(0xab, 5) -#define NBD_PRINT_DEBUG _IO(0xab, 6) -#define NBD_SET_SIZE_BLOCKS _IO(0xab, 7) -#define NBD_DISCONNECT _IO(0xab, 8) -#define NBD_SET_TIMEOUT _IO(0xab, 9) -#define NBD_SET_FLAGS _IO(0xab, 10) +#define NBD_REQUEST_MAGIC 0x25609513 +#define NBD_SIMPLE_REPLY_MAGIC 0x67446698 +#define NBD_OPTS_MAGIC 0x49484156454F5054LL +#define NBD_CLIENT_MAGIC 0x0000420281861253LL +#define NBD_REP_MAGIC 0x0003e889045565a9LL + +#define NBD_SET_SOCK _IO(0xab, 0) +#define NBD_SET_BLKSIZE _IO(0xab, 1) +#define NBD_SET_SIZE _IO(0xab, 2) +#define NBD_DO_IT _IO(0xab, 3) +#define NBD_CLEAR_SOCK _IO(0xab, 4) +#define NBD_CLEAR_QUE _IO(0xab, 5) +#define NBD_PRINT_DEBUG _IO(0xab, 6) +#define NBD_SET_SIZE_BLOCKS _IO(0xab, 7) +#define NBD_DISCONNECT _IO(0xab, 8) +#define NBD_SET_TIMEOUT _IO(0xab, 9) +#define NBD_SET_FLAGS _IO(0xab, 10) =20 /* NBD errors are based on errno numbers, so there is a 1:1 mapping, * but only a limited set of errno values is specified in the protocol. --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) 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=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802136853503.3363605492832; Thu, 12 Oct 2017 02:55:36 -0700 (PDT) Received: from localhost ([::1]:44516 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aDE-0002UB-1m for importer@patchew.org; Thu, 12 Oct 2017 05:55:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35459) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001Fd-8Q for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000Hl-G8 for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:21884 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBE-0000DU-Vf for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:29 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVp025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:15 +0300 Message-Id: <20171012095319.136610-10-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 09/13] nbd: Minimal structured read for server 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Minimal implementation of structured read: one structured reply chunk, no segmentation. Minimal structured error implementation: no text message. Support DF flag, but just ignore it, as there is no segmentation any way. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- include/block/nbd.h | 33 +++++++++++++++++ nbd/nbd-internal.h | 1 + nbd/server.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++= ---- 3 files changed, 128 insertions(+), 6 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index a6df5ce8b5..dd261f66f0 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -69,6 +69,25 @@ typedef struct NBDSimpleReply { uint64_t handle; } QEMU_PACKED NBDSimpleReply; =20 +typedef struct NBDStructuredReplyChunk { + uint32_t magic; /* NBD_STRUCTURED_REPLY_MAGIC */ + uint16_t flags; /* combination of NBD_SREP_FLAG_* */ + uint16_t type; /* NBD_SREP_TYPE_* */ + uint64_t handle; /* request handle */ + uint32_t length; /* length of payload */ +} QEMU_PACKED NBDStructuredReplyChunk; + +typedef struct NBDStructuredRead { + NBDStructuredReplyChunk h; + uint64_t offset; +} QEMU_PACKED NBDStructuredRead; + +typedef struct NBDStructuredError { + NBDStructuredReplyChunk h; + uint32_t error; + uint16_t message_length; +} QEMU_PACKED NBDStructuredError; + /* Transmission (export) flags: sent from server to client during handshak= e, but describe what will happen during transmission */ #define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */ @@ -79,6 +98,7 @@ typedef struct NBDSimpleReply { rotational media */ #define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */ #define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */ +#define NBD_FLAG_SEND_DF (1 << 7) /* Send DF (Do not Fragment) */ =20 /* New-style handshake (global) flags, sent from server to client, and control what will happen during handshake phase. */ @@ -125,6 +145,7 @@ typedef struct NBDSimpleReply { /* Request flags, sent from client to server during transmission phase */ #define NBD_CMD_FLAG_FUA (1 << 0) /* 'force unit access' during wri= te */ #define NBD_CMD_FLAG_NO_HOLE (1 << 1) /* don't punch hole on zero run */ +#define NBD_CMD_FLAG_DF (1 << 2) /* don't fragment structured read= */ =20 /* Supported request types */ enum { @@ -149,6 +170,18 @@ enum { * aren't overflowing some other buffer. */ #define NBD_MAX_NAME_SIZE 256 =20 +/* Structured reply flags */ +#define NBD_SREP_FLAG_DONE (1 << 0) /* This reply-chunk is last */ + +/* Structured reply types */ +#define NBD_SREP_ERR(value) ((1 << 15) | (value)) + +#define NBD_SREP_TYPE_NONE 0 +#define NBD_SREP_TYPE_OFFSET_DATA 1 +#define NBD_SREP_TYPE_OFFSET_HOLE 2 +#define NBD_SREP_TYPE_ERROR NBD_SREP_ERR(1) +#define NBD_SREP_TYPE_ERROR_OFFSET NBD_SREP_ERR(2) + /* Details collected by NBD_OPT_EXPORT_NAME and NBD_OPT_GO */ struct NBDExportInfo { /* Set by client before nbd_receive_negotiate() */ diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h index 11a130d050..beb30a7a3e 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -48,6 +48,7 @@ =20 #define NBD_REQUEST_MAGIC 0x25609513 #define NBD_SIMPLE_REPLY_MAGIC 0x67446698 +#define NBD_STRUCTURED_REPLY_MAGIC 0x668e33ef #define NBD_OPTS_MAGIC 0x49484156454F5054LL #define NBD_CLIENT_MAGIC 0x0000420281861253LL #define NBD_REP_MAGIC 0x0003e889045565a9LL diff --git a/nbd/server.c b/nbd/server.c index c1bbe8d2d1..502873b645 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -98,6 +98,8 @@ struct NBDClient { QTAILQ_ENTRY(NBDClient) next; int nb_requests; bool closing; + + bool structured_reply; }; =20 /* That's all folks */ @@ -760,6 +762,20 @@ static int nbd_negotiate_options(NBDClient *client, ui= nt16_t myflags, return ret; } break; + + case NBD_OPT_STRUCTURED_REPLY: + if (client->structured_reply) { + error_setg(errp, "Double negotiation of structured rep= ly"); + return -EINVAL; + } + ret =3D nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK, o= ption, + errp); + if (ret < 0) { + return ret; + } + client->structured_reply =3D true; + break; + default: if (nbd_drop(client->ioc, length, errp) < 0) { return -EIO; @@ -1233,6 +1249,61 @@ static int nbd_co_send_simple_reply(NBDClient *clien= t, return nbd_co_send_iov(client, iov, len ? 2 : 1, errp); } =20 +static inline void set_be_chunk(NBDStructuredReplyChunk *chunk, uint16_t f= lags, + uint16_t type, uint64_t handle, uint32_t l= ength) +{ + stl_be_p(&chunk->magic, NBD_STRUCTURED_REPLY_MAGIC); + stw_be_p(&chunk->flags, flags); + stw_be_p(&chunk->type, type); + stq_be_p(&chunk->handle, handle); + stl_be_p(&chunk->length, length); +} + +static inline int coroutine_fn nbd_co_send_buf(NBDClient *client, void *bu= f, + size_t size, Error **errp) +{ + struct iovec iov[] =3D { + {.iov_base =3D buf, .iov_len =3D size} + }; + + return nbd_co_send_iov(client, iov, 1, errp); +} + +static int coroutine_fn nbd_co_send_structured_read(NBDClient *client, + uint64_t handle, + uint64_t offset, + void *data, + size_t size, + Error **errp) +{ + NBDStructuredRead chunk; + struct iovec iov[] =3D { + {.iov_base =3D &chunk, .iov_len =3D sizeof(chunk)}, + {.iov_base =3D data, .iov_len =3D size} + }; + + set_be_chunk(&chunk.h, NBD_SREP_FLAG_DONE, NBD_SREP_TYPE_OFFSET_DATA, + handle, sizeof(chunk) - sizeof(chunk.h) + size); + stq_be_p(&chunk.offset, offset); + + return nbd_co_send_iov(client, iov, 2, errp); +} + +static int coroutine_fn nbd_co_send_structured_error(NBDClient *client, + uint64_t handle, + uint32_t error, + Error **errp) +{ + NBDStructuredError chunk; + + set_be_chunk(&chunk.h, NBD_SREP_FLAG_DONE, NBD_SREP_TYPE_ERROR, handle, + sizeof(chunk) - sizeof(chunk.h)); + stl_be_p(&chunk.error, error); + stw_be_p(&chunk.message_length, 0); + + return nbd_co_send_buf(client, &chunk, sizeof(chunk), errp); +} + /* nbd_co_receive_request * Collect a client request. Return 0 if request looks valid, -EIO to drop * connection right away, and any other negative value to report an error = to @@ -1304,10 +1375,17 @@ static int nbd_co_receive_request(NBDRequestData *r= eq, NBDRequest *request, (uint64_t)client->exp->size); return request->type =3D=3D NBD_CMD_WRITE ? -ENOSPC : -EINVAL; } - if (request->flags & ~(NBD_CMD_FLAG_FUA | NBD_CMD_FLAG_NO_HOLE)) { + if (request->flags & ~(NBD_CMD_FLAG_FUA | NBD_CMD_FLAG_NO_HOLE | + NBD_CMD_FLAG_DF)) + { error_setg(errp, "unsupported flags (got 0x%x)", request->flags); return -EINVAL; } + if (request->type !=3D NBD_CMD_READ && (request->flags & NBD_CMD_FLAG_= DF)) { + error_setg(errp, "DF flag used with command %d (%s) which is not R= EAD", + request->type, nbd_cmd_lookup(request->type)); + return -EINVAL; + } if (request->type !=3D NBD_CMD_WRITE_ZEROES && (request->flags & NBD_CMD_FLAG_NO_HOLE)) { error_setg(errp, "unexpected flags (got 0x%x)", request->flags); @@ -1374,7 +1452,6 @@ static coroutine_fn void nbd_trip(void *opaque) } =20 reply_data_len =3D request.len; - break; case NBD_CMD_WRITE: if (exp->nbdflags & NBD_FLAG_READ_ONLY) { @@ -1447,10 +1524,21 @@ reply: local_err =3D NULL; } =20 - if (nbd_co_send_simple_reply(req->client, request.handle, - ret < 0 ? -ret : 0, - req->data, reply_data_len, &local_err) < = 0) - { + if (client->structured_reply && request.type =3D=3D NBD_CMD_READ) { + if (ret < 0) { + ret =3D nbd_co_send_structured_error(req->client, request.hand= le, + -ret, &local_err); + } else { + ret =3D nbd_co_send_structured_read(req->client, request.handl= e, + request.from, req->data, + reply_data_len, &local_err); + } + } else { + ret =3D nbd_co_send_simple_reply(req->client, request.handle, + ret < 0 ? -ret : 0, + req->data, reply_data_len, &local_e= rr); + } + if (ret < 0) { error_prepend(&local_err, "Failed to send reply: "); goto disconnect; } --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802137507725.9617447592555; Thu, 12 Oct 2017 02:55:37 -0700 (PDT) Received: from localhost ([::1]:44517 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aDE-0002Vy-W5 for importer@patchew.org; Thu, 12 Oct 2017 05:55:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35438) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001FT-4E for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000IA-KM for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:48462 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBF-0000DW-6J for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:29 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVq025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:16 +0300 Message-Id: <20171012095319.136610-11-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 10/13] nbd/client: refactor nbd_receive_starttls 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Split out nbd_receive_simple_option to be reused for structured reply option. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- nbd/client.c | 64 ++++++++++++++++++++++++++++++++++++++++------------= ---- nbd/trace-events | 7 ++++--- 2 files changed, 50 insertions(+), 21 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index cd5a2c80ac..c8702a80b1 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -540,35 +540,63 @@ static int nbd_receive_query_exports(QIOChannel *ioc, } } =20 -static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, - QCryptoTLSCreds *tlscreds, - const char *hostname, Error **errp) +/* nbd_request_simple_option + * return 1 for successful negotiation, + * 0 if operation is unsupported, + * -1 with errp set for any other error + */ +static int nbd_request_simple_option(QIOChannel *ioc, int opt, Error **err= p) { nbd_opt_reply reply; - QIOChannelTLS *tioc; - struct NBDTLSHandshakeData data =3D { 0 }; =20 - trace_nbd_receive_starttls_request(); - if (nbd_send_option_request(ioc, NBD_OPT_STARTTLS, 0, NULL, errp) < 0)= { - return NULL; + trace_nbd_receive_simple_option_request(opt, nbd_opt_lookup(opt)); + if (nbd_send_option_request(ioc, opt, 0, NULL, errp) < 0) { + return -1; } =20 - trace_nbd_receive_starttls_reply(); - if (nbd_receive_option_reply(ioc, NBD_OPT_STARTTLS, &reply, errp) < 0)= { - return NULL; + trace_nbd_receive_simple_option_reply(opt, nbd_opt_lookup(opt)); + if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) { + return -1; } =20 - if (reply.type !=3D NBD_REP_ACK) { - error_setg(errp, "Server rejected request to start TLS %" PRIx32, - reply.type); + if (reply.length !=3D 0) { + error_setg(errp, "Option %d ('%s') response length is %" PRIu32 + " (it should be zero)", opt, nbd_opt_lookup(opt), + reply.length); nbd_send_opt_abort(ioc); - return NULL; + return -1; } =20 - if (reply.length !=3D 0) { - error_setg(errp, "Start TLS response was not zero %" PRIu32, - reply.length); + if (reply.type =3D=3D NBD_REP_ERR_UNSUP) { + return 0; + } + + if (reply.type !=3D NBD_REP_ACK) { + error_setg(errp, "Server rejected request for option %d (%s) " + "with reply %" PRIx32 " (%s)", opt, nbd_opt_lookup(opt), + reply.type, nbd_rep_lookup(reply.type)); nbd_send_opt_abort(ioc); + return -1; + } + + trace_nbd_receive_simple_option_approved(opt, nbd_opt_lookup(opt)); + return 1; +} + +static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, + QCryptoTLSCreds *tlscreds, + const char *hostname, Error **errp) +{ + int ret; + QIOChannelTLS *tioc; + struct NBDTLSHandshakeData data =3D { 0 }; + + ret =3D nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, errp); + if (ret <=3D 0) { + if (ret =3D=3D 0) { + error_setg(errp, "Server don't support STARTTLS option"); + nbd_send_opt_abort(ioc); + } return NULL; } =20 diff --git a/nbd/trace-events b/nbd/trace-events index c5f2d97be2..3235922370 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -9,9 +9,10 @@ nbd_opt_go_info_unknown(int info, const char *name) "Ignor= ing unknown info %d (% nbd_opt_go_info_block_size(uint32_t minimum, uint32_t preferred, uint32_t = maximum) "Block sizes are 0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32 nbd_receive_query_exports_start(const char *wantname) "Querying export lis= t for '%s'" nbd_receive_query_exports_success(const char *wantname) "Found desired exp= ort name '%s'" -nbd_receive_starttls_request(void) "Requesting TLS from server" -nbd_receive_starttls_reply(void) "Getting TLS reply from server" -nbd_receive_starttls_new_client(void) "TLS request approved, setting up TL= S" +nbd_receive_simple_option_request(int opt, const char *name) "Requesting o= ption %d (%s) from server" +nbd_receive_simple_option_reply(int opt, const char *name) "Getting reply = for option %d (%s) from server" +nbd_receive_simple_option_approved(int opt, const char *name) "Option %d (= %s) approved" +nbd_receive_starttls_new_client(void) "Setting up TLS" nbd_receive_starttls_tls_handshake(void) "Starting TLS handshake" 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.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 150780246414994.14948977848735; Thu, 12 Oct 2017 03:01:04 -0700 (PDT) Received: from localhost ([::1]:44546 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aIK-00075a-Iq for importer@patchew.org; Thu, 12 Oct 2017 06:00:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35457) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001Fc-7T for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000IX-SS for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:49086 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBF-0000DV-F5 for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:29 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVr025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:17 +0300 Message-Id: <20171012095319.136610-12-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 11/13] nbd: share some nbd entities to be reused in block/nbd-client.c 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Vladimir Sementsov-Ogievskiy --- include/block/nbd.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ nbd/nbd-internal.h | 25 ------------------------- nbd/client.c | 32 -------------------------------- 3 files changed, 48 insertions(+), 57 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index dd261f66f0..09e4592971 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -77,6 +77,9 @@ typedef struct NBDStructuredReplyChunk { uint32_t length; /* length of payload */ } QEMU_PACKED NBDStructuredReplyChunk; =20 +#define NBD_SIMPLE_REPLY_MAGIC 0x67446698 +#define NBD_STRUCTURED_REPLY_MAGIC 0x668e33ef + typedef struct NBDStructuredRead { NBDStructuredReplyChunk h; uint64_t offset; @@ -182,6 +185,40 @@ enum { #define NBD_SREP_TYPE_ERROR NBD_SREP_ERR(1) #define NBD_SREP_TYPE_ERROR_OFFSET NBD_SREP_ERR(2) =20 +/* NBD errors are based on errno numbers, so there is a 1:1 mapping, + * but only a limited set of errno values is specified in the protocol. + * Everything else is squashed to EINVAL. + */ +#define NBD_SUCCESS 0 +#define NBD_EPERM 1 +#define NBD_EIO 5 +#define NBD_ENOMEM 12 +#define NBD_EINVAL 22 +#define NBD_ENOSPC 28 +#define NBD_ESHUTDOWN 108 + +static inline int nbd_errno_to_system_errno(int err) +{ + switch (err) { + case NBD_SUCCESS: + return 0; + case NBD_EPERM: + return EPERM; + case NBD_EIO: + return EIO; + case NBD_ENOMEM: + return ENOMEM; + case NBD_ENOSPC: + return ENOSPC; + case NBD_ESHUTDOWN: + return ESHUTDOWN; + case NBD_EINVAL: + return EINVAL; + } + + return EINVAL; +} + /* Details collected by NBD_OPT_EXPORT_NAME and NBD_OPT_GO */ struct NBDExportInfo { /* Set by client before nbd_receive_negotiate() */ @@ -235,4 +272,15 @@ void nbd_client_put(NBDClient *client); void nbd_server_start(SocketAddress *addr, const char *tls_creds, Error **errp); =20 +/* nbd_read + * Reads @size bytes from @ioc. Returns 0 on success. + */ +static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size, + Error **errp) +{ + return qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0; +} + +int nbd_drop(QIOChannel *ioc, size_t size, Error **errp); + #endif diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h index beb30a7a3e..970b560d11 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -47,8 +47,6 @@ #define NBD_OLDSTYLE_NEGOTIATE_SIZE (8 + 8 + 8 + 4 + 124) =20 #define NBD_REQUEST_MAGIC 0x25609513 -#define NBD_SIMPLE_REPLY_MAGIC 0x67446698 -#define NBD_STRUCTURED_REPLY_MAGIC 0x668e33ef #define NBD_OPTS_MAGIC 0x49484156454F5054LL #define NBD_CLIENT_MAGIC 0x0000420281861253LL #define NBD_REP_MAGIC 0x0003e889045565a9LL @@ -65,18 +63,6 @@ #define NBD_SET_TIMEOUT _IO(0xab, 9) #define NBD_SET_FLAGS _IO(0xab, 10) =20 -/* NBD errors are based on errno numbers, so there is a 1:1 mapping, - * but only a limited set of errno values is specified in the protocol. - * Everything else is squashed to EINVAL. - */ -#define NBD_SUCCESS 0 -#define NBD_EPERM 1 -#define NBD_EIO 5 -#define NBD_ENOMEM 12 -#define NBD_EINVAL 22 -#define NBD_ENOSPC 28 -#define NBD_ESHUTDOWN 108 - /* nbd_read_eof * Tries to read @size bytes from @ioc. * Returns 1 on success @@ -96,15 +82,6 @@ static inline int nbd_read_eof(QIOChannel *ioc, void *bu= ffer, size_t size, return ret; } =20 -/* nbd_read - * Reads @size bytes from @ioc. Returns 0 on success. - */ -static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size, - Error **errp) -{ - return qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0; -} - /* nbd_write * Writes @size bytes to @ioc. Returns 0 on success. */ @@ -128,6 +105,4 @@ const char *nbd_rep_lookup(uint32_t rep); const char *nbd_info_lookup(uint16_t info); const char *nbd_cmd_lookup(uint16_t info); =20 -int nbd_drop(QIOChannel *ioc, size_t size, Error **errp); - #endif diff --git a/nbd/client.c b/nbd/client.c index c8702a80b1..f0f3075569 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -22,38 +22,6 @@ #include "trace.h" #include "nbd-internal.h" =20 -static int nbd_errno_to_system_errno(int err) -{ - int ret; - switch (err) { - case NBD_SUCCESS: - ret =3D 0; - break; - case NBD_EPERM: - ret =3D EPERM; - break; - case NBD_EIO: - ret =3D EIO; - break; - case NBD_ENOMEM: - ret =3D ENOMEM; - break; - case NBD_ENOSPC: - ret =3D ENOSPC; - break; - case NBD_ESHUTDOWN: - ret =3D ESHUTDOWN; - break; - default: - trace_nbd_unknown_error(err); - /* fallthrough */ - case NBD_EINVAL: - ret =3D EINVAL; - break; - } - return ret; -} - /* Definitions for opaque data types */ =20 static QTAILQ_HEAD(, NBDExport) exports =3D QTAILQ_HEAD_INITIALIZER(export= s); --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802619151287.0850014870191; Thu, 12 Oct 2017 03:03:39 -0700 (PDT) Received: from localhost ([::1]:44563 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aL4-00011n-6w for importer@patchew.org; Thu, 12 Oct 2017 06:03:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35443) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBI-0001FX-5f for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000I3-JH for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:8192 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBF-0000De-2Q for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:29 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVs025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:18 +0300 Message-Id: <20171012095319.136610-13-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 12/13] nbd/client: prepare nbd_receive_reply for structured reply 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" In following patch nbd_receive_reply will be used both for simple and structured reply header receiving. NBDReply is altered into union of simple reply header and structured reply chunk header, simple error translation moved to block/nbd-client to be consistent with further structured reply error translation. Signed-off-by: Vladimir Sementsov-Ogievskiy --- include/block/nbd.h | 30 ++++++++++++---- block/nbd-client.c | 8 +++-- nbd/client.c | 102 +++++++++++++++++++++++++++++++++++++++++-------= ---- nbd/trace-events | 3 +- 4 files changed, 113 insertions(+), 30 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 09e4592971..1ef8c8897f 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -57,12 +57,6 @@ struct NBDRequest { }; typedef struct NBDRequest NBDRequest; =20 -struct NBDReply { - uint64_t handle; - uint32_t error; -}; -typedef struct NBDReply NBDReply; - typedef struct NBDSimpleReply { uint32_t magic; /* NBD_SIMPLE_REPLY_MAGIC */ uint32_t error; @@ -77,9 +71,33 @@ typedef struct NBDStructuredReplyChunk { uint32_t length; /* length of payload */ } QEMU_PACKED NBDStructuredReplyChunk; =20 +typedef union NBDReply { + NBDSimpleReply simple; + NBDStructuredReplyChunk structured; + struct { + /* @magic and @handle fields have the same offset and size both in + * simple reply and structured reply chunk, so let them be accessi= ble + * without ".simple." or ".structured." specification + */ + uint32_t magic; + uint32_t _skip; + uint64_t handle; + } QEMU_PACKED; +} NBDReply; + #define NBD_SIMPLE_REPLY_MAGIC 0x67446698 #define NBD_STRUCTURED_REPLY_MAGIC 0x668e33ef =20 +static inline bool nbd_reply_is_simple(NBDReply *reply) +{ + return reply->magic =3D=3D NBD_SIMPLE_REPLY_MAGIC; +} + +static inline bool nbd_reply_is_structured(NBDReply *reply) +{ + return reply->magic =3D=3D NBD_STRUCTURED_REPLY_MAGIC; +} + typedef struct NBDStructuredRead { NBDStructuredReplyChunk h; uint64_t offset; diff --git a/block/nbd-client.c b/block/nbd-client.c index c0683c3c83..58493b7ac4 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -92,7 +92,9 @@ static coroutine_fn void nbd_read_reply_entry(void *opaqu= e) i =3D HANDLE_TO_INDEX(s, s->reply.handle); if (i >=3D MAX_NBD_REQUESTS || !s->requests[i].coroutine || - !s->requests[i].receiving) { + !s->requests[i].receiving || + nbd_reply_is_structured(&s->reply)) + { break; } =20 @@ -194,8 +196,8 @@ static int nbd_co_receive_reply(NBDClientSession *s, ret =3D -EIO; } else { assert(s->reply.handle =3D=3D handle); - ret =3D -s->reply.error; - if (qiov && s->reply.error =3D=3D 0) { + ret =3D -nbd_errno_to_system_errno(s->reply.simple.error); + if (qiov && ret =3D=3D 0) { if (qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov, NULL) < 0) { ret =3D -EIO; diff --git a/nbd/client.c b/nbd/client.c index f0f3075569..a38e1a7d8e 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -910,6 +910,57 @@ int nbd_send_request(QIOChannel *ioc, NBDRequest *requ= est) return nbd_write(ioc, buf, sizeof(buf), NULL); } =20 +/* nbd_receive_simple_reply + * Read simple reply except magic field (which should be already read). + * Payload is not read (payload is possible for CMD_READ, but here we even + * don't know whether it take place or not). + */ +static int nbd_receive_simple_reply(QIOChannel *ioc, NBDSimpleReply *reply, + Error **errp) +{ + int ret; + + assert(reply->magic =3D=3D NBD_SIMPLE_REPLY_MAGIC); + + ret =3D nbd_read(ioc, (uint8_t *)reply + sizeof(reply->magic), + sizeof(*reply) - sizeof(reply->magic), errp); + if (ret < 0) { + return ret; + } + + be32_to_cpus(&reply->error); + be64_to_cpus(&reply->handle); + + return 0; +} + +/* nbd_receive_structured_reply_chunk + * Read structured reply chunk except magic field (which should be already + * read). + * Payload is not read. + */ +static int nbd_receive_structured_reply_chunk(QIOChannel *ioc, + NBDStructuredReplyChunk *chu= nk, + Error **errp) +{ + int ret; + + assert(chunk->magic =3D=3D NBD_STRUCTURED_REPLY_MAGIC); + + ret =3D nbd_read(ioc, (uint8_t *)chunk + sizeof(chunk->magic), + sizeof(*chunk) - sizeof(chunk->magic), errp); + if (ret < 0) { + return ret; + } + + be16_to_cpus(&chunk->flags); + be16_to_cpus(&chunk->type); + be64_to_cpus(&chunk->handle); + be32_to_cpus(&chunk->length); + + return 0; +} + /* nbd_receive_reply * Returns 1 on success * 0 on eof, when no data was read (errp is not set) @@ -917,37 +968,48 @@ int nbd_send_request(QIOChannel *ioc, NBDRequest *req= uest) */ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp) { - uint8_t buf[NBD_REPLY_SIZE]; - uint32_t magic; int ret; =20 - ret =3D nbd_read_eof(ioc, buf, sizeof(buf), errp); + ret =3D nbd_read_eof(ioc, &reply->magic, sizeof(reply->magic), errp); if (ret <=3D 0) { return ret; } =20 - /* Reply - [ 0 .. 3] magic (NBD_SIMPLE_REPLY_MAGIC) - [ 4 .. 7] error (0 =3D=3D no error) - [ 7 .. 15] handle - */ + be32_to_cpus(&reply->magic); =20 - magic =3D ldl_be_p(buf); - reply->error =3D ldl_be_p(buf + 4); - reply->handle =3D ldq_be_p(buf + 8); + switch (reply->magic) { + case NBD_SIMPLE_REPLY_MAGIC: + ret =3D nbd_receive_simple_reply(ioc, &reply->simple, errp); + if (ret < 0) { + break; + } =20 - reply->error =3D nbd_errno_to_system_errno(reply->error); + if (reply->simple.error =3D=3D NBD_ESHUTDOWN) { + /* This works even on mingw which lacks a native ESHUTDOWN */ + error_setg(errp, "server shutting down"); + return -EINVAL; + } =20 - if (reply->error =3D=3D ESHUTDOWN) { - /* This works even on mingw which lacks a native ESHUTDOWN */ - error_setg(errp, "server shutting down"); + trace_nbd_receive_simple_reply( + nbd_errno_to_system_errno(reply->simple.error), + reply->simple.handle); + break; + case NBD_STRUCTURED_REPLY_MAGIC: + ret =3D nbd_receive_structured_reply_chunk(ioc, &reply->structured= , errp); + if (ret < 0) { + break; + } + trace_nbd_receive_structured_reply_chunk(reply->structured.flags, + reply->structured.type, + reply->structured.handle, + reply->structured.length); + break; + default: + error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", reply->magic= ); return -EINVAL; } - trace_nbd_receive_reply(magic, reply->error, reply->handle); - - if (magic !=3D NBD_SIMPLE_REPLY_MAGIC) { - error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic); - return -EINVAL; + if (ret < 0) { + return ret; } =20 return 1; diff --git a/nbd/trace-events b/nbd/trace-events index 3235922370..c5b24f6715 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -30,7 +30,8 @@ nbd_client_loop_ret(int ret, const char *error) "NBD loop= returned %d: %s" nbd_client_clear_queue(void) "Clearing NBD queue" nbd_client_clear_socket(void) "Clearing NBD socket" nbd_send_request(uint64_t from, uint32_t len, uint64_t handle, uint16_t fl= ags, uint16_t type, const char *name) "Sending request to server: { .from = =3D %" PRIu64", .len =3D %" PRIu32 ", .handle =3D %" PRIu64 ", .flags =3D 0= x%" PRIx16 ", .type =3D %" PRIu16 " (%s) }" -nbd_receive_reply(uint32_t magic, int32_t error, uint64_t handle) "Got rep= ly: { magic =3D 0x%" PRIx32 ", .error =3D % " PRId32 ", handle =3D %" PRIu6= 4" }" +nbd_receive_simple_reply(int32_t error, uint64_t handle) "Got simple reply= : { error =3D % " PRId32 ", handle =3D %" PRIu64" }" +nbd_receive_structured_reply_chunk(uint16_t flags, uint16_t type, uint64_t= handle, uint32_t length) "Got structured reply chunk: { flags =3D 0x%" PRI= x16 ", type =3D %d, handle =3D %" PRIu64 ", length =3D %" PRIu32 " }" =20 # nbd/server.c nbd_negotiate_send_rep_len(uint32_t opt, const char *optname, uint32_t typ= e, const char *typename, uint32_t len) "Reply opt=3D0x%" PRIx32 " (%s), typ= e=3D0x%" PRIx32 " (%s), len=3D%" PRIu32 --=20 2.11.1 From nobody Fri Apr 19 13:13:18 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507802624827314.4414968618112; Thu, 12 Oct 2017 03:03:44 -0700 (PDT) Received: from localhost ([::1]:44565 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aL7-00015l-F8 for importer@patchew.org; Thu, 12 Oct 2017 06:03:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35519) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2aBL-0001Gq-Ee for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2aBF-0000Hb-Eg for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:35 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:18428 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2aBE-0000DY-Tt for qemu-devel@nongnu.org; Thu, 12 Oct 2017 05:53:29 -0400 Received: from kvm.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9C9rJVt025088; Thu, 12 Oct 2017 12:53:21 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 12:53:19 +0300 Message-Id: <20171012095319.136610-14-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171012095319.136610-1-vsementsov@virtuozzo.com> References: <20171012095319.136610-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v3 13/13] nbd: Minimal structured read for client 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: kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Minimal implementation: for structured error only error_report error message. Signed-off-by: Vladimir Sementsov-Ogievskiy --- include/block/nbd.h | 6 + block/nbd-client.c | 395 ++++++++++++++++++++++++++++++++++++++++++++++++= ---- nbd/client.c | 7 + 3 files changed, 379 insertions(+), 29 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 1ef8c8897f..e3350b67a4 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -203,6 +203,11 @@ enum { #define NBD_SREP_TYPE_ERROR NBD_SREP_ERR(1) #define NBD_SREP_TYPE_ERROR_OFFSET NBD_SREP_ERR(2) =20 +static inline bool nbd_srep_type_is_error(int type) +{ + return type & (1 << 15); +} + /* NBD errors are based on errno numbers, so there is a 1:1 mapping, * but only a limited set of errno values is specified in the protocol. * Everything else is squashed to EINVAL. @@ -241,6 +246,7 @@ static inline int nbd_errno_to_system_errno(int err) struct NBDExportInfo { /* Set by client before nbd_receive_negotiate() */ bool request_sizes; + bool structured_reply; /* Set by server results during nbd_receive_negotiate() */ uint64_t size; uint16_t flags; diff --git a/block/nbd-client.c b/block/nbd-client.c index 58493b7ac4..4d08cf3fd3 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -29,6 +29,7 @@ =20 #include "qemu/osdep.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include "nbd-client.h" =20 #define HANDLE_TO_INDEX(bs, handle) ((handle) ^ (uint64_t)(intptr_t)(bs)) @@ -93,7 +94,7 @@ static coroutine_fn void nbd_read_reply_entry(void *opaqu= e) if (i >=3D MAX_NBD_REQUESTS || !s->requests[i].coroutine || !s->requests[i].receiving || - nbd_reply_is_structured(&s->reply)) + (nbd_reply_is_structured(&s->reply) && !s->info.structured_rep= ly)) { break; } @@ -181,75 +182,406 @@ err: return rc; } =20 -static int nbd_co_receive_reply(NBDClientSession *s, - uint64_t handle, - QEMUIOVector *qiov) +static inline void payload_advance16(uint8_t **payload, uint16_t **ptr) +{ + *ptr =3D (uint16_t *)*payload; + be16_to_cpus(*ptr); + *payload +=3D sizeof(**ptr); +} + +static inline void payload_advance32(uint8_t **payload, uint32_t **ptr) +{ + *ptr =3D (uint32_t *)*payload; + be32_to_cpus(*ptr); + *payload +=3D sizeof(**ptr); +} + +static inline void payload_advance64(uint8_t **payload, uint64_t **ptr) +{ + *ptr =3D (uint64_t *)*payload; + be64_to_cpus(*ptr); + *payload +=3D sizeof(**ptr); +} + +static int nbd_parse_offset_hole_payload(NBDStructuredReplyChunk *chunk, + uint8_t *payload, QEMUIOVector *q= iov) +{ + uint64_t *offset; + uint32_t *hole_size; + + if (chunk->length !=3D sizeof(*offset) + sizeof(*hole_size)) { + return -EINVAL; + } + + payload_advance64(&payload, &offset); + payload_advance32(&payload, &hole_size); + + if (*offset + *hole_size > qiov->size) { + return -EINVAL; + } + + qemu_iovec_memset(qiov, *offset, 0, *hole_size); + + return 0; +} + +static int nbd_parse_error_payload(NBDStructuredReplyChunk *chunk, + uint8_t *payload, int *request_ret) +{ + uint32_t *error; + uint16_t *message_size; + + assert(chunk->type & (1 << 15)); + + if (chunk->length < sizeof(error) + sizeof(message_size)) { + return -EINVAL; + } + + payload_advance32(&payload, &error); + payload_advance16(&payload, &message_size); + + error_report("%.*s", *message_size, payload); + + /* TODO add special case for ERROR_OFFSET */ + + *request_ret =3D nbd_errno_to_system_errno(*error); + + return 0; +} + +static int nbd_co_receive_offset_data_payload(NBDClientSession *s, + QEMUIOVector *qiov) +{ + QEMUIOVector sub_qiov; + uint64_t offset; + size_t data_size; + int ret; + NBDStructuredReplyChunk *chunk =3D &s->reply.structured; + + assert(nbd_reply_is_structured(&s->reply)); + + if (chunk->length < sizeof(offset)) { + return -EINVAL; + } + + if (nbd_read(s->ioc, &offset, sizeof(offset), NULL) < 0) { + return -EIO; + } + be64_to_cpus(&offset); + + data_size =3D chunk->length - sizeof(offset); + if (offset + data_size > qiov->size) { + return -EINVAL; + } + + qemu_iovec_init(&sub_qiov, qiov->niov); + qemu_iovec_concat(&sub_qiov, qiov, offset, data_size); + ret =3D qio_channel_readv_all(s->ioc, sub_qiov.iov, sub_qiov.niov, NUL= L); + qemu_iovec_destroy(&sub_qiov); + + return ret < 0 ? -EIO : 0; +} + +#define NBD_MAX_MALLOC_PAYLOAD 1000 +static int nbd_co_receive_structured_payload(NBDClientSession *s, + void **payload) +{ + int ret; + uint32_t len; + + assert(nbd_reply_is_structured(&s->reply)); + + len =3D s->reply.structured.length; + + if (len =3D=3D 0) { + return 0; + } + + if (payload =3D=3D NULL) { + return -EINVAL; + } + + if (len > NBD_MAX_MALLOC_PAYLOAD) { + return -EINVAL; + } + + *payload =3D qemu_memalign(8, len); + ret =3D nbd_read(s->ioc, *payload, len, NULL); + if (ret < 0) { + qemu_vfree(*payload); + *payload =3D NULL; + return ret; + } + + return 0; +} + +/* nbd_co_do_receive_one_chunk + * for simple reply: + * set request_ret to received reply error + * if qiov is not NULL: read payload to @qiov + * for structured reply chunk: + * if error chunk: read payload, set @request_ret, do not set @payload + * else if offset_data chunk: read payload data to @qiov, do not set @pa= yload + * else: read payload to @payload + */ +static int nbd_co_do_receive_one_chunk(NBDClientSession *s, uint64_t handl= e, + bool only_structured, int *request_= ret, + QEMUIOVector *qiov, void **payload) { int ret; int i =3D HANDLE_TO_INDEX(s, handle); + void *local_payload =3D NULL; + + if (payload) { + *payload =3D NULL; + } + *request_ret =3D 0; =20 /* Wait until we're woken up by nbd_read_reply_entry. */ s->requests[i].receiving =3D true; qemu_coroutine_yield(); s->requests[i].receiving =3D false; if (!s->ioc || s->quit) { - ret =3D -EIO; - } else { - assert(s->reply.handle =3D=3D handle); - ret =3D -nbd_errno_to_system_errno(s->reply.simple.error); - if (qiov && ret =3D=3D 0) { - if (qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov, - NULL) < 0) { - ret =3D -EIO; - s->quit =3D true; - } + return -EIO; + } + + assert(s->reply.handle =3D=3D handle); + + if (nbd_reply_is_simple(&s->reply)) { + if (only_structured) { + return -EINVAL; } =20 - /* Tell the read handler to read another header. */ - s->reply.handle =3D 0; + *request_ret =3D -nbd_errno_to_system_errno(s->reply.simple.error); + if (*request_ret < 0 || !qiov) { + return 0; + } + + return qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov, + NULL) < 0 ? -EIO : 0; + } + + /* handle structured reply chunk */ + assert(s->info.structured_reply); + + if (s->reply.structured.type =3D=3D NBD_SREP_TYPE_NONE) { + return 0; + } + + if (s->reply.structured.type =3D=3D NBD_SREP_TYPE_OFFSET_DATA) { + if (!qiov) { + return -EINVAL; + } + + return nbd_co_receive_offset_data_payload(s, qiov); + } + + if (nbd_srep_type_is_error(s->reply.structured.type)) { + payload =3D &local_payload; + } + + ret =3D nbd_co_receive_structured_payload(s, payload); + if (ret < 0) { + return ret; } =20 - s->requests[i].coroutine =3D NULL; + if (nbd_srep_type_is_error(s->reply.structured.type)) { + ret =3D nbd_parse_error_payload(&s->reply.structured, local_payloa= d, + request_ret); + qemu_vfree(local_payload); + return ret; + } + + return 0; +} + +/* nbd_co_receive_one_chunk + * Read reply, wake up read_reply_co and set s->quit if needed. + * Return value is a fatal error code or normal nbd reply error code + */ +static int nbd_co_receive_one_chunk(NBDClientSession *s, uint64_t handle, + bool only_structured, + QEMUIOVector *qiov, NBDReply *reply, + void **payload) +{ + int request_ret; + int ret =3D nbd_co_do_receive_one_chunk(s, handle, only_structured, + &request_ret, qiov, payload); + + if (ret < 0) { + s->quit =3D true; + } else { + /* For assert at loop start in nbd_read_reply_entry */ + if (reply) { + *reply =3D s->reply; + } + s->reply.handle =3D 0; + ret =3D request_ret; + } =20 - /* Kick the read_reply_co to get the next reply. */ if (s->read_reply_co) { aio_co_wake(s->read_reply_co); } =20 + return ret; +} + +typedef struct NBDReplyChunkIter { + int ret; + bool done, only_structured; +} NBDReplyChunkIter; + +#define NBD_FOREACH_REPLY_CHUNK(s, iter, handle, structured, \ + qiov, reply, payload) \ + for (iter =3D (NBDReplyChunkIter) { .only_structured =3D structured };= \ + nbd_reply_chunk_iter_receive(s, &iter, handle, qiov, reply, paylo= ad);) + +static bool nbd_reply_chunk_iter_receive(NBDClientSession *s, + NBDReplyChunkIter *iter, + uint64_t handle, + QEMUIOVector *qiov, NBDReply *rep= ly, + void **payload) +{ + int ret; + NBDReply local_reply; + NBDStructuredReplyChunk *chunk; + if (s->quit) { + if (iter->ret =3D=3D 0) { + iter->ret =3D -EIO; + } + goto break_loop; + } + + if (iter->done) { + /* Previous iteration was last. */ + goto break_loop; + } + + if (reply =3D=3D NULL) { + reply =3D &local_reply; + } + + ret =3D nbd_co_receive_one_chunk(s, handle, iter->only_structured, + qiov, reply, payload); + if (ret < 0 && iter->ret =3D=3D 0) { + /* If it is a fatal error s->qiov is set by nbd_co_receive_one_chu= nk */ + iter->ret =3D ret; + } + + /* Do not execute the body of NBD_FOREACH_REPLY_CHUNK for simple reply= . */ + if (nbd_reply_is_simple(&s->reply) || s->quit) { + goto break_loop; + } + + chunk =3D &reply->structured; + iter->only_structured =3D true; + + if (chunk->type =3D=3D NBD_SREP_TYPE_NONE) { + if (!(chunk->flags & NBD_SREP_FLAG_DONE)) { + /* protocol error */ + s->quit =3D true; + if (iter->ret =3D=3D 0) { + iter->ret =3D -EIO; + } + } + goto break_loop; + } + + if (chunk->flags & NBD_SREP_FLAG_DONE) { + /* This iteration is last. */ + iter->done =3D true; + } + + /* Execute the loop body */ + return true; + +break_loop: + s->requests[HANDLE_TO_INDEX(s, handle)].coroutine =3D NULL; + qemu_co_mutex_lock(&s->send_mutex); s->in_flight--; qemu_co_queue_next(&s->free_sema); qemu_co_mutex_unlock(&s->send_mutex); =20 - return ret; + return false; +} + +static int nbd_co_receive_return_code(NBDClientSession *s, uint64_t handle) +{ + NBDReplyChunkIter iter; + + NBD_FOREACH_REPLY_CHUNK(s, iter, handle, false, NULL, NULL, NULL) { + /* nbd_reply_chunk_iter_receive does all the work */ + ; + } + + return iter.ret; +} + +static int nbd_co_receive_cmdread_reply(NBDClientSession *s, uint64_t hand= le, + QEMUIOVector *qiov) +{ + NBDReplyChunkIter iter; + NBDReply reply; + void *payload =3D NULL; + + NBD_FOREACH_REPLY_CHUNK(s, iter, handle, s->info.structured_reply, + qiov, &reply, &payload) + { + int ret; + + switch (reply.structured.type) { + case NBD_SREP_TYPE_OFFSET_DATA: + /* special cased in nbd_co_receive_one_chunk, data is already + * in qiov */ + break; + case NBD_SREP_TYPE_OFFSET_HOLE: + ret =3D nbd_parse_offset_hole_payload(&reply.structured, paylo= ad, + qiov); + if (ret < 0) { + s->quit =3D true; + } + break; + default: + /* not allowed reply type */ + s->quit =3D true; + } + + qemu_vfree(payload); + payload =3D NULL; + } + + return iter.ret; } =20 static int nbd_co_request(BlockDriverState *bs, NBDRequest *request, - QEMUIOVector *qiov) + QEMUIOVector *write_qiov) { NBDClientSession *client =3D nbd_get_client_session(bs); int ret; =20 - if (qiov) { - assert(request->type =3D=3D NBD_CMD_WRITE || request->type =3D=3D = NBD_CMD_READ); - assert(request->len =3D=3D iov_size(qiov->iov, qiov->niov)); + assert(request->type !=3D NBD_CMD_READ); + if (write_qiov) { + assert(request->type =3D=3D NBD_CMD_WRITE); + assert(request->len =3D=3D iov_size(write_qiov->iov, write_qiov->n= iov)); } else { - assert(request->type !=3D NBD_CMD_WRITE && request->type !=3D NBD_= CMD_READ); + assert(request->type !=3D NBD_CMD_WRITE); } - ret =3D nbd_co_send_request(bs, request, - request->type =3D=3D NBD_CMD_WRITE ? qiov : = NULL); + ret =3D nbd_co_send_request(bs, request, write_qiov); if (ret < 0) { return ret; } =20 - return nbd_co_receive_reply(client, request->handle, - request->type =3D=3D NBD_CMD_READ ? qiov := NULL); + return nbd_co_receive_return_code(client, request->handle); } =20 int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { + int ret; + NBDClientSession *client =3D nbd_get_client_session(bs); NBDRequest request =3D { .type =3D NBD_CMD_READ, .from =3D offset, @@ -259,7 +591,12 @@ int nbd_client_co_preadv(BlockDriverState *bs, uint64_= t offset, assert(bytes <=3D NBD_MAX_BUFFER_SIZE); assert(!flags); =20 - return nbd_co_request(bs, &request, qiov); + ret =3D nbd_co_send_request(bs, &request, NULL); + if (ret < 0) { + return ret; + } + + return nbd_co_receive_cmdread_reply(client, request.handle, qiov); } =20 int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset, diff --git a/nbd/client.c b/nbd/client.c index a38e1a7d8e..2f256ee771 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -687,6 +687,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char = *name, if (fixedNewStyle) { int result; =20 + result =3D nbd_request_simple_option(ioc, NBD_OPT_STRUCTURED_R= EPLY, + errp); + if (result < 0) { + goto fail; + } + info->structured_reply =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 --=20 2.11.1