dirty_bitmap_mig_init();
}
-static void migration_bh_schedule(MigrationState *s, QEMUBH *bh)
+typedef struct {
+ QEMUBH *bh;
+ QEMUBHFunc *cb;
+ void *opaque;
+} MigrationBH;
+
+static void migration_bh_dispatch_bh(void *opaque)
{
+ MigrationState *s = migrate_get_current();
+ MigrationBH *migbh = opaque;
+
+ /* cleanup this BH */
+ qemu_bh_delete(migbh->bh);
+ migbh->bh = NULL;
+
+ /* dispatch the other one */
+ migbh->cb(migbh->opaque);
+ object_unref(OBJECT(s));
+
+ g_free(migbh);
+}
+
+void migration_bh_schedule(QEMUBHFunc *cb, void *opaque)
+{
+ MigrationState *s = migrate_get_current();
+ MigrationBH *migbh = g_new0(MigrationBH, 1);
+ QEMUBH *bh = qemu_bh_new(migration_bh_dispatch_bh, migbh);
+
+ /* Store these to dispatch when the BH runs */
+ migbh->bh = bh;
+ migbh->cb = cb;
+ migbh->opaque = opaque;
+
/*
* Ref the state for bh, because it may be called when
* there're already no other refs
*/
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
MIGRATION_STATUS_COMPLETED);
- qemu_bh_delete(mis->bh);
migration_incoming_state_destroy();
- object_unref(OBJECT(migrate_get_current()));
}
static void coroutine_fn
goto fail;
}
- mis->bh = qemu_bh_new(process_incoming_migration_bh, mis);
- migration_bh_schedule(migrate_get_current(), mis->bh);
+ migration_bh_schedule(process_incoming_migration_bh, mis);
return;
fail:
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
static void migrate_fd_cleanup(MigrationState *s)
{
- qemu_bh_delete(s->cleanup_bh);
- s->cleanup_bh = NULL;
-
g_free(s->hostname);
s->hostname = NULL;
json_writer_free(s->vmdesc);
static void migrate_fd_cleanup_bh(void *opaque)
{
- MigrationState *s = opaque;
- migrate_fd_cleanup(s);
- object_unref(OBJECT(s));
+ migrate_fd_cleanup(opaque);
}
void migrate_set_error(MigrationState *s, const Error *error)
* parameters/capabilities that the user set, and
* locks.
*/
- s->cleanup_bh = 0;
- s->vm_start_bh = 0;
s->to_dst_file = NULL;
s->state = MIGRATION_STATUS_NONE;
s->rp_state.from_dst_file = NULL;
error_report("%s: Unknown ending state %d", __func__, s->state);
break;
}
- migration_bh_schedule(s, s->cleanup_bh);
+
+ migration_bh_schedule(migrate_fd_cleanup_bh, s);
bql_unlock();
}
break;
}
- migration_bh_schedule(s, s->cleanup_bh);
+ migration_bh_schedule(migrate_fd_cleanup_bh, s);
bql_unlock();
}
{
MigrationState *s = opaque;
- qemu_bh_delete(s->vm_start_bh);
- s->vm_start_bh = NULL;
-
vm_resume(s->vm_old_state);
migration_downtime_end(s);
- object_unref(OBJECT(s));
}
/**
* calling VM state change notifiers from vm_start() would initiate
* writes to virtio VQs memory which is in write-protected region.
*/
- s->vm_start_bh = qemu_bh_new(bg_migration_vm_start_bh, s);
- migration_bh_schedule(s, s->vm_start_bh);
+ migration_bh_schedule(bg_migration_vm_start_bh, s);
bql_unlock();
while (migration_is_active(s)) {
migrate_error_free(s);
s->expected_downtime = migrate_downtime_limit();
- if (resume) {
- assert(s->cleanup_bh);
- } else {
- assert(!s->cleanup_bh);
- s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s);
- }
if (error_in) {
migrate_fd_error(s, error_in);
if (resume) {
runstate_set(RUN_STATE_PAUSED);
}
- qemu_bh_delete(mis->bh);
-
trace_vmstate_downtime_checkpoint("dst-postcopy-bh-vm-started");
- object_unref(OBJECT(migration_get_current()));
}
/* After all discards we can start running and asking for pages */
}
postcopy_state_set(POSTCOPY_INCOMING_RUNNING);
- mis->bh = qemu_bh_new(loadvm_postcopy_handle_run_bh, mis);
- object_ref(OBJECT(migration_get_current()));
- qemu_bh_schedule(mis->bh);
+ migration_bh_schedule(loadvm_postcopy_handle_run_bh, mis);
/* We need to finish reading the stream from the package
* and also stop reading anything more from the stream that loaded the