qcow2: introduce icount field for snapshots

This patch introduces the icount field for saving within the snapshot.
It is required for navigation between the snapshots in record/replay mode.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
Acked-by: Kevin Wolf <kwolf@redhat.com>

--

v7 changes:
 - also fix the test which checks qcow2 snapshot extra data
Message-Id: <160174518284.12451.2301137308458777398.stgit@pasha-ThinkPad-X280>

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Pavel Dovgalyuk 2020-10-03 20:13:02 +03:00 committed by Paolo Bonzini
parent 56db1198a4
commit bbacffc5f7
5 changed files with 58 additions and 23 deletions

View File

@ -164,6 +164,12 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair,
sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
}
if (sn->extra_data_size >= endof(QCowSnapshotExtraData, icount)) {
sn->icount = be64_to_cpu(extra.icount);
} else {
sn->icount = -1ULL;
}
if (sn->extra_data_size > sizeof(extra)) {
uint64_t extra_data_end;
size_t unknown_extra_data_size;
@ -333,6 +339,7 @@ int qcow2_write_snapshots(BlockDriverState *bs)
memset(&extra, 0, sizeof(extra));
extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size);
extra.disk_size = cpu_to_be64(sn->disk_size);
extra.icount = cpu_to_be64(sn->icount);
id_str_size = strlen(sn->id_str);
name_size = strlen(sn->name);

View File

@ -206,6 +206,7 @@ typedef struct QEMU_PACKED QCowSnapshotHeader {
typedef struct QEMU_PACKED QCowSnapshotExtraData {
uint64_t vm_state_size_large;
uint64_t disk_size;
uint64_t icount;
} QCowSnapshotExtraData;
@ -219,6 +220,8 @@ typedef struct QCowSnapshot {
uint32_t date_sec;
uint32_t date_nsec;
uint64_t vm_clock_nsec;
/* icount value for the moment when snapshot was taken */
uint64_t icount;
/* Size of all extra data, including QCowSnapshotExtraData if available */
uint32_t extra_data_size;
/* Data beyond QCowSnapshotExtraData, if any */

View File

@ -707,6 +707,11 @@ Snapshot table entry:
Byte 48 - 55: Virtual disk size of the snapshot in bytes
Byte 56 - 63: icount value which corresponds to
the record/replay instruction count
when the snapshot was taken. Set to -1
if icount was disabled
Version 3 images must include extra data at least up to
byte 55.

View File

@ -91,7 +91,10 @@ print_snapshot_table()
if [ $extra_len -ge 16 ]; then
echo " Disk size: $(peek_file_be "$1" $((extra_ofs + 8)) 8)"
fi
if [ $extra_len -gt 16 ]; then
if [ $extra_len -ge 24 ]; then
echo " Icount: $(peek_file_be "$1" $((extra_ofs + 16)) 8)"
fi
if [ $extra_len -gt 24 ]; then
echo ' Unknown extra data:' \
"$(peek_file_raw "$1" $((extra_ofs + 16)) $((extra_len - 16)) \
| tr -d '\0')"
@ -198,12 +201,12 @@ truncate -s 0 "$TEST_DIR/sn0-extra"
truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn0-pre") - 40)) \
"$TEST_DIR/sn0-post"
# Set sn1's extra data size to 42
poke_file "$TEST_DIR/sn1-pre" 36 '\x00\x00\x00\x2a'
truncate -s 42 "$TEST_DIR/sn1-extra"
poke_file "$TEST_DIR/sn1-extra" 16 'very important data'
# Set sn1's extra data size to 50
poke_file "$TEST_DIR/sn1-pre" 36 '\x00\x00\x00\x32'
truncate -s 50 "$TEST_DIR/sn1-extra"
poke_file "$TEST_DIR/sn1-extra" 24 'very important data'
# Grow sn1-post to pad
truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn1-pre") - 82)) \
truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn1-pre") - 90)) \
"$TEST_DIR/sn1-post"
# Set sn2's extra data size to 8

View File

@ -12,9 +12,10 @@ Snapshots in TEST_DIR/t.IMGFMT.v2.orig:
[1]
ID: 2
Name: sn1
Extra data size: 42
Extra data size: 50
VM state size: 0
Disk size: 67108864
Icount: 0
Unknown extra data: very important data
[2]
ID: 3
@ -29,22 +30,25 @@ Snapshots in TEST_DIR/t.IMGFMT.v3.orig:
[0]
ID: 1
Name: sn0
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
[1]
ID: 2
Name: sn1
Extra data size: 42
Extra data size: 50
VM state size: 0
Disk size: 67108864
Icount: 0
Unknown extra data: very important data
[2]
ID: 3
Name: sn2
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
=== Repair botched v3 ===
@ -61,22 +65,25 @@ Snapshots in TEST_DIR/t.IMGFMT:
[0]
ID: 1
Name: sn0
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
[1]
ID: 2
Name: sn1
Extra data size: 42
Extra data size: 50
VM state size: 0
Disk size: 67108864
Icount: 0
Unknown extra data: very important data
[2]
ID: 3
Name: sn2
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
=== Add new snapshot ===
@ -85,28 +92,32 @@ Snapshots in TEST_DIR/t.IMGFMT:
[0]
ID: 1
Name: sn0
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
[1]
ID: 2
Name: sn1
Extra data size: 42
Extra data size: 50
VM state size: 0
Disk size: 67108864
Icount: 0
Unknown extra data: very important data
[2]
ID: 3
Name: sn2
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
[3]
ID: 4
Name: sn3
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 0
=== Remove different snapshots ===
@ -116,16 +127,18 @@ Snapshots in TEST_DIR/t.IMGFMT:
[0]
ID: 2
Name: sn1
Extra data size: 42
Extra data size: 50
VM state size: 0
Disk size: 67108864
Icount: 0
Unknown extra data: very important data
[1]
ID: 3
Name: sn2
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
--- sn1 ---
No errors were found on the image.
@ -133,15 +146,17 @@ Snapshots in TEST_DIR/t.IMGFMT:
[0]
ID: 1
Name: sn0
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
[1]
ID: 3
Name: sn2
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
--- sn2 ---
No errors were found on the image.
@ -149,15 +164,17 @@ Snapshots in TEST_DIR/t.IMGFMT:
[0]
ID: 1
Name: sn0
Extra data size: 16
Extra data size: 24
VM state size: 0
Disk size: 67108864
Icount: 18446744073709551615
[1]
ID: 2
Name: sn1
Extra data size: 42
Extra data size: 50
VM state size: 0
Disk size: 67108864
Icount: 0
Unknown extra data: very important data
=== Reject too much unknown extra data ===