Statistics
| Branch: | Revision:

root / block-migration.c @ 6aaa9dae

History | View | Annotate | Download (20 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
    int64_t dirty;
54
    QSIMPLEQ_ENTRY(BlkMigDevState) entry;
55
    unsigned long *aio_bitmap;
56
} BlkMigDevState;
57

    
58
typedef 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

    
70
typedef 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

    
84
static BlkMigState block_mig_state;
85

    
86
static 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

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

    
107
uint64_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

    
118
uint64_t blk_mig_bytes_remaining(void)
119
{
120
    return blk_mig_bytes_total() - blk_mig_bytes_transferred();
121
}
122

    
123
uint64_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

    
134
static 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

    
146
static 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

    
168
static 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

    
180
static 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

    
197
static 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

    
253
static 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

    
262
static 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

    
296
static 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

    
308
static 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

    
345
static 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

    
354
static 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

    
413
error:
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
*/
424
static 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

    
439
static 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

    
473
static 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

    
485
static 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

    
509
static void block_migration_cancel(void *opaque)
510
{
511
    blk_mig_cleanup();
512
}
513

    
514
static 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

    
539
static 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

    
589
static 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

    
626
static 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

    
642
static 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

    
719
static 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

    
728
static bool block_is_active(void *opaque)
729
{
730
    return block_mig_state.blk_enable == 1;
731
}
732

    
733
SaveVMHandlers 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

    
744
void 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
}