[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 11/14] qcow2: Allow >4 GB VM state
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PATCH 11/14] qcow2: Allow >4 GB VM state |
Date: |
Thu, 15 Dec 2011 15:09:26 +0100 |
This is a compatible extension to the snapshot header format that allows
saving a 64 bit VM state size.
Signed-off-by: Kevin Wolf <address@hidden>
---
block.h | 2 +-
block/qcow2-snapshot.c | 34 ++++++++++++++++++++++++++++++++--
block/qcow2.h | 2 +-
docs/specs/qcow2.txt | 8 +++++++-
savevm.c | 2 +-
5 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/block.h b/block.h
index 0e3ff9f..3bd4398 100644
--- a/block.h
+++ b/block.h
@@ -22,7 +22,7 @@ typedef struct QEMUSnapshotInfo {
/* the following fields are informative. They are not needed for
the consistency of the snapshot */
char name[256]; /* user chosen name */
- uint32_t vm_state_size; /* VM state info size */
+ uint64_t vm_state_size; /* VM state info size */
uint32_t date_sec; /* UTC date of the snapshot */
uint32_t date_nsec;
uint64_t vm_clock_nsec; /* VM clock relative to boot */
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index c3112bf..7d3fde5 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -46,6 +46,10 @@ typedef struct QEMU_PACKED QCowSnapshotHeader {
/* name follows */
} QCowSnapshotHeader;
+typedef struct QEMU_PACKED QCowSnapshotExtraData {
+ uint64_t vm_state_size_large;
+} QCowSnapshotExtraData;
+
void qcow2_free_snapshots(BlockDriverState *bs)
{
BDRVQcowState *s = bs->opaque;
@@ -64,6 +68,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
{
BDRVQcowState *s = bs->opaque;
QCowSnapshotHeader h;
+ QCowSnapshotExtraData extra;
QCowSnapshot *sn;
int i, id_str_size, name_size;
int64_t offset;
@@ -100,9 +105,18 @@ int qcow2_read_snapshots(BlockDriverState *bs)
id_str_size = be16_to_cpu(h.id_str_size);
name_size = be16_to_cpu(h.name_size);
- /* Skip extra data */
+ /* Read extra data */
+ ret = bdrv_pread(bs->file, offset, &extra,
+ MIN(sizeof(extra), extra_data_size));
+ if (ret < 0) {
+ goto fail;
+ }
offset += extra_data_size;
+ if (extra_data_size >= 8) {
+ sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large);
+ }
+
/* Read snapshot ID */
sn->id_str = g_malloc(id_str_size + 1);
ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size);
@@ -136,6 +150,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
BDRVQcowState *s = bs->opaque;
QCowSnapshot *sn;
QCowSnapshotHeader h;
+ QCowSnapshotExtraData extra;
int i, name_size, id_str_size, snapshots_size;
struct {
uint32_t nb_snapshots;
@@ -150,6 +165,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
sn = s->snapshots + i;
offset = align_offset(offset, 8);
offset += sizeof(h);
+ offset += sizeof(extra);
offset += strlen(sn->id_str);
offset += strlen(sn->name);
}
@@ -169,10 +185,18 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
memset(&h, 0, sizeof(h));
h.l1_table_offset = cpu_to_be64(sn->l1_table_offset);
h.l1_size = cpu_to_be32(sn->l1_size);
- h.vm_state_size = cpu_to_be32(sn->vm_state_size);
+ /* If it doesn't fit in 32 bit, older implementations should treat it
+ * as a disk-only snapshot rather than truncate the VM state */
+ if (sn->vm_state_size <= 0xffffffff) {
+ h.vm_state_size = cpu_to_be32(sn->vm_state_size);
+ }
h.date_sec = cpu_to_be32(sn->date_sec);
h.date_nsec = cpu_to_be32(sn->date_nsec);
h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);
+ h.extra_data_size = cpu_to_be32(sizeof(extra));
+
+ memset(&extra, 0, sizeof(extra));
+ extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size);
id_str_size = strlen(sn->id_str);
name_size = strlen(sn->name);
@@ -186,6 +210,12 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
}
offset += sizeof(h);
+ ret = bdrv_pwrite(bs->file, offset, &extra, sizeof(extra));
+ if (ret < 0) {
+ goto fail;
+ }
+ offset += sizeof(extra);
+
ret = bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size);
if (ret < 0) {
goto fail;
diff --git a/block/qcow2.h b/block/qcow2.h
index 4e44eea..99e4536 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -78,7 +78,7 @@ typedef struct QCowSnapshot {
uint32_t l1_size;
char *id_str;
char *name;
- uint32_t vm_state_size;
+ uint64_t vm_state_size;
uint32_t date_sec;
uint32_t date_nsec;
uint64_t vm_clock_nsec;
diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
index e792953..b6adcad 100644
--- a/docs/specs/qcow2.txt
+++ b/docs/specs/qcow2.txt
@@ -253,7 +253,13 @@ Snapshot table entry:
36 - 39: Size of extra data in the table entry (used for future
extensions of the format)
- variable: Extra data for future extensions. Must be ignored.
+ variable: Extra data for future extensions. Unknown fields must be
+ ignored. Currently defined are (offset relative to snapshot
+ table entry):
+
+ Byte 40 - 47: Size of the VM state in bytes. 0 if no VM
+ state is saved. If this field is present,
+ the 32-bit value in bytes 32-35 is ignored.
variable: Unique ID string for the snapshot (not null terminated)
diff --git a/savevm.c b/savevm.c
index b72f6c0..f153c25 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2002,7 +2002,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
int ret;
QEMUFile *f;
int saved_vm_running;
- uint32_t vm_state_size;
+ uint64_t vm_state_size;
#ifdef _WIN32
struct _timeb tb;
struct tm *ptm;
--
1.7.6.4
- [Qemu-devel] [PULL 00/14] Block patches, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 01/14] block: bdrv_aio_* do not return NULL, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 02/14] block: simplify failure handling for bdrv_aio_multiwrite, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 06/14] block: avoid useless checks on acb->bh, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 03/14] block: qemu_aio_get does not return NULL, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 07/14] block/qcow2.c: call qcow2_free_snapshots in the function of qcow2_close, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 04/14] dma: the passed io_func does not return NULL, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 08/14] rbd: always set out parameter in qemu_rbd_snap_list, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 05/14] block: dma_bdrv_* does not return NULL, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 11/14] qcow2: Allow >4 GB VM state,
Kevin Wolf <=
- [Qemu-devel] [PATCH 09/14] qemu-img rebase: Fix for undersized backing files, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 13/14] block/cow: Return real error code, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 14/14] qiov: prevent double free or use-after-free, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 10/14] Documentation: Add qemu-img -t parameter in man page, Kevin Wolf, 2011/12/15
- [Qemu-devel] [PATCH 12/14] coroutine: switch per-thread free pool to a global pool, Kevin Wolf, 2011/12/15
- Re: [Qemu-devel] [PULL 00/14] Block patches, Anthony Liguori, 2011/12/19