qemu/block-migration.c
<<
>>
Prefs
   1/*
   2 * QEMU live block migration
   3 *
   4 * Copyright IBM, Corp. 2009
   5 *
   6 * Authors:
   7 *  Liran Schour   <lirans@il.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2.  See
  10 * the COPYING file in the top-level directory.
  11 *
  12 * Contributions after 2012-01-13 are licensed under the terms of the
  13 * GNU GPL, version 2 or (at your option) any later version.
  14 */
  15
  16#include "qemu-common.h"
  17#include "block/block_int.h"
  18#include "hw/hw.h"
  19#include "qemu/queue.h"
  20#include "qemu/timer.h"
  21#include "migration/block.h"
  22#include "migration/migration.h"
  23#include "sysemu/blockdev.h"
  24#include <assert.h>
  25
  26#define BLOCK_SIZE                       (1 << 20)
  27#define BDRV_SECTORS_PER_DIRTY_CHUNK     (BLOCK_SIZE >> BDRV_SECTOR_BITS)
  28
  29#define BLK_MIG_FLAG_DEVICE_BLOCK       0x01
  30#define BLK_MIG_FLAG_EOS                0x02
  31#define BLK_MIG_FLAG_PROGRESS           0x04
  32
  33#define MAX_IS_ALLOCATED_SEARCH 65536
  34
  35//#define DEBUG_BLK_MIGRATION
  36
  37#ifdef DEBUG_BLK_MIGRATION
  38#define DPRINTF(fmt, ...) \
  39    do { printf("blk_migration: " fmt, ## __VA_ARGS__); } while (0)
  40#else
  41#define DPRINTF(fmt, ...) \
  42    do { } while (0)
  43#endif
  44
  45typedef struct BlkMigDevState {
  46    BlockDriverState *bs;
  47    int bulk_completed;
  48    int shared_base;
  49    int64_t cur_sector;
  50    int64_t cur_dirty;
  51    int64_t completed_sectors;
  52    int64_t total_sectors;
  53    int64_t dirty;
  54    QSIMPLEQ_ENTRY(BlkMigDevState) entry;
  55    unsigned long *aio_bitmap;
  56} BlkMigDevState;
  57
  58typedef struct BlkMigBlock {
  59    uint8_t *buf;
  60    BlkMigDevState *bmds;
  61    int64_t sector;
  62    int nr_sectors;
  63    struct iovec iov;
  64    QEMUIOVector qiov;
  65    BlockDriverAIOCB *aiocb;
  66    int ret;
  67    QSIMPLEQ_ENTRY(BlkMigBlock) entry;
  68} BlkMigBlock;
  69
  70typedef struct BlkMigState {
  71    int blk_enable;
  72    int shared_base;
  73    QSIMPLEQ_HEAD(bmds_list, BlkMigDevState) bmds_list;
  74    QSIMPLEQ_HEAD(blk_list, BlkMigBlock) blk_list;
  75    int submitted;
  76    int read_done;
  77    int transferred;
  78    int64_t total_sector_sum;
  79    int prev_progress;
  80    int bulk_completed;
  81    long double prev_time_offset;
  82} BlkMigState;
  83
  84static BlkMigState block_mig_state;
  85
  86static void blk_send(QEMUFile *f, BlkMigBlock * blk)
  87{
  88    int len;
  89
  90    /* sector number and flags */
  91    qemu_put_be64(f, (blk->sector << BDRV_SECTOR_BITS)
  92                     | BLK_MIG_FLAG_DEVICE_BLOCK);
  93
  94    /* device name */
  95    len = strlen(blk->bmds->bs->device_name);
  96    qemu_put_byte(f, len);
  97    qemu_put_buffer(f, (uint8_t *)blk->bmds->bs->device_name, len);
  98
  99    qemu_put_buffer(f, blk->buf, BLOCK_SIZE);
 100}
 101
 102int blk_mig_active(void)
 103{
 104    return !QSIMPLEQ_EMPTY(&block_mig_state.bmds_list);
 105}
 106
 107uint64_t blk_mig_bytes_transferred(void)
 108{
 109    BlkMigDevState *bmds;
 110    uint64_t sum = 0;
 111
 112    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
 113        sum += bmds->completed_sectors;
 114    }
 115    return sum << BDRV_SECTOR_BITS;
 116}
 117
 118uint64_t blk_mig_bytes_remaining(void)
 119{
 120    return blk_mig_bytes_total() - blk_mig_bytes_transferred();
 121}
 122
 123uint64_t blk_mig_bytes_total(void)
 124{
 125    BlkMigDevState *bmds;
 126    uint64_t sum = 0;
 127
 128    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
 129        sum += bmds->total_sectors;
 130    }
 131    return sum << BDRV_SECTOR_BITS;
 132}
 133
 134static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector)
 135{
 136    int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
 137
 138    if ((sector << BDRV_SECTOR_BITS) < bdrv_getlength(bmds->bs)) {
 139        return !!(bmds->aio_bitmap[chunk / (sizeof(unsigned long) * 8)] &
 140            (1UL << (chunk % (sizeof(unsigned long) * 8))));
 141    } else {
 142        return 0;
 143    }
 144}
 145
 146static void bmds_set_aio_inflight(BlkMigDevState *bmds, int64_t sector_num,
 147                             int nb_sectors, int set)
 148{
 149    int64_t start, end;
 150    unsigned long val, idx, bit;
 151
 152    start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
 153    end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
 154
 155    for (; start <= end; start++) {
 156        idx = start / (sizeof(unsigned long) * 8);
 157        bit = start % (sizeof(unsigned long) * 8);
 158        val = bmds->aio_bitmap[idx];
 159        if (set) {
 160            val |= 1UL << bit;
 161        } else {
 162            val &= ~(1UL << bit);
 163        }
 164        bmds->aio_bitmap[idx] = val;
 165    }
 166}
 167
 168static void alloc_aio_bitmap(BlkMigDevState *bmds)
 169{
 170    BlockDriverState *bs = bmds->bs;
 171    int64_t bitmap_size;
 172
 173    bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
 174            BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
 175    bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
 176
 177    bmds->aio_bitmap = g_malloc0(bitmap_size);
 178}
 179
 180static void blk_mig_read_cb(void *opaque, int ret)
 181{
 182    long double curr_time = qemu_get_clock_ns(rt_clock);
 183    BlkMigBlock *blk = opaque;
 184
 185    blk->ret = ret;
 186
 187    block_mig_state.prev_time_offset = curr_time;
 188
 189    QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry);
 190    bmds_set_aio_inflight(blk->bmds, blk->sector, blk->nr_sectors, 0);
 191
 192    block_mig_state.submitted--;
 193    block_mig_state.read_done++;
 194    assert(block_mig_state.submitted >= 0);
 195}
 196
 197static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
 198{
 199    int64_t total_sectors = bmds->total_sectors;
 200    int64_t cur_sector = bmds->cur_sector;
 201    BlockDriverState *bs = bmds->bs;
 202    BlkMigBlock *blk;
 203    int nr_sectors;
 204
 205    if (bmds->shared_base) {
 206        while (cur_sector < total_sectors &&
 207               !bdrv_is_allocated(bs, cur_sector, MAX_IS_ALLOCATED_SEARCH,
 208                                  &nr_sectors)) {
 209            cur_sector += nr_sectors;
 210        }
 211    }
 212
 213    if (cur_sector >= total_sectors) {
 214        bmds->cur_sector = bmds->completed_sectors = total_sectors;
 215        return 1;
 216    }
 217
 218    bmds->completed_sectors = cur_sector;
 219
 220    cur_sector &= ~((int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK - 1);
 221
 222    /* we are going to transfer a full block even if it is not allocated */
 223    nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
 224
 225    if (total_sectors - cur_sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {
 226        nr_sectors = total_sectors - cur_sector;
 227    }
 228
 229    blk = g_malloc(sizeof(BlkMigBlock));
 230    blk->buf = g_malloc(BLOCK_SIZE);
 231    blk->bmds = bmds;
 232    blk->sector = cur_sector;
 233    blk->nr_sectors = nr_sectors;
 234
 235    blk->iov.iov_base = blk->buf;
 236    blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
 237    qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
 238
 239    if (block_mig_state.submitted == 0) {
 240        block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock);
 241    }
 242
 243    blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov,
 244                                nr_sectors, blk_mig_read_cb, blk);
 245    block_mig_state.submitted++;
 246
 247    bdrv_reset_dirty(bs, cur_sector, nr_sectors);
 248    bmds->cur_sector = cur_sector + nr_sectors;
 249
 250    return (bmds->cur_sector >= total_sectors);
 251}
 252
 253static void set_dirty_tracking(int enable)
 254{
 255    BlkMigDevState *bmds;
 256
 257    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
 258        bdrv_set_dirty_tracking(bmds->bs, enable ? BLOCK_SIZE : 0);
 259    }
 260}
 261
 262static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
 263{
 264    BlkMigDevState *bmds;
 265    int64_t sectors;
 266
 267    if (!bdrv_is_read_only(bs)) {
 268        sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
 269        if (sectors <= 0) {
 270            return;
 271        }
 272
 273        bmds = g_malloc0(sizeof(BlkMigDevState));
 274        bmds->bs = bs;
 275        bmds->bulk_completed = 0;
 276        bmds->total_sectors = sectors;
 277        bmds->completed_sectors = 0;
 278        bmds->shared_base = block_mig_state.shared_base;
 279        alloc_aio_bitmap(bmds);
 280        drive_get_ref(drive_get_by_blockdev(bs));
 281        bdrv_set_in_use(bs, 1);
 282
 283        block_mig_state.total_sector_sum += sectors;
 284
 285        if (bmds->shared_base) {
 286            DPRINTF("Start migration for %s with shared base image\n",
 287                    bs->device_name);
 288        } else {
 289            DPRINTF("Start full migration for %s\n", bs->device_name);
 290        }
 291
 292        QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);
 293    }
 294}
 295
 296static void init_blk_migration(QEMUFile *f)
 297{
 298    block_mig_state.submitted = 0;
 299    block_mig_state.read_done = 0;
 300    block_mig_state.transferred = 0;
 301    block_mig_state.total_sector_sum = 0;
 302    block_mig_state.prev_progress = -1;
 303    block_mig_state.bulk_completed = 0;
 304
 305    bdrv_iterate(init_blk_migration_it, NULL);
 306}
 307
 308static int blk_mig_save_bulked_block(QEMUFile *f)
 309{
 310    int64_t completed_sector_sum = 0;
 311    BlkMigDevState *bmds;
 312    int progress;
 313    int ret = 0;
 314
 315    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
 316        if (bmds->bulk_completed == 0) {
 317            if (mig_save_device_bulk(f, bmds) == 1) {
 318                /* completed bulk section for this device */
 319                bmds->bulk_completed = 1;
 320            }
 321            completed_sector_sum += bmds->completed_sectors;
 322            ret = 1;
 323            break;
 324        } else {
 325            completed_sector_sum += bmds->completed_sectors;
 326        }
 327    }
 328
 329    if (block_mig_state.total_sector_sum != 0) {
 330        progress = completed_sector_sum * 100 /
 331                   block_mig_state.total_sector_sum;
 332    } else {
 333        progress = 100;
 334    }
 335    if (progress != block_mig_state.prev_progress) {
 336        block_mig_state.prev_progress = progress;
 337        qemu_put_be64(f, (progress << BDRV_SECTOR_BITS)
 338                         | BLK_MIG_FLAG_PROGRESS);
 339        DPRINTF("Completed %d %%\r", progress);
 340    }
 341
 342    return ret;
 343}
 344
 345static void blk_mig_reset_dirty_cursor(void)
 346{
 347    BlkMigDevState *bmds;
 348
 349    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
 350        bmds->cur_dirty = 0;
 351    }
 352}
 353
 354static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
 355                                 int is_async)
 356{
 357    BlkMigBlock *blk;
 358    int64_t total_sectors = bmds->total_sectors;
 359    int64_t sector;
 360    int nr_sectors;
 361    int ret = -EIO;
 362
 363    for (sector = bmds->cur_dirty; sector < bmds->total_sectors;) {
 364        if (bmds_aio_inflight(bmds, sector)) {
 365            bdrv_drain_all();
 366        }
 367        if (bdrv_get_dirty(bmds->bs, sector)) {
 368
 369            if (total_sectors - sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {
 370                nr_sectors = total_sectors - sector;
 371            } else {
 372                nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
 373            }
 374            blk = g_malloc(sizeof(BlkMigBlock));
 375            blk->buf = g_malloc(BLOCK_SIZE);
 376            blk->bmds = bmds;
 377            blk->sector = sector;
 378            blk->nr_sectors = nr_sectors;
 379
 380            if (is_async) {
 381                blk->iov.iov_base = blk->buf;
 382                blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
 383                qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
 384
 385                if (block_mig_state.submitted == 0) {
 386                    block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock);
 387                }
 388
 389                blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov,
 390                                            nr_sectors, blk_mig_read_cb, blk);
 391                block_mig_state.submitted++;
 392                bmds_set_aio_inflight(bmds, sector, nr_sectors, 1);
 393            } else {
 394                ret = bdrv_read(bmds->bs, sector, blk->buf, nr_sectors);
 395                if (ret < 0) {
 396                    goto error;
 397                }
 398                blk_send(f, blk);
 399
 400                g_free(blk->buf);
 401                g_free(blk);
 402            }
 403
 404            bdrv_reset_dirty(bmds->bs, sector, nr_sectors);
 405            break;
 406        }
 407        sector += BDRV_SECTORS_PER_DIRTY_CHUNK;
 408        bmds->cur_dirty = sector;
 409    }
 410
 411    return (bmds->cur_dirty >= bmds->total_sectors);
 412
 413error:
 414    DPRINTF("Error reading sector %" PRId64 "\n", sector);
 415    g_free(blk->buf);
 416    g_free(blk);
 417    return ret;
 418}
 419
 420/* return value:
 421 * 0: too much data for max_downtime
 422 * 1: few enough data for max_downtime
 423*/
 424static int blk_mig_save_dirty_block(QEMUFile *f, int is_async)
 425{
 426    BlkMigDevState *bmds;
 427    int ret = 1;
 428
 429    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
 430        ret = mig_save_device_dirty(f, bmds, is_async);
 431        if (ret <= 0) {
 432            break;
 433        }
 434    }
 435
 436    return ret;
 437}
 438
 439static int flush_blks(QEMUFile *f)
 440{
 441    BlkMigBlock *blk;
 442    int ret = 0;
 443
 444    DPRINTF("%s Enter submitted %d read_done %d transferred %d\n",
 445            __FUNCTION__, block_mig_state.submitted, block_mig_state.read_done,
 446            block_mig_state.transferred);
 447
 448    while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) {
 449        if (qemu_file_rate_limit(f)) {
 450            break;
 451        }
 452        if (blk->ret < 0) {
 453            ret = blk->ret;
 454            break;
 455        }
 456        blk_send(f, blk);
 457
 458        QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry);
 459        g_free(blk->buf);
 460        g_free(blk);
 461
 462        block_mig_state.read_done--;
 463        block_mig_state.transferred++;
 464        assert(block_mig_state.read_done >= 0);
 465    }
 466
 467    DPRINTF("%s Exit submitted %d read_done %d transferred %d\n", __FUNCTION__,
 468            block_mig_state.submitted, block_mig_state.read_done,
 469            block_mig_state.transferred);
 470    return ret;
 471}
 472
 473static int64_t get_remaining_dirty(void)
 474{
 475    BlkMigDevState *bmds;
 476    int64_t dirty = 0;
 477
 478    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
 479        dirty += bdrv_get_dirty_count(bmds->bs);
 480    }
 481
 482    return dirty << BDRV_SECTOR_BITS;
 483}
 484
 485static void blk_mig_cleanup(void)
 486{
 487    BlkMigDevState *bmds;
 488    BlkMigBlock *blk;
 489
 490    bdrv_drain_all();
 491
 492    set_dirty_tracking(0);
 493
 494    while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) {
 495        QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry);
 496        bdrv_set_in_use(bmds->bs, 0);
 497        drive_put_ref(drive_get_by_blockdev(bmds->bs));
 498        g_free(bmds->aio_bitmap);
 499        g_free(bmds);
 500    }
 501
 502    while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) {
 503        QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry);
 504        g_free(blk->buf);
 505        g_free(blk);
 506    }
 507}
 508
 509static void block_migration_cancel(void *opaque)
 510{
 511    blk_mig_cleanup();
 512}
 513
 514static int block_save_setup(QEMUFile *f, void *opaque)
 515{
 516    int ret;
 517
 518    DPRINTF("Enter save live setup submitted %d transferred %d\n",
 519            block_mig_state.submitted, block_mig_state.transferred);
 520
 521    init_blk_migration(f);
 522
 523    /* start track dirty blocks */
 524    set_dirty_tracking(1);
 525
 526    ret = flush_blks(f);
 527    if (ret) {
 528        blk_mig_cleanup();
 529        return ret;
 530    }
 531
 532    blk_mig_reset_dirty_cursor();
 533
 534    qemu_put_be64(f, BLK_MIG_FLAG_EOS);
 535
 536    return 0;
 537}
 538
 539static int block_save_iterate(QEMUFile *f, void *opaque)
 540{
 541    int ret;
 542    int64_t last_ftell = qemu_ftell(f);
 543
 544    DPRINTF("Enter save live iterate submitted %d transferred %d\n",
 545            block_mig_state.submitted, block_mig_state.transferred);
 546
 547    ret = flush_blks(f);
 548    if (ret) {
 549        blk_mig_cleanup();
 550        return ret;
 551    }
 552
 553    blk_mig_reset_dirty_cursor();
 554
 555    /* control the rate of transfer */
 556    while ((block_mig_state.submitted +
 557            block_mig_state.read_done) * BLOCK_SIZE <
 558           qemu_file_get_rate_limit(f)) {
 559        if (block_mig_state.bulk_completed == 0) {
 560            /* first finish the bulk phase */
 561            if (blk_mig_save_bulked_block(f) == 0) {
 562                /* finished saving bulk on all devices */
 563                block_mig_state.bulk_completed = 1;
 564            }
 565        } else {
 566            ret = blk_mig_save_dirty_block(f, 1);
 567            if (ret != 0) {
 568                /* no more dirty blocks */
 569                break;
 570            }
 571        }
 572    }
 573    if (ret < 0) {
 574        blk_mig_cleanup();
 575        return ret;
 576    }
 577
 578    ret = flush_blks(f);
 579    if (ret) {
 580        blk_mig_cleanup();
 581        return ret;
 582    }
 583
 584    qemu_put_be64(f, BLK_MIG_FLAG_EOS);
 585
 586    return qemu_ftell(f) - last_ftell;
 587}
 588
 589static int block_save_complete(QEMUFile *f, void *opaque)
 590{
 591    int ret;
 592
 593    DPRINTF("Enter save live complete submitted %d transferred %d\n",
 594            block_mig_state.submitted, block_mig_state.transferred);
 595
 596    ret = flush_blks(f);
 597    if (ret) {
 598        blk_mig_cleanup();
 599        return ret;
 600    }
 601
 602    blk_mig_reset_dirty_cursor();
 603
 604    /* we know for sure that save bulk is completed and
 605       all async read completed */
 606    assert(block_mig_state.submitted == 0);
 607
 608    do {
 609        ret = blk_mig_save_dirty_block(f, 0);
 610    } while (ret == 0);
 611
 612    blk_mig_cleanup();
 613    if (ret < 0) {
 614        return ret;
 615    }
 616    /* report completion */
 617    qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS);
 618
 619    DPRINTF("Block migration completed\n");
 620
 621    qemu_put_be64(f, BLK_MIG_FLAG_EOS);
 622
 623    return 0;
 624}
 625
 626static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)
 627{
 628    /* Estimate pending number of bytes to send */
 629    uint64_t pending = get_remaining_dirty() +
 630                       block_mig_state.submitted * BLOCK_SIZE +
 631                       block_mig_state.read_done * BLOCK_SIZE;
 632
 633    /* Report at least one block pending during bulk phase */
 634    if (pending == 0 && !block_mig_state.bulk_completed) {
 635        pending = BLOCK_SIZE;
 636    }
 637
 638    DPRINTF("Enter save live pending  %" PRIu64 "\n", pending);
 639    return pending;
 640}
 641
 642static int block_load(QEMUFile *f, void *opaque, int version_id)
 643{
 644    static int banner_printed;
 645    int len, flags;
 646    char device_name[256];
 647    int64_t addr;
 648    BlockDriverState *bs, *bs_prev = NULL;
 649    uint8_t *buf;
 650    int64_t total_sectors = 0;
 651    int nr_sectors;
 652    int ret;
 653
 654    do {
 655        addr = qemu_get_be64(f);
 656
 657        flags = addr & ~BDRV_SECTOR_MASK;
 658        addr >>= BDRV_SECTOR_BITS;
 659
 660        if (flags & BLK_MIG_FLAG_DEVICE_BLOCK) {
 661            /* get device name */
 662            len = qemu_get_byte(f);
 663            qemu_get_buffer(f, (uint8_t *)device_name, len);
 664            device_name[len] = '\0';
 665
 666            bs = bdrv_find(device_name);
 667            if (!bs) {
 668                fprintf(stderr, "Error unknown block device %s\n",
 669                        device_name);
 670                return -EINVAL;
 671            }
 672
 673            if (bs != bs_prev) {
 674                bs_prev = bs;
 675                total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
 676                if (total_sectors <= 0) {
 677                    error_report("Error getting length of block device %s",
 678                                 device_name);
 679                    return -EINVAL;
 680                }
 681            }
 682
 683            if (total_sectors - addr < BDRV_SECTORS_PER_DIRTY_CHUNK) {
 684                nr_sectors = total_sectors - addr;
 685            } else {
 686                nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
 687            }
 688
 689            buf = g_malloc(BLOCK_SIZE);
 690
 691            qemu_get_buffer(f, buf, BLOCK_SIZE);
 692            ret = bdrv_write(bs, addr, buf, nr_sectors);
 693
 694            g_free(buf);
 695            if (ret < 0) {
 696                return ret;
 697            }
 698        } else if (flags & BLK_MIG_FLAG_PROGRESS) {
 699            if (!banner_printed) {
 700                printf("Receiving block device images\n");
 701                banner_printed = 1;
 702            }
 703            printf("Completed %d %%%c", (int)addr,
 704                   (addr == 100) ? '\n' : '\r');
 705            fflush(stdout);
 706        } else if (!(flags & BLK_MIG_FLAG_EOS)) {
 707            fprintf(stderr, "Unknown block migration flags: %#x\n", flags);
 708            return -EINVAL;
 709        }
 710        ret = qemu_file_get_error(f);
 711        if (ret != 0) {
 712            return ret;
 713        }
 714    } while (!(flags & BLK_MIG_FLAG_EOS));
 715
 716    return 0;
 717}
 718
 719static void block_set_params(const MigrationParams *params, void *opaque)
 720{
 721    block_mig_state.blk_enable = params->blk;
 722    block_mig_state.shared_base = params->shared;
 723
 724    /* shared base means that blk_enable = 1 */
 725    block_mig_state.blk_enable |= params->shared;
 726}
 727
 728static bool block_is_active(void *opaque)
 729{
 730    return block_mig_state.blk_enable == 1;
 731}
 732
 733SaveVMHandlers savevm_block_handlers = {
 734    .set_params = block_set_params,
 735    .save_live_setup = block_save_setup,
 736    .save_live_iterate = block_save_iterate,
 737    .save_live_complete = block_save_complete,
 738    .save_live_pending = block_save_pending,
 739    .load_state = block_load,
 740    .cancel = block_migration_cancel,
 741    .is_active = block_is_active,
 742};
 743
 744void blk_mig_init(void)
 745{
 746    QSIMPLEQ_INIT(&block_mig_state.bmds_list);
 747    QSIMPLEQ_INIT(&block_mig_state.blk_list);
 748
 749    register_savevm_live(NULL, "block", 0, 1, &savevm_block_handlers,
 750                         &block_mig_state);
 751}
 752