Statistics
| Branch: | Revision:

root / block-migration.c @ a55ce1c8

History | View | Annotate | Download (19.4 kB)

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

    
45
typedef 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
    QSIMPLEQ_ENTRY(BlkMigDevState) entry;
54
    unsigned long *aio_bitmap;
55
} BlkMigDevState;
56

    
57
typedef struct BlkMigBlock {
58
    uint8_t *buf;
59
    BlkMigDevState *bmds;
60
    int64_t sector;
61
    int nr_sectors;
62
    struct iovec iov;
63
    QEMUIOVector qiov;
64
    BlockDriverAIOCB *aiocb;
65
    int ret;
66
    QSIMPLEQ_ENTRY(BlkMigBlock) entry;
67
} BlkMigBlock;
68

    
69
typedef struct BlkMigState {
70
    int blk_enable;
71
    int shared_base;
72
    QSIMPLEQ_HEAD(bmds_list, BlkMigDevState) bmds_list;
73
    QSIMPLEQ_HEAD(blk_list, BlkMigBlock) blk_list;
74
    int submitted;
75
    int read_done;
76
    int transferred;
77
    int64_t total_sector_sum;
78
    int prev_progress;
79
    int bulk_completed;
80
} BlkMigState;
81

    
82
static BlkMigState block_mig_state;
83

    
84
static void blk_send(QEMUFile *f, BlkMigBlock * blk)
85
{
86
    int len;
87

    
88
    /* sector number and flags */
89
    qemu_put_be64(f, (blk->sector << BDRV_SECTOR_BITS)
90
                     | BLK_MIG_FLAG_DEVICE_BLOCK);
91

    
92
    /* device name */
93
    len = strlen(blk->bmds->bs->device_name);
94
    qemu_put_byte(f, len);
95
    qemu_put_buffer(f, (uint8_t *)blk->bmds->bs->device_name, len);
96

    
97
    qemu_put_buffer(f, blk->buf, BLOCK_SIZE);
98
}
99

    
100
int blk_mig_active(void)
101
{
102
    return !QSIMPLEQ_EMPTY(&block_mig_state.bmds_list);
103
}
104

    
105
uint64_t blk_mig_bytes_transferred(void)
106
{
107
    BlkMigDevState *bmds;
108
    uint64_t sum = 0;
109

    
110
    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
111
        sum += bmds->completed_sectors;
112
    }
113
    return sum << BDRV_SECTOR_BITS;
114
}
115

    
116
uint64_t blk_mig_bytes_remaining(void)
117
{
118
    return blk_mig_bytes_total() - blk_mig_bytes_transferred();
119
}
120

    
121
uint64_t blk_mig_bytes_total(void)
122
{
123
    BlkMigDevState *bmds;
124
    uint64_t sum = 0;
125

    
126
    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
127
        sum += bmds->total_sectors;
128
    }
129
    return sum << BDRV_SECTOR_BITS;
130
}
131

    
132
static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector)
133
{
134
    int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
135

    
136
    if ((sector << BDRV_SECTOR_BITS) < bdrv_getlength(bmds->bs)) {
137
        return !!(bmds->aio_bitmap[chunk / (sizeof(unsigned long) * 8)] &
138
            (1UL << (chunk % (sizeof(unsigned long) * 8))));
139
    } else {
140
        return 0;
141
    }
142
}
143

    
144
static void bmds_set_aio_inflight(BlkMigDevState *bmds, int64_t sector_num,
145
                             int nb_sectors, int set)
146
{
147
    int64_t start, end;
148
    unsigned long val, idx, bit;
149

    
150
    start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
151
    end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
152

    
153
    for (; start <= end; start++) {
154
        idx = start / (sizeof(unsigned long) * 8);
155
        bit = start % (sizeof(unsigned long) * 8);
156
        val = bmds->aio_bitmap[idx];
157
        if (set) {
158
            val |= 1UL << bit;
159
        } else {
160
            val &= ~(1UL << bit);
161
        }
162
        bmds->aio_bitmap[idx] = val;
163
    }
164
}
165

    
166
static void alloc_aio_bitmap(BlkMigDevState *bmds)
167
{
168
    BlockDriverState *bs = bmds->bs;
169
    int64_t bitmap_size;
170

    
171
    bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
172
            BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
173
    bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
174

    
175
    bmds->aio_bitmap = g_malloc0(bitmap_size);
176
}
177

    
178
static void blk_mig_read_cb(void *opaque, int ret)
179
{
180
    BlkMigBlock *blk = opaque;
181

    
182
    blk->ret = ret;
183

    
184
    QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry);
