From nobody Mon May 6 13:32:17 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553834282049541.8753069326874; Thu, 28 Mar 2019 21:38:02 -0700 (PDT) Received: from localhost ([127.0.0.1]:46090 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jH9-0002dd-Mr for importer@patchew.org; Fri, 29 Mar 2019 00:37:55 -0400 Received: from eggs.gnu.org ([209.51.188.92]:59280) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jFU-0001eH-Ci for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:36:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h9j8h-0000VH-RH for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:29:13 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48606) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h9j8g-0000Ug-3N; Fri, 29 Mar 2019 00:29:10 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 65D183082E57; Fri, 29 Mar 2019 04:29:09 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-59.phx2.redhat.com [10.3.116.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id B1F7360BE2; Fri, 29 Mar 2019 04:29:08 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 28 Mar 2019 23:27:45 -0500 Message-Id: <20190329042750.14704-2-eblake@redhat.com> In-Reply-To: <20190329042750.14704-1-eblake@redhat.com> References: <20190329042750.14704-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 29 Mar 2019 04:29:09 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 1/6] iotests: Add 241 to test NBD on unaligned images X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, rjones@redhat.com, "open list:Block layer core" , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Add a test for the NBD client workaround in the previous patch. It's not really feasible for an iotest to assume a specific tracing engine, so we can't really probe trace_nbd_parse_blockstatus_compliance to see if the server was fixed vs. whether the client just worked around the server (other than by rearranging order between code patches and this test). But having a successful exchange sure beats the previous state of an error message. Not tested yet, but worth adding to this test in future patches: an NBD server that can advertise a non-sector-aligned size (such as nbdkit) causes qemu as the NBD client to misbehave when it rounds the size up and accesses beyond the advertised size. Qemu as NBD server never advertises a non-sector-aligned size (since bdrv_getlength() currently rounds up to sector boundaries); until qemu can act as such a server, testing that flaw will have to rely on external binaries. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy Tested-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/241 | 70 ++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/241.out | 7 ++++ tests/qemu-iotests/group | 1 + 3 files changed, 78 insertions(+) create mode 100755 tests/qemu-iotests/241 create mode 100644 tests/qemu-iotests/241.out diff --git a/tests/qemu-iotests/241 b/tests/qemu-iotests/241 new file mode 100755 index 00000000000..44871158918 --- /dev/null +++ b/tests/qemu-iotests/241 @@ -0,0 +1,70 @@ +#!/bin/bash +# +# Test qemu-nbd vs. unaligned images +# +# Copyright (C) 2018-2019 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +seq=3D"$(basename $0)" +echo "QA output created by $seq" + +status=3D1 # failure is the default! + +nbd_unix_socket=3D$TEST_DIR/test_qemu_nbd_socket + +_cleanup() +{ + _cleanup_test_img + nbd_server_stop +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.nbd + +_supported_fmt raw +_supported_proto nbd +_supported_os Linux +_require_command QEMU_NBD + +echo +echo "=3D=3D=3D Exporting unaligned raw image =3D=3D=3D" +echo + +# can't use _make_test_img, because qemu-img rounds image size up, +# and because we want to use Unix socket rather than TCP port. Likewise, +# we have to redirect TEST_IMG to our server. +# This tests that we can deal with the hole at the end of an unaligned +# raw file (either because the server doesn't advertise alignment too +# large, or because the client ignores the server's noncompliance). +printf %01000d 0 > "$TEST_IMG_FILE" +nbd_server_start_unix_socket -f $IMGFMT "$TEST_IMG_FILE" +TEST_IMG=3D"nbd:unix:$nbd_unix_socket" + +$QEMU_IMG map --output=3Djson "$TEST_IMG" | _filter_qemu_img_map +$QEMU_IO -c map "$TEST_IMG" + +# Not tested yet: we also want to ensure that qemu as NBD client does +# not access beyond the end of a server's advertised unaligned size. +# However, since qemu as server always rounds up to a sector alignment, +# we would have to use nbdkit to provoke the current client failures. + +# success, all done +echo '*** done' +rm -f $seq.full +status=3D0 diff --git a/tests/qemu-iotests/241.out b/tests/qemu-iotests/241.out new file mode 100644 index 00000000000..044afc0c6f8 --- /dev/null +++ b/tests/qemu-iotests/241.out @@ -0,0 +1,7 @@ +QA output created by 241 + +=3D=3D=3D Exporting unaligned raw image =3D=3D=3D + +[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true}] +1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 41da10c6cf5..bae77183809 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -240,6 +240,7 @@ 238 auto quick 239 rw auto quick 240 auto quick +241 rw auto quick 242 rw auto quick 243 rw auto quick 244 rw auto quick --=20 2.20.1 From nobody Mon May 6 13:32:17 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 155383456050337.78416000579239; Thu, 28 Mar 2019 21:42:40 -0700 (PDT) Received: from localhost ([127.0.0.1]:46173 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jLV-00077J-Ed for importer@patchew.org; Fri, 29 Mar 2019 00:42:25 -0400 Received: from eggs.gnu.org ([209.51.188.92]:59599) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jG2-000222-8b for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:36:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h9j8k-0000WH-5S for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:29:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43922) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h9j8i-0000VL-Ih; Fri, 29 Mar 2019 00:29:12 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C34B3307D90E; Fri, 29 Mar 2019 04:29:11 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-59.phx2.redhat.com [10.3.116.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 91CE060BE2; Fri, 29 Mar 2019 04:29:09 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 28 Mar 2019 23:27:46 -0500 Message-Id: <20190329042750.14704-3-eblake@redhat.com> In-Reply-To: <20190329042750.14704-1-eblake@redhat.com> References: <20190329042750.14704-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 29 Mar 2019 04:29:11 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 2/6] nbd/client: Lower min_block for block-status, unaligned size X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, rjones@redhat.com, "open list:Network Block Dev..." , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" We have a latent bug in our NBD client code, tickled by the brand new nbdkit 1.11.10 block status support: $ nbdkit --filter=3Dlog --filter=3Dtruncate -U - \ data data=3D"1" size=3D511 truncate=3D64K logfile=3D/dev/stdout \ --run 'qemu-img convert $nbd /var/tmp/out' ... qemu-img: block/io.c:2122: bdrv_co_block_status: Assertion `*pnum && QEMU_I= S_ALIGNED(*pnum, align) && align > offset - aligned_offset' failed. The culprit? Our implementation of .bdrv_co_block_status can return unaligned block status for any server that operates with a lower actual alignment than what we tell the block layer in request_alignment, in violation of the block layer's constraints. To date, we've been unable to trip the bug, because qemu as NBD server always advertises block sizing (at which point it is a server bug if the server sends unaligned status - although qemu 3.1 is such a server and I've sent separate patches for 4.0 both to get the server to obey the spec, and to let the client to tolerate server oddities at EOF). But nbdkit does not (yet) advertise block sizing, and therefore is not in violation of the spec for returning block status at whatever boundaries it wants, and those unaligned results can occur anywhere rather than just at EOF. While we are still wise to avoid sending sub-sector read/write requests to a server of unknown origin, we MUST consider that a server telling us block status without an advertised block size is correct. So, we either have to munge unaligned answers from the server into aligned ones that we hand back to the block layer, or we have to tell the block layer about a smaller alignment. Similarly, if the server advertises an image size that is not sector-aligned, we might as well assume that the server intends to let us access those tail bytes, and therefore supports a minimum block size of 1, regardless of whether the server supports block status (although we still need more patches to fix the problem that with an unaligned image, we can send read or block status requests that exceed EOF to the server). Again, qemu as server cannot trip this problem (because it rounds images to sector alignment), but nbdkit advertised unaligned size even before it gained block status support. Solve both alignment problems at once by using better heuristics on what alignment to report to the block layer when the server did not give us something to work with. Note that very few NBD servers implement block status (to date, only qemu and nbdkit are known to do so); and as the NBD spec mentioned block sizing constraints prior to documenting block status, it can be assumed that any future implementations of block status are aware that they must advertise block size if they want a minimum size other than 1. We've had a long history of struggles with picking the right alignment to use in the block layer, as evidenced by the commit message of fd8d372d (v2.12) that introduced the current choice of forced 512-byte alignment. There is no iotest coverage for this fix, because qemu can't provoke it, and I didn't want to make test 241 dependent on nbdkit. Fixes: fd8d372d Reported-by: Richard W.M. Jones Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/nbd.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/block/nbd.c b/block/nbd.c index 2e72df528ac..208be596027 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -437,7 +437,24 @@ static void nbd_refresh_limits(BlockDriverState *bs, E= rror **errp) uint32_t min =3D s->info.min_block; uint32_t max =3D MIN_NON_ZERO(NBD_MAX_BUFFER_SIZE, s->info.max_block); - bs->bl.request_alignment =3D min ? min : BDRV_SECTOR_SIZE; + /* + * If the server did not advertise an alignment: + * - a size that is not sector-aligned implies that an alignment + * of 1 can be used to access those tail bytes + * - advertisement of block status requires an alignment of 1, so + * that we don't violate block layer constraints that block + * status is always aligned (as we can't control whether the + * server will report sub-sector extents, such as a hole at EOF + * on an unaligned POSIX file) + * - otherwise, assume the server is so old that we are safer avoiding + * sub-sector requests + */ + if (!min) { + min =3D (!QEMU_IS_ALIGNED(s->info.size, BDRV_SECTOR_SIZE) || + s->info.base_allocation) ? 1 : BDRV_SECTOR_SIZE; + } + + bs->bl.request_alignment =3D min; bs->bl.max_pdiscard =3D max; bs->bl.max_pwrite_zeroes =3D max; bs->bl.max_transfer =3D max; --=20 2.20.1 From nobody Mon May 6 13:32:17 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553834419958500.82426913457834; Thu, 28 Mar 2019 21:40:19 -0700 (PDT) Received: from localhost ([127.0.0.1]:46122 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jJQ-00053U-MJ for importer@patchew.org; Fri, 29 Mar 2019 00:40:16 -0400 Received: from eggs.gnu.org ([209.51.188.92]:59305) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jFz-0001fH-7H for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:36:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h9j8l-0000Wd-3e for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:29:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48614) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h9j8j-0000Ve-CJ; Fri, 29 Mar 2019 00:29:13 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A8B5D3082E50; Fri, 29 Mar 2019 04:29:12 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-59.phx2.redhat.com [10.3.116.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 01BD3619EE; Fri, 29 Mar 2019 04:29:11 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 28 Mar 2019 23:27:47 -0500 Message-Id: <20190329042750.14704-4-eblake@redhat.com> In-Reply-To: <20190329042750.14704-1-eblake@redhat.com> References: <20190329042750.14704-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 29 Mar 2019 04:29:12 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 3/6] nbd/client: Report offsets in bdrv_block_status X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, rjones@redhat.com, "open list:Network Block Dev..." , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" It is desirable for 'qemu-img map' to have the same output for a file whether it is served over file or nbd protocols. However, ever since we implemented block status for NBD (2.12), the NBD protocol forgot to inform the block layer that as the final layer in the chain, the offset is valid; without an offset, the human-readable form of qemu-img map gives up with the unhelpful: $ nbdkit -U - data data=3D"1" size=3D512 --run 'qemu-img map $nbd' Offset Length Mapped to File qemu-img: File contains external, encrypted or compressed clusters. The --output=3Djson form always works, because it is reporting the lower-level bdrv_block_status results directly rather than trying to filter out sparse ranges for human consumption. With this patch, the output changes to: Offset Length Mapped to File 0 0x200 0 nbd+unix://?socket=3D/tmp/n= bdkitOxeoLa/socket This change is observable to several iotests. Fixes: 78a33ab5 Reported-by: Richard W.M. Jones Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/nbd-client.c | 9 +++++++-- tests/qemu-iotests/209.out | 4 ++-- tests/qemu-iotests/223.out | 18 +++++++++--------- tests/qemu-iotests/241.out | 2 +- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/block/nbd-client.c b/block/nbd-client.c index 150af9cc46f..3edb508f668 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -972,7 +972,9 @@ int coroutine_fn nbd_client_co_block_status(BlockDriver= State *bs, if (!client->info.base_allocation) { *pnum =3D bytes; - return BDRV_BLOCK_DATA; + *map =3D offset; + *file =3D bs; + return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID; } ret =3D nbd_co_send_request(bs, &request, NULL); @@ -995,8 +997,11 @@ int coroutine_fn nbd_client_co_block_status(BlockDrive= rState *bs, assert(extent.length); *pnum =3D extent.length; + *map =3D offset; + *file =3D bs; return (extent.flags & NBD_STATE_HOLE ? 0 : BDRV_BLOCK_DATA) | - (extent.flags & NBD_STATE_ZERO ? BDRV_BLOCK_ZERO : 0); + (extent.flags & NBD_STATE_ZERO ? BDRV_BLOCK_ZERO : 0) | + BDRV_BLOCK_OFFSET_VALID; } void nbd_client_detach_aio_context(BlockDriverState *bs) diff --git a/tests/qemu-iotests/209.out b/tests/qemu-iotests/209.out index 0d29724e84a..214e27bfcec 100644 --- a/tests/qemu-iotests/209.out +++ b/tests/qemu-iotests/209.out @@ -1,2 +1,2 @@ -[{ "start": 0, "length": 524288, "depth": 0, "zero": false, "data": true}, -{ "start": 524288, "length": 524288, "depth": 0, "zero": true, "data": fal= se}] +[{ "start": 0, "length": 524288, "depth": 0, "zero": false, "data": true, = "offset": 0}, +{ "start": 524288, "length": 524288, "depth": 0, "zero": true, "data": fal= se, "offset": 524288}] diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out index 95c40a17ad7..7828a447392 100644 --- a/tests/qemu-iotests/223.out +++ b/tests/qemu-iotests/223.out @@ -67,18 +67,18 @@ read 1048576/1048576 bytes at offset 1048576 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) read 2097152/2097152 bytes at offset 2097152 2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true}, -{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": fals= e}, -{ "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": = true}] +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "o= ffset": OFFSET}, +{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": fals= e, "offset": OFFSET}, +{ "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": = true, "offset": OFFSET}] [{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false}, -{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": tr= ue}, +{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": tr= ue, "offset": OFFSET}, { "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": = false}] =3D=3D=3D Contrast to small granularity dirty-bitmap =3D=3D=3D -[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true}, +[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true, "of= fset": OFFSET}, { "start": 512, "length": 512, "depth": 0, "zero": false, "data": false}, -{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": tru= e}, +{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": tru= e, "offset": OFFSET}, { "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": = false}] =3D=3D=3D End qemu NBD server =3D=3D=3D @@ -94,10 +94,10 @@ read 2097152/2097152 bytes at offset 2097152 =3D=3D=3D Use qemu-nbd as server =3D=3D=3D [{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false}, -{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": tr= ue}, +{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": tr= ue, "offset": OFFSET}, { "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": = false}] -[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true}, +[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true, "of= fset": OFFSET}, { "start": 512, "length": 512, "depth": 0, "zero": false, "data": false}, -{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": tru= e}, +{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": tru= e, "offset": OFFSET}, { "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": = false}] *** done diff --git a/tests/qemu-iotests/241.out b/tests/qemu-iotests/241.out index 044afc0c6f8..91dcde97560 100644 --- a/tests/qemu-iotests/241.out +++ b/tests/qemu-iotests/241.out @@ -2,6 +2,6 @@ QA output created by 241 =3D=3D=3D Exporting unaligned raw image =3D=3D=3D -[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true}] +[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true, "o= ffset": OFFSET}] 1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) *** done --=20 2.20.1 From nobody Mon May 6 13:32:17 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553834557122443.94987413272133; Thu, 28 Mar 2019 21:42:37 -0700 (PDT) Received: from localhost ([127.0.0.1]:46171 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jLR-00074k-PQ for importer@patchew.org; Fri, 29 Mar 2019 00:42:21 -0400 Received: from eggs.gnu.org ([209.51.188.92]:59280) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jFy-0001eH-Gc for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:36:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h9j8l-0000YJ-R3 for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:29:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37326) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h9j8k-0000W8-8g; Fri, 29 Mar 2019 00:29:14 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8BA123082B67; Fri, 29 Mar 2019 04:29:13 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-59.phx2.redhat.com [10.3.116.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id D745560BE2; Fri, 29 Mar 2019 04:29:12 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 28 Mar 2019 23:27:48 -0500 Message-Id: <20190329042750.14704-5-eblake@redhat.com> In-Reply-To: <20190329042750.14704-1-eblake@redhat.com> References: <20190329042750.14704-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 29 Mar 2019 04:29:13 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 4/6] nbd/client: Support qemu-img convert from unaligned size X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, rjones@redhat.com, "open list:Network Block Dev..." , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" If an NBD server advertises a size that is not a multiple of a sector, the block layer rounds up that size, even though we set info.size to the exact byte value sent by the server. The block layer then proceeds to let us read or query block status on the hole that it added past EOF, which the NBD server is unlikely to be happy with. Fortunately, qemu as a server never advertizes an unaligned size, so we generally don't run into this problem; but the nbdkit server makes it easy to test: $ printf %1000d 1 > f1 $ ~/nbdkit/nbdkit -fv file f1 & pid=3D$! $ qemu-img convert -f raw nbd://localhost:10809 f2 $ kill $pid $ qemu-img compare f1 f2 Pre-patch, the server attempts a 1024-byte read, which nbdkit rightfully rejects as going beyond its advertised 1000 byte size; the conversion fails and the output files differ (not even the first sector is copied, because qemu-img does not follow ddrescue's habit of trying smaller reads to get as much information as possible in spite of errors). Post-patch, the client's attempts to read (and query block status, for new enough nbdkit) are properly truncated to the server's length, with sane handling of the hole the block layer forced on us. Although f2 ends up as a larger file (1024 bytes instead of 1000), qemu-img compare shows the two images to have identical contents for display to the guest. I didn't add iotests coverage since I didn't want to add a dependency on nbdkit in iotests. I also did NOT patch write, trim, or write zeroes - these commands continue to fail (usually with ENOSPC, but whatever the server chose), because we really can't write to the end of the file, and because 'qemu-img convert' is the most common case where we care about being tolerant (which is read-only). Perhaps we could truncate the request if the client is writing zeros to the tail, but that seems like more work, especially if the block layer is fixed in 4.1 to track byte-accurate sizing (in which case this patch would be reverted as unnecessary). Signed-off-by: Eric Blake --- block/nbd-client.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/block/nbd-client.c b/block/nbd-client.c index 3edb508f668..409c2171bc3 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -848,6 +848,25 @@ int nbd_client_co_preadv(BlockDriverState *bs, uint64_= t offset, if (!bytes) { return 0; } + /* + * Work around the fact that the block layer doesn't do + * byte-accurate sizing yet - if the read exceeds the server's + * advertised size because the block layer rounded size up, then + * truncate the request to the server and tail-pad with zero. + */ + if (offset >=3D client->info.size) { + assert(bytes < BDRV_SECTOR_SIZE); + qemu_iovec_memset(qiov, 0, 0, bytes); + return 0; + } + if (offset + bytes > client->info.size) { + uint64_t slop =3D offset + bytes - client->info.size; + + assert(slop < BDRV_SECTOR_SIZE); + qemu_iovec_memset(qiov, bytes - slop, 0, slop); + request.len -=3D slop; + } + ret =3D nbd_co_send_request(bs, &request, NULL); if (ret < 0) { return ret; @@ -966,7 +985,8 @@ int coroutine_fn nbd_client_co_block_status(BlockDriver= State *bs, .from =3D offset, .len =3D MIN(MIN_NON_ZERO(QEMU_ALIGN_DOWN(INT_MAX, bs->bl.request_alignment), - client->info.max_block), bytes), + client->info.max_block), + MIN(bytes, client->info.size - offset)), .flags =3D NBD_CMD_FLAG_REQ_ONE, }; @@ -977,6 +997,23 @@ int coroutine_fn nbd_client_co_block_status(BlockDrive= rState *bs, return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID; } + /* + * Work around the fact that the block layer doesn't do + * byte-accurate sizing yet - if the status request exceeds the + * server's advertised size because the block layer rounded size + * up, we truncated the request to the server (above), or are + * called on just the hole. + */ + if (offset >=3D client->info.size) { + *pnum =3D bytes; + assert(bytes < BDRV_SECTOR_SIZE); + /* Intentionally don't report offset_valid for the hole */ + return BDRV_BLOCK_ZERO; + } + + if (client->info.min_block) { + assert(QEMU_IS_ALIGNED(request.len, client->info.min_block)); + } ret =3D nbd_co_send_request(bs, &request, NULL); if (ret < 0) { return ret; --=20 2.20.1 From nobody Mon May 6 13:32:17 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553834448242607.8074649470702; Thu, 28 Mar 2019 21:40:48 -0700 (PDT) Received: from localhost ([127.0.0.1]:46155 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jJv-0005ms-1F for importer@patchew.org; Fri, 29 Mar 2019 00:40:47 -0400 Received: from eggs.gnu.org ([209.51.188.92]:59305) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jFy-0001fH-0k for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:36:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h9j8m-0000Yk-Do for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:29:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48620) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h9j8l-0000WT-3v; Fri, 29 Mar 2019 00:29:15 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6D5843082E57; Fri, 29 Mar 2019 04:29:14 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-59.phx2.redhat.com [10.3.116.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id BB5BD60BE2; Fri, 29 Mar 2019 04:29:13 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 28 Mar 2019 23:27:49 -0500 Message-Id: <20190329042750.14704-6-eblake@redhat.com> In-Reply-To: <20190329042750.14704-1-eblake@redhat.com> References: <20190329042750.14704-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 29 Mar 2019 04:29:14 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 5/6] block: Add bdrv_get_request_alignment() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, rjones@redhat.com, "open list:Block layer core" , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The next patch needs access to a device's minimum permitted alignment, since NBD wants to advertise this to clients. Add an accessor function, borrowing from blk_get_max_transfer() for accessing a backend's block limits. Signed-off-by: Eric Blake Message-Id: <20180802144834.520904-2-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/sysemu/block-backend.h | 1 + block/block-backend.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index e2066eb06b2..3be05c2d689 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -177,6 +177,7 @@ bool blk_is_available(BlockBackend *blk); void blk_lock_medium(BlockBackend *blk, bool locked); void blk_eject(BlockBackend *blk, bool eject_flag); int blk_get_flags(BlockBackend *blk); +uint32_t blk_get_request_alignment(BlockBackend *blk); uint32_t blk_get_max_transfer(BlockBackend *blk); int blk_get_max_iov(BlockBackend *blk); void blk_set_guest_block_size(BlockBackend *blk, int align); diff --git a/block/block-backend.c b/block/block-backend.c index edad02a0f2a..f78e82a707f 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1764,6 +1764,13 @@ int blk_get_flags(BlockBackend *blk) } } +/* Returns the minimum request alignment, in bytes; guaranteed nonzero */ +uint32_t blk_get_request_alignment(BlockBackend *blk) +{ + BlockDriverState *bs =3D blk_bs(blk); + return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE; +} + /* Returns the maximum transfer length, in bytes; guaranteed nonzero */ uint32_t blk_get_max_transfer(BlockBackend *blk) { --=20 2.20.1 From nobody Mon May 6 13:32:17 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 155383432013117.475884406341606; Thu, 28 Mar 2019 21:38:40 -0700 (PDT) Received: from localhost ([127.0.0.1]:46102 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jHp-0003FU-2l for importer@patchew.org; Fri, 29 Mar 2019 00:38:37 -0400 Received: from eggs.gnu.org ([209.51.188.92]:59305) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9jFw-0001fH-Ko for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:36:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h9j8n-0000ZC-JS for qemu-devel@nongnu.org; Fri, 29 Mar 2019 00:29:18 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47808) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h9j8m-0000Xo-0N; Fri, 29 Mar 2019 00:29:16 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5034459454; Fri, 29 Mar 2019 04:29:15 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-59.phx2.redhat.com [10.3.116.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9EFFA619EE; Fri, 29 Mar 2019 04:29:14 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 28 Mar 2019 23:27:50 -0500 Message-Id: <20190329042750.14704-7-eblake@redhat.com> In-Reply-To: <20190329042750.14704-1-eblake@redhat.com> References: <20190329042750.14704-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 29 Mar 2019 04:29:15 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 6/6] nbd/server: Advertise actual minimum block size X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, rjones@redhat.com, "open list:Network Block Dev..." , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Both NBD_CMD_BLOCK_STATUS and structured NBD_CMD_READ will split their reply according to bdrv_block_status() boundaries. If the block device has a request_alignment smaller than 512, but we advertise a block alignment of 512 to the client, then this can result in the server reply violating client expectations by reporting a smaller region of the export than what the client is permitted to address (although this is less of an issue for qemu 4.0 clients, given recent client patches to overlook our non-compliance at EOF). Since it's always better to be strict in what we send, it is worth advertising the actual minimum block limit rather than blindly rounding it up to 512. Note that this patch is not foolproof - it is still possible to provoke non-compliant server behavior using: $ qemu-nbd --image-opts driver=3Dblkdebug,align=3D512,image.driver=3Dfile,i= mage.filename=3D/path/to/non-aligned-file That is arguably a bug in the blkdebug driver (it should never pass back block status smaller than its alignment, even if it has to make multiple bdrv_get_status calls and determine the least-common-denominator status among the group to return). It may also be possible to observe issues with a backing layer with smaller alignment than the active layer, although so far I have been unable to write a reliable iotest for that scenario (but again, an issue like that could be argued to be a bug in the block layer, or something where we need a flag to bdrv_block_status() to state whether the result must be aligned to the current layer's limits or can be subdivided for accuracy when chasing backing files). Anyways, as blkdebug is not normally used, and as this patch makes our server more interoperable with qemu 3.1 clients, it is worth applying now, even while we still work on a larger patch series for the 4.1 timeframe to have byte-accurate file lengths. Note that the iotests output changes - both pre- and post-patch, the server is reporting a mid-sector hole; but pre-patch, the client was then rounding that up to a sector boundary as a workaround, while post-patch the client doesn't have to round because it sees the server's smaller advertised block size. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- nbd/server.c | 13 ++++++++----- tests/qemu-iotests/241.out | 3 ++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index fd013a2817a..218a2aa5e65 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -607,13 +607,16 @@ static int nbd_negotiate_handle_info(NBDClient *clien= t, uint16_t myflags, /* Send NBD_INFO_BLOCK_SIZE always, but tweak the minimum size * according to whether the client requested it, and according to * whether this is OPT_INFO or OPT_GO. */ - /* minimum - 1 for back-compat, or 512 if client is new enough. - * TODO: consult blk_bs(blk)->bl.request_alignment? */ - sizes[0] =3D - (client->opt =3D=3D NBD_OPT_INFO || blocksize) ? BDRV_SECTOR_S= IZE : 1; + /* minimum - 1 for back-compat, or actual if client will obey it. */ + if (client->opt =3D=3D NBD_OPT_INFO || blocksize) { + sizes[0] =3D blk_get_request_alignment(exp->blk); + } else { + sizes[0] =3D 1; + } + assert(sizes[0] <=3D NBD_MAX_BUFFER_SIZE); /* preferred - Hard-code to 4096 for now. * TODO: is blk_bs(blk)->bl.opt_transfer appropriate? */ - sizes[1] =3D 4096; + sizes[1] =3D MAX(4096, sizes[0]); /* maximum - At most 32M, but smaller as appropriate. */ sizes[2] =3D MIN(blk_get_max_transfer(exp->blk), NBD_MAX_BUFFER_SIZE); trace_nbd_negotiate_handle_info_block_size(sizes[0], sizes[1], sizes[2= ]); diff --git a/tests/qemu-iotests/241.out b/tests/qemu-iotests/241.out index 91dcde97560..eccc7254d12 100644 --- a/tests/qemu-iotests/241.out +++ b/tests/qemu-iotests/241.out @@ -2,6 +2,7 @@ QA output created by 241 =3D=3D=3D Exporting unaligned raw image =3D=3D=3D -[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true, "o= ffset": OFFSET}] +[{ "start": 0, "length": 1000, "depth": 0, "zero": false, "data": true, "o= ffset": OFFSET}, +{ "start": 1000, "length": 24, "depth": 0, "zero": true, "data": true, "of= fset": OFFSET}] 1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) *** done --=20 2.20.1 From nobody Mon May 6 13:32:17 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553879049574875.842539897671; Fri, 29 Mar 2019 10:04:09 -0700 (PDT) Received: from localhost ([127.0.0.1]:33125 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9uvF-0006HG-IO for importer@patchew.org; Fri, 29 Mar 2019 13:04:05 -0400 Received: from eggs.gnu.org ([209.51.188.92]:37613) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9uqK-0002IO-8P for qemu-devel@nongnu.org; Fri, 29 Mar 2019 12:59:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h9uSL-0003AG-Qx for qemu-devel@nongnu.org; Fri, 29 Mar 2019 12:34:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51800) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h9uSK-00039j-FM; Fri, 29 Mar 2019 12:34:12 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BCA77C066458; Fri, 29 Mar 2019 16:34:11 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-59.phx2.redhat.com [10.3.116.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id E2F3F61781; Fri, 29 Mar 2019 16:34:08 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 29 Mar 2019 11:34:07 -0500 Message-Id: <20190329163407.26919-1-eblake@redhat.com> In-Reply-To: <20190329042750.14704-1-eblake@redhat.com> References: <20190329042750.14704-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Fri, 29 Mar 2019 16:34:11 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 7/6] nbd/client: Ignore inaccessible tail of inconsistent 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: vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The NBD spec suggests that a server should never advertise a size inconsistent with its minimum block alignment, as that tail is effectively inaccessible to a compliant client obeying those block constraints. Although the block layer likes to round up, here, we'd prefer to truncate down to obey the spec, and note that it is the server's fault for advertising bogus size. Does not impact either qemu (which always sends properly aligned sizes) or nbdkit (which does not send minimum block requirements yet); so this is mostly theoretical, to avoid potential asserts elsewhere in the code that assume the size is aligned. Signed-off-by: Eric Blake --- nbd/client.c | 8 +++++++- nbd/trace-events | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/nbd/client.c b/nbd/client.c index de7da48246b..be437051429 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2018 Red Hat, Inc. + * Copyright (C) 2016-2019 Red Hat, Inc. * Copyright (C) 2005 Anthony Liguori * * Network Block Device Client Side @@ -426,6 +426,12 @@ static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_= t opt, nbd_send_opt_abort(ioc); return -1; } + if (info->min_block && + !QEMU_IS_ALIGNED(info->size, info->min_block)) { + trace_nbd_opt_info_go_unaligned_size(info->size, + info->min_block); + info->size =3D QEMU_ALIGN_DOWN(info->size, info->min_block= ); + } trace_nbd_receive_negotiate_size_flags(info->size, info->flags= ); break; diff --git a/nbd/trace-events b/nbd/trace-events index a6cca8fdf83..49dd48c9620 100644 --- a/nbd/trace-events +++ b/nbd/trace-events @@ -8,6 +8,7 @@ nbd_reply_err_unsup(uint32_t option, const char *name) "ser= ver doesn't understan nbd_receive_list(const char *name, const char *desc) "export list includes= '%s', description '%s'" nbd_opt_info_go_start(const char *opt, const char *name) "Attempting %s fo= r export '%s'" nbd_opt_info_go_success(const char *opt) "Export is ready after %s request" +nbd_opt_info_go_unaligned_size(uint64_t size, uint32_t align) "Server repo= rted unaligned size 0x%" PRIx64 " for alignment 0x%x; truncating" nbd_opt_info_unknown(int info, const char *name) "Ignoring unknown info %d= (%s)" nbd_opt_info_block_size(uint32_t minimum, uint32_t preferred, uint32_t max= imum) "Block sizes are 0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32 nbd_receive_query_exports_start(const char *wantname) "Querying export lis= t for '%s'" --=20 2.20.1 From nobody Mon May 6 13:32:17 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553961591885821.6759946741547; Sat, 30 Mar 2019 08:59:51 -0700 (PDT) Received: from localhost ([127.0.0.1]:46492 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hAGOO-0001OW-0v for importer@patchew.org; Sat, 30 Mar 2019 11:59:36 -0400 Received: from eggs.gnu.org ([209.51.188.92]:56179) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hAGNV-00015l-5i for qemu-devel@nongnu.org; Sat, 30 Mar 2019 11:58:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hAGNM-0000sB-TW for qemu-devel@nongnu.org; Sat, 30 Mar 2019 11:58:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40914) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hAGMx-0000Oq-CO; Sat, 30 Mar 2019 11:58:09 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8E48381DF4; Sat, 30 Mar 2019 15:57:09 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-75.phx2.redhat.com [10.3.116.75]) by smtp.corp.redhat.com (Postfix) with ESMTP id 494195C1A1; Sat, 30 Mar 2019 15:57:06 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Sat, 30 Mar 2019 10:57:04 -0500 Message-Id: <20190330155704.24191-1-eblake@redhat.com> In-Reply-To: <20190329042750.14704-1-eblake@redhat.com> References: <20190329042750.14704-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Sat, 30 Mar 2019 15:57:09 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3.1 3.5/6] nbd/client: Reject inaccessible tail of inconsistent 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: vsementsov@virtuozzo.com, jsnow@redhat.com, rjones@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The NBD spec suggests that a server should never advertise a size inconsistent with its minimum block alignment, as that tail is effectively inaccessible to a compliant client obeying those block constraints. Since we have a habit of rounding up rather than truncating, to avoid losing the last few bytes of user input, and we cannot access the tail when the server advertises bogus block sizing, abort the connection to alert the server to fix their bug. And rejecting such servers matches what we already did for a min_block that was not a power of 2 or which was larger than max_block. Does not impact either qemu (which always sends properly aligned sizes) or nbdkit (which does not send minimum block requirements yet); so this is mostly aimed at new NBD server implementations, and ensures that the rest of our code can assume the size is aligned. Signed-off-by: Eric Blake Message-Id: <20190329163407.26919-1-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy --- This is the rewrite of the original 7/6 that I posted, retitled and hoisted earlier in the series (since Vladimir was right that 4/6 depends on it). I've added patches 1-3 to my NBD queue for a pull request on Monday as they now have R-b; I'd love to also have enough reviews for 3.5, 4, 5, 6, and also another thread on fixing 'qemu-img info' output, to include those as well. nbd/client.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nbd/client.c b/nbd/client.c index de7da48246b..9f5eb79930c 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -426,6 +426,14 @@ static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_= t opt, nbd_send_opt_abort(ioc); return -1; } + if (info->min_block && + !QEMU_IS_ALIGNED(info->size, info->min_block)) { + error_setg(errp, "server size %" PRIu64 "is not multiple o= f " + "minimum block size %" PRIu32, info->size, + info->min_block); + nbd_send_opt_abort(ioc); + return -1; + } trace_nbd_receive_negotiate_size_flags(info->size, info->flags= ); break; --=20 2.20.1 From nobody Mon May 6 13:32:17 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553965120628770.1098351335901; Sat, 30 Mar 2019 09:58:40 -0700 (PDT) Received: from localhost ([127.0.0.1]:35348 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hAHJG-0007aF-HC for importer@patchew.org; Sat, 30 Mar 2019 12:58:22 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33923) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hAHIK-0007HI-LV for qemu-devel@nongnu.org; Sat, 30 Mar 2019 12:57:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hAHI2-00065f-Jx for qemu-devel@nongnu.org; Sat, 30 Mar 2019 12:57:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35770) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hAHHH-0004TU-HG; Sat, 30 Mar 2019 12:56:24 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D5622308339D; Sat, 30 Mar 2019 16:53:56 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-75.phx2.redhat.com [10.3.116.75]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2BB655C1A1; Sat, 30 Mar 2019 16:53:54 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Sat, 30 Mar 2019 11:53:49 -0500 Message-Id: <20190330165349.32256-1-eblake@redhat.com> In-Reply-To: <20190329042750.14704-1-eblake@redhat.com> References: <20190329042750.14704-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Sat, 30 Mar 2019 16:53:56 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 6.5/6] nbd/client: Trace server noncompliance on structured reads X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, qemu-block@nongnu.org, rjones@redhat.com, Max Reitz , jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Just as we recently added a trace for a server sending block status that doesn't match the server's advertised minimum block alignment, let's do the same for read chunks. But since qemu 3.1 is such a server (because it advertised 512-byte alignment, but when serving a file that ends in data but is not sector-aligned, NBD_CMD_READ would detect a mid-sector change between data and hole at EOF and the resulting read chunks are unaligned), we don't want to change our behavior of otherwise tolerating unaligned reads. Note that even though we fixed the server for 4.0 to advertise an actual block alignment (which gets rid of the unaligned reads at EOF for posix files), we can still trigger it via other means: $ qemu-nbd --image-opts driver=3Dblkdebug,align=3D512,image.driver=3Dfile,i= mage.filename=3D/path/to/non-aligned-file Arguably, that is a bug in the blkdebug block status function, for leaking a block status that is not aligned. It may also be possible to observe issues with a backing layer with smaller alignment than the active layer, although so far I have been unable to write a reliable iotest for that scenario. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/nbd-client.c | 12 ++++++++++-- block/trace-events | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/block/nbd-client.c b/block/nbd-client.c index 409c2171bc3..790ecc1ee1c 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -211,7 +211,8 @@ static inline uint64_t payload_advance64(uint8_t **payl= oad) return ldq_be_p(*payload - 8); } -static int nbd_parse_offset_hole_payload(NBDStructuredReplyChunk *chunk, +static int nbd_parse_offset_hole_payload(NBDClientSession *client, + NBDStructuredReplyChunk *chunk, uint8_t *payload, uint64_t orig_o= ffset, QEMUIOVector *qiov, Error **errp) { @@ -233,6 +234,10 @@ static int nbd_parse_offset_hole_payload(NBDStructured= ReplyChunk *chunk, " region"); return -EINVAL; } + if (client->info.min_block && + !QEMU_IS_ALIGNED(hole_size, client->info.min_block)) { + trace_nbd_structured_read_compliance("hole"); + } qemu_iovec_memset(qiov, offset - orig_offset, 0, hole_size); @@ -390,6 +395,9 @@ static int nbd_co_receive_offset_data_payload(NBDClient= Session *s, " region"); return -EINVAL; } + if (s->info.min_block && !QEMU_IS_ALIGNED(data_size, s->info.min_block= )) { + trace_nbd_structured_read_compliance("data"); + } qemu_iovec_init(&sub_qiov, qiov->niov); qemu_iovec_concat(&sub_qiov, qiov, offset - orig_offset, data_size); @@ -712,7 +720,7 @@ static int nbd_co_receive_cmdread_reply(NBDClientSessio= n *s, uint64_t handle, * in qiov */ break; case NBD_REPLY_TYPE_OFFSET_HOLE: - ret =3D nbd_parse_offset_hole_payload(&reply.structured, paylo= ad, + ret =3D nbd_parse_offset_hole_payload(s, &reply.structured, pa= yload, offset, qiov, &local_err); if (ret < 0) { s->quit =3D true; diff --git a/block/trace-events b/block/trace-events index debb25c0ac8..7335a425404 100644 --- a/block/trace-events +++ b/block/trace-events @@ -158,6 +158,7 @@ iscsi_xcopy(void *src_lun, uint64_t src_off, void *dst_= lun, uint64_t dst_off, ui # nbd-client.c nbd_parse_blockstatus_compliance(const char *err) "ignoring extra data fro= m non-compliant server: %s" +nbd_structured_read_compliance(const char *type) "server sent non-complian= t unaligned read %s chunk" nbd_read_reply_entry_fail(int ret, const char *err) "ret =3D %d, err: %s" nbd_co_request_fail(uint64_t from, uint32_t len, uint64_t handle, uint16_t= flags, uint16_t type, const char *name, int ret, const char *err) "Request= failed { .from =3D %" PRIu64", .len =3D %" PRIu32 ", .handle =3D %" PRIu64= ", .flags =3D 0x%" PRIx16 ", .type =3D %" PRIu16 " (%s) } ret =3D %d, err:= %s" --=20 2.20.1