Il 21/08/2013 09:18, Lei Li ha scritto: > Integrate localhost migration thread to migration_thread. As the mechanism > of local migration is different than the current migration, and it does > not need to do iterate. > > So the whole thread can split into two stages, it will send all the ram > pages in qemu_savevm_state_begin stage, and send the device states in > qemu_save_device_state stage.
This is not needed. Skipping the iteration should happen automatically if you stop the VM before invoking migration. Paolo > Signed-off-by: Lei Li <li...@linux.vnet.ibm.com> > --- > migration.c | 73 ++++++++++++++++++++++++++++++++++++---------------------- > 1 files changed, 45 insertions(+), 28 deletions(-) > > diff --git a/migration.c b/migration.c > index 2f85358..2471664 100644 > --- a/migration.c > +++ b/migration.c > @@ -565,37 +565,54 @@ static void *migration_thread(void *opaque) > while (s->state == MIG_STATE_ACTIVE) { > int64_t current_time; > uint64_t pending_size; > + int ret; > > - if (!qemu_file_rate_limit(s->file)) { > - DPRINTF("iterate\n"); > - pending_size = qemu_savevm_state_pending(s->file, max_size); > - DPRINTF("pending size %lu max %lu\n", pending_size, max_size); > - if (pending_size && pending_size >= max_size) { > - qemu_savevm_state_iterate(s->file); > - } else { > - int ret; > - > - DPRINTF("done iterating\n"); > - qemu_mutex_lock_iothread(); > - start_time = qemu_get_clock_ms(rt_clock); > - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); > - old_vm_running = runstate_is_running(); > - > - ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); > - if (ret >= 0) { > - qemu_file_set_rate_limit(s->file, INT_MAX); > - qemu_savevm_state_complete(s->file); > - } > - qemu_mutex_unlock_iothread(); > + if (s->enabled_capabilities[MIGRATION_CAPABILITY_LOCALHOST]) { > + DPRINTF("local migration start\n"); > > - if (ret < 0) { > - migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); > - break; > - } > + ret = qemu_save_device_state(s->file); > + if (ret < 0) { > + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); > + break; > + } > > - if (!qemu_file_get_error(s->file)) { > - migrate_set_state(s, MIG_STATE_ACTIVE, > MIG_STATE_COMPLETED); > - break; > + if (!qemu_file_get_error(s->file)) { > + DPRINTF("local migration completed\n"); > + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED); > + break; > + } > + } else { > + if (!qemu_file_rate_limit(s->file)) { > + DPRINTF("iterate\n"); > + pending_size = qemu_savevm_state_pending(s->file, max_size); > + DPRINTF("pending size %lu max %lu\n", pending_size, > max_size); > + if (pending_size && pending_size >= max_size) { > + qemu_savevm_state_iterate(s->file); > + } else { > + int ret; > + > + DPRINTF("done iterating\n"); > + qemu_mutex_lock_iothread(); > + start_time = qemu_get_clock_ms(rt_clock); > + qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); > + old_vm_running = runstate_is_running(); > + > + ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); > + if (ret >= 0) { > + qemu_file_set_rate_limit(s->file, INT_MAX); > + qemu_savevm_state_complete(s->file); > + } > + qemu_mutex_unlock_iothread(); > + > + if (ret < 0) { > + migrate_set_state(s, MIG_STATE_ACTIVE, > MIG_STATE_ERROR); > + break; > + } > + > + if (!qemu_file_get_error(s->file)) { > + migrate_set_state(s, MIG_STATE_ACTIVE, > MIG_STATE_COMPLETED); > + break; > + } > } > } > } >