From nobody Fri Oct 24 22:15:02 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 151870307111627.230684205967236; Thu, 15 Feb 2018 05:57:51 -0800 (PST) Received: from localhost ([::1]:51243 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1emK2h-0007us-5g for importer@patchew.org; Thu, 15 Feb 2018 08:57:43 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51182) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1emJxX-0001rv-4B for qemu-devel@nongnu.org; Thu, 15 Feb 2018 08:52:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1emJxS-00010d-CP for qemu-devel@nongnu.org; Thu, 15 Feb 2018 08:52:23 -0500 Received: from mail-db5eur01on0094.outbound.protection.outlook.com ([104.47.2.94]:28352 helo=EUR01-DB5-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1emJxR-0000zX-VJ; Thu, 15 Feb 2018 08:52:18 -0500 Received: from vova-pc.sw.ru (195.214.232.6) by AM5PR0801MB2052.eurprd08.prod.outlook.com (2603:10a6:203:4c::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.506.18; Thu, 15 Feb 2018 13:52:15 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=SiBAFZM5X2e4WlYicjfsuk54GJz/XhEhi8/deNTgzAg=; b=MrxZCxfW26iumb7TQwUG4uYtakZIGovKyhiMki0MzMv4o3c8uKx/33OM902TZns1JneBk0EVLeGEaWuNWqwL94UlFffyd+S3PdrnQprIIY4REkVM2K8ExVTY/nZ0e4opsSstTOE7T/HF5uSIzVl7sEX8R/PwT+u68fyBGyap/h4= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=vsementsov@virtuozzo.com; From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Thu, 15 Feb 2018 16:51:44 +0300 Message-Id: <1518702707-7077-7-git-send-email-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1518702707-7077-1-git-send-email-vsementsov@virtuozzo.com> References: <1518702707-7077-1-git-send-email-vsementsov@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: HE1PR07CA0005.eurprd07.prod.outlook.com (2603:10a6:7:67::15) To AM5PR0801MB2052.eurprd08.prod.outlook.com (2603:10a6:203:4c::14) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 78a99187-b336-4f0e-4913-08d5747b5276 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(5600026)(4604075)(2017052603307)(7153060)(7193020); SRVR:AM5PR0801MB2052; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB2052; 3:Fc8jQBaffCMp73p99iu3FFefDgzRSa3dKs5Qxy28yH7xP10TC2KF4yBKwYU1TXF/PlZ9DXHRvz2x44n9sVJUp65NYiYhHgTtBJrOVjTL8um9BBMXRzyANK5EbZFaBQ5PdfJ3SqM4+HfC0nOuU0sbgWzCCyQBspcFi+QHZdQ1qPmVJsu0WgJ2+3JWoiTZAFrnb+g3tr5OZfcSPSlaEKgK4FnZHYCh417XnF2pbbv/LzOUe61jsD91Ooi8Pmes7+iu; 25:V58TDHz44g7ejP2ZPlh/XCRJXJzgA7XrgG/vavi4eTdoFn5zQXzlvU3df1mtcyQyB8VysVIR0NwgNl0UoMLBiuk5amU4XX3rZO2i9DTGyHYcvK8j1uyrlTZYmcxWsGlyggv+BO6GwsYTbQUXzJg5BPVAMnAbQd0oBS4J7B8c5pfk1lbynad6pS7ze0d/9XdOvIjI6nHC7i6sZVbv2jyHlt8rtwPfAoQ9t1edrESjDvNygXwFxIZ8T2FQJGVtKN8Q0yxalm7fWToNa4FVJkng8BH46wIRfd6tMbEn3Tbw7x9AjFKzbaXcr1TZbIBsS4WPiILGxsDpbwBZ1aYP2lak/w==; 31:mWOFblfa9SD848XTD9e2bVsAVGwAKJbGw3J3VcN6WJrc8vw6vYJQpIEsnjHH2AlfeIY+aJYqmpDLRUza9jTAmb+sXc3FsmEBHQBqO+spif9/u7T0S9/G8sbnnxurnmckOzHRzZOUhw1ejiHMjv/PngJdxom31bEUoiKamUHWCf+KXAlbfNdToOVf1QChH1X8pcAi2H9FRiFWQYV4C2sbAu62yZ6znCENazXPCWcHnBM= X-MS-TrafficTypeDiagnostic: AM5PR0801MB2052: X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB2052; 20:FfNovrKEJ3NbpPNKoHaPh1wykGOCbl65i0lx3NAY30yMt943gnHxKHHghodL/6Q6OmmFSdsNp5jYy6TATQTTFh3CQJLaIvwHGjj0hYhXzhzjCKHAw7XYQZtJE7Rp0ZDCuogvSI00GuwxLdOG940PU4GOb9mD8iqpPCKxnJ7SxmysOtFHdcARXxsPLvlv8WES12ckJ2ybHOj9JJZ5rt16ZDYBXhHDLngSt5bV6hPC5Sm7RkptITEtB4cZFN/C9Z5oKSHFYewTdo79McObs0mycO2fMFia65ich6OLxU5+qn/03M351O/MzOeer0WnOFq0mAIUeVBgSROXSOTe3bpmW/h7LUSBi92ajNk+V0KYC27pPqBIjtvUc2QJQft8XfQRr3vo8J7IerV7qgQPp4YsaS3tNRs7aWzNqFYJqOAUYGYuRWhYy/DWETZLyyfuWs82prqkJpqFfT/e9C+gCtu05jdlQmHvBCnbvwvNrExqvgF66gwaLjnLQNgPFaglEO9W; 4:ZsDWQ7/4EQJVjlpbSW20BKamwUH0cyrqVHm8nu5DXNYQL/skSb1bGYnfF0zPXHmPMCrxOKPLdDa1kc6482O3aX6B08VWqEFLmT0oYhACiFPnlnhTP91fUcsTvpMoDRQ36FGsWZXN9KMw5Y35CQaPIOZxjplRtUuwFkj1fj7DyQKm0q25DNl5K3z9nE699Fipa4onzPBSTcwQYb4qFc7Xnh2GYe3m3HbwuLTfQS4KjO5ErTsPRI1lZOWbyiGx+JeH7ZGvC195SfdLiHZeNkedhueu8z9q6D5TueSqwWHNdK/1TymoTaKeljrv6aV8m48t/5+MRoXzwizaZ/bTv6sro65iUMb9I4auSHK+B7yEvAw= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(158342451672863)(150554046322364); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(10201501046)(3002001)(3231101)(944501161)(93006095)(93001095)(6041288)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123560045)(6072148)(201708071742011); SRVR:AM5PR0801MB2052; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0801MB2052; X-Forefront-PRVS: 058441C12A X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(396003)(39380400002)(376002)(346002)(39840400004)(366004)(189003)(199004)(105586002)(52116002)(305945005)(8676002)(81166006)(26005)(6512007)(51416003)(76176011)(5660300001)(81156014)(53936002)(25786009)(7736002)(97736004)(55236004)(16586007)(69596002)(6506007)(36756003)(47776003)(86362001)(66066001)(316002)(386003)(59450400001)(6486002)(575784001)(106356001)(68736007)(50226002)(4326008)(53416004)(3846002)(2906002)(8936002)(478600001)(6116002)(5890100001)(16526019)(186003)(107886003)(48376002)(2950100002)(6666003)(50466002)(21314002)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM5PR0801MB2052; H:vova-pc.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; 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; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0801MB2052; 23:1T7MGAwIMEx9pHXGFRwC4/uomgyyHqDCQ0jZE9V?= =?us-ascii?Q?iUITbDO8DmGpT56DN8SMYWuVtS3vEn7kx2V8Hkslk85sIWFYaxmQ6xPjSRbJ?= =?us-ascii?Q?Gglfg9MkOEpYg7xDl9Ohje+VcpS5iaBk2e+0UUeHRC/xa1QUwCaeT8WiDtEB?= =?us-ascii?Q?ZZ5QOgF+SMssYWE4fdHkguIn2MXQ3LBccDbVBOWtcaNS6rVSNrDnRQxxcw4/?= =?us-ascii?Q?tKjCYWy8uEbDxKpmJmCF8jQZB1Al/HxiAcnFgvtXSJ3lrgsJr2Lsp119JjMt?= =?us-ascii?Q?ZL1/d2Vo3wq9RYxoO7MsLonbUl9Pc32LcpFJ2UB7xi7kuzIM+daF5C303IBP?= =?us-ascii?Q?gtkPXZ9oY2lZ1i8QlUJQs4vdgP+7Q14jaOycqu5MylB8het8SapRBv79p3Ue?= =?us-ascii?Q?Z7hwzxCo8FwrynWdH1NiFnaCDGRdhfGEUsb1SyVcCsDVMxnJAk6E/b27JtPU?= =?us-ascii?Q?CLXoJDmiGH5zJPgwy52LkM+XU1uE6lhb7NFF146H52Siyx2By3SE4IGgQxja?= =?us-ascii?Q?Ch5wRuezeoMNi8Ksq2yHV9C+0iOR6bUS8NiJaVhhKkIiNj4FyGlYB3y8tqQz?= =?us-ascii?Q?QoPgrtM+bv0DLkAL8fqKG2NGwgMr88fj1NpyhhnFKhnkdHnLzyTb0YqSHRvh?= =?us-ascii?Q?qQq7JCLbuuhS85v8OaJ+FLff2h4RmlAQQ6NGXmjKF1cwFOciXgR3rgJpgWMW?= =?us-ascii?Q?/Db/owHy+oDQP8+WoDSsFYnEEh4HNRBpoliWF2UaZAim4Ged3fJsQLpb2nTz?= =?us-ascii?Q?3JC+Ui3+eax/ldl1ETBv9Gn9728c8lzxF+i/ptSETwRw4IkOLuY3WFyQquVt?= =?us-ascii?Q?zg+VkHk8ePNbI9hMwSDejg/l2tmOr4DpcT4bKK6NKXQxsWJzphdLYAMnNohE?= =?us-ascii?Q?2ux+bituZm0AsCniHdHUgkghKZApu8EVDxMQFY200AnOdG5HFmE3jRUg0wdF?= =?us-ascii?Q?wAo9AtUE1xmuijacYMwplzqYIHHH1pdOOuS9Gs9XYvnqnLsUcJiit67EkQ5N?= =?us-ascii?Q?7pVZyeuu1gVpAxVGa30im+bh+ezUhjSVYv7EsewmVQvPM3MKtJbFtM/GWpfr?= =?us-ascii?Q?MHr2FB055bnQ+4TYt4Gmbxx/VW+yAIzLSFikxZzfyiGOoFc9FL907Gnl9yh7?= =?us-ascii?Q?APDoFhdr1WUr98e/57M2zcCItpZisVg0Sn9SLs6o8AQUmJp8/o8H6x8rOQVz?= =?us-ascii?Q?msRL3SaDSmI7tMc/KPAu4g+o00eO2ng2ewpGAO8V3bjbzvwa1xgopvrzknLS?= =?us-ascii?Q?4pHn9jOxlmsZRom7YA4phkmmfFvFuAd8896hCeBbeAHQftBdHckXRTIVDR0M?= =?us-ascii?Q?MTQ=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB2052; 6:B/bDpLEWtzOvwRiNsWFvHqGQoTDTj5qLiwOEbxN/svPdys6hYSZ67L7yzDd8LO0NT0KnJrmf+hxoYeQvwXarcRSkBrLnv2uVDWLS3+b2Zf7t7gyB2eLl1p5Zd1NPNCqxNHdzafgT0R9guzemN8rVM3h/DkTv3/7qp1TGGwINSCqCROG78vHKsqV8af51j9hb14sSJLaX/MZuDhs/yUvO6Y1ABG6cXMDqN7ncKQt14nqh0An94IRb5e1+ggVADFdo+jbpdUVdIVLhJnMPcq5CFu5Ma85jGaDp3dFl0hwfcRnSgXRjtKdapX84uoU4JJ/TPWMYLHrtn2fUxxmyBk895pk4AJ2jvgj0BfKhYJrr5PY=; 5:4M42BlqrsnqqnmGVIkeLQDg0iyxaauAaj7RVmkfkSjxM6Pq/Fxn18LSUQnnBiL+M8+L+0M7oTlLN0vBAGEOEOGSP52twhK86EMtFDpgxZFNLUmkjxgA+XzozbxaTNoDv4I36uFNaCj7CN3wXWcn26QKWJ8xWsue0b8pMcPaa1Aw=; 24:IP3tfZ3lN+iz1hZ6pIMl5aSlOcFKpuxA/jdWKXQsxfBuULllLu1OJQBdfn1gS+n2Dxys6EyNF5q5xRvbSnz0MPfMtsX1Sw20FoHGZo2l2I0=; 7:SvJtGShqrCSzgiLSzuSeTi9IAjXlxRM0yNTHOY8GmmVii1bY2ID6EMHbNrwPocdLLy8XUynKlNnQZyKVQpyKPcPXLLIiERqWcRWcxh+XRei0uuNR/zTtV9EIEr5NQu/OKEj/kjGt5rOYOhQfC0dgAwy4rsksCfahbXKeBqAx6ao4SlelVQFLgdeWp6aYx3P018KrtlNFbnVZqYgSgFBH/XC2jN7NV6tmuMwcDid33Tc+WVoEbef2tJIWqInoe/nu SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB2052; 20:dkBAIEfzbRE3KqvGtDNZZGF3Oper2cYCbnJsNpY/e3jaegWYcqXNnTip3PbVFFuAcC8pB0aQv/jMhZ+6v4P3au30q06jmWMnsv7SjCWHLVYe910Z0b2AXjksUlvpzrdJzRu+qyZbRsCxQtbRUdQ5gxXURyArHqJIyauqQqa8iK4= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Feb 2018 13:52:15.0138 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 78a99187-b336-4f0e-4913-08d5747b5276 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB2052 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.2.94 Subject: [Qemu-devel] [PATCH 6/9] nbd: BLOCK_STATUS for standard get_block_status function: client part 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-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Minimal realization: only one extent in server answer is supported. Flag NBD_CMD_FLAG_REQ_ONE is used to force this behavior. Tests 140, 147 and 205 are fixed due to now server failed on searching export in context of NBD_OPT_SET_META_CONTEXT option negotiation. Signed-off-by: Vladimir Sementsov-Ogievskiy --- block/nbd-client.h | 5 ++ include/block/nbd.h | 3 + block/nbd-client.c | 139 +++++++++++++++++++++++++++++++++++++++++= ++++ block/nbd.c | 3 + nbd/client.c | 114 +++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/140.out | 2 +- tests/qemu-iotests/143.out | 2 +- tests/qemu-iotests/205 | 3 +- 8 files changed, 268 insertions(+), 3 deletions(-) diff --git a/block/nbd-client.h b/block/nbd-client.h index 612c4c21a0..ca0cc141c0 100644 --- a/block/nbd-client.h +++ b/block/nbd-client.h @@ -61,4 +61,9 @@ void nbd_client_detach_aio_context(BlockDriverState *bs); void nbd_client_attach_aio_context(BlockDriverState *bs, AioContext *new_context); =20 +int64_t coroutine_fn nbd_client_co_get_block_status(BlockDriverState *bs, + int64_t sector_num, + int nb_sectors, int *p= num, + BlockDriverState **fil= e); + #endif /* NBD_CLIENT_H */ diff --git a/include/block/nbd.h b/include/block/nbd.h index b16215d17a..baf12e5428 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -262,6 +262,7 @@ struct NBDExportInfo { /* In-out fields, set by client before nbd_receive_negotiate() and * updated by server results during nbd_receive_negotiate() */ bool structured_reply; + bool base_allocation; /* base:allocation context for NBD_CMD_BLOCK_STA= TUS */ =20 /* Set by server results during nbd_receive_negotiate() */ uint64_t size; @@ -269,6 +270,8 @@ struct NBDExportInfo { uint32_t min_block; uint32_t opt_block; uint32_t max_block; + + uint32_t meta_base_allocation_id; }; typedef struct NBDExportInfo NBDExportInfo; =20 diff --git a/block/nbd-client.c b/block/nbd-client.c index b1cbe95b13..a80d69d3cd 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -228,6 +228,45 @@ static int nbd_parse_offset_hole_payload(NBDStructured= ReplyChunk *chunk, return 0; } =20 +/* nbd_parse_blockstatus_payload + * support only one extent in reply and only for + * base:allocation context + */ +static int nbd_parse_blockstatus_payload(NBDClientSession *client, + NBDStructuredReplyChunk *chunk, + uint8_t *payload, uint64_t orig_l= ength, + NBDExtent *extent, Error **errp) +{ + uint32_t context_id; + + if (chunk->length !=3D sizeof(context_id) + sizeof(extent)) { + error_setg(errp, "Protocol error: invalid payload for " + "NBD_REPLY_TYPE_BLOCK_STATUS"); + return -EINVAL; + } + + context_id =3D payload_advance32(&payload); + if (client->info.meta_base_allocation_id !=3D context_id) { + error_setg(errp, "Protocol error: unexpected context id: %d for " + "NBD_REPLY_TYPE_BLOCK_STATUS, when negotiated con= text " + "id is %d", context_id, + client->info.meta_base_allocation_id); + return -EINVAL; + } + + memcpy(extent, payload, sizeof(*extent)); + be32_to_cpus(&extent->length); + be32_to_cpus(&extent->flags); + + if (extent->length > orig_length) { + error_setg(errp, "Protocol error: server sent chunk exceeding requ= ested" + " region"); + return -EINVAL; + } + + return 0; +} + /* nbd_parse_error_payload * on success @errp contains message describing nbd error reply */ @@ -642,6 +681,61 @@ static int nbd_co_receive_cmdread_reply(NBDClientSessi= on *s, uint64_t handle, return iter.ret; } =20 +static int nbd_co_receive_blockstatus_reply(NBDClientSession *s, + uint64_t handle, uint64_t leng= th, + NBDExtent *extent, Error **err= p) +{ + NBDReplyChunkIter iter; + NBDReply reply; + void *payload =3D NULL; + Error *local_err =3D NULL; + bool received =3D false; + + NBD_FOREACH_REPLY_CHUNK(s, iter, handle, s->info.structured_reply, + NULL, &reply, &payload) + { + int ret; + NBDStructuredReplyChunk *chunk =3D &reply.structured; + + assert(nbd_reply_is_structured(&reply)); + + switch (chunk->type) { + case NBD_REPLY_TYPE_BLOCK_STATUS: + if (received) { + s->quit =3D true; + error_setg(&local_err, "Several BLOCK_STATUS chunks in rep= ly"); + nbd_iter_error(&iter, true, -EINVAL, &local_err); + } + received =3D true; + + ret =3D nbd_parse_blockstatus_payload(s, &reply.structured, + payload, length, extent, + &local_err); + if (ret < 0) { + s->quit =3D true; + nbd_iter_error(&iter, true, ret, &local_err); + } + break; + default: + if (!nbd_reply_type_is_error(chunk->type)) { + /* not allowed reply type */ + s->quit =3D true; + error_setg(&local_err, + "Unexpected reply type: %d (%s) " + "for CMD_BLOCK_STATUS", + chunk->type, nbd_reply_type_lookup(chunk->type)= ); + nbd_iter_error(&iter, true, -EINVAL, &local_err); + } + } + + g_free(payload); + payload =3D NULL; + } + + error_propagate(errp, iter.err); + return iter.ret; +} + static int nbd_co_request(BlockDriverState *bs, NBDRequest *request, QEMUIOVector *write_qiov) { @@ -784,6 +878,50 @@ int nbd_client_co_pdiscard(BlockDriverState *bs, int64= _t offset, int bytes) return nbd_co_request(bs, &request, NULL); } =20 +int64_t coroutine_fn nbd_client_co_get_block_status(BlockDriverState *bs, + int64_t sector_num, + int nb_sectors, int *p= num, + BlockDriverState **fil= e) +{ + int64_t ret; + NBDExtent extent; + NBDClientSession *client =3D nbd_get_client_session(bs); + Error *local_err =3D NULL; + + uint64_t offset =3D sector_num << BDRV_SECTOR_BITS; + uint32_t bytes =3D nb_sectors << BDRV_SECTOR_BITS; + + NBDRequest request =3D { + .type =3D NBD_CMD_BLOCK_STATUS, + .from =3D offset, + .len =3D bytes, + .flags =3D NBD_CMD_FLAG_REQ_ONE, + }; + + if (!client->info.base_allocation) { + *pnum =3D nb_sectors; + return BDRV_BLOCK_DATA; + } + + ret =3D nbd_co_send_request(bs, &request, NULL); + if (ret < 0) { + return ret; + } + + ret =3D nbd_co_receive_blockstatus_reply(client, request.handle, bytes, + &extent, &local_err); + if (local_err) { + error_report_err(local_err); + } + if (ret < 0) { + return ret; + } + + *pnum =3D extent.length >> BDRV_SECTOR_BITS; + return (extent.flags & NBD_STATE_HOLE ? 0 : BDRV_BLOCK_DATA) | + (extent.flags & NBD_STATE_ZERO ? BDRV_BLOCK_ZERO : 0); +} + void nbd_client_detach_aio_context(BlockDriverState *bs) { NBDClientSession *client =3D nbd_get_client_session(bs); @@ -828,6 +966,7 @@ int nbd_client_init(BlockDriverState *bs, =20 client->info.request_sizes =3D true; client->info.structured_reply =3D true; + client->info.base_allocation =3D true; ret =3D nbd_receive_negotiate(QIO_CHANNEL(sioc), export, tlscreds, hostname, &client->ioc, &client->info, errp); diff --git a/block/nbd.c b/block/nbd.c index ef81a9f53b..72c90c3c27 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -583,6 +583,7 @@ static BlockDriver bdrv_nbd =3D { .bdrv_detach_aio_context =3D nbd_detach_aio_context, .bdrv_attach_aio_context =3D nbd_attach_aio_context, .bdrv_refresh_filename =3D nbd_refresh_filename, + .bdrv_co_get_block_status =3D nbd_client_co_get_block_status, }; =20 static BlockDriver bdrv_nbd_tcp =3D { @@ -602,6 +603,7 @@ static BlockDriver bdrv_nbd_tcp =3D { .bdrv_detach_aio_context =3D nbd_detach_aio_context, .bdrv_attach_aio_context =3D nbd_attach_aio_context, .bdrv_refresh_filename =3D nbd_refresh_filename, + .bdrv_co_get_block_status =3D nbd_client_co_get_block_status, }; =20 static BlockDriver bdrv_nbd_unix =3D { @@ -621,6 +623,7 @@ static BlockDriver bdrv_nbd_unix =3D { .bdrv_detach_aio_context =3D nbd_detach_aio_context, .bdrv_attach_aio_context =3D nbd_attach_aio_context, .bdrv_refresh_filename =3D nbd_refresh_filename, + .bdrv_co_get_block_status =3D nbd_client_co_get_block_status, }; =20 static void bdrv_nbd_init(void) diff --git a/nbd/client.c b/nbd/client.c index 1f730341c0..61e012ecb0 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -594,6 +594,108 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *i= oc, return QIO_CHANNEL(tioc); } =20 +/* nbd_negotiate_simple_meta_context: + * Set one meta context. Simple means that reply must contain zero (not + * negotiated) or one (negotiated) contexts. More contexts would be consid= ered + * as a protocol error. + * return 1 for successful negotiation, context_id is set + * 0 if operation is unsupported, + * -errno with errp set for any other error + */ +static int nbd_negotiate_simple_meta_context(QIOChannel *ioc, + const char *export, + const char *context, + uint32_t *context_id, + Error **errp) +{ + int ret; + NBDOptionReply reply; + uint32_t received_id; + bool received; + size_t export_len =3D strlen(export); + size_t context_len =3D strlen(context); + size_t data_len =3D 4 + export_len + 4 + 4 + context_len; + + char *data =3D g_malloc(data_len); + char *p =3D data; + + stl_be_p(p, export_len); + memcpy(p +=3D 4, export, export_len); + stl_be_p(p +=3D export_len, 1); + stl_be_p(p +=3D 4, context_len); + memcpy(p +=3D 4, context, context_len); + + ret =3D nbd_send_option_request(ioc, NBD_OPT_SET_META_CONTEXT, data_le= n, data, + errp); + g_free(data); + if (ret < 0) { + return ret; + } + + if (nbd_receive_option_reply(ioc, NBD_OPT_SET_META_CONTEXT, &reply, + errp) < 0) + { + return -1; + } + + ret =3D nbd_handle_reply_err(ioc, &reply, errp); + if (ret <=3D 0) { + return ret; + } + + if (reply.type =3D=3D NBD_REP_META_CONTEXT) { + char *name; + size_t len; + + if (nbd_read(ioc, &received_id, sizeof(received_id), errp) < 0) { + return -EIO; + } + be32_to_cpus(&received_id); + + len =3D reply.length - sizeof(received_id); + name =3D g_malloc(len + 1); + if (nbd_read(ioc, name, len, errp) < 0) { + g_free(name); + return -EIO; + } + name[len] =3D '\0'; + if (strcmp(context, name)) { + error_setg(errp, "Failed to negotiate meta context '%s', serve= r " + "answered with different context '%s'", context, + name); + g_free(name); + return -1; + } + g_free(name); + + received =3D true; + + /* receive NBD_REP_ACK */ + if (nbd_receive_option_reply(ioc, NBD_OPT_SET_META_CONTEXT, &reply, + errp) < 0) + { + return -1; + } + + ret =3D nbd_handle_reply_err(ioc, &reply, errp); + if (ret <=3D 0) { + return ret; + } + } + + if (reply.type !=3D NBD_REP_ACK) { + error_setg(errp, "Unexpected reply type %" PRIx32 " expected %x", + reply.type, NBD_REP_ACK); + return -1; + } + + if (received) { + *context_id =3D received_id; + return 1; + } + + return 0; +} =20 int nbd_receive_negotiate(QIOChannel *ioc, const char *name, QCryptoTLSCreds *tlscreds, const char *hostname, @@ -605,10 +707,12 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char= *name, int rc; bool zeroes =3D true; bool structured_reply =3D info->structured_reply; + bool base_allocation =3D info->base_allocation; =20 trace_nbd_receive_negotiate(tlscreds, hostname ? hostname : ""); =20 info->structured_reply =3D false; + info->base_allocation =3D false; rc =3D -EINVAL; =20 if (outioc) { @@ -699,6 +803,16 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char = *name, info->structured_reply =3D result =3D=3D 1; } =20 + if (info->structured_reply && base_allocation) { + result =3D nbd_negotiate_simple_meta_context( + ioc, name, "base:allocation", + &info->meta_base_allocation_id, errp); + if (result < 0) { + goto fail; + } + info->base_allocation =3D result =3D=3D 1; + } + /* Try NBD_OPT_GO first - if it works, we are done (it * also gives us a good message if the server requires * TLS). If it is not available, fall back to diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out index 7295b3d975..b083e2effd 100644 --- a/tests/qemu-iotests/140.out +++ b/tests/qemu-iotests/140.out @@ -8,7 +8,7 @@ wrote 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} -can't open device nbd+unix:///drv?socket=3DTEST_DIR/nbd: Requested export = not available +can't open device nbd+unix:///drv?socket=3DTEST_DIR/nbd: Invalid parameter= s for option 10 (set meta context) server reported: export 'drv' not present {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "SHUTDOWN", "data": {"guest": false}} diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out index 1c7fb45543..ab6b29b8fb 100644 --- a/tests/qemu-iotests/143.out +++ b/tests/qemu-iotests/143.out @@ -1,7 +1,7 @@ QA output created by 143 {"return": {}} {"return": {}} -can't open device nbd+unix:///no_such_export?socket=3DTEST_DIR/nbd: Reques= ted export not available +can't open device nbd+unix:///no_such_export?socket=3DTEST_DIR/nbd: Invali= d parameters for option 10 (set meta context) server reported: export 'no_such_export' not present {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "SHUTDOWN", "data": {"guest": false}} diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205 index e7b2eae51d..8a8e0df40f 100644 --- a/tests/qemu-iotests/205 +++ b/tests/qemu-iotests/205 @@ -79,7 +79,8 @@ class TestNbdServerRemove(iotests.QMPTestCase): def assertConnectFailed(self, qemu_io_output): self.assertEqual(filter_qemu_io(qemu_io_output).strip(), "can't open device " + nbd_uri + - ": Requested export not available\n" + ": Invalid parameters for option 10 " + "(set meta context)\n" "server reported: export 'exp' not present") =20 def do_test_connect_after_remove(self, mode=3DNone): --=20 2.11.1