qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

nbd/client: Report offsets in bdrv_block_status

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="1" size=512 --run 'qemu-img map $nbd'
Offset Length Mapped to File
qemu-img: File contains external, encrypted or compressed clusters.

The --output=json 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 - but now it also
shows the offset member.

With this patch, the human output changes to:

Offset Length Mapped to File
0 0x200 0 nbd+unix://?socket=/tmp/nbdkitOxeoLa/socket

This change is observable to several iotests.

Fixes: 78a33ab5
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20190329042750.14704-4-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>

+21 -16
+7 -2
block/nbd-client.c
··· 972 972 973 973 if (!client->info.base_allocation) { 974 974 *pnum = bytes; 975 - return BDRV_BLOCK_DATA; 975 + *map = offset; 976 + *file = bs; 977 + return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID; 976 978 } 977 979 978 980 ret = nbd_co_send_request(bs, &request, NULL); ··· 995 997 996 998 assert(extent.length); 997 999 *pnum = extent.length; 1000 + *map = offset; 1001 + *file = bs; 998 1002 return (extent.flags & NBD_STATE_HOLE ? 0 : BDRV_BLOCK_DATA) | 999 - (extent.flags & NBD_STATE_ZERO ? BDRV_BLOCK_ZERO : 0); 1003 + (extent.flags & NBD_STATE_ZERO ? BDRV_BLOCK_ZERO : 0) | 1004 + BDRV_BLOCK_OFFSET_VALID; 1000 1005 } 1001 1006 1002 1007 void nbd_client_detach_aio_context(BlockDriverState *bs)
+2 -2
tests/qemu-iotests/209.out
··· 1 - [{ "start": 0, "length": 524288, "depth": 0, "zero": false, "data": true}, 2 - { "start": 524288, "length": 524288, "depth": 0, "zero": true, "data": false}] 1 + [{ "start": 0, "length": 524288, "depth": 0, "zero": false, "data": true, "offset": 0}, 2 + { "start": 524288, "length": 524288, "depth": 0, "zero": true, "data": false, "offset": 524288}]
+9 -9
tests/qemu-iotests/223.out
··· 67 67 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 68 68 read 2097152/2097152 bytes at offset 2097152 69 69 2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 70 - [{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true}, 71 - { "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false}, 72 - { "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": true}] 70 + [{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, 71 + { "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, 72 + { "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] 73 73 [{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false}, 74 - { "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true}, 74 + { "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, 75 75 { "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}] 76 76 77 77 === Contrast to small granularity dirty-bitmap === 78 78 79 - [{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true}, 79 + [{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, 80 80 { "start": 512, "length": 512, "depth": 0, "zero": false, "data": false}, 81 - { "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true}, 81 + { "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, 82 82 { "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}] 83 83 84 84 === End qemu NBD server === ··· 94 94 === Use qemu-nbd as server === 95 95 96 96 [{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false}, 97 - { "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true}, 97 + { "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, 98 98 { "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}] 99 - [{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true}, 99 + [{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, 100 100 { "start": 512, "length": 512, "depth": 0, "zero": false, "data": false}, 101 - { "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true}, 101 + { "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, 102 102 { "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}] 103 103 *** done
+3 -3
tests/qemu-iotests/241.out
··· 4 4 5 5 size: 1024 6 6 min block: 512 7 - [{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true}] 7 + [{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] 8 8 1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) 9 9 10 10 === Exporting unaligned raw image, forced server sector alignment === ··· 14 14 Specify the 'raw' format explicitly to remove the restrictions. 15 15 size: 1024 16 16 min block: 512 17 - [{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true}] 17 + [{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] 18 18 1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) 19 19 20 20 === Exporting unaligned raw image, forced client sector alignment === 21 21 22 22 size: 1024 23 23 min block: 512 24 - [{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true}] 24 + [{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] 25 25 1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) 26 26 *** done