Skip to content

Commit

Permalink
block migration: Add support for restore progress reporting
Browse files Browse the repository at this point in the history
Inject progress report in percentage into the block live stream. This
can be read out and displayed easily on restore.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
  • Loading branch information
jan-kiszka authored and Anthony Liguori committed Dec 3, 2009
1 parent 25f2364 commit 01e61e2
Showing 1 changed file with 22 additions and 8 deletions.
30 changes: 22 additions & 8 deletions block-migration.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#define BLK_MIG_FLAG_DEVICE_BLOCK 0x01
#define BLK_MIG_FLAG_EOS 0x02
#define BLK_MIG_FLAG_PROGRESS 0x04

#define MAX_IS_ALLOCATED_SEARCH 65536
#define MAX_BLOCKS_READ 10000
Expand Down Expand Up @@ -70,7 +71,7 @@ typedef struct BlkMigState {
int read_done;
int transferred;
int64_t total_sector_sum;
int64_t print_completion;
int prev_progress;
} BlkMigState;

static BlkMigState block_mig_state;
Expand Down Expand Up @@ -226,7 +227,7 @@ static void init_blk_migration(Monitor *mon, QEMUFile *f)
block_mig_state.read_done = 0;
block_mig_state.transferred = 0;
block_mig_state.total_sector_sum = 0;
block_mig_state.print_completion = 0;
block_mig_state.prev_progress = -1;

for (bs = bdrv_first; bs != NULL; bs = bs->next) {
if (bs->type == BDRV_TYPE_HD) {
Expand Down Expand Up @@ -257,6 +258,7 @@ static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f, int is_async)
{
int64_t completed_sector_sum = 0;
BlkMigDevState *bmds;
int progress;
int ret = 0;

QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
Expand All @@ -273,13 +275,13 @@ static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f, int is_async)
}
}

if (completed_sector_sum >= block_mig_state.print_completion) {
monitor_printf(mon, "Completed %" PRId64 " %%\r",
completed_sector_sum * 100 /
block_mig_state.total_sector_sum);
progress = completed_sector_sum * 100 / block_mig_state.total_sector_sum;
if (progress != block_mig_state.prev_progress) {
block_mig_state.prev_progress = progress;
qemu_put_be64(f, (progress << BDRV_SECTOR_BITS)
| BLK_MIG_FLAG_PROGRESS);
monitor_printf(mon, "Completed %d %%\r", progress);
monitor_flush(mon);
block_mig_state.print_completion +=
(BDRV_SECTORS_PER_DIRTY_CHUNK * 10000);
}

return ret;
Expand Down Expand Up @@ -445,6 +447,9 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
blk_mig_save_dirty_blocks(mon, f);
blk_mig_cleanup(mon);

/* report completion */
qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS);

if (qemu_file_has_error(f)) {
return 0;
}
Expand All @@ -459,6 +464,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)

static int block_load(QEMUFile *f, void *opaque, int version_id)
{
static int banner_printed;
int len, flags;
char device_name[256];
int64_t addr;
Expand Down Expand Up @@ -490,6 +496,14 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
bdrv_write(bs, addr, buf, BDRV_SECTORS_PER_DIRTY_CHUNK);

qemu_free(buf);
} else if (flags & BLK_MIG_FLAG_PROGRESS) {
if (!banner_printed) {
printf("Receiving block device images\n");
banner_printed = 1;
}
printf("Completed %d %%%c", (int)addr,
(addr == 100) ? '\n' : '\r');
fflush(stdout);
} else if (!(flags & BLK_MIG_FLAG_EOS)) {
fprintf(stderr, "Unknown flags\n");
return -EINVAL;
Expand Down

0 comments on commit 01e61e2

Please sign in to comment.