b02bea3a85cc939f09aa674a3f1e4f36d418c007 added a check on the return value of bdrv_write and aborts migration when it fails. However, if the size of the block device to migrate is not a multiple of BLOCK_SIZE (currently 1 MB), the last bdrv_write will fail with -EIO.
Fixed by calling bdrv_write with the correct size of the last block. --- block-migration.c | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletions(-) diff --git a/block-migration.c b/block-migration.c index 1475325..eeb9c62 100644 --- a/block-migration.c +++ b/block-migration.c @@ -635,6 +635,8 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) int64_t addr; BlockDriverState *bs; uint8_t *buf; + int64_t total_sectors; + int nr_sectors; do { addr = qemu_get_be64(f); @@ -656,10 +658,22 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) return -EINVAL; } + total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; + if (total_sectors <= 0) { + fprintf(stderr, "Error getting length of block device %s\n", device_name); + return -EINVAL; + } + + if (total_sectors - addr < BDRV_SECTORS_PER_DIRTY_CHUNK) { + nr_sectors = total_sectors - addr; + } else { + nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK; + } + buf = qemu_malloc(BLOCK_SIZE); qemu_get_buffer(f, buf, BLOCK_SIZE); - ret = bdrv_write(bs, addr, buf, BDRV_SECTORS_PER_DIRTY_CHUNK); + ret = bdrv_write(bs, addr, buf, nr_sectors); qemu_free(buf); if (ret < 0) { -- 1.7.3.5