qcow2: Make qemu-img check detect corrupted L1 tables in snapshots
'qemu-img check' cannot detect if a snapshot's L1 table is corrupted. This patch checks the table's offset and size and reports corruption if the values are not valid. This patch doesn't add code to fix that corruption yet, only to detect and report it. Signed-off-by: Alberto Garcia <berto@igalia.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
db5794f1f1
commit
0c2ada8136
@ -2047,6 +2047,20 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
/* snapshots */
|
||||
for (i = 0; i < s->nb_snapshots; i++) {
|
||||
sn = s->snapshots + i;
|
||||
if (offset_into_cluster(s, sn->l1_table_offset)) {
|
||||
fprintf(stderr, "ERROR snapshot %s (%s) l1_offset=%#" PRIx64 ": "
|
||||
"L1 table is not cluster aligned; snapshot table entry "
|
||||
"corrupted\n", sn->id_str, sn->name, sn->l1_table_offset);
|
||||
res->corruptions++;
|
||||
continue;
|
||||
}
|
||||
if (sn->l1_size > QCOW_MAX_L1_SIZE / sizeof(uint64_t)) {
|
||||
fprintf(stderr, "ERROR snapshot %s (%s) l1_size=%#" PRIx32 ": "
|
||||
"L1 table is too large; snapshot table entry corrupted\n",
|
||||
sn->id_str, sn->name, sn->l1_size);
|
||||
res->corruptions++;
|
||||
continue;
|
||||
}
|
||||
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
|
||||
sn->l1_table_offset, sn->l1_size, 0, fix);
|
||||
if (ret < 0) {
|
||||
|
@ -182,6 +182,7 @@ poke_file "$TEST_IMG" "$offset_snap1_l1_offset" "\x00\x00\x00\x00\x00\x40\x02\x0
|
||||
-c 'write 0 4k'; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IMG snapshot -a test $TEST_IMG; } 2>&1 | _filter_testdir
|
||||
{ $QEMU_IMG snapshot -d test $TEST_IMG; } 2>&1 | _filter_testdir
|
||||
_check_test_img
|
||||
|
||||
echo
|
||||
echo "== Invalid snapshot L1 table size =="
|
||||
@ -195,6 +196,7 @@ poke_file "$TEST_IMG" "$offset_snap1_l1_size" "\x10\x00\x00\x00"
|
||||
-c 'write 0 4k'; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IMG snapshot -a test $TEST_IMG; } 2>&1 | _filter_testdir
|
||||
{ $QEMU_IMG snapshot -d test $TEST_IMG; } 2>&1 | _filter_testdir
|
||||
_check_test_img
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
|
@ -71,6 +71,16 @@ write failed: Invalid argument
|
||||
qemu-img: Snapshot L1 table offset invalid
|
||||
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: Invalid argument
|
||||
qemu-img: Could not delete snapshot 'test': Snapshot L1 table offset invalid
|
||||
ERROR snapshot 1 (test) l1_offset=0x400200: L1 table is not cluster aligned; snapshot table entry corrupted
|
||||
Leaked cluster 4 refcount=2 reference=1
|
||||
Leaked cluster 5 refcount=2 reference=1
|
||||
Leaked cluster 6 refcount=1 reference=0
|
||||
|
||||
1 errors were found on the image.
|
||||
Data may be corrupted, or further writes to the image may corrupt it.
|
||||
|
||||
3 leaked clusters were found on the image.
|
||||
This means waste of disk space, but no harm to data.
|
||||
|
||||
== Invalid snapshot L1 table size ==
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
@ -84,4 +94,14 @@ write failed: File too large
|
||||
qemu-img: Snapshot L1 table too large
|
||||
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: File too large
|
||||
qemu-img: Could not delete snapshot 'test': Snapshot L1 table too large
|
||||
ERROR snapshot 1 (test) l1_size=0x10000000: L1 table is too large; snapshot table entry corrupted
|
||||
Leaked cluster 4 refcount=2 reference=1
|
||||
Leaked cluster 5 refcount=2 reference=1
|
||||
Leaked cluster 6 refcount=1 reference=0
|
||||
|
||||
1 errors were found on the image.
|
||||
Data may be corrupted, or further writes to the image may corrupt it.
|
||||
|
||||
3 leaked clusters were found on the image.
|
||||
This means waste of disk space, but no harm to data.
|
||||
*** done
|
||||
|
Loading…
Reference in New Issue
Block a user