@@ -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;
@@ -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);
@@ -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