Diff for /qemu/block-migration.c between versions 1.1.1.5 and 1.1.1.6

version 1.1.1.5, 2018/04/24 19:18:01 version 1.1.1.6, 2018/04/24 19:35:23
Line 9 Line 9
  * This work is licensed under the terms of the GNU GPL, version 2.  See   * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.   * the COPYING file in the top-level directory.
  *   *
    * Contributions after 2012-01-13 are licensed under the terms of the
    * GNU GPL, version 2 or (at your option) any later version.
  */   */
   
 #include "qemu-common.h"  #include "qemu-common.h"
Line 16 Line 18
 #include "hw/hw.h"  #include "hw/hw.h"
 #include "qemu-queue.h"  #include "qemu-queue.h"
 #include "qemu-timer.h"  #include "qemu-timer.h"
 #include "monitor.h"  
 #include "block-migration.h"  #include "block-migration.h"
 #include "migration.h"  #include "migration.h"
 #include "blockdev.h"  #include "blockdev.h"
Line 202  static void blk_mig_read_cb(void *opaque Line 203  static void blk_mig_read_cb(void *opaque
     assert(block_mig_state.submitted >= 0);      assert(block_mig_state.submitted >= 0);
 }  }
   
 static int mig_save_device_bulk(Monitor *mon, QEMUFile *f,  static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
                                 BlkMigDevState *bmds)  
 {  {
     int64_t total_sectors = bmds->total_sectors;      int64_t total_sectors = bmds->total_sectors;
     int64_t cur_sector = bmds->cur_sector;      int64_t cur_sector = bmds->cur_sector;
Line 251  static int mig_save_device_bulk(Monitor  Line 251  static int mig_save_device_bulk(Monitor 
   
     blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov,      blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov,
                                 nr_sectors, blk_mig_read_cb, blk);                                  nr_sectors, blk_mig_read_cb, blk);
     if (!blk->aiocb) {  
         goto error;  
     }  
     block_mig_state.submitted++;      block_mig_state.submitted++;
   
     bdrv_reset_dirty(bs, cur_sector, nr_sectors);      bdrv_reset_dirty(bs, cur_sector, nr_sectors);
     bmds->cur_sector = cur_sector + nr_sectors;      bmds->cur_sector = cur_sector + nr_sectors;
   
     return (bmds->cur_sector >= total_sectors);      return (bmds->cur_sector >= total_sectors);
   
 error:  
     monitor_printf(mon, "Error reading sector %" PRId64 "\n", cur_sector);  
     qemu_file_set_error(f, -EIO);  
     g_free(blk->buf);  
     g_free(blk);  
     return 0;  
 }  }
   
 static void set_dirty_tracking(int enable)  static void set_dirty_tracking(int enable)