185
    bmds_set_aio_inflight(blk->bmds, blk->sector, blk->nr_sectors, 0);
186

    
187
    block_mig_state.submitted--;
188
    block_mig_state.read_done++;
189
    assert(block_mig_state.submitted >= 0);
190
}
191

    
192
static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
193
{
194
    int64_t total_sectors = bmds->total_sectors;
195
    int64_t cur_sector = bmds->cur_sector;
196
    BlockDriverState *bs = bmds->bs;
197
    BlkMigBlock *blk;
198
    int nr_sectors;
199

    
200
    if (bmds->shared_base) {
201
        while (cur_sector < total_sectors &&
202
               !bdrv_is_allocated(bs, cur_sector, MAX_IS_ALLOCATED_SEARCH,
203
                                  &nr_sectors)) {
204
            cur_sector += nr_sectors;
205
        }
206
    }
207

    
208
    if (cur_sector >= total_sectors) {
209
        bmds->cur_sector = bmds->completed_sectors = total_sectors;
210
        return 1;
211
    }
212

    
213
    bmds->completed_sectors = cur_sector;
214

    
215
    cur_sector &= ~((int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK - 1);
216

    
217
    /* we are going to transfer a full block even if it is not allocated */
218
    nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
219

    
220
    if (total_sectors - cur_sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {
221
        nr_sectors = total_sectors - cur_sector;
222
    }
223

    
224
    blk = g_malloc(sizeof(BlkMigBlock));
225
    blk->buf = g_malloc(BLOCK_SIZE);
226
    blk->bmds = bmds;
227
    blk->sector = cur_sector;
228
    blk->nr_sectors = nr_sectors;
229

    
230
    blk->iov.iov_base = blk->buf;
231
    blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
232
    qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
233

    
234
    blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov,
235
                                nr_sectors, blk_mig_read_cb, blk);
236
    block_mig_state.submitted++;
237

    
238
    bdrv_reset_dirty(bs, cur_sector, nr_sectors);
239
    bmds->cur_sector = cur_sector + nr_sectors;
240

    
241
    return (bmds->cur_sector >= total_sectors);
242
}
243

    
244
static void set_dirty_tracking(int enable)
245
{
246
    BlkMigDevState *bmds;
247

    
248
    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
249
        bdrv_set_dirty_tracking(bmds->bs, enable ? BLOCK_SIZE : 0);
250
    }
251
}
252

    
253
static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
254
{
255
    BlkMigDevState *bmds;
256
    int64_t sectors;
257

    
258
    if (!bdrv_is_read_only(bs)) {
259
        sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
260
        if (sectors <= 0) {
261
            return;
262
        }
263

    
264
        bmds = g_malloc0(sizeof(BlkMigDevState));
265
        bmds->bs = bs;
266
        bmds->bulk_completed = 0;
267
        bmds->total_sectors = sectors;
268
        bmds->completed_sectors = 0;
269
        bmds->shared_base = block_mig_state.shared_base;
270
        alloc_aio_bitmap(bmds);
271
        drive_get_ref(drive_get_by_blockdev(bs));
272
        bdrv_set_in_use(bs, 1);
273

    
274
        block_mig_state.total_sector_sum += sectors;
275

    
276
        if (bmds->shared_base) {
277
            DPRINTF("Start migration for %s with shared base image\n",
278
                    bs->device_name);
279
        } else {
280
            DPRINTF("Start full migration for %s\n", bs->device_name);
281
        }
282

    
283
        QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);
284
    }
285
}
286

    
287
static void init_blk_migration(QEMUFile *f)
288
{
289
    block_mig_state.submitted = 0;
290
    block_mig_state.read_done = 0;
291
    block_mig_state.transferred = 0;
292
    block_mig_state.total_sector_sum = 0;
293
    block_mig_state.prev_progress = -1;
294
    block_mig_state.bulk_completed = 0;
295

    
296
    bdrv_iterate(init_blk_migration_it, NULL);
297
}
298

    
299
static int blk_mig_save_bulked_block(QEMUFile *f)
300
{
301
    int64_t completed_sector_sum = 0;
302
    BlkMigDevState *bmds;
303
    int progress;
304
    int ret = 0;
305

    
306
    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
307
        if (bmds->bulk_completed == 0) {
308
            if (mig_save_device_bulk(f, bmds) == 1) {
309
                /* completed bulk section for this device */
310
                bmds->bulk_completed = 1;
311
            }
312
            completed_sector_sum += bmds->completed_sectors;
313
            ret = 1;
314
            break;
315
        } else {
316
            completed_sector_sum += bmds->completed_sectors;
317
        }
318
    }
