We should avoid to image file at migration end when BDRV_O_INACTIVE
is set on the block driver state. All modifications should be done
in advance, i.e. in bdrv_inactivate.

The patch also adds final bdrv_flush() to be sure that changes have
reached disk finally before other side will access the image.

Signed-off-by: Denis V. Lunev <[email protected]>
CC: Stefan Hajnoczi <[email protected]>
---
 block/parallels.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 90acf79..9dea09e 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -728,18 +728,35 @@ fail_options:
     goto fail;
 }
 
-
-static void parallels_close(BlockDriverState *bs)
+static int parallels_inactivate(BlockDriverState *bs)
 {
+    int err;
     BDRVParallelsState *s = bs->opaque;
 
-    if (bs->open_flags & BDRV_O_RDWR) {
-        s->header->inuse = 0;
-        parallels_update_header(bs);
+    if (!(bs->open_flags & BDRV_O_RDWR)) {
+        return 0;
+    }
+
+    s->header->inuse = 0;
+    err = parallels_update_header(bs);
+    if (err < 0) {
+        return err;
+    }
+
+    err = bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS);
+    if (err < 0) {
+        return err;
     }
 
-    if (bs->open_flags & BDRV_O_RDWR) {
-        bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS);
+    return bdrv_flush(bs->file->bs);
+}
+
+static void parallels_close(BlockDriverState *bs)
+{
+    BDRVParallelsState *s = bs->opaque;
+
+    if (!(bs->open_flags & BDRV_O_INACTIVE)) {
+        parallels_inactivate(bs);
     }
 
     g_free(s->bat_dirty_bmap);
@@ -777,6 +794,7 @@ static BlockDriver bdrv_parallels = {
     .bdrv_co_flush_to_os      = parallels_co_flush_to_os,
     .bdrv_co_readv  = parallels_co_readv,
     .bdrv_co_writev = parallels_co_writev,
+    .bdrv_inactivate = parallels_inactivate,
 
     .bdrv_create    = parallels_create,
     .bdrv_check     = parallels_check,
-- 
2.7.4


Reply via email to