Line 280  static void set_dirty_tracking(int enabl Line 270  static void set_dirty_tracking(int enabl
   
 static void init_blk_migration_it(void *opaque, BlockDriverState *bs)  static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
 {  {
     Monitor *mon = opaque;  
     BlkMigDevState *bmds;      BlkMigDevState *bmds;
     int64_t sectors;      int64_t sectors;
   
Line 303  static void init_blk_migration_it(void * Line 292  static void init_blk_migration_it(void *
         block_mig_state.total_sector_sum += sectors;          block_mig_state.total_sector_sum += sectors;
   
         if (bmds->shared_base) {          if (bmds->shared_base) {
             monitor_printf(mon, "Start migration for %s with shared base "              DPRINTF("Start migration for %s with shared base image\n",
                                 "image\n",                      bs->device_name);
                            bs->device_name);  
         } else {          } else {
             monitor_printf(mon, "Start full migration for %s\n",              DPRINTF("Start full migration for %s\n", bs->device_name);
                            bs->device_name);  
         }          }
   
         QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);          QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);
     }      }
 }  }
   
 static void init_blk_migration(Monitor *mon, QEMUFile *f)  static void init_blk_migration(QEMUFile *f)
 {  {
     block_mig_state.submitted = 0;      block_mig_state.submitted = 0;
     block_mig_state.read_done = 0;      block_mig_state.read_done = 0;
Line 326  static void init_blk_migration(Monitor * Line 313  static void init_blk_migration(Monitor *
     block_mig_state.total_time = 0;      block_mig_state.total_time = 0;
     block_mig_state.reads = 0;      block_mig_state.reads = 0;
   
     bdrv_iterate(init_blk_migration_it, mon);      bdrv_iterate(init_blk_migration_it, NULL);
 }  }
   
 static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f)  static int blk_mig_save_bulked_block(QEMUFile *f)
 {  {
     int64_t completed_sector_sum = 0;      int64_t completed_sector_sum = 0;
     BlkMigDevState *bmds;      BlkMigDevState *bmds;
Line 338  static int blk_mig_save_bulked_block(Mon Line 325  static int blk_mig_save_bulked_block(Mon
   
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {      QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
         if (bmds->bulk_completed == 0) {          if (bmds->bulk_completed == 0) {
             if (mig_save_device_bulk(mon, f, bmds) == 1) {              if (mig_save_device_bulk(f, bmds) == 1) {
                 /* completed bulk section for this device */                  /* completed bulk section for this device */
                 bmds->bulk_completed = 1;                  bmds->bulk_completed = 1;
             }              }
Line 360  static int blk_mig_save_bulked_block(Mon Line 347  static int blk_mig_save_bulked_block(Mon
         block_mig_state.prev_progress = progress;          block_mig_state.prev_progress = progress;
         qemu_put_be64(f, (progress << BDRV_SECTOR_BITS)          qemu_put_be64(f, (progress << BDRV_SECTOR_BITS)
                          | BLK_MIG_FLAG_PROGRESS);                           | BLK_MIG_FLAG_PROGRESS);
         monitor_printf(mon, "Completed %d %%\r", progress);          DPRINTF("Completed %d %%\r", progress);
         monitor_flush(mon);  
     }      }
   
     return ret;      return ret;
Line 376  static void blk_mig_reset_dirty_cursor(v Line 362  static void blk_mig_reset_dirty_cursor(v
     }      }
 }  }
   
 static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,  static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
                                  BlkMigDevState *bmds, int is_async)                                   int is_async)
 {  {
     BlkMigBlock *blk;      BlkMigBlock *blk;
     int64_t total_sectors = bmds->total_sectors;      int64_t total_sectors = bmds->total_sectors;
Line 387  static int mig_save_device_dirty(Monitor Line 373  static int mig_save_device_dirty(Monitor
   
     for (sector = bmds->cur_dirty; sector < bmds->total_sectors;) {      for (sector = bmds->cur_dirty; sector < bmds->total_sectors;) {
         if (bmds_aio_inflight(bmds, sector)) {          if (bmds_aio_inflight(bmds, sector)) {
             qemu_aio_flush();              bdrv_drain_all();
         }          }
         if (bdrv_get_dirty(bmds->bs, sector)) {          if (bdrv_get_dirty(bmds->bs, sector)) {
   
Line 413  static int mig_save_device_dirty(Monitor Line 399  static int mig_save_device_dirty(Monitor
   
                 blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov,                  blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov,
                                             nr_sectors, blk_mig_read_cb, blk);                                              nr_sectors, blk_mig_read_cb, blk);
                 if (!blk->aiocb) {  
                     goto error;  
                 }  
                 block_mig_state.submitted++;                  block_mig_state.submitted++;
                 bmds_set_aio_inflight(bmds, sector, nr_sectors, 1);                  bmds_set_aio_inflight(bmds, sector, nr_sectors, 1);
             } else {              } else {
Line 439  static int mig_save_device_dirty(Monitor Line 422  static int mig_save_device_dirty(Monitor
     return (bmds->cur_dirty >= bmds->total_sectors);      return (bmds->cur_dirty >= bmds->total_sectors);
   
 error:  error:
     monitor_printf(mon, "Error reading sector %" PRId64 "\n", sector);      DPRINTF("Error reading sector %" PRId64 "\n", sector);
     qemu_file_set_error(f, ret);      qemu_file_set_error(f, ret);
     g_free(blk->buf);      g_free(blk->buf);
     g_free(blk);      g_free(blk);
     return 0;      return 0;
 }  }
   
 static int blk_mig_save_dirty_block(Monitor *mon, QEMUFile *f, int is_async)  static int blk_mig_save_dirty_block(QEMUFile *f, int is_async)
 {  {
     BlkMigDevState *bmds;      BlkMigDevState *bmds;
     int ret = 0;      int ret = 0;
   
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {      QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
         if (mig_save_device_dirty(mon, f, bmds, is_async) == 0) {          if (mig_save_device_dirty(f, bmds, is_async) == 0) {
             ret = 1;              ret = 1;
             break;              break;
         }          }
Line 531  static int is_stage2_completed(void) Line 514  static int is_stage2_completed(void)
     return 0;      return 0;
 }  }
   
 static void blk_mig_cleanup(Monitor *mon)  static void blk_mig_cleanup(void)
 {  {
     BlkMigDevState *bmds;      BlkMigDevState *bmds;
     BlkMigBlock *blk;      BlkMigBlock *blk;
Line 551  static void blk_mig_cleanup(Monitor *mon Line 534  static void blk_mig_cleanup(Monitor *mon
         g_free(blk->buf);          g_free(blk->buf);
         g_free(blk);          g_free(blk);
     }      }
   
     monitor_printf(mon, "\n");  
 }  }
   
 static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)  static int block_save_live(QEMUFile *f, int stage, void *opaque)
 {  {
     int ret;      int ret;
   
Line 563  static int block_save_live(Monitor *mon, Line 544  static int block_save_live(Monitor *mon,
             stage, block_mig_state.submitted, block_mig_state.transferred);              stage, block_mig_state.submitted, block_mig_state.transferred);
   
     if (stage < 0) {      if (stage < 0) {
         blk_mig_cleanup(mon);          blk_mig_cleanup();
         return 0;          return 0;
     }      }
   
Line 574  static int block_save_live(Monitor *mon, Line 555  static int block_save_live(Monitor *mon,
     }      }
   
     if (stage == 1) {      if (stage == 1) {
         init_blk_migration(mon, f);          init_blk_migration(f);
   
         /* start track dirty blocks */          /* start track dirty blocks */
         set_dirty_tracking(1);          set_dirty_tracking(1);
Line 584  static int block_save_live(Monitor *mon, Line 565  static int block_save_live(Monitor *mon,
   
     ret = qemu_file_get_error(f);      ret = qemu_file_get_error(f);
     if (ret) {      if (ret) {
         blk_mig_cleanup(mon);          blk_mig_cleanup();
         return ret;          return ret;
     }      }
   
Line 597  static int block_save_live(Monitor *mon, Line 578  static int block_save_live(Monitor *mon,
                qemu_file_get_rate_limit(f)) {                 qemu_file_get_rate_limit(f)) {
             if (block_mig_state.bulk_completed == 0) {              if (block_mig_state.bulk_completed == 0) {
                 /* first finish the bulk phase */                  /* first finish the bulk phase */
                 if (blk_mig_save_bulked_block(mon, f) == 0) {                  if (blk_mig_save_bulked_block(f) == 0) {
                     /* finished saving bulk on all devices */                      /* finished saving bulk on all devices */
                     block_mig_state.bulk_completed = 1;                      block_mig_state.bulk_completed = 1;
                 }                  }
             } else {              } else {
                 if (blk_mig_save_dirty_block(mon, f, 1) == 0) {                  if (blk_mig_save_dirty_block(f, 1) == 0) {
                     /* no more dirty blocks */                      /* no more dirty blocks */
                     break;                      break;
                 }                  }
Line 613  static int block_save_live(Monitor *mon, Line 594  static int block_save_live(Monitor *mon,
   
         ret = qemu_file_get_error(f);          ret = qemu_file_get_error(f);
         if (ret) {          if (ret) {
             blk_mig_cleanup(mon);              blk_mig_cleanup();
             return ret;              return ret;
         }          }
     }      }
Line 623  static int block_save_live(Monitor *mon, Line 604  static int block_save_live(Monitor *mon,
            all async read completed */             all async read completed */
         assert(block_mig_state.submitted == 0);          assert(block_mig_state.submitted == 0);
   
         while (blk_mig_save_dirty_block(mon, f, 0) != 0);          while (blk_mig_save_dirty_block(f, 0) != 0);
         blk_mig_cleanup(mon);          blk_mig_cleanup();
   
         /* report completion */          /* report completion */
         qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS);          qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS);
Line 634  static int block_save_live(Monitor *mon, Line 615  static int block_save_live(Monitor *mon,
             return ret;              return ret;
         }          }
   
         monitor_printf(mon, "Block migration completed\n");          DPRINTF("Block migration completed\n");
     }      }
   
     qemu_put_be64(f, BLK_MIG_FLAG_EOS);      qemu_put_be64(f, BLK_MIG_FLAG_EOS);

Removed from v.1.1.1.5  
changed lines
  Added in v.1.1.1.6


unix.superglobalmegacorp.com