319

    
320
    if (block_mig_state.total_sector_sum != 0) {
321
        progress = completed_sector_sum * 100 /
322
                   block_mig_state.total_sector_sum;
323
    } else {
324
        progress = 100;
325
    }
326
    if (progress != block_mig_state.prev_progress) {
327
        block_mig_state.prev_progress = progress;
328
        qemu_put_be64(f, (progress << BDRV_SECTOR_BITS)
329
                         | BLK_MIG_FLAG_PROGRESS);
330
        DPRINTF("Completed %d %%\r", progress);
331
    }
332

    
333
    return ret;
334
}
335

    
336
static void blk_mig_reset_dirty_cursor(void)
337
{
338
    BlkMigDevState *bmds;
339

    
340
    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
341
        bmds->cur_dirty = 0;
342
    }
343
}
344

    
345
static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
346
                                 int is_async)
347
{
348
    BlkMigBlock *blk;
349
    int64_t total_sectors = bmds->total_sectors;
350
    int64_t sector;
351
    int nr_sectors;
352
    int ret = -EIO;
353

    
354
    for (sector = bmds->cur_dirty; sector < bmds->total_sectors;) {
355
        if (bmds_aio_inflight(bmds, sector)) {
356
            bdrv_drain_all();
357
        }
358
        if (bdrv_get_dirty(bmds->bs, sector)) {
359

    
360
            if (total_sectors - sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {
361
                nr_sectors = total_sectors - sector;
362
            } else {
363
                nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
364
            }
365
            blk = g_malloc(sizeof(BlkMigBlock));
366
            blk->buf = g_malloc(BLOCK_SIZE);
367
            blk->bmds = bmds;
368
            blk->sector = sector;
369
            blk->nr_sectors = nr_sectors;
370

    
371
            if (is_async) {
372
                blk->iov.iov_base = blk->buf;
373
                blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
374
                qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
375

    
376
                blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov,
377
                                            nr_sectors, blk_mig_read_cb, blk);
378
                block_mig_state.submitted++;
379
                bmds_set_aio_inflight(bmds, sector, nr_sectors, 1);
380
            } else {
381
                ret = bdrv_read(bmds->bs, sector, blk->buf, nr_sectors);
382
                if (ret < 0) {
383
                    goto error;
384
                }
385
                blk_send(f, blk);
386

    
387
                g_free(blk->buf);
388
                g_free(blk);
389
            }
390

    
391
            bdrv_reset_dirty(bmds->bs, sector, nr_sectors);
392
            break;
393
        }
394
        sector += BDRV_SECTORS_PER_DIRTY_CHUNK;
395
        bmds->cur_dirty = sector;
396
    }
397

    
398
    return (bmds->cur_dirty >= bmds->total_sectors);
399

    
400
error:
401
    DPRINTF("Error reading sector %" PRId64 "\n", sector);
402
    g_free(blk->buf);
403
    g_free(blk);
404
    return ret;
405
}
406

    
407
/* return value:
408
 * 0: too much data for max_downtime
409
 * 1: few enough data for max_downtime
410
*/
411
static int blk_mig_save_dirty_block(QEMUFile *f, int is_async)
412
{
413
    BlkMigDevState *bmds;
414
    int ret = 1;
415

    
416
    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
417
        ret = mig_save_device_dirty(f, bmds, is_async);
418
        if (ret <= 0) {
419
            break;
420
        }
421
    }
422

    
423
    return ret;
424
}
425

    
426
static int flush_blks(QEMUFile *f)
427
{
428
    BlkMigBlock *blk;
429
    int ret = 0;
430

    
431
    DPRINTF("%s Enter submitted %d read_done %d transferred %d\n",
432
            __FUNCTION__, block_mig_state.submitted, block_mig_state.read_done,
433
            block_mig_state.transferred);
434

    
435
    while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) {
436
        if (qemu_file_rate_limit(f)) {
437
            break;
438
        }
439
        if (blk->ret < 0) {
440
            ret = blk->ret;
441
            break;
442
        }
443
        blk_send(f, blk);
444

    
445
        QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry);
446
        g_free(blk->buf);
447
        g_free(blk);
448

    
449
        block_mig_state.read_done--;
450
        block_mig_state.transferred++;
451
        assert(block_mig_state.read_done >= 0);
452
    }
