Commit 45566e9c authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Anthony Liguori
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKevin Wolf <kwolf@redhat.com>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent e1e8f35a
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -1158,24 +1158,26 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *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;
    if (!drv)
        return -ENOMEDIUM;
    if (!drv->bdrv_put_buffer)
    if (!drv->bdrv_save_vmstate)
        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;
    if (!drv)
        return -ENOMEDIUM;
    if (!drv->bdrv_get_buffer)
    if (!drv->bdrv_load_vmstate)
        return -ENOTSUP;
    return drv->bdrv_get_buffer(bs, buf, pos, size);
    return drv->bdrv_load_vmstate(bs, buf, pos, size);
}

/**************************************************************/
+4 −3
Original line number Diff line number Diff line
@@ -159,9 +159,10 @@ void path_combine(char *dest, int dest_size,
                  const char *base_path,
                  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);

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
+14 −8
Original line number Diff line number Diff line
@@ -890,12 +890,16 @@ static void qcow_flush(BlockDriverState *bs)
    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)
{
    BDRVQcowState *s = bs->opaque;
    bdi->cluster_size = s->cluster_size;
    bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
        (s->cluster_bits + s->l2_bits);
    bdi->vm_state_offset = qcow_vm_state_offset(s);
    return 0;
}

@@ -925,26 +929,28 @@ static void dump_refcounts(BlockDriverState *bs)
}
#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)
{
    BDRVQcowState *s = bs->opaque;
    int growable = bs->growable;

    bs->growable = 1;
    bdrv_pwrite(bs, pos, buf, size);
    bdrv_pwrite(bs, qcow_vm_state_offset(s) + pos, buf, size);
    bs->growable = growable;

    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)
{
    BDRVQcowState *s = bs->opaque;
    int growable = bs->growable;
    int ret;

    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;

    return ret;
@@ -1001,8 +1007,8 @@ static BlockDriver bdrv_qcow2 = {
    .bdrv_snapshot_list     = qcow2_snapshot_list,
    .bdrv_get_info	= qcow_get_info,

    .bdrv_put_buffer    = qcow_put_buffer,
    .bdrv_get_buffer    = qcow_get_buffer,
    .bdrv_save_vmstate    = qcow_save_vmstate,
    .bdrv_load_vmstate    = qcow_load_vmstate,

    .create_options = qcow_create_options,
    .bdrv_check = qcow_check,
+4 −4
Original line number Diff line number Diff line
@@ -84,9 +84,9 @@ struct BlockDriver {
                              QEMUSnapshotInfo **psn_info);
    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);
    int (*bdrv_get_buffer)(BlockDriverState *bs, uint8_t *buf,
    int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf,
                             int64_t pos, int size);

    /* removable device specific */
+7 −39
Original line number Diff line number Diff line
@@ -337,46 +337,28 @@ fail:
    return NULL;
}

typedef struct QEMUFileBdrv
{
    BlockDriverState *bs;
    int64_t base_offset;
} QEMUFileBdrv;

static int block_put_buffer(void *opaque, const uint8_t *buf,
                           int64_t pos, int size)
{
    QEMUFileBdrv *s = opaque;
    bdrv_put_buffer(s->bs, buf, s->base_offset + pos, size);
    bdrv_save_vmstate(opaque, buf, pos, size);
    return size;
}

static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
{
    QEMUFileBdrv *s = opaque;
    return bdrv_get_buffer(s->bs, buf, s->base_offset + pos, size);
    return bdrv_load_vmstate(opaque, buf, pos, size);
}

static int bdrv_fclose(void *opaque)
{
    QEMUFileBdrv *s = opaque;
    qemu_free(s);
    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)
        return qemu_fopen_ops(s, block_put_buffer, NULL, bdrv_fclose, NULL, NULL);

    return qemu_fopen_ops(s, NULL, block_get_buffer, 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);
}

QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
@@ -1069,7 +1051,6 @@ void do_savevm(Monitor *mon, const char *name)
    BlockDriverState *bs, *bs1;
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
    int must_delete, ret, i;
    BlockDriverInfo bdi1, *bdi = &bdi1;
    QEMUFile *f;
    int saved_vm_running;
    uint32_t vm_state_size;
@@ -1119,14 +1100,8 @@ void do_savevm(Monitor *mon, const char *name)
#endif
    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 */
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
    f = qemu_fopen_bdrv(bs, 1);
    if (!f) {
        monitor_printf(mon, "Could not open VM state file\n");
        goto the_end;
@@ -1170,7 +1145,6 @@ void do_savevm(Monitor *mon, const char *name)
void do_loadvm(Monitor *mon, const char *name)
{
    BlockDriverState *bs, *bs1;
    BlockDriverInfo bdi1, *bdi = &bdi1;
    QEMUSnapshotInfo sn;
    QEMUFile *f;
    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 */
    ret = bdrv_snapshot_find(bs, &sn, name);
    if ((ret >= 0) && (sn.vm_state_size == 0))
        goto the_end;

    /* restore the VM state */
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
    f = qemu_fopen_bdrv(bs, 0);
    if (!f) {
        monitor_printf(mon, "Could not open VM state file\n");
        goto the_end;