diff mbox

[RFC,19/23] Introduce ft_tranx_ready(), and modify migrate_fd_put_ready() when ft_mode is on.

Message ID 1274776624-16435-21-git-send-email-tamura.yoshiaki@lab.ntt.co.jp (mailing list archive)
State New, archived
Headers show

Commit Message

Yoshiaki Tamura May 25, 2010, 8:37 a.m. UTC
None
diff mbox

Patch

diff --git a/migration.c b/migration.c
index 2adf7ad..5b90d37 100644
--- a/migration.c
+++ b/migration.c
@@ -21,6 +21,7 @@ 
 #include "qemu_socket.h"
 #include "block-migration.h"
 #include "qemu-objects.h"
+#include "event-tap.h"
 
 //#define DEBUG_MIGRATION
 
@@ -375,6 +376,49 @@  void migrate_fd_connect(FdMigrationState *s)
     migrate_fd_put_ready(s);
 }
 
+static int ft_tranx_ready(void)
+{
+    FdMigrationState *s = migrate_to_fms(current_migration);
+    int ret = -1;
+    
+    if (ft_mode != FT_TRANSACTION && ft_mode != FT_INIT) {
+        return ret;
+    }
+
+    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;
+    goto unpause_out;
+
+error_out:
+    ft_mode = FT_OFF;
+    qemu_savevm_state_cancel(s->mon, s->file);
+    migrate_fd_cleanup(s);
+    event_tap_unregister();
+
+unpause_out:
+    vm_start();
+    return ret;
+}
+
 void migrate_fd_put_ready(void *opaque)
 {
     FdMigrationState *s = opaque;
@@ -402,8 +446,30 @@  void migrate_fd_put_ready(void *opaque)
         } else {
             state = MIG_STATE_COMPLETED;
         }
-        migrate_fd_cleanup(s);
-        s->state = state;
+
+        if (ft_mode && state == MIG_STATE_COMPLETED) {
+            /* close buffered_file and open ft_transaction.
+             * Note: file discriptor won't get closed,
+             * but reused by ft_transaction. */
+            socket_set_block(s->fd);
+            socket_set_nodelay(s->fd);
+            qemu_fclose(s->file);
+            s->file = qemu_fopen_ops_ft_tranx(s,
+                                              migrate_fd_put_buffer,
+                                              migrate_fd_get_buffer,
+                                              migrate_fd_close,
+                                              1);
+
+            /* events are tapped from now. */
+            event_tap_register(ft_tranx_ready);
+
+            if (old_vm_running) {
+                vm_start();
+            }
+        } else {
+            migrate_fd_cleanup(s);
+            s->state = state;
+        }
     }
 }
 
@@ -423,8 +489,14 @@  void migrate_fd_cancel(MigrationState *mig_state)
     DPRINTF("cancelling migration\n");
 
     s->state = MIG_STATE_CANCELLED;
-    qemu_savevm_state_cancel(s->mon, s->file);
 
+    if (ft_mode == FT_TRANSACTION) {
+        qemu_transaction_cancel(s->file);
+        ft_mode = FT_OFF;
+        event_tap_unregister();
+    }
+
+    qemu_savevm_state_cancel(s->mon, s->file);
     migrate_fd_cleanup(s);
 }