453

    
454
    DPRINTF("%s Exit submitted %d read_done %d transferred %d\n", __FUNCTION__,
455
            block_mig_state.submitted, block_mig_state.read_done,
456
            block_mig_state.transferred);
457
    return ret;
458
}
459

    
460
static int64_t get_remaining_dirty(void)
461
{
462
    BlkMigDevState *bmds;
463
    int64_t dirty = 0;
464

    
465
    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
466
        dirty += bdrv_get_dirty_count(bmds->bs);
467
    }
468

    
469
    return dirty << BDRV_SECTOR_BITS;
470
}
471

    
472
static void blk_mig_cleanup(void)
473
{
474
    BlkMigDevState *bmds;
475
    BlkMigBlock *blk;
476

    
477
    bdrv_drain_all();
478

    
479
    set_dirty_tracking(0);
480

    
481
    while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) {
482
        QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry);
483
        bdrv_set_in_use(bmds->bs, 0);
484
        drive_put_ref(drive_get_by_blockdev(bmds->bs));
485
        g_free(bmds->aio_bitmap);
486
        g_free(bmds);
487
    }
488

    
489
    while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) {
490
        QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry);
491
        g_free(blk->buf);
492
        g_free(blk);
493
    }
494
}
495

    
496
static void block_migration_cancel(void *opaque)
497
{
498
    blk_mig_cleanup();
499
}
500

    
501
static int block_save_setup(QEMUFile *f, void *opaque)
502
{
503
    int ret;
504

    
505
    DPRINTF("Enter save live setup submitted %d transferred %d\n",
506
            block_mig_state.submitted, block_mig_state.transferred);
507

    
508
    init_blk_migration(f);
509

    
510
    /* start track dirty blocks */
511
    set_dirty_tracking(1);
512

    
513
    ret = flush_blks(f);
514
    blk_mig_reset_dirty_cursor();
515
    qemu_put_be64(f, BLK_MIG_FLAG_EOS);
516

    
517
    return ret;
518
}
519

    
520
static int block_save_iterate(QEMUFile *f, void *opaque)
521
{
522
    int ret;
523
    int64_t last_ftell = qemu_ftell(f);
524

    
525
    DPRINTF("Enter save live iterate submitted %d transferred %d\n",
526
            block_mig_state.submitted, block_mig_state.transferred);
527

    
528
    ret = flush_blks(f);
529
    if (ret) {
530
        return ret;
531
    }
532

    
533
    blk_mig_reset_dirty_cursor();
534

    
535
    /* control the rate of transfer */
536
    while ((block_mig_state.submitted +
537
            block_mig_state.read_done) * BLOCK_SIZE <
538
           qemu_file_get_rate_limit(f)) {
539
        if (block_mig_state.bulk_completed == 0) {
540
            /* first finish the bulk phase */
541
            if (blk_mig_save_bulked_block(f) == 0) {
542
                /* finished saving bulk on all devices */
543
                block_mig_state.bulk_completed = 1;
544
            }
545
        } else {
546
            ret = blk_mig_save_dirty_block(f, 1);
547
            if (ret < 0) {
548
                return ret;
549
            }
550
            if (ret != 0) {
551
                /* no more dirty blocks */
552
                break;
553
            }
554
        }
555
    }
556

    
557
    ret = flush_blks(f);
558
    if (ret) {
559
        return ret;
560
    }
561

    
562
    qemu_put_be64(f, BLK_MIG_FLAG_EOS);
563

    
564
    return qemu_ftell(f) - last_ftell;
565
}
566

    
567
static int block_save_complete(QEMUFile *f, void *opaque)
568
{
569
    int ret;
570

    
571
    DPRINTF("Enter save live complete submitted %d transferred %d\n",
572
            block_mig_state.submitted, block_mig_state.transferred);
573

    
574
    ret = flush_blks(f);
575
    if (ret) {
576
        return ret;
577
    }
578

    
579
    blk_mig_reset_dirty_cursor();
580

    
581
    /* we know for sure that save bulk is completed and
582
       all async read completed */
583
    assert(block_mig_state.submitted == 0);
584

    
585
    do {
586
        ret = blk_mig_save_dirty_block(f, 0);
587
        if (ret < 0) {
588
            return ret;
589
        }
590
    } while (ret == 0);
591

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

    
595
    DPRINTF("Block migration completed\n");
596

    
597
    qemu_put_be64(f, BLK_MIG_FLAG_EOS);
598

    
599
    blk_mig_cleanup();
600
    return 0;
601
}
602

    
603
static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)
604
{
605
    /* Estimate pending number of bytes to send */
606
    uint64_t pending = get_remaining_dirty() +
607
                       block_mig_state.submitted * BLOCK_SIZE +
608
                       block_mig_state.read_done * BLOCK_SIZE;
609

    
610
    /* Report at least one block pending during bulk phase */
611
    if (pending == 0 && !block_mig_state.bulk_completed) {
612
        pending = BLOCK_SIZE;
613
    }
614

    
615
    DPRINTF("Enter save live pending  %" PRIu64 "\n", pending);
616
    return pending;
617
}
618

    
619
static int block_load(QEMUFile *f, void *opaque, int version_id)
620
{
621
    static int banner_printed;
622
    int len, flags;
623
    char device_name[256];
624
    int64_t addr;
625
    BlockDriverState *bs, *bs_prev = NULL;
626
    uint8_t *buf;
627
    int64_t total_sectors = 0;
628
    int nr_sectors;
629
    int ret;
630

    
631
    do {
632
        addr = qemu_get_be64(f);
633

    
634
        flags = addr & ~BDRV_SECTOR_MASK;
635
        addr >>= BDRV_SECTOR_BITS;
636

    
637
        if (flags & BLK_MIG_FLAG_DEVICE_BLOCK) {
638
            /* get device name */
639
            len = qemu_get_byte(f);
640
            qemu_get_buffer(f, (uint8_t *)device_name, len);
641
            device_name[len] = '\0';
642

    
643
            bs = bdrv_find(device_name);
644
            if (!bs) {
645
                fprintf(stderr, "Error unknown block device %s\n",
646
                        device_name);
647
                return -EINVAL;
648
            }
649

    
650
            if (bs != bs_prev) {
651
                bs_prev = bs;
652
                total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
653
                if (total_sectors <= 0) {
654
                    error_report("Error getting length of block device %s",
655
                                 device_name);
656
                    return -EINVAL;
657
                }
658
            }
659

    
660
            if (total_sectors - addr < BDRV_SECTORS_PER_DIRTY_CHUNK) {
661
                nr_sectors = total_sectors - addr;
662
            } else {
663
                nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
664
            }
665

    
666
            buf = g_malloc(BLOCK_SIZE);
667

    
668
            qemu_get_buffer(f, buf, BLOCK_SIZE);
669
            ret = bdrv_write(bs, addr, buf, nr_sectors);
670

    
671
            g_free(buf);
672
            if (ret < 0) {
673
                return ret;
674
            }
675
        } else if (flags & BLK_MIG_FLAG_PROGRESS) {
676
            if (!banner_printed) {
677
                printf("Receiving block device images\n");
678
                banner_printed = 1;
679
            }
680
            printf("Completed %d %%%c", (int)addr,
681
                   (addr == 100) ? '\n' : '\r');
682
            fflush(stdout);
683
        } else if (!(flags & BLK_MIG_FLAG_EOS)) {
684
            fprintf(stderr, "Unknown block migration flags: %#x\n", flags);
685
            return -EINVAL;
686
        }
687
        ret = qemu_file_get_error(f);
688
        if (ret != 0) {
689
            return ret;
690
        }
691
    } while (!(flags & BLK_MIG_FLAG_EOS));
692

    
693
    return 0;
694
}
695

    
696
static void block_set_params(const MigrationParams *params, void *opaque)
697
{
698
    block_mig_state.blk_enable = params->blk;
699
    block_mig_state.shared_base = params->shared;
700

    
701
    /* shared base means that blk_enable = 1 */
702
    block_mig_state.blk_enable |= params->shared;
703
}
704

    
705
static bool block_is_active(void *opaque)
706
{
707
    return block_mig_state.blk_enable == 1;
708
}
709

    
710
SaveVMHandlers savevm_block_handlers = {
711
    .set_params = block_set_params,
712
    .save_live_setup = block_save_setup,
713
    .save_live_iterate = block_save_iterate,
714
    .save_live_complete = block_save_complete,
715
    .save_live_pending = block_save_pending,
716
    .load_state = block_load,
717
    .cancel = block_migration_cancel,
718
    .is_active = block_is_active,
719
};
720

    
721
void blk_mig_init(void)
722
{
723
    QSIMPLEQ_INIT(&block_mig_state.bmds_list);
724
    QSIMPLEQ_INIT(&block_mig_state.blk_list);
725

    
726
    register_savevm_live(NULL, "block", 0, 1, &savevm_block_handlers,
727
                         &block_mig_state);
728
}