Revision 45566e9c

b/block.c
1158 1158
    return drv->bdrv_get_info(bs, bdi);
1159 1159
}
1160 1160

  
1161
int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size)
1161
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
1162
                      int64_t pos, int size)
1162 1163
{
1163 1164
    BlockDriver *drv = bs->drv;
1164 1165
    if (!drv)
1165 1166
        return -ENOMEDIUM;
1166
    if (!drv->bdrv_put_buffer)
1167
    if (!drv->bdrv_save_vmstate)
1167 1168
        return -ENOTSUP;
1168
    return drv->bdrv_put_buffer(bs, buf, pos, size);
1169
    return drv->bdrv_save_vmstate(bs, buf, pos, size);
1169 1170
}
1170 1171

  
1171
int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size)
1172
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
1173
                      int64_t pos, int size)
1172 1174
{
1173 1175
    BlockDriver *drv = bs->drv;
1174 1176
    if (!drv)
1175 1177
        return -ENOMEDIUM;
1176
    if (!drv->bdrv_get_buffer)
1178
    if (!drv->bdrv_load_vmstate)
1177 1179
        return -ENOTSUP;
1178
    return drv->bdrv_get_buffer(bs, buf, pos, size);
1180
    return drv->bdrv_load_vmstate(bs, buf, pos, size);
1179 1181
}
1180 1182

  
1181 1183
/**************************************************************/
b/block.h
159 159
                  const char *base_path,
160 160
                  const char *filename);
161 161

  
162
int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf,
163
                    int64_t pos, int size);
162
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
163
                      int64_t pos, int size);
164 164

  
165
int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size);
165
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
166
                      int64_t pos, int size);
166 167

  
167 168
#endif
b/block/qcow2.c
890 890
    bdrv_flush(s->hd);
891 891
}
892 892

  
893
static int64_t qcow_vm_state_offset(BDRVQcowState *s)
894
{
895
	return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
896
}
897

  
893 898
static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
894 899
{
895 900
    BDRVQcowState *s = bs->opaque;
896 901
    bdi->cluster_size = s->cluster_size;
897
    bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
898
        (s->cluster_bits + s->l2_bits);
902
    bdi->vm_state_offset = qcow_vm_state_offset(s);
899 903
    return 0;
900 904
}
901 905

  
......
925 929
}
926 930
#endif
927 931

  
928
static int qcow_put_buffer(BlockDriverState *bs, const uint8_t *buf,
932
static int qcow_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
929 933
                           int64_t pos, int size)
930 934
{
935
    BDRVQcowState *s = bs->opaque;
931 936
    int growable = bs->growable;
932 937

  
933 938
    bs->growable = 1;
934
    bdrv_pwrite(bs, pos, buf, size);
939
    bdrv_pwrite(bs, qcow_vm_state_offset(s) + pos, buf, size);
935 940
    bs->growable = growable;
936 941

  
937 942
    return size;
938 943
}
939 944

  
940
static int qcow_get_buffer(BlockDriverState *bs, uint8_t *buf,
945
static int qcow_load_vmstate(BlockDriverState *bs, uint8_t *buf,
941 946
                           int64_t pos, int size)
942 947
{
948
    BDRVQcowState *s = bs->opaque;
943 949
    int growable = bs->growable;
944 950
    int ret;
945 951

  
946 952
    bs->growable = 1;
947
    ret = bdrv_pread(bs, pos, buf, size);
953
    ret = bdrv_pread(bs, qcow_vm_state_offset(s) + pos, buf, size);
948 954
    bs->growable = growable;
949 955

  
950 956
    return ret;
......
1001 1007
    .bdrv_snapshot_list     = qcow2_snapshot_list,
1002 1008
    .bdrv_get_info	= qcow_get_info,
1003 1009

  
1004
    .bdrv_put_buffer    = qcow_put_buffer,
1005
    .bdrv_get_buffer    = qcow_get_buffer,
1010
    .bdrv_save_vmstate    = qcow_save_vmstate,
1011
    .bdrv_load_vmstate    = qcow_load_vmstate,
1006 1012

  
1007 1013
    .create_options = qcow_create_options,
1008 1014
    .bdrv_check = qcow_check,
b/block_int.h
84 84
                              QEMUSnapshotInfo **psn_info);
85 85
    int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
86 86

  
87
    int (*bdrv_put_buffer)(BlockDriverState *bs, const uint8_t *buf,
88
                           int64_t pos, int size);
89
    int (*bdrv_get_buffer)(BlockDriverState *bs, uint8_t *buf,
90
                           int64_t pos, int size);
87
    int (*bdrv_save_vmstate)(BlockDriverState *bs, const uint8_t *buf,
88
                             int64_t pos, int size);
89
    int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf,
90
                             int64_t pos, int size);
