]> git.proxmox.com Git - qemu.git/blobdiff - block-migration.c
Merge remote-tracking branch 'afaerber/qom-cpu' into staging
[qemu.git] / block-migration.c
index 6acf3e1682f401025906d1342a54ca2ee13086f2..43ab2028c0bb544f422c11677e729897e6500256 100644 (file)
@@ -23,7 +23,8 @@
 #include "sysemu/blockdev.h"
 #include <assert.h>
 
-#define BLOCK_SIZE (BDRV_SECTORS_PER_DIRTY_CHUNK << BDRV_SECTOR_BITS)
+#define BLOCK_SIZE                       (1 << 20)
+#define BDRV_SECTORS_PER_DIRTY_CHUNK     (BLOCK_SIZE >> BDRV_SECTOR_BITS)
 
 #define BLK_MIG_FLAG_DEVICE_BLOCK       0x01
 #define BLK_MIG_FLAG_EOS                0x02
@@ -254,7 +255,7 @@ static void set_dirty_tracking(int enable)
     BlkMigDevState *bmds;
 
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
-        bdrv_set_dirty_tracking(bmds->bs, enable);
+        bdrv_set_dirty_tracking(bmds->bs, enable ? BLOCK_SIZE : 0);
     }
 }
 
@@ -478,7 +479,7 @@ static int64_t get_remaining_dirty(void)
         dirty += bdrv_get_dirty_count(bmds->bs);
     }
 
-    return dirty * BLOCK_SIZE;
+    return dirty << BDRV_SECTOR_BITS;
 }
 
 static void blk_mig_cleanup(void)
@@ -538,6 +539,7 @@ static int block_save_setup(QEMUFile *f, void *opaque)
 static int block_save_iterate(QEMUFile *f, void *opaque)
 {
     int ret;
+    int64_t last_ftell = qemu_ftell(f);
 
     DPRINTF("Enter save live iterate submitted %d transferred %d\n",
             block_mig_state.submitted, block_mig_state.transferred);
@@ -568,7 +570,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
             }
         }
     }
-    if (ret) {
+    if (ret < 0) {
         blk_mig_cleanup();
         return ret;
     }
@@ -581,7 +583,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
 
     qemu_put_be64(f, BLK_MIG_FLAG_EOS);
 
-    return 0;
+    return qemu_ftell(f) - last_ftell;
 }
 
 static int block_save_complete(QEMUFile *f, void *opaque)
@@ -608,7 +610,7 @@ static int block_save_complete(QEMUFile *f, void *opaque)
     } while (ret == 0);
 
     blk_mig_cleanup();
-    if (ret) {
+    if (ret < 0) {
         return ret;
     }
     /* report completion */
@@ -623,10 +625,18 @@ static int block_save_complete(QEMUFile *f, void *opaque)
 
 static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)
 {
+    /* Estimate pending number of bytes to send */
+    uint64_t pending = get_remaining_dirty() +
+                       block_mig_state.submitted * BLOCK_SIZE +
+                       block_mig_state.read_done * BLOCK_SIZE;
+
+    /* Report at least one block pending during bulk phase */
+    if (pending == 0 && !block_mig_state.bulk_completed) {
+        pending = BLOCK_SIZE;
+    }
 
-    DPRINTF("Enter save live pending  %ld\n", get_remaining_dirty());
-
-    return get_remaining_dirty();
+    DPRINTF("Enter save live pending  %" PRIu64 "\n", pending);
+    return pending;
 }
 
 static int block_load(QEMUFile *f, void *opaque, int version_id)
@@ -694,7 +704,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
                    (addr == 100) ? '\n' : '\r');
             fflush(stdout);
         } else if (!(flags & BLK_MIG_FLAG_EOS)) {
-            fprintf(stderr, "Unknown flags\n");
+            fprintf(stderr, "Unknown block migration flags: %#x\n", flags);
             return -EINVAL;
         }
         ret = qemu_file_get_error(f);