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. Signed-off-by: Pierre Riteau <pierre.rit...@irisa.fr> --- This v2 has the following changes: - use error_report instead of fprintf (comment from Yoshiaki Tamura) - don't recompute total_sectors when the device hasn't changed since the previous iteration (comment from Kevin Wolf) block-migration.c | 22 ++++++++++++++++++++-- 1 files changed, 20 insertions(+), 2 deletions(-) diff --git a/block-migration.c b/block-migration.c index 1475325..5f1473a 100644 --- a/block-migration.c +++ b/block-migration.c @@ -633,8 +633,10 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) int len, flags; char device_name[256]; int64_t addr; - BlockDriverState *bs; + BlockDriverState *bs, *bs_prev = NULL; uint8_t *buf; + int64_t total_sectors = 0; + int nr_sectors; do { addr = qemu_get_be64(f); @@ -656,10 +658,26 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) return -EINVAL; } + if (bs != bs_prev) { + bs_prev = bs; + total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; + if (total_sectors <= 0) { + error_report("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