91 91

  
92 92
    /* removable device specific */
93 93
    int (*bdrv_is_inserted)(BlockDriverState *bs);
b/savevm.c
337 337
    return NULL;
338 338
}
339 339

  
340
typedef struct QEMUFileBdrv
341
{
342
    BlockDriverState *bs;
343
    int64_t base_offset;
344
} QEMUFileBdrv;
345

  
346 340
static int block_put_buffer(void *opaque, const uint8_t *buf,
347 341
                           int64_t pos, int size)
348 342
{
349
    QEMUFileBdrv *s = opaque;
350
    bdrv_put_buffer(s->bs, buf, s->base_offset + pos, size);
343
    bdrv_save_vmstate(opaque, buf, pos, size);
351 344
    return size;
352 345
}
353 346

  
354 347
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
355 348
{
356
    QEMUFileBdrv *s = opaque;
357
    return bdrv_get_buffer(s->bs, buf, s->base_offset + pos, size);
349
    return bdrv_load_vmstate(opaque, buf, pos, size);
358 350
}
359 351

  
360 352
static int bdrv_fclose(void *opaque)
361 353
{
362
    QEMUFileBdrv *s = opaque;
363
    qemu_free(s);
364 354
    return 0;
365 355
}
366 356

  
367
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
357
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
368 358
{
369
    QEMUFileBdrv *s;
370

  
371
    s = qemu_mallocz(sizeof(QEMUFileBdrv));
372

  
373
    s->bs = bs;
374
    s->base_offset = offset;
375

  
376 359
    if (is_writable)
377
        return qemu_fopen_ops(s, block_put_buffer, NULL, bdrv_fclose, NULL, NULL);
378

  
379
    return qemu_fopen_ops(s, NULL, block_get_buffer, bdrv_fclose, NULL, NULL);
360
        return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose, NULL, NULL);
361
    return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclose, NULL, NULL);
380 362
}
381 363

  
382 364
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
......
1069 1051
    BlockDriverState *bs, *bs1;
1070 1052
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
1071 1053
    int must_delete, ret, i;
1072
    BlockDriverInfo bdi1, *bdi = &bdi1;
1073 1054
    QEMUFile *f;
1074 1055
    int saved_vm_running;
1075 1056
    uint32_t vm_state_size;
......
1119 1100
#endif
1120 1101
    sn->vm_clock_nsec = qemu_get_clock(vm_clock);
1121 1102

  
1122
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
1123
        monitor_printf(mon, "Device %s does not support VM state snapshots\n",
1124
                       bdrv_get_device_name(bs));
1125
        goto the_end;
1126
    }
1127

  
1128 1103
    /* save the VM state */
1129
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
1104
    f = qemu_fopen_bdrv(bs, 1);
1130 1105
    if (!f) {
1131 1106
        monitor_printf(mon, "Could not open VM state file\n");
1132 1107
        goto the_end;
......
1170 1145
void do_loadvm(Monitor *mon, const char *name)
1171 1146
{
1172 1147
    BlockDriverState *bs, *bs1;
1173
    BlockDriverInfo bdi1, *bdi = &bdi1;
1174 1148
    QEMUSnapshotInfo sn;
1175 1149
    QEMUFile *f;
1176 1150
    int i, ret;
......
1218 1192
        }
1219 1193
    }
1220 1194

  
1221
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
1222
        monitor_printf(mon, "Device %s does not support VM state snapshots\n",
1223
                       bdrv_get_device_name(bs));
1224
        return;
1225
    }
1226

  
1227 1195
    /* Don't even try to load empty VM states */
1228 1196
    ret = bdrv_snapshot_find(bs, &sn, name);
1229 1197
    if ((ret >= 0) && (sn.vm_state_size == 0))
1230 1198
        goto the_end;
1231 1199

  
1232 1200
    /* restore the VM state */
1233
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
1201
    f = qemu_fopen_bdrv(bs, 0);
1234 1202
    if (!f) {
1235 1203
        monitor_printf(mon, "Could not open VM state file\n");
1236 1204
        goto the_end;

Also available in: Unified diff