11.06.2021 17:01, Eric Blake wrote:
The recently-added NBD context qemu:allocation-depth is able to
distinguish between locally-present data (even with that data is
sparse) [shown as depth 1 over NBD], and data that could not be found
anywhere in the backing chain [shown as depth 0]. But qemu-img map
--output=json predates that addition, and prior to this patch has the
unfortunate behavior that all portions of the backing chain that
resolve without finding a hit in any backing layer report the same
depth as the final backing layer. This makes it harder to reconstruct
a qcow2 backing chain using just 'qemu-img map' output, especially
when using "backing":null to artificially limit a backing chain,
because it is impossible to distinguish between a
QCOW2_CLUSTER_UNALLOCATED (which defers to a [missing] backing file)
and a QCOW2_CLUSTER_ZERO_PLAIN cluster (which would override any
backing file), since both types of clusters otherwise show as
"data":false,"zero":true" (but note that we can distinguish a
QCOW2_CLUSTER_ZERO_ALLOCATED, which would also have an "offset":
listing).
The task of reconstructing a qcow2 chain was made harder in commit
0da9856851 (nbd: server: Report holes for raw images), because prior
to that point, it was possible to abuse NBD's block status command to
see which portions of a qcow2 file resulted in BDRV_BLOCK_ALLOCATED
(showing up as NBD_STATE_ZERO in isolation) vs. missing from the chain
(showing up as NBD_STATE_ZERO|NBD_STATE_HOLE); but now qemu reports
more accurate sparseness information over NBD.
An obvious solution is to make 'qemu-img map --output=json'
distinguish between clusters that have a local allocation from those
that are found nowhere in the chain. We already have a one-off
mismatch between qemu-img map and NBD qemu:allocation-depth (the
former chose 0, and the latter 1 for the local layer), so exposing the
latter's choice of 0 for unallocated in the entire chain would mean
using using "depth":-1 in the former, but a negative depth may confuse
existing tools. But there is an easy out: for any chain of length N,
we can simply represent an unallocated cluster as "depth":N+1. This
does have a slight risk of confusing any tool that might try to
dereference NULL when finding the backing image for the last file in
the backing chain, but that risk sseems worth the more precise output.
The iotests have several examples where this distinction demonstrates
the additional accuracy.
Signed-off-by: Eric Blake <ebl...@redhat.com>
---
Replaces v1: 20210610213906.1313440-1-ebl...@redhat.com
(qemu-img: Use "depth":-1 to make backing probes obvious)
Use N+1 instead of -1 for unallocated [Kevin]
Bit in contrast with -1, or with separate boolean flag, you lose the
possibility to distinguish case when we have 3 layers and the cluster is absent
in all of them, and the case when we have 4 layers and the cluster is absent in
top 3 but in 4 it is qcow2 UNALLOCATED_ZERO cluster.
So, if someone use this API to reconstruct the chain, then for original 3 empty
layers he will create 3 empty layers and 4rd additional ZERO layer. And such
reconstructed chain would not be equal to original chain (as if we take these
two chains and add additional backing file as a new bottom layer, effect would
be different).. I'm not sure is it a problem in the task you are solving :\
--
Best regards,
Vladimir