Revision e970ec0b
b/block-migration.c | ||
---|---|---|
26 | 26 |
#define BLK_MIG_FLAG_PROGRESS 0x04 |
27 | 27 |
|
28 | 28 |
#define MAX_IS_ALLOCATED_SEARCH 65536 |
29 |
#define MAX_BLOCKS_READ 10000 |
|
30 |
#define BLOCKS_READ_CHANGE 100 |
|
31 |
#define INITIAL_BLOCKS_READ 100 |
|
32 | 29 |
|
33 | 30 |
//#define DEBUG_BLK_MIGRATION |
34 | 31 |
|
... | ... | |
72 | 69 |
int transferred; |
73 | 70 |
int64_t total_sector_sum; |
74 | 71 |
int prev_progress; |
72 |
int bulk_completed; |
|
75 | 73 |
} BlkMigState; |
76 | 74 |
|
77 | 75 |
static BlkMigState block_mig_state; |
... | ... | |
138 | 136 |
} |
139 | 137 |
|
140 | 138 |
static int mig_save_device_bulk(Monitor *mon, QEMUFile *f, |
141 |
BlkMigDevState *bmds, int is_async)
|
|
139 |
BlkMigDevState *bmds) |
|
142 | 140 |
{ |
143 | 141 |
int64_t total_sectors = bmds->total_sectors; |
144 | 142 |
int64_t cur_sector = bmds->cur_sector; |
... | ... | |
175 | 173 |
blk->bmds = bmds; |
176 | 174 |
blk->sector = cur_sector; |
177 | 175 |
|
178 |
if (is_async) { |
|
179 |
blk->iov.iov_base = blk->buf; |
|
180 |
blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; |
|
181 |
qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); |
|
182 |
|
|
183 |
blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, |
|
184 |
nr_sectors, blk_mig_read_cb, blk); |
|
185 |
if (!blk->aiocb) { |
|
186 |
goto error; |
|
187 |
} |
|
188 |
block_mig_state.submitted++; |
|
189 |
} else { |
|
190 |
if (bdrv_read(bs, cur_sector, blk->buf, nr_sectors) < 0) { |
|
191 |
goto error; |
|
192 |
} |
|
193 |
blk_send(f, blk); |
|
176 |
blk->iov.iov_base = blk->buf; |
|
177 |
blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; |
|
178 |
qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); |
|
194 | 179 |
|
195 |
qemu_free(blk->buf); |
|
196 |
qemu_free(blk); |
|
180 |
blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, |
|
181 |
nr_sectors, blk_mig_read_cb, blk); |
|
182 |
if (!blk->aiocb) { |
|
183 |
goto error; |
|
197 | 184 |
} |
198 |
|
|
185 |
block_mig_state.submitted++; |
|
199 | 186 |
bdrv_reset_dirty(bs, cur_sector, nr_sectors); |
200 | 187 |
bmds->cur_sector = cur_sector + nr_sectors; |
201 | 188 |
|
... | ... | |
229 | 216 |
block_mig_state.transferred = 0; |
230 | 217 |
block_mig_state.total_sector_sum = 0; |
231 | 218 |
block_mig_state.prev_progress = -1; |
219 |
block_mig_state.bulk_completed = 0; |
|
232 | 220 |
|
233 | 221 |
for (bs = bdrv_first; bs != NULL; bs = bs->next) { |
234 | 222 |
if (bs->type == BDRV_TYPE_HD) { |
... | ... | |
260 | 248 |
} |
261 | 249 |
} |
262 | 250 |
|
263 |
static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f, int is_async)
|
|
251 |
static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f) |
|
264 | 252 |
{ |
265 | 253 |
int64_t completed_sector_sum = 0; |
266 | 254 |
BlkMigDevState *bmds; |
... | ... | |
269 | 257 |
|
270 | 258 |
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { |
271 | 259 |
if (bmds->bulk_completed == 0) { |
272 |
if (mig_save_device_bulk(mon, f, bmds, is_async) == 1) {
|
|
260 |
if (mig_save_device_bulk(mon, f, bmds) == 1) { |
|
273 | 261 |
/* completed bulk section for this device */ |
274 | 262 |
bmds->bulk_completed = 1; |
275 | 263 |
} |
... | ... | |
362 | 350 |
|
363 | 351 |
static int is_stage2_completed(void) |
364 | 352 |
{ |
365 |
BlkMigDevState *bmds; |
|
366 |
|
|
367 |
if (block_mig_state.submitted > 0) { |
|
368 |
return 0; |
|
369 |
} |
|
370 |
|
|
371 |
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { |
|
372 |
if (bmds->bulk_completed == 0) { |
|
373 |
return 0; |
|
374 |
} |
|
375 |
} |
|
376 |
|
|
377 |
return 1; |
|
353 |
return (block_mig_state.submitted == 0 && block_mig_state.bulk_completed); |
|
378 | 354 |
} |
379 | 355 |
|
380 | 356 |
static void blk_mig_cleanup(Monitor *mon) |
... | ... | |
432 | 408 |
while ((block_mig_state.submitted + |
433 | 409 |
block_mig_state.read_done) * BLOCK_SIZE < |
434 | 410 |
qemu_file_get_rate_limit(f)) { |
435 |
if (blk_mig_save_bulked_block(mon, f, 1) == 0) { |
|
436 |
/* no more bulk blocks for now */ |
|
411 |
if (blk_mig_save_bulked_block(mon, f) == 0) { |
|
412 |
/* finished saving bulk on all devices */ |
|
413 |
block_mig_state.bulk_completed = 1; |
|
437 | 414 |
break; |
438 | 415 |
} |
439 | 416 |
} |
... | ... | |
446 | 423 |
} |
447 | 424 |
|
448 | 425 |
if (stage == 3) { |
449 |
while (blk_mig_save_bulked_block(mon, f, 0) != 0) { |
|
450 |
/* empty */ |
|
451 |
} |
|
426 |
/* we know for sure that save bulk is completed */ |
|
452 | 427 |
|
453 | 428 |
blk_mig_save_dirty_blocks(mon, f); |
454 | 429 |
blk_mig_cleanup(mon); |
Also available in: Unified diff