Commit c6bb9ad1 authored by Federico Simoncelli's avatar Federico Simoncelli Committed by Kevin Wolf
Browse files

qemu-img: find the image end offset during check



This patch adds the support for reporting the image end offset (in
bytes). This is particularly useful after a conversion (or a rebase)
where the destination is a block device in order to find the first
unused byte at the end of the image.

Signed-off-by: default avatarFederico Simoncelli <fsimonce@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 5cbb0828
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -1112,7 +1112,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
                          BdrvCheckMode fix)
{
    BDRVQcowState *s = bs->opaque;
    int64_t size, i;
    int64_t size, i, highest_cluster;
    int nb_clusters, refcount1, refcount2;
    QCowSnapshot *sn;
    uint16_t *refcount_table;
@@ -1183,7 +1183,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
    }

    /* compare ref counts */
    for(i = 0; i < nb_clusters; i++) {
    for (i = 0, highest_cluster = 0; i < nb_clusters; i++) {
        refcount1 = get_refcount(bs, i);
        if (refcount1 < 0) {
            fprintf(stderr, "Can't get refcount for cluster %" PRId64 ": %s\n",
@@ -1193,6 +1193,11 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
        }

        refcount2 = refcount_table[i];

        if (refcount1 > 0 || refcount2 > 0) {
            highest_cluster = i;
        }

        if (refcount1 != refcount2) {

            /* Check if we're allowed to fix the mismatch */
@@ -1227,6 +1232,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
        }
    }

    res->image_end_offset = (highest_cluster + 1) * s->cluster_size;
    ret = 0;

fail:
+1 −0
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ typedef struct BdrvCheckResult {
    int check_errors;
    int corruptions_fixed;
    int leaks_fixed;
    int64_t image_end_offset;
    BlockFragInfo bfi;
} BdrvCheckResult;

+4 −0
Original line number Diff line number Diff line
@@ -475,6 +475,10 @@ static int img_check(int argc, char **argv)
        result.bfi.fragmented_clusters * 100.0 / result.bfi.allocated_clusters);
    }

    if (result.image_end_offset > 0) {
        printf("Image end offset: %" PRId64 "\n", result.image_end_offset);
    }

    bdrv_delete(bs);

    if (ret < 0 || result.check_errors) {
+3 −3
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ if [ "$event" == "l2_load" ]; then
    $QEMU_IO -c "read $vmstate 0 128k " $BLKDBG_TEST_IMG | _filter_qemu_io
fi

$QEMU_IMG check $TEST_IMG 2>&1 | grep -v "refcount=1 reference=0"
_check_test_img 2>&1 | grep -v "refcount=1 reference=0"

done
done
@@ -147,7 +147,7 @@ echo
echo "Event: $event; errno: $errno; imm: $imm; once: $once; write $vmstate"
$QEMU_IO -c "write $vmstate 0 64M" $BLKDBG_TEST_IMG | _filter_qemu_io

$QEMU_IMG check $TEST_IMG 2>&1 | grep -v "refcount=1 reference=0"
_check_test_img 2>&1 | grep -v "refcount=1 reference=0"

done
done
@@ -186,7 +186,7 @@ echo
echo "Event: $event; errno: $errno; imm: $imm; once: $once"
$QEMU_IO -c "write -b 0 64k" $BLKDBG_TEST_IMG | _filter_qemu_io

$QEMU_IMG check $TEST_IMG 2>&1 | grep -v "refcount=1 reference=0"
_check_test_img 2>&1 | grep -v "refcount=1 reference=0"

done
done
+2 −1
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ _make_test_img 64M
echo
echo === Repair image ===
echo
$QEMU_IMG check -r all $TEST_IMG
_check_test_img -r all

./qcow2.py $TEST_IMG dump-header

# success, all done
Loading