#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
#include "qemu/cutils.h"
#include "qemu/queue.h"
#include "block.h"
#include "migration/vmstate.h"
#include "sysemu/block-backend.h"
-#define BLOCK_SIZE (1 << 20)
-#define BDRV_SECTORS_PER_DIRTY_CHUNK (BLOCK_SIZE >> BDRV_SECTOR_BITS)
+#define BLK_MIG_BLOCK_SIZE (1 << 20)
+#define BDRV_SECTORS_PER_DIRTY_CHUNK (BLK_MIG_BLOCK_SIZE >> BDRV_SECTOR_BITS)
#define BLK_MIG_FLAG_DEVICE_BLOCK 0x01
#define BLK_MIG_FLAG_EOS 0x02
BlkMigDevState *bmds;
int64_t sector;
int nr_sectors;
- struct iovec iov;
QEMUIOVector qiov;
BlockAIOCB *aiocb;
uint64_t flags = BLK_MIG_FLAG_DEVICE_BLOCK;
if (block_mig_state.zero_blocks &&
- buffer_is_zero(blk->buf, BLOCK_SIZE)) {
+ buffer_is_zero(blk->buf, BLK_MIG_BLOCK_SIZE)) {
flags |= BLK_MIG_FLAG_ZERO_BLOCK;
}
return;
}
- qemu_put_buffer(f, blk->buf, BLOCK_SIZE);
+ qemu_put_buffer(f, blk->buf, BLK_MIG_BLOCK_SIZE);
}
int blk_mig_active(void)
}
blk = g_new(BlkMigBlock, 1);
- blk->buf = g_malloc(BLOCK_SIZE);
+ blk->buf = g_malloc(BLK_MIG_BLOCK_SIZE);
blk->bmds = bmds;
blk->sector = cur_sector;
blk->nr_sectors = nr_sectors;
- blk->iov.iov_base = blk->buf;
- blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
- qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
+ qemu_iovec_init_buf(&blk->qiov, blk->buf, nr_sectors * BDRV_SECTOR_SIZE);
blk_mig_lock();
block_mig_state.submitted++;
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
bmds->dirty_bitmap = bdrv_create_dirty_bitmap(blk_bs(bmds->blk),
- BLOCK_SIZE, NULL, NULL);
+ BLK_MIG_BLOCK_SIZE,
+ NULL, NULL);
if (!bmds->dirty_bitmap) {
ret = -errno;
goto fail;
fail:
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
if (bmds->dirty_bitmap) {
- bdrv_release_dirty_bitmap(blk_bs(bmds->blk), bmds->dirty_bitmap);
+ bdrv_release_dirty_bitmap(bmds->dirty_bitmap);
}
}
return ret;
BlkMigDevState *bmds;
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
- bdrv_release_dirty_bitmap(blk_bs(bmds->blk), bmds->dirty_bitmap);
+ bdrv_release_dirty_bitmap(bmds->dirty_bitmap);
}
}
}
bmds = g_new0(BlkMigDevState, 1);
- bmds->blk = blk_new(BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
+ bmds->blk = blk_new(qemu_get_aio_context(),
+ BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
bmds->blk_name = g_strdup(bdrv_get_device_name(bs));
bmds->bulk_completed = 0;
bmds->total_sectors = sectors;
int is_async)
{
BlkMigBlock *blk;
- BlockDriverState *bs = blk_bs(bmds->blk);
int64_t total_sectors = bmds->total_sectors;
int64_t sector;
int nr_sectors;
blk_mig_unlock();
}
bdrv_dirty_bitmap_lock(bmds->dirty_bitmap);
- if (bdrv_get_dirty_locked(bs, bmds->dirty_bitmap,
- sector * BDRV_SECTOR_SIZE)) {
+ if (bdrv_dirty_bitmap_get_locked(bmds->dirty_bitmap,
+ sector * BDRV_SECTOR_SIZE)) {
if (total_sectors - sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {
nr_sectors = total_sectors - sector;
} else {
bdrv_dirty_bitmap_unlock(bmds->dirty_bitmap);
blk = g_new(BlkMigBlock, 1);
- blk->buf = g_malloc(BLOCK_SIZE);
+ blk->buf = g_malloc(BLK_MIG_BLOCK_SIZE);
blk->bmds = bmds;
blk->sector = sector;
blk->nr_sectors = nr_sectors;
if (is_async) {
- blk->iov.iov_base = blk->buf;
- blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
- qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
+ qemu_iovec_init_buf(&blk->qiov, blk->buf,
+ nr_sectors * BDRV_SECTOR_SIZE);
blk->aiocb = blk_aio_preadv(bmds->blk,
sector * BDRV_SECTOR_SIZE,
/* control the rate of transfer */
blk_mig_lock();
- while (block_mig_state.read_done * BLOCK_SIZE <
+ while (block_mig_state.read_done * BLK_MIG_BLOCK_SIZE <
qemu_file_get_rate_limit(f) &&
block_mig_state.submitted < MAX_PARALLEL_IO &&
(block_mig_state.submitted + block_mig_state.read_done) <
qemu_mutex_unlock_iothread();
blk_mig_lock();
- pending += block_mig_state.submitted * BLOCK_SIZE +
- block_mig_state.read_done * BLOCK_SIZE;
+ pending += block_mig_state.submitted * BLK_MIG_BLOCK_SIZE +
+ block_mig_state.read_done * BLK_MIG_BLOCK_SIZE;
blk_mig_unlock();
/* Report at least one block pending during bulk phase */
if (pending <= max_size && !block_mig_state.bulk_completed) {
- pending = max_size + BLOCK_SIZE;
+ pending = max_size + BLK_MIG_BLOCK_SIZE;
}
DPRINTF("Enter save live pending %" PRIu64 "\n", pending);
int nr_sectors;
int ret;
BlockDriverInfo bdi;
- int cluster_size = BLOCK_SIZE;
+ int cluster_size = BLK_MIG_BLOCK_SIZE;
do {
addr = qemu_get_be64(f);
- flags = addr & ~BDRV_SECTOR_MASK;
+ flags = addr & (BDRV_SECTOR_SIZE - 1);
addr >>= BDRV_SECTOR_BITS;
if (flags & BLK_MIG_FLAG_DEVICE_BLOCK) {
ret = bdrv_get_info(blk_bs(blk), &bdi);
if (ret == 0 && bdi.cluster_size > 0 &&
- bdi.cluster_size <= BLOCK_SIZE &&
- BLOCK_SIZE % bdi.cluster_size == 0) {
+ bdi.cluster_size <= BLK_MIG_BLOCK_SIZE &&
+ BLK_MIG_BLOCK_SIZE % bdi.cluster_size == 0) {
cluster_size = bdi.cluster_size;
} else {
- cluster_size = BLOCK_SIZE;
+ cluster_size = BLK_MIG_BLOCK_SIZE;
}
}
int64_t cur_addr;
uint8_t *cur_buf;
- buf = g_malloc(BLOCK_SIZE);
- qemu_get_buffer(f, buf, BLOCK_SIZE);
- for (i = 0; i < BLOCK_SIZE / cluster_size; i++) {
+ buf = g_malloc(BLK_MIG_BLOCK_SIZE);
+ qemu_get_buffer(f, buf, BLK_MIG_BLOCK_SIZE);
+ for (i = 0; i < BLK_MIG_BLOCK_SIZE / cluster_size; i++) {
cur_addr = addr * BDRV_SECTOR_SIZE + i * cluster_size;
cur_buf = buf + i * cluster_size;
if ((!block_mig_state.zero_blocks ||
- cluster_size < BLOCK_SIZE) &&
+ cluster_size < BLK_MIG_BLOCK_SIZE) &&
buffer_is_zero(cur_buf, cluster_size)) {
ret = blk_pwrite_zeroes(blk, cur_addr,
cluster_size,
QSIMPLEQ_INIT(&block_mig_state.blk_list);
qemu_mutex_init(&block_mig_state.lock);
- register_savevm_live(NULL, "block", 0, 1, &savevm_block_handlers,
+ register_savevm_live("block", 0, 1, &savevm_block_handlers,
&block_mig_state);
}