From nobody Sat May 4 00:01:36 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 150634806689461.41178660828234; Mon, 25 Sep 2017 07:01:06 -0700 (PDT) Received: from localhost ([::1]:42582 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTwM-0008HQ-RW for importer@patchew.org; Mon, 25 Sep 2017 10:00:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39660) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTtz-0006Yc-LR for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwTtw-0007Dw-0e for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:27 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:45202 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 1dwTtv-0007CD-Kc for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:23 -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 v8PDw1fr013085; Mon, 25 Sep 2017 16:58:02 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Mon, 25 Sep 2017 16:57:54 +0300 Message-Id: <20170925135801.144261-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170925135801.144261-1-vsementsov@virtuozzo.com> References: <20170925135801.144261-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 1/8] 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, Hmreitz@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 --- block/nbd-client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block/nbd-client.c b/block/nbd-client.c index 9d1e154feb..88fd10270e 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; @@ -233,6 +231,7 @@ static int nbd_co_request(BlockDriverState *bs, =20 assert(!qiov || request->type =3D=3D NBD_CMD_WRITE || request->type =3D=3D NBD_CMD_READ); + assert(!qiov || request->len =3D=3D iov_size(qiov->iov, qiov->niov)); 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 Sat May 4 00:01:36 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 1506348238037789.8828654425535; Mon, 25 Sep 2017 07:03:58 -0700 (PDT) Received: from localhost ([::1]:42598 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTz8-0002Wq-Ok for importer@patchew.org; Mon, 25 Sep 2017 10:03:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39733) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTu2-0006bH-6X for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwTu1-0007HZ-8n for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:30 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:22094 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 1dwTu0-0007G0-UH for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58: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 v8PDw1fs013085; Mon, 25 Sep 2017 16:58:02 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Mon, 25 Sep 2017 16:57:55 +0300 Message-Id: <20170925135801.144261-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170925135801.144261-1-vsementsov@virtuozzo.com> References: <20170925135801.144261-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 2/8] 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, Hmreitz@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 88fd10270e..e4f0c789f4 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, @@ -238,7 +238,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 Sat May 4 00:01:36 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 1506348468063303.5006073544473; Mon, 25 Sep 2017 07:07:48 -0700 (PDT) Received: from localhost ([::1]:42647 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwU2u-0006dC-2U for importer@patchew.org; Mon, 25 Sep 2017 10:07:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39735) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTu2-0006bI-7H for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwTu1-0007HR-67 for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:30 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:20137 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 1dwTu0-0007G1-RT for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58: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 v8PDw1ft013085; Mon, 25 Sep 2017 16:58:02 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Mon, 25 Sep 2017 16:57:56 +0300 Message-Id: <20170925135801.144261-4-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170925135801.144261-1-vsementsov@virtuozzo.com> References: <20170925135801.144261-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 3/8] nbd: rename NBD_REPLY_MAGIC to NBD_SIMPLE_REPLY_MAGIC 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, Hmreitz@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 NBD_STRUCTURED_REPLY_MAGIC 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 | 4 ++-- tests/qemu-iotests/nbd-fault-injector.py | 4 ++-- 4 files changed, 7 insertions(+), 7 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..a1b21a6951 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 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 Sat May 4 00:01:36 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 1506348288207504.4375750345491; Mon, 25 Sep 2017 07:04:48 -0700 (PDT) Received: from localhost ([::1]:42603 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwU06-0003Fb-T1 for importer@patchew.org; Mon, 25 Sep 2017 10:04:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39655) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTtz-0006YX-Jn for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwTtw-0007E8-5R for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:27 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:46327 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 1dwTtv-0007CS-K7 for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:24 -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 v8PDw1fu013085; Mon, 25 Sep 2017 16:58:02 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Mon, 25 Sep 2017 16:57:57 +0300 Message-Id: <20170925135801.144261-5-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170925135801.144261-1-vsementsov@virtuozzo.com> References: <20170925135801.144261-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 4/8] nbd-server: refactor simple reply 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, Hmreitz@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" Get rid of calculating structure fields offsets by hand and set_cork, rename nbd_co_send_reply to nbd_co_send_simple_reply. Do not use NBDReply which 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 --- include/block/nbd.h | 6 ++++ nbd/nbd-internal.h | 9 +++++ nbd/server.c | 97 ++++++++++++++++++++++---------------------------= ---- 3 files changed, 56 insertions(+), 56 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/nbd-internal.h b/nbd/nbd-internal.h index 2d6663de23..320abef296 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -113,6 +113,15 @@ static inline int nbd_write(QIOChannel *ioc, const voi= d *buffer, size_t size, return qio_channel_write_all(ioc, buffer, size, errp) < 0 ? -EIO : 0; } =20 +/* nbd_writev + * Writes @size bytes to @ioc. Returns 0 on success. + */ +static inline int nbd_writev(QIOChannel *ioc, const struct iovec *iov, + size_t niov, Error **errp) +{ + return qio_channel_writev_all(ioc, iov, niov, errp) < 0 ? -EIO : 0; +} + struct NBDTLSHandshakeData { GMainLoop *loop; bool complete; diff --git a/nbd/server.c b/nbd/server.c index a1b21a6951..57d5598e0f 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,38 +1188,51 @@ void nbd_export_close_all(void) } } =20 -static int nbd_co_send_reply(NBDRequestData *req, NBDReply *reply, int len, - Error **errp) +static int coroutine_fn nbd_co_send_iov(NBDClient *client, struct iovec *i= ov, + unsigned niov, Error **errp) { - NBDClient *client =3D req->client; int ret; =20 g_assert(qemu_in_coroutine()); - - trace_nbd_co_send_reply(reply->handle, reply->error, len); - 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); - } else { - qio_channel_set_cork(client->ioc, true); - ret =3D nbd_send_reply(client->ioc, reply, errp); - if (ret =3D=3D 0) { - ret =3D nbd_write(client->ioc, req->data, len, errp); - if (ret < 0) { - ret =3D -EIO; - } - } - qio_channel_set_cork(client->ioc, false); - } + ret =3D nbd_writev(client->ioc, iov, niov, errp); =20 client->send_coroutine =3D NULL; qemu_co_mutex_unlock(&client->send_lock); + return ret; } =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(NBDClient *client, + uint64_t handle, + uint32_t error, + void *data, + size_t size, + Error **errp) +{ + NBDSimpleReply reply; + struct iovec iov[] =3D { + {.iov_base =3D &reply, .iov_len =3D sizeof(reply)}, + {.iov_base =3D data, .iov_len =3D size} + }; + + trace_nbd_co_send_reply(handle, error, size); + + set_be_simple_reply(&reply, system_errno_to_nbd_errno(error), handle); + + return nbd_co_send_iov(client, iov, size ? 2 : 1, 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 @@ -1331,7 +1324,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; @@ -1351,11 +1343,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 @@ -1374,7 +1362,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; } } @@ -1383,7 +1370,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 @@ -1392,7 +1378,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 @@ -1404,14 +1390,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 @@ -1426,7 +1411,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; @@ -1438,7 +1422,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; @@ -1447,25 +1430,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 are here local_err is not fatal error, which should be se= nt + * to client. */ error_report_err(local_err); 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->client, request.handle, + ret < 0 ? -ret : 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 Sat May 4 00:01:36 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 1506348356408486.9680865940553; Mon, 25 Sep 2017 07:05:56 -0700 (PDT) Received: from localhost ([::1]:42639 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwU1D-0004Ou-NW for importer@patchew.org; Mon, 25 Sep 2017 10:05:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39654) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTtz-0006YW-Ja for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwTtv-0007DJ-MB for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:27 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:43985 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 1dwTtv-0007Bp-Al for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:23 -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 v8PDw1fv013085; Mon, 25 Sep 2017 16:58:03 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Mon, 25 Sep 2017 16:57:58 +0300 Message-Id: <20170925135801.144261-6-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170925135801.144261-1-vsementsov@virtuozzo.com> References: <20170925135801.144261-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 5/8] 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, Hmreitz@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 --- 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 320abef296..d96c9cc7fd 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 Sat May 4 00:01:36 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 1506348059226960.6933832158926; Mon, 25 Sep 2017 07:00:59 -0700 (PDT) Received: from localhost ([::1]:42583 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTwO-0008IM-A4 for importer@patchew.org; Mon, 25 Sep 2017 10:00:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39657) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTtz-0006YZ-KV for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwTtv-0007DW-RN for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:27 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:33731 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 1dwTtv-0007C2-An for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:23 -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 v8PDw1fw013085; Mon, 25 Sep 2017 16:58:03 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Mon, 25 Sep 2017 16:57:59 +0300 Message-Id: <20170925135801.144261-7-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170925135801.144261-1-vsementsov@virtuozzo.com> References: <20170925135801.144261-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 6/8] 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, Hmreitz@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 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 --- include/block/nbd.h | 31 ++++++++++++++++ nbd/nbd-internal.h | 1 + nbd/server.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++= ---- 3 files changed, 126 insertions(+), 6 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index a6df5ce8b5..314f2f9bbc 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,16 @@ 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_ERROR NBD_SREP_ERR(1) + /* 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 d96c9cc7fd..6b0d1183ba 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 57d5598e0f..0af94a293d 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, size ? 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 Sat May 4 00:01:36 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 1506348155224747.2672704099929; Mon, 25 Sep 2017 07:02:35 -0700 (PDT) Received: from localhost ([::1]:42595 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTxy-0001Pv-83 for importer@patchew.org; Mon, 25 Sep 2017 10:02:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39739) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTu2-0006bN-Af for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwTtv-0007Dk-Tc for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:30 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:21547 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 1dwTtv-0007CH-Ex for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:23 -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 v8PDw1fx013085; Mon, 25 Sep 2017 16:58:03 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Mon, 25 Sep 2017 16:58:00 +0300 Message-Id: <20170925135801.144261-8-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170925135801.144261-1-vsementsov@virtuozzo.com> References: <20170925135801.144261-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 7/8] 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, Hmreitz@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 --- 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..51ae492e92 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 1; + } + + 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 0; +} + +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 48a4f27682..ea44e6963f 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 Sat May 4 00:01:36 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 1506348038848645.3760500065049; Mon, 25 Sep 2017 07:00:38 -0700 (PDT) Received: from localhost ([::1]:42578 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTw1-0007wd-1G for importer@patchew.org; Mon, 25 Sep 2017 10:00:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39689) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwTu0-0006Zo-Oj for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwTtv-0007Dh-TN for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:28 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:8054 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 1dwTtv-0007C9-Ak for qemu-devel@nongnu.org; Mon, 25 Sep 2017 09:58:23 -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 v8PDw1g0013085; Mon, 25 Sep 2017 16:58:03 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Mon, 25 Sep 2017 16:58:01 +0300 Message-Id: <20170925135801.144261-9-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170925135801.144261-1-vsementsov@virtuozzo.com> References: <20170925135801.144261-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 8/8] 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, Hmreitz@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: drop most of additional error information. Signed-off-by: Vladimir Sementsov-Ogievskiy --- block/nbd-client.h | 2 + include/block/nbd.h | 15 ++++- block/nbd-client.c | 97 +++++++++++++++++++++++++----- nbd/client.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++-= ---- 4 files changed, 249 insertions(+), 34 deletions(-) diff --git a/block/nbd-client.h b/block/nbd-client.h index b435754b82..9e178de510 100644 --- a/block/nbd-client.h +++ b/block/nbd-client.h @@ -35,6 +35,8 @@ typedef struct NBDClientSession { NBDClientRequest requests[MAX_NBD_REQUESTS]; NBDReply reply; bool quit; + + bool structured_reply; } NBDClientSession; =20 NBDClientSession *nbd_get_client_session(BlockDriverState *bs); diff --git a/include/block/nbd.h b/include/block/nbd.h index 314f2f9bbc..7604e80c49 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -57,11 +57,17 @@ struct NBDRequest { }; typedef struct NBDRequest NBDRequest; =20 -struct NBDReply { +typedef struct NBDReply { + bool simple; uint64_t handle; uint32_t error; -}; -typedef struct NBDReply NBDReply; + + uint16_t flags; + uint16_t type; + uint32_t tail_length; + uint64_t offset; + uint32_t hole_size; +} NBDReply; =20 typedef struct NBDSimpleReply { uint32_t magic; /* NBD_SIMPLE_REPLY_MAGIC */ @@ -178,12 +184,15 @@ enum { =20 #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) =20 /* Details collected by NBD_OPT_EXPORT_NAME and NBD_OPT_GO */ 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 e4f0c789f4..bdf9299bb9 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -179,9 +179,10 @@ err: return rc; } =20 -static int nbd_co_receive_reply(NBDClientSession *s, - uint64_t handle, - QEMUIOVector *qiov) +static int nbd_co_receive_1_reply_or_chunk(NBDClientSession *s, + uint64_t handle, + bool *cont, + QEMUIOVector *qiov) { int ret; int i =3D HANDLE_TO_INDEX(s, handle); @@ -191,29 +192,95 @@ static int nbd_co_receive_reply(NBDClientSession *s, 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 -s->reply.error; - if (qiov && s->reply.error =3D=3D 0) { + *cont =3D false; + return -EIO; + } + + assert(s->reply.handle =3D=3D handle); + *cont =3D !(s->reply.simple || (s->reply.flags & NBD_SREP_FLAG_DONE)); + ret =3D -s->reply.error; + if (ret < 0) { + goto out; + } + + if (s->reply.simple) { + if (qiov) { if (qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov, - NULL) < 0) { - ret =3D -EIO; - s->quit =3D true; + NULL) < 0) + { + goto fatal; } } + goto out; + } =20 - /* Tell the read handler to read another header. */ - s->reply.handle =3D 0; + /* here we deal with successful structured reply */ + switch (s->reply.type) { + QEMUIOVector sub_qiov; + case NBD_SREP_TYPE_OFFSET_DATA: + if (!qiov || s->reply.offset + s->reply.tail_length > qiov->size) { + goto fatal; + } + qemu_iovec_init(&sub_qiov, qiov->niov); + qemu_iovec_concat(&sub_qiov, qiov, s->reply.offset, + s->reply.tail_length); + ret =3D qio_channel_readv_all(s->ioc, sub_qiov.iov, sub_qiov.niov,= NULL); + qemu_iovec_destroy(&sub_qiov); + if (ret < 0) { + goto fatal; + } + assert(ret =3D=3D 0); + break; + case NBD_SREP_TYPE_OFFSET_HOLE: + if (!qiov || s->reply.offset + s->reply.hole_size > qiov->size) { + goto fatal; + } + qemu_iovec_memset(qiov, s->reply.offset, 0, s->reply.hole_size); + break; + case NBD_SREP_TYPE_NONE: + break; + default: + goto fatal; } =20 - s->requests[i].coroutine =3D NULL; +out: + /* For assert at loop start in nbd_read_reply_entry */ + s->reply.handle =3D 0; + + if (s->read_reply_co) { + aio_co_wake(s->read_reply_co); + } + + return ret; =20 - /* Kick the read_reply_co to get the next reply. */ +fatal: + /* protocol or ioc failure */ + *cont =3D false; + s->quit =3D true; if (s->read_reply_co) { aio_co_wake(s->read_reply_co); } =20 + return -EIO; +} + +static int nbd_co_receive_reply(NBDClientSession *s, + uint64_t handle, + QEMUIOVector *qiov) +{ + int ret =3D 0; + int i =3D HANDLE_TO_INDEX(s, handle); + bool cont =3D true; + + while (cont) { + int rc =3D nbd_co_receive_1_reply_or_chunk(s, handle, &cont, qiov); + if (rc < 0 && ret =3D=3D 0) { + ret =3D rc; + } + } + + s->requests[i].coroutine =3D NULL; + qemu_co_mutex_lock(&s->send_mutex); s->in_flight--; qemu_co_queue_next(&s->free_sema); diff --git a/nbd/client.c b/nbd/client.c index 51ae492e92..880eb17b85 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -719,6 +719,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 > 0; + /* 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 @@ -759,6 +766,12 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char = *name, goto fail; } be16_to_cpus(&info->flags); + + if (info->structured_reply && !(info->flags & NBD_CMD_FLAG_DF)) { + error_setg(errp, "Structured reply is negotiated, " + "but DF flag is not."); + goto fail; + } } else if (magic =3D=3D NBD_CLIENT_MAGIC) { uint32_t oldflags; =20 @@ -942,6 +955,128 @@ int nbd_send_request(QIOChannel *ioc, NBDRequest *req= uest) return nbd_write(ioc, buf, sizeof(buf), NULL); } =20 +/* nbd_receive_simple_reply + * Read simple reply except magic field (which should be already read) + */ +static int nbd_receive_simple_reply(QIOChannel *ioc, NBDReply *reply, + Error **errp) +{ + NBDSimpleReply simple_reply; + int ret; + + ret =3D nbd_read(ioc, (uint8_t *)&simple_reply + sizeof(simple_reply.m= agic), + sizeof(simple_reply) - sizeof(simple_reply.magic), errp= ); + if (ret < 0) { + return ret; + } + + reply->error =3D be32_to_cpu(simple_reply.error); + reply->handle =3D be64_to_cpu(simple_reply.handle); + + return 0; +} + +/* nbd_receive_structured_reply_chunk + * Read structured reply chunk except magic field (which should be already= read) + * Data for NBD_SREP_TYPE_OFFSET_DATA is not read too. + * tail_length field of reply out parameter corresponds to unread part of = reply. + */ +static int nbd_receive_structured_reply_chunk(QIOChannel *ioc, NBDReply *r= eply, + Error **errp) +{ + NBDStructuredReplyChunk chunk; + ssize_t ret; + uint16_t message_size; + + ret =3D nbd_read(ioc, (uint8_t *)&chunk + sizeof(chunk.magic), + sizeof(chunk) - sizeof(chunk.magic), errp); + if (ret < 0) { + return ret; + } + + reply->flags =3D be16_to_cpu(chunk.flags); + reply->type =3D be16_to_cpu(chunk.type); + reply->handle =3D be64_to_cpu(chunk.handle); + reply->tail_length =3D be32_to_cpu(chunk.length); + + switch (reply->type) { + case NBD_SREP_TYPE_NONE: + break; + case NBD_SREP_TYPE_OFFSET_DATA: + if (reply->tail_length < sizeof(reply->offset)) { + return -EIO; + } + ret =3D nbd_read(ioc, &reply->offset, sizeof(reply->offset), errp); + if (ret < 0) { + return ret; + } + be64_to_cpus(&reply->offset); + reply->tail_length -=3D sizeof(reply->offset); + + break; + case NBD_SREP_TYPE_OFFSET_HOLE: + ret =3D nbd_read(ioc, &reply->offset, sizeof(reply->offset), errp); + if (ret < 0) { + return ret; + } + be64_to_cpus(&reply->offset); + + ret =3D nbd_read(ioc, &reply->hole_size, sizeof(reply->hole_size),= errp); + if (ret < 0) { + return ret; + } + be32_to_cpus(&reply->hole_size); + + break; + case NBD_SREP_TYPE_ERROR: + case NBD_SREP_TYPE_ERROR_OFFSET: + ret =3D nbd_read(ioc, &reply->error, sizeof(reply->error), errp); + if (ret < 0) { + return ret; + } + be32_to_cpus(&reply->error); + + ret =3D nbd_read(ioc, &message_size, sizeof(message_size), errp); + if (ret < 0) { + return ret; + } + be16_to_cpus(&message_size); + + if (message_size > 0) { + /* TODO: provide error message to user */ + ret =3D nbd_drop(ioc, message_size, errp); + if (ret < 0) { + return ret; + } + } + + if (reply->type =3D=3D NBD_SREP_TYPE_ERROR_OFFSET) { + /* drop 64bit offset */ + ret =3D nbd_drop(ioc, 8, errp); + if (ret < 0) { + return ret; + } + } + break; + default: + if (reply->type & (1 << 15)) { + /* unknown error */ + ret =3D nbd_drop(ioc, reply->tail_length, errp); + if (ret < 0) { + return ret; + } + + reply->error =3D NBD_EINVAL; + reply->tail_length =3D 0; + } else { + /* unknown non-error reply type */ + return -EINVAL; + } + } + + return 0; +} + /* nbd_receive_reply * Returns 1 on success * 0 on eof, when no data was read (errp is not set) @@ -949,24 +1084,32 @@ int nbd_send_request(QIOChannel *ioc, NBDRequest *re= quest) */ 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, &magic, sizeof(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(&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 (magic) { + case NBD_SIMPLE_REPLY_MAGIC: + reply->simple =3D true; + ret =3D nbd_receive_simple_reply(ioc, reply, errp); + break; + case NBD_STRUCTURED_REPLY_MAGIC: + reply->simple =3D false; + ret =3D nbd_receive_structured_reply_chunk(ioc, reply, errp); + break; + default: + error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic); + return -EINVAL; + } + if (ret < 0) { + return ret; + } =20 reply->error =3D nbd_errno_to_system_errno(reply->error); =20 @@ -977,11 +1120,5 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *repl= y, Error **errp) } trace_nbd_receive_reply(magic, reply->error, reply->handle); =20 - if (magic !=3D NBD_SIMPLE_REPLY_MAGIC) { - error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic); - return -EINVAL; - } - return 1; } - --=20 2.11.1