* [Qemu-devel] [PATCH 0/2] block/file-posix: Fix unaligned O_DIRECT block status @ 2019-05-14 21:42 Max Reitz 2019-05-14 21:42 ` [Qemu-devel] [PATCH 1/2] block/file-posix: Unaligned O_DIRECT block-status Max Reitz 2019-05-14 21:42 ` [Qemu-devel] [PATCH 2/2] iotests: Test unaligned raw images with O_DIRECT Max Reitz 0 siblings, 2 replies; 6+ messages in thread From: Max Reitz @ 2019-05-14 21:42 UTC (permalink / raw) To: qemu-block; +Cc: Kevin Wolf, qemu-stable, qemu-devel, Max Reitz The user-visible problem: $ echo > foo $ qemu-img map --image-opts driver=file,filename=foo,cache.direct=on Offset Length Mapped to File qemu-img: block/io.c:2093: bdrv_co_block_status: Assertion `*pnum && QEMU_IS_ALIGNED(*pnum, align) && align > offset - aligned_offset' failed. The internal problem: file-posix truncates status requests to the EOF. If the EOF is not aligned at the request_alignment, bdrv_co_block_status() won't like that. See patch 1 for a deeper discussion (including two possible alternatives how we could address the problem). (As I note there, I’ve looked through all block drivers, and I didn’t find any other which could have the same problem. gluster uses the same block-status code, but it doesn’t set a request_alignment. NBD force-aligns the server response in nbd_parse_blockstatus_payload(). qcow2... Should be fine as long as no crypto driver has a block limit exceeding the qcow2 cluster size. And so on.) Patch 2 adds a test. After writing that test, I noticed that we already had one: 109 fails with -c none before patch 1. Er, well, at least the new test is more succinct and has the correct default cache mode, so it will actually do the test if you run ./check without enforcing any cache on a filesystem that supports O_DIRECT. Max Reitz (2): block/file-posix: Unaligned O_DIRECT block-status iotests: Test unaligned raw images with O_DIRECT block/file-posix.c | 17 ++++++++ tests/qemu-iotests/221 | 4 ++ tests/qemu-iotests/253 | 84 ++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/253.out | 14 +++++++ tests/qemu-iotests/group | 1 + 5 files changed, 120 insertions(+) create mode 100755 tests/qemu-iotests/253 create mode 100644 tests/qemu-iotests/253.out -- 2.21.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 1/2] block/file-posix: Unaligned O_DIRECT block-status 2019-05-14 21:42 [Qemu-devel] [PATCH 0/2] block/file-posix: Fix unaligned O_DIRECT block status Max Reitz @ 2019-05-14 21:42 ` Max Reitz 2019-05-14 21:50 ` Eric Blake 2019-05-14 21:42 ` [Qemu-devel] [PATCH 2/2] iotests: Test unaligned raw images with O_DIRECT Max Reitz 1 sibling, 1 reply; 6+ messages in thread From: Max Reitz @ 2019-05-14 21:42 UTC (permalink / raw) To: qemu-block; +Cc: Kevin Wolf, qemu-stable, qemu-devel, Max Reitz Currently, qemu crashes whenever someone queries the block status of an unaligned image tail of an O_DIRECT image: $ echo > foo $ qemu-img map --image-opts driver=file,filename=foo,cache.direct=on Offset Length Mapped to File qemu-img: block/io.c:2093: bdrv_co_block_status: Assertion `*pnum && QEMU_IS_ALIGNED(*pnum, align) && align > offset - aligned_offset' failed. This is because bdrv_co_block_status() checks that the result returned by the driver's implementation is aligned to the request_alignment, but file-posix can fail to do so, which is actually mentioned in a comment there: "[...] possibly including a partial sector at EOF". Fix this by rounding up those partial sectors. There are two possible alternative fixes: (1) We could refuse to open unaligned image files with O_DIRECT altogether. That sounds reasonable until you realize that qcow2 does necessarily not fill up its metadata clusters, and that nobody runs qemu-img create with O_DIRECT. Therefore, unpreallocated qcow2 files usually have an unaligned image tail. (2) bdrv_co_block_status() could ignore unaligned tails. It actually throws away everything past the EOF already, so that sounds reasonable. Unfortunately, the block layer knows file lengths only with a granularity of BDRV_SECTOR_SIZE, so bdrv_co_block_status() usually would have to guess whether its file length information is inexact or whether the driver is broken. Fixing what raw_co_block_status() returns is the safest thing to do. There seems to be no other block driver that sets request_alignment and does not make sure that it always returns aligned values. Cc: qemu-stable@nongnu.org Signed-off-by: Max Reitz <mreitz@redhat.com> --- block/file-posix.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/block/file-posix.c b/block/file-posix.c index e09e15bbf8..f489a5420c 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2488,6 +2488,9 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, off_t data = 0, hole = 0; int ret; + assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment) && + QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment)); + ret = fd_open(bs); if (ret < 0) { return ret; @@ -2513,6 +2516,20 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, /* On a data extent, compute bytes to the end of the extent, * possibly including a partial sector at EOF. */ *pnum = MIN(bytes, hole - offset); + + /* + * We are not allowed to return partial sectors, though, so + * round up if necessary. + */ + if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) { + int64_t file_length = raw_getlength(bs); + if (file_length > 0) { + /* Ignore errors, this is just a safeguard */ + assert(hole == file_length); + } + *pnum = ROUND_UP(*pnum, bs->bl.request_alignment); + } + ret = BDRV_BLOCK_DATA; } else { /* On a hole, compute bytes to the beginning of the next extent. */ -- 2.21.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] block/file-posix: Unaligned O_DIRECT block-status 2019-05-14 21:42 ` [Qemu-devel] [PATCH 1/2] block/file-posix: Unaligned O_DIRECT block-status Max Reitz @ 2019-05-14 21:50 ` Eric Blake 2019-05-15 4:08 ` Max Reitz 0 siblings, 1 reply; 6+ messages in thread From: Eric Blake @ 2019-05-14 21:50 UTC (permalink / raw) To: Max Reitz, qemu-block; +Cc: Kevin Wolf, qemu-devel, qemu-stable [-- Attachment #1: Type: text/plain, Size: 4351 bytes --] On 5/14/19 4:42 PM, Max Reitz wrote: > Currently, qemu crashes whenever someone queries the block status of an > unaligned image tail of an O_DIRECT image: > $ echo > foo > $ qemu-img map --image-opts driver=file,filename=foo,cache.direct=on > Offset Length Mapped to File > qemu-img: block/io.c:2093: bdrv_co_block_status: Assertion `*pnum && > QEMU_IS_ALIGNED(*pnum, align) && align > offset - aligned_offset' > failed. > > This is because bdrv_co_block_status() checks that the result returned > by the driver's implementation is aligned to the request_alignment, but > file-posix can fail to do so, which is actually mentioned in a comment > there: "[...] possibly including a partial sector at EOF". > > Fix this by rounding up those partial sectors. > > There are two possible alternative fixes: > (1) We could refuse to open unaligned image files with O_DIRECT > altogether. That sounds reasonable until you realize that qcow2 > does necessarily not fill up its metadata clusters, and that nobody > runs qemu-img create with O_DIRECT. Therefore, unpreallocated qcow2 > files usually have an unaligned image tail. Yep, non-starter. > > (2) bdrv_co_block_status() could ignore unaligned tails. It actually > throws away everything past the EOF already, so that sounds > reasonable. > Unfortunately, the block layer knows file lengths only with a > granularity of BDRV_SECTOR_SIZE, so bdrv_co_block_status() usually > would have to guess whether its file length information is inexact > or whether the driver is broken. Well, if I ever get around to my thread of making the block layer honor byte-accurate sizes, instead of rounding up, then there is no longer than inexactness. I think our mails crossed, and you missed another idea of mine of having block drivers (probably only file-posix, per your audit) set BDRV_BLOCK_EOF when returning an unaligned answer due to EOF, as the key for letting the block layer know whether the unaligned answer was due to size rounding. > > Fixing what raw_co_block_status() returns is the safest thing to do. Agree. > > There seems to be no other block driver that sets request_alignment and > does not make sure that it always returns aligned values. Thanks for auditing. > > Cc: qemu-stable@nongnu.org > Signed-off-by: Max Reitz <mreitz@redhat.com> > --- > block/file-posix.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/block/file-posix.c b/block/file-posix.c > index e09e15bbf8..f489a5420c 100644 > --- a/block/file-posix.c > +++ b/block/file-posix.c > @@ -2488,6 +2488,9 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, > off_t data = 0, hole = 0; > int ret; > > + assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment) && > + QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment)); > + Can write in one line as: assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment)); > ret = fd_open(bs); > if (ret < 0) { > return ret; > @@ -2513,6 +2516,20 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, > /* On a data extent, compute bytes to the end of the extent, > * possibly including a partial sector at EOF. */ > *pnum = MIN(bytes, hole - offset); > + > + /* > + * We are not allowed to return partial sectors, though, so > + * round up if necessary. > + */ > + if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) { > + int64_t file_length = raw_getlength(bs); > + if (file_length > 0) { > + /* Ignore errors, this is just a safeguard */ > + assert(hole == file_length); > + } > + *pnum = ROUND_UP(*pnum, bs->bl.request_alignment); > + } Reviewed-by: Eric Blake <eblake@redhat.com> bl.request_alignment is normally 1 (making this a no-op), but is definitely larger for O_DIRECT images (where rounding up and treating the post-EOF hole the same as the rest of the sector is the same thing that NBD chose to do). -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] block/file-posix: Unaligned O_DIRECT block-status 2019-05-14 21:50 ` Eric Blake @ 2019-05-15 4:08 ` Max Reitz 0 siblings, 0 replies; 6+ messages in thread From: Max Reitz @ 2019-05-15 4:08 UTC (permalink / raw) To: Eric Blake, qemu-block; +Cc: Kevin Wolf, qemu-devel, qemu-stable [-- Attachment #1: Type: text/plain, Size: 4938 bytes --] On 14.05.19 23:50, Eric Blake wrote: > On 5/14/19 4:42 PM, Max Reitz wrote: >> Currently, qemu crashes whenever someone queries the block status of an >> unaligned image tail of an O_DIRECT image: >> $ echo > foo >> $ qemu-img map --image-opts driver=file,filename=foo,cache.direct=on >> Offset Length Mapped to File >> qemu-img: block/io.c:2093: bdrv_co_block_status: Assertion `*pnum && >> QEMU_IS_ALIGNED(*pnum, align) && align > offset - aligned_offset' >> failed. >> >> This is because bdrv_co_block_status() checks that the result returned >> by the driver's implementation is aligned to the request_alignment, but >> file-posix can fail to do so, which is actually mentioned in a comment >> there: "[...] possibly including a partial sector at EOF". >> >> Fix this by rounding up those partial sectors. >> >> There are two possible alternative fixes: >> (1) We could refuse to open unaligned image files with O_DIRECT >> altogether. That sounds reasonable until you realize that qcow2 >> does necessarily not fill up its metadata clusters, and that nobody >> runs qemu-img create with O_DIRECT. Therefore, unpreallocated qcow2 >> files usually have an unaligned image tail. > > Yep, non-starter. > >> >> (2) bdrv_co_block_status() could ignore unaligned tails. It actually >> throws away everything past the EOF already, so that sounds >> reasonable. >> Unfortunately, the block layer knows file lengths only with a >> granularity of BDRV_SECTOR_SIZE, so bdrv_co_block_status() usually >> would have to guess whether its file length information is inexact >> or whether the driver is broken. > > Well, if I ever get around to my thread of making the block layer honor > byte-accurate sizes, instead of rounding up, then there is no longer > than inexactness. I think our mails crossed, and you missed another idea > of mine of having block drivers (probably only file-posix, per your > audit) set BDRV_BLOCK_EOF when returning an unaligned answer due to EOF, > as the key for letting the block layer know whether the unaligned answer > was due to size rounding. Yes, that EOF change makes sense, I think. Not least because right now the EOF detection in block/io.c has to be a bit wonky considering that it's inexact... But to be honest, returning the EOF flag from the drivers would have required me to modify all drivers. I felt like maybe that something to be left for another time. :-) OTOH, I don’t know whether returning the EOF flag from the drivers would still sense if we had a byte-accurate bdrv_getlength()... >> Fixing what raw_co_block_status() returns is the safest thing to do. > > Agree. > >> >> There seems to be no other block driver that sets request_alignment and >> does not make sure that it always returns aligned values. > > Thanks for auditing. > >> >> Cc: qemu-stable@nongnu.org >> Signed-off-by: Max Reitz <mreitz@redhat.com> >> --- >> block/file-posix.c | 17 +++++++++++++++++ >> 1 file changed, 17 insertions(+) >> >> diff --git a/block/file-posix.c b/block/file-posix.c >> index e09e15bbf8..f489a5420c 100644 >> --- a/block/file-posix.c >> +++ b/block/file-posix.c >> @@ -2488,6 +2488,9 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, >> off_t data = 0, hole = 0; >> int ret; >> >> + assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment) && >> + QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment)); >> + > > Can write in one line as: > > assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment)); Ah, yeah, sure, why not. >> ret = fd_open(bs); >> if (ret < 0) { >> return ret; >> @@ -2513,6 +2516,20 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, >> /* On a data extent, compute bytes to the end of the extent, >> * possibly including a partial sector at EOF. */ >> *pnum = MIN(bytes, hole - offset); >> + >> + /* >> + * We are not allowed to return partial sectors, though, so >> + * round up if necessary. >> + */ >> + if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) { >> + int64_t file_length = raw_getlength(bs); >> + if (file_length > 0) { >> + /* Ignore errors, this is just a safeguard */ >> + assert(hole == file_length); >> + } >> + *pnum = ROUND_UP(*pnum, bs->bl.request_alignment); >> + } > > Reviewed-by: Eric Blake <eblake@redhat.com> Thanks! I'll send a v2 with shorter assert(). Max > bl.request_alignment is normally 1 (making this a no-op), but is > definitely larger for O_DIRECT images (where rounding up and treating > the post-EOF hole the same as the rest of the sector is the same thing > that NBD chose to do). [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 2/2] iotests: Test unaligned raw images with O_DIRECT 2019-05-14 21:42 [Qemu-devel] [PATCH 0/2] block/file-posix: Fix unaligned O_DIRECT block status Max Reitz 2019-05-14 21:42 ` [Qemu-devel] [PATCH 1/2] block/file-posix: Unaligned O_DIRECT block-status Max Reitz @ 2019-05-14 21:42 ` Max Reitz 2019-05-14 21:52 ` Eric Blake 1 sibling, 1 reply; 6+ messages in thread From: Max Reitz @ 2019-05-14 21:42 UTC (permalink / raw) To: qemu-block; +Cc: Kevin Wolf, qemu-stable, qemu-devel, Max Reitz We already have 221 for accesses through the page cache, but it is better to create a new file for O_DIRECT instead of integrating those test cases into 221. This way, we can make use of _supported_cache_modes (and _default_cache_mode) so the test is automatically skipped on filesystems that do not support O_DIRECT. As part of the split, add _supported_cache_modes to 221. With that, it no longer fails when run with -c none or -c directsync. Signed-off-by: Max Reitz <mreitz@redhat.com> --- tests/qemu-iotests/221 | 4 ++ tests/qemu-iotests/253 | 84 ++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/253.out | 14 +++++++ tests/qemu-iotests/group | 1 + 4 files changed, 103 insertions(+) create mode 100755 tests/qemu-iotests/253 create mode 100644 tests/qemu-iotests/253.out diff --git a/tests/qemu-iotests/221 b/tests/qemu-iotests/221 index 25dd47bcfe..0e9096fec7 100755 --- a/tests/qemu-iotests/221 +++ b/tests/qemu-iotests/221 @@ -1,6 +1,7 @@ #!/usr/bin/env bash # # Test qemu-img vs. unaligned images +# (See also 253, which is the O_DIRECT version) # # Copyright (C) 2018-2019 Red Hat, Inc. # @@ -37,6 +38,9 @@ _supported_fmt raw _supported_proto file _supported_os Linux +_default_cache_mode writeback +_supported_cache_modes writeback writethrough unsafe + echo echo "=== Check mapping of unaligned raw image ===" echo diff --git a/tests/qemu-iotests/253 b/tests/qemu-iotests/253 new file mode 100755 index 0000000000..d88d5afa45 --- /dev/null +++ b/tests/qemu-iotests/253 @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +# +# Test qemu-img vs. unaligned images; O_DIRECT version +# (Originates from 221) +# +# Copyright (C) 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 <http://www.gnu.org/licenses/>. +# + +seq="$(basename $0)" +echo "QA output created by $seq" + +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt raw +_supported_proto file +_supported_os Linux + +_default_cache_mode none +_supported_cache_modes none directsync + +echo +echo "=== Check mapping of unaligned raw image ===" +echo + +# We do not know how large a physical sector is, but it is certainly +# going to be a factor of 1 MB +size=$((1 * 1024 * 1024 - 1)) + +# qemu-img create rounds size up to BDRV_SECTOR_SIZE +_make_test_img $size +$QEMU_IMG map --output=json --image-opts \ + "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \ + | _filter_qemu_img_map + +# so we resize it and check again +truncate --size=$size "$TEST_IMG" +$QEMU_IMG map --output=json --image-opts \ + "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \ + | _filter_qemu_img_map + +# qemu-io with O_DIRECT always writes whole physical sectors. Again, +# we do not know how large a physical sector is, so we just start +# writing from a 64 kB boundary, which should always be aligned. +offset=$((1 * 1024 * 1024 - 64 * 1024)) +$QEMU_IO -c "w $offset $((size - offset))" "$TEST_IMG" | _filter_qemu_io +$QEMU_IMG map --output=json --image-opts \ + "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \ + | _filter_qemu_img_map + +# Resize it and check again -- contrary to 221, we may not get partial +# sectors here, so there should be only two areas (one zero, one +# data). +truncate --size=$size "$TEST_IMG" +$QEMU_IMG map --output=json --image-opts \ + "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \ + | _filter_qemu_img_map + +# success, all done +echo '*** done' +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/253.out b/tests/qemu-iotests/253.out new file mode 100644 index 0000000000..607c0baa0b --- /dev/null +++ b/tests/qemu-iotests/253.out @@ -0,0 +1,14 @@ +QA output created by 253 + +=== Check mapping of unaligned raw image === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048575 +[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] +[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] +wrote 65535/65535 bytes at offset 983040 +63.999 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, +{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] +[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, +{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 00e474ab0a..52b7c16e15 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -250,3 +250,4 @@ 248 rw auto quick 249 rw auto quick 252 rw auto backing quick +253 rw auto quick -- 2.21.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH 2/2] iotests: Test unaligned raw images with O_DIRECT 2019-05-14 21:42 ` [Qemu-devel] [PATCH 2/2] iotests: Test unaligned raw images with O_DIRECT Max Reitz @ 2019-05-14 21:52 ` Eric Blake 0 siblings, 0 replies; 6+ messages in thread From: Eric Blake @ 2019-05-14 21:52 UTC (permalink / raw) To: Max Reitz, qemu-block; +Cc: Kevin Wolf, qemu-devel, qemu-stable [-- Attachment #1: Type: text/plain, Size: 6248 bytes --] On 5/14/19 4:42 PM, Max Reitz wrote: > We already have 221 for accesses through the page cache, but it is > better to create a new file for O_DIRECT instead of integrating those > test cases into 221. This way, we can make use of > _supported_cache_modes (and _default_cache_mode) so the test is > automatically skipped on filesystems that do not support O_DIRECT. > > As part of the split, add _supported_cache_modes to 221. With that, it > no longer fails when run with -c none or -c directsync. > > Signed-off-by: Max Reitz <mreitz@redhat.com> > --- > tests/qemu-iotests/221 | 4 ++ > tests/qemu-iotests/253 | 84 ++++++++++++++++++++++++++++++++++++++ > tests/qemu-iotests/253.out | 14 +++++++ > tests/qemu-iotests/group | 1 + > 4 files changed, 103 insertions(+) > create mode 100755 tests/qemu-iotests/253 > create mode 100644 tests/qemu-iotests/253.out Reviewed-by: Eric Blake <eblake@redhat.com> > > diff --git a/tests/qemu-iotests/221 b/tests/qemu-iotests/221 > index 25dd47bcfe..0e9096fec7 100755 > --- a/tests/qemu-iotests/221 > +++ b/tests/qemu-iotests/221 > @@ -1,6 +1,7 @@ > #!/usr/bin/env bash > # > # Test qemu-img vs. unaligned images > +# (See also 253, which is the O_DIRECT version) > # > # Copyright (C) 2018-2019 Red Hat, Inc. > # > @@ -37,6 +38,9 @@ _supported_fmt raw > _supported_proto file > _supported_os Linux > > +_default_cache_mode writeback > +_supported_cache_modes writeback writethrough unsafe > + > echo > echo "=== Check mapping of unaligned raw image ===" > echo > diff --git a/tests/qemu-iotests/253 b/tests/qemu-iotests/253 > new file mode 100755 > index 0000000000..d88d5afa45 > --- /dev/null > +++ b/tests/qemu-iotests/253 > @@ -0,0 +1,84 @@ > +#!/usr/bin/env bash > +# > +# Test qemu-img vs. unaligned images; O_DIRECT version > +# (Originates from 221) > +# > +# Copyright (C) 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 <http://www.gnu.org/licenses/>. > +# > + > +seq="$(basename $0)" > +echo "QA output created by $seq" > + > +status=1 # failure is the default! > + > +_cleanup() > +{ > + _cleanup_test_img > +} > +trap "_cleanup; exit \$status" 0 1 2 3 15 > + > +# get standard environment, filters and checks > +. ./common.rc > +. ./common.filter > + > +_supported_fmt raw > +_supported_proto file > +_supported_os Linux > + > +_default_cache_mode none > +_supported_cache_modes none directsync > + > +echo > +echo "=== Check mapping of unaligned raw image ===" > +echo > + > +# We do not know how large a physical sector is, but it is certainly > +# going to be a factor of 1 MB > +size=$((1 * 1024 * 1024 - 1)) > + > +# qemu-img create rounds size up to BDRV_SECTOR_SIZE > +_make_test_img $size > +$QEMU_IMG map --output=json --image-opts \ > + "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \ > + | _filter_qemu_img_map > + > +# so we resize it and check again > +truncate --size=$size "$TEST_IMG" > +$QEMU_IMG map --output=json --image-opts \ > + "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \ > + | _filter_qemu_img_map > + > +# qemu-io with O_DIRECT always writes whole physical sectors. Again, > +# we do not know how large a physical sector is, so we just start > +# writing from a 64 kB boundary, which should always be aligned. > +offset=$((1 * 1024 * 1024 - 64 * 1024)) > +$QEMU_IO -c "w $offset $((size - offset))" "$TEST_IMG" | _filter_qemu_io > +$QEMU_IMG map --output=json --image-opts \ > + "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \ > + | _filter_qemu_img_map > + > +# Resize it and check again -- contrary to 221, we may not get partial > +# sectors here, so there should be only two areas (one zero, one > +# data). > +truncate --size=$size "$TEST_IMG" > +$QEMU_IMG map --output=json --image-opts \ > + "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \ > + | _filter_qemu_img_map > + > +# success, all done > +echo '*** done' > +rm -f $seq.full > +status=0 > diff --git a/tests/qemu-iotests/253.out b/tests/qemu-iotests/253.out > new file mode 100644 > index 0000000000..607c0baa0b > --- /dev/null > +++ b/tests/qemu-iotests/253.out > @@ -0,0 +1,14 @@ > +QA output created by 253 > + > +=== Check mapping of unaligned raw image === > + > +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048575 > +[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] > +[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] > +wrote 65535/65535 bytes at offset 983040 > +63.999 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) > +[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, > +{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] > +[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, > +{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] > +*** done > diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group > index 00e474ab0a..52b7c16e15 100644 > --- a/tests/qemu-iotests/group > +++ b/tests/qemu-iotests/group > @@ -250,3 +250,4 @@ > 248 rw auto quick > 249 rw auto quick > 252 rw auto backing quick > +253 rw auto quick > -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-05-15 4:09 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-05-14 21:42 [Qemu-devel] [PATCH 0/2] block/file-posix: Fix unaligned O_DIRECT block status Max Reitz 2019-05-14 21:42 ` [Qemu-devel] [PATCH 1/2] block/file-posix: Unaligned O_DIRECT block-status Max Reitz 2019-05-14 21:50 ` Eric Blake 2019-05-15 4:08 ` Max Reitz 2019-05-14 21:42 ` [Qemu-devel] [PATCH 2/2] iotests: Test unaligned raw images with O_DIRECT Max Reitz 2019-05-14 21:52 ` Eric Blake
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).