event_tap controls when to start ft transaction. do_event_tap() should be instered to the device emulators. ft_tranx_ready() kicks the transaction. Signed-off-by: Yoshiaki Tamura <tamura.yoshiaki@xxxxxxxxxxxxx> --- migration.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ migration.h | 2 + qemu-common.h | 19 ++++++++++++++ 3 files changed, 98 insertions(+), 0 deletions(-) diff --git a/migration.c b/migration.c index 4eed0b7..3cc47fc 100644 --- a/migration.c +++ b/migration.c @@ -39,6 +39,45 @@ static uint32_t max_throttle = (32 << 20); static MigrationState *current_migration; +#ifdef CONFIG_FT_MODE +static enum EVENT_TAP_STATE event_tap_state = EVENT_TAP_OFF; + +void event_tap_on(void) +{ + event_tap_state = EVENT_TAP_ON; +} + +void event_tap_off(void) +{ + event_tap_state = EVENT_TAP_OFF; +} + +void event_tap_suspend(void) +{ + if (event_tap_state == EVENT_TAP_ON) + event_tap_state = EVENT_TAP_SUSPEND; +} + +void event_tap_resume(void) +{ + if (event_tap_state == EVENT_TAP_SUSPEND) + event_tap_state = EVENT_TAP_ON; +} + +void do_event_tap(void) +{ + if (event_tap_state != EVENT_TAP_ON) + return; + + if (ft_mode == FT_TRANSACTION || ft_mode == FT_INIT) { + if (ft_tranx_ready(current_migration) < 0) { + event_tap_off(); + vm_start(); + } + } +} +#endif + void qemu_start_incoming_migration(const char *uri) { const char *p; @@ -390,6 +429,44 @@ void migrate_fd_connect(FdMigrationState *s) migrate_fd_put_ready(s); } +int ft_tranx_ready(void *opaque) +{ + FdMigrationState *s = migrate_to_fms(opaque); + int ret = -1; + + if (qemu_transaction_begin(s->file) < 0) { + fprintf(stderr, "tranx_begin failed\n"); + goto error_out; + } + + /* make the VM state consistent by flushing outstanding requests. */ + vm_stop(0); + qemu_aio_flush(); + bdrv_flush_all(); + + if (qemu_savevm_state_all(s->mon, s->file) < 0) { + fprintf(stderr, "savevm_state_all failed\n"); + goto error_out; + } + + if (qemu_transaction_commit(s->file) < 0) { + fprintf(stderr, "tranx_commit failed\n"); + goto error_out; + } + + ret = 0; + vm_start(); + + return ret; + +error_out: + ft_mode = FT_OFF; + qemu_savevm_state_cancel(s->mon, s->file); + migrate_fd_cleanup(s); + + return ret; +} + void migrate_fd_put_ready(void *opaque) { FdMigrationState *s = opaque; diff --git a/migration.h b/migration.h index ddc1d42..41ee3fe 100644 --- a/migration.h +++ b/migration.h @@ -133,6 +133,8 @@ void migrate_fd_wait_for_unfreeze(void *opaque); int migrate_fd_close(void *opaque); +int ft_tranx_ready(void *opaque); + static inline FdMigrationState *migrate_to_fms(MigrationState *mig_state) { return container_of(mig_state, FdMigrationState, mig_state); diff --git a/qemu-common.h b/qemu-common.h index 0af30d2..5753af2 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -294,4 +294,23 @@ static inline uint8_t from_bcd(uint8_t val) #endif /* dyngen-exec.h hack */ +#ifdef CONFIG_FT_MODE +enum EVENT_TAP_STATE { + EVENT_TAP_OFF, + EVENT_TAP_ON, + EVENT_TAP_SUSPEND, +}; +void event_tap_on(void); +void event_tap_off(void); +void event_tap_suspend(void); +void event_tap_resume(void); +void do_event_tap(void); +#else +#define event_tap_on() do { } while (0) +#define event_tap_off() do { } while (0) +#define event_tap_suspend() do { } while (0) +#define event_tap_resume() do { } while (0) +#define do_event_tap() do { } while (0) +#endif + #endif -- 1.7.0.31.g1df487 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html