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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**************************************************************/
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								block.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								block.h
									
									
									
									
									
								
							@ -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
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										46
									
								
								savevm.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								savevm.c
									
									
									
									
									
								
							@ -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;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user