mirror of https://github.com/xqemu/xqemu.git
replace bdrv_{get, put}_buffer with bdrv_{load, save}_vmstate
The VM state offset is a concept internal to the image format. Replace the old bdrv_{get,put}_buffer method that require an index into the image file that is constructed from the VM state offset and an offset into the vmstate with the bdrv_{load,save}_vmstate that just take an offset into the VM state. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
e1e8f35a4f
commit
45566e9c99
14
block.c
14
block.c
|
@ -1158,24 +1158,26 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||||
return drv->bdrv_get_info(bs, bdi);
|
return drv->bdrv_get_info(bs, bdi);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size)
|
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||||
|
int64_t pos, int size)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
if (!drv)
|
if (!drv)
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
if (!drv->bdrv_put_buffer)
|
if (!drv->bdrv_save_vmstate)
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
return drv->bdrv_put_buffer(bs, buf, pos, size);
|
return drv->bdrv_save_vmstate(bs, buf, pos, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size)
|
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
||||||
|
int64_t pos, int size)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
if (!drv)
|
if (!drv)
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
if (!drv->bdrv_get_buffer)
|
if (!drv->bdrv_load_vmstate)
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
return drv->bdrv_get_buffer(bs, buf, pos, size);
|
return drv->bdrv_load_vmstate(bs, buf, pos, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
|
7
block.h
7
block.h
|
@ -159,9 +159,10 @@ void path_combine(char *dest, int dest_size,
|
||||||
const char *base_path,
|
const char *base_path,
|
||||||
const char *filename);
|
const char *filename);
|
||||||
|
|
||||||
int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf,
|
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||||
int64_t pos, int size);
|
int64_t pos, int size);
|
||||||
|
|
||||||
int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size);
|
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
||||||
|
int64_t pos, int size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -890,12 +890,16 @@ static void qcow_flush(BlockDriverState *bs)
|
||||||
bdrv_flush(s->hd);
|
bdrv_flush(s->hd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int64_t qcow_vm_state_offset(BDRVQcowState *s)
|
||||||
|
{
|
||||||
|
return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
|
||||||
|
}
|
||||||
|
|
||||||
static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
bdi->cluster_size = s->cluster_size;
|
bdi->cluster_size = s->cluster_size;
|
||||||
bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
|
bdi->vm_state_offset = qcow_vm_state_offset(s);
|
||||||
(s->cluster_bits + s->l2_bits);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,26 +929,28 @@ static void dump_refcounts(BlockDriverState *bs)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int qcow_put_buffer(BlockDriverState *bs, const uint8_t *buf,
|
static int qcow_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||||
int64_t pos, int size)
|
int64_t pos, int size)
|
||||||
{
|
{
|
||||||
|
BDRVQcowState *s = bs->opaque;
|
||||||
int growable = bs->growable;
|
int growable = bs->growable;
|
||||||
|
|
||||||
bs->growable = 1;
|
bs->growable = 1;
|
||||||
bdrv_pwrite(bs, pos, buf, size);
|
bdrv_pwrite(bs, qcow_vm_state_offset(s) + pos, buf, size);
|
||||||
bs->growable = growable;
|
bs->growable = growable;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_get_buffer(BlockDriverState *bs, uint8_t *buf,
|
static int qcow_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
||||||
int64_t pos, int size)
|
int64_t pos, int size)
|
||||||
{
|
{
|
||||||
|
BDRVQcowState *s = bs->opaque;
|
||||||
int growable = bs->growable;
|
int growable = bs->growable;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
bs->growable = 1;
|
bs->growable = 1;
|
||||||
ret = bdrv_pread(bs, pos, buf, size);
|
ret = bdrv_pread(bs, qcow_vm_state_offset(s) + pos, buf, size);
|
||||||
bs->growable = growable;
|
bs->growable = growable;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1001,8 +1007,8 @@ static BlockDriver bdrv_qcow2 = {
|
||||||
.bdrv_snapshot_list = qcow2_snapshot_list,
|
.bdrv_snapshot_list = qcow2_snapshot_list,
|
||||||
.bdrv_get_info = qcow_get_info,
|
.bdrv_get_info = qcow_get_info,
|
||||||
|
|
||||||
.bdrv_put_buffer = qcow_put_buffer,
|
.bdrv_save_vmstate = qcow_save_vmstate,
|
||||||
.bdrv_get_buffer = qcow_get_buffer,
|
.bdrv_load_vmstate = qcow_load_vmstate,
|
||||||
|
|
||||||
.create_options = qcow_create_options,
|
.create_options = qcow_create_options,
|
||||||
.bdrv_check = qcow_check,
|
.bdrv_check = qcow_check,
|
||||||
|
|
|
@ -84,10 +84,10 @@ struct BlockDriver {
|
||||||
QEMUSnapshotInfo **psn_info);
|
QEMUSnapshotInfo **psn_info);
|
||||||
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
|
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
|
||||||
|
|
||||||
int (*bdrv_put_buffer)(BlockDriverState *bs, const uint8_t *buf,
|
int (*bdrv_save_vmstate)(BlockDriverState *bs, const uint8_t *buf,
|
||||||
int64_t pos, int size);
|
int64_t pos, int size);
|
||||||
int (*bdrv_get_buffer)(BlockDriverState *bs, uint8_t *buf,
|
int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf,
|
||||||
int64_t pos, int size);
|
int64_t pos, int size);
|
||||||
|
|
||||||
/* removable device specific */
|
/* removable device specific */
|
||||||
int (*bdrv_is_inserted)(BlockDriverState *bs);
|
int (*bdrv_is_inserted)(BlockDriverState *bs);
|
||||||
|
|
46
savevm.c
46
savevm.c
|
@ -337,46 +337,28 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct QEMUFileBdrv
|
|
||||||
{
|
|
||||||
BlockDriverState *bs;
|
|
||||||
int64_t base_offset;
|
|
||||||
} QEMUFileBdrv;
|
|
||||||
|
|
||||||
static int block_put_buffer(void *opaque, const uint8_t *buf,
|
static int block_put_buffer(void *opaque, const uint8_t *buf,
|
||||||
int64_t pos, int size)
|
int64_t pos, int size)
|
||||||
{
|
{
|
||||||
QEMUFileBdrv *s = opaque;
|
bdrv_save_vmstate(opaque, buf, pos, size);
|
||||||
bdrv_put_buffer(s->bs, buf, s->base_offset + pos, size);
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
|
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
|
||||||
{
|
{
|
||||||
QEMUFileBdrv *s = opaque;
|
return bdrv_load_vmstate(opaque, buf, pos, size);
|
||||||
return bdrv_get_buffer(s->bs, buf, s->base_offset + pos, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bdrv_fclose(void *opaque)
|
static int bdrv_fclose(void *opaque)
|
||||||
{
|
{
|
||||||
QEMUFileBdrv *s = opaque;
|
|
||||||
qemu_free(s);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
|
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
|
||||||
{
|
{
|
||||||
QEMUFileBdrv *s;
|
|
||||||
|
|
||||||
s = qemu_mallocz(sizeof(QEMUFileBdrv));
|
|
||||||
|
|
||||||
s->bs = bs;
|
|
||||||
s->base_offset = offset;
|
|
||||||
|
|
||||||
if (is_writable)
|
if (is_writable)
|
||||||
return qemu_fopen_ops(s, block_put_buffer, NULL, bdrv_fclose, NULL, NULL);
|
return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose, NULL, NULL);
|
||||||
|
return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclose, NULL, NULL);
|
||||||
return qemu_fopen_ops(s, NULL, block_get_buffer, bdrv_fclose, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
|
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
|
||||||
|
@ -1069,7 +1051,6 @@ void do_savevm(Monitor *mon, const char *name)
|
||||||
BlockDriverState *bs, *bs1;
|
BlockDriverState *bs, *bs1;
|
||||||
QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
|
QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
|
||||||
int must_delete, ret, i;
|
int must_delete, ret, i;
|
||||||
BlockDriverInfo bdi1, *bdi = &bdi1;
|
|
||||||
QEMUFile *f;
|
QEMUFile *f;
|
||||||
int saved_vm_running;
|
int saved_vm_running;
|
||||||
uint32_t vm_state_size;
|
uint32_t vm_state_size;
|
||||||
|
@ -1119,14 +1100,8 @@ void do_savevm(Monitor *mon, const char *name)
|
||||||
#endif
|
#endif
|
||||||
sn->vm_clock_nsec = qemu_get_clock(vm_clock);
|
sn->vm_clock_nsec = qemu_get_clock(vm_clock);
|
||||||
|
|
||||||
if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
|
|
||||||
monitor_printf(mon, "Device %s does not support VM state snapshots\n",
|
|
||||||
bdrv_get_device_name(bs));
|
|
||||||
goto the_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* save the VM state */
|
/* save the VM state */
|
||||||
f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
|
f = qemu_fopen_bdrv(bs, 1);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
monitor_printf(mon, "Could not open VM state file\n");
|
monitor_printf(mon, "Could not open VM state file\n");
|
||||||
goto the_end;
|
goto the_end;
|
||||||
|
@ -1170,7 +1145,6 @@ void do_savevm(Monitor *mon, const char *name)
|
||||||
void do_loadvm(Monitor *mon, const char *name)
|
void do_loadvm(Monitor *mon, const char *name)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs, *bs1;
|
BlockDriverState *bs, *bs1;
|
||||||
BlockDriverInfo bdi1, *bdi = &bdi1;
|
|
||||||
QEMUSnapshotInfo sn;
|
QEMUSnapshotInfo sn;
|
||||||
QEMUFile *f;
|
QEMUFile *f;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
@ -1218,19 +1192,13 @@ void do_loadvm(Monitor *mon, const char *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
|
|
||||||
monitor_printf(mon, "Device %s does not support VM state snapshots\n",
|
|
||||||
bdrv_get_device_name(bs));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't even try to load empty VM states */
|
/* Don't even try to load empty VM states */
|
||||||
ret = bdrv_snapshot_find(bs, &sn, name);
|
ret = bdrv_snapshot_find(bs, &sn, name);
|
||||||
if ((ret >= 0) && (sn.vm_state_size == 0))
|
if ((ret >= 0) && (sn.vm_state_size == 0))
|
||||||
goto the_end;
|
goto the_end;
|
||||||
|
|
||||||
/* restore the VM state */
|
/* restore the VM state */
|
||||||
f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
|
f = qemu_fopen_bdrv(bs, 0);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
monitor_printf(mon, "Could not open VM state file\n");
|
monitor_printf(mon, "Could not open VM state file\n");
|
||||||
goto the_end;
|
goto the_end;
|
||||||
|
|
Loading…
Reference in New Issue