The function uses a ternary return value (<, >, == 0) defined as an int. The
code in in this function uses int64_t types to collect ftell() return values
and use their difference as the return value. Unfortunately, narrowing of
integer types results in the disposal of the left-most bits that won't fit in
the target type. Here, for values larger than 2GB, the resulting value will be
randomly negative or positive, based on total number of blocks. The patch
ensures that only +1, -1, or 0 are returned to properly report status.
diff -u -r a/block-migration.c b/block-migration.c
--- a/block-migration.c 2014-04-17 08:30:59.000000000 -0500
+++ b/block-migration.c 2014-11-10 12:39:10.727431187 -0600
@@ -628,6 +628,7 @@
{
int ret;
int64_t last_ftell = qemu_ftell(f);
+ int64_t delta_ftell;
DPRINTF("Enter save live iterate submitted %d transferred %d\n",
block_mig_state.submitted, block_mig_state.transferred);
@@ -677,7 +678,8 @@
}
qemu_put_be64(f, BLK_MIG_FLAG_EOS);
- return qemu_ftell(f) - last_ftell;
+ delta_ftell = qemu_ftell(f) - last_ftell;
+ return( (delta_ftell > 0) ? 1 : (delta_ftell < 0) ? -1 : 0 );
}
/* Called with iothread lock taken. */