]> git.proxmox.com Git - qemu.git/blobdiff - migration.c
live migration: Propagate output monitor to callback handler
[qemu.git] / migration.c
index e6c8b16a1f77ed3c1b30c6018235a5f302f57f4e..f4d30222da53e3652f7db94e620bcd9c7ae94735 100644 (file)
@@ -43,21 +43,45 @@ void qemu_start_incoming_migration(const char *uri)
 #if !defined(WIN32)
     else if (strstart(uri, "exec:", &p))
         exec_start_incoming_migration(p);
+    else if (strstart(uri, "unix:", &p))
+        unix_start_incoming_migration(p);
+    else if (strstart(uri, "fd:", &p))
+        fd_start_incoming_migration(p);
 #endif
     else
         fprintf(stderr, "unknown migration protocol: %s\n", uri);
 }
 
-void do_migrate(Monitor *mon, int detach, const char *uri)
+void do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
     MigrationState *s = NULL;
     const char *p;
+    int detach = qdict_get_int(qdict, "detach");
+    const char *uri = qdict_get_str(qdict, "uri");
+
+    if (current_migration &&
+        current_migration->get_status(current_migration) == MIG_STATE_ACTIVE) {
+        monitor_printf(mon, "migration already in progress\n");
+        return;
+    }
 
     if (strstart(uri, "tcp:", &p))
-        s = tcp_start_outgoing_migration(p, max_throttle, detach);
+        s = tcp_start_outgoing_migration(mon, p, max_throttle, detach,
+                                         (int)qdict_get_int(qdict, "blk"), 
+                                         (int)qdict_get_int(qdict, "inc"));
 #if !defined(WIN32)
     else if (strstart(uri, "exec:", &p))
-        s = exec_start_outgoing_migration(p, max_throttle, detach);
+        s = exec_start_outgoing_migration(mon, p, max_throttle, detach,
+                                          (int)qdict_get_int(qdict, "blk"), 
+                                          (int)qdict_get_int(qdict, "inc"));
+    else if (strstart(uri, "unix:", &p))
+        s = unix_start_outgoing_migration(mon, p, max_throttle, detach,
+                                         (int)qdict_get_int(qdict, "blk"), 
+                                          (int)qdict_get_int(qdict, "inc"));
+    else if (strstart(uri, "fd:", &p))
+        s = fd_start_outgoing_migration(mon, p, max_throttle, detach, 
+                                        (int)qdict_get_int(qdict, "blk"), 
+                                        (int)qdict_get_int(qdict, "inc"));
 #endif
     else
         monitor_printf(mon, "unknown migration protocol: %s\n", uri);
@@ -72,7 +96,7 @@ void do_migrate(Monitor *mon, int detach, const char *uri)
     }
 }
 
-void do_migrate_cancel(Monitor *mon)
+void do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
     MigrationState *s = current_migration;
 
@@ -80,11 +104,12 @@ void do_migrate_cancel(Monitor *mon)
         s->cancel(s);
 }
 
-void do_migrate_set_speed(Monitor *mon, const char *value)
+void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
     double d;
     char *ptr;
     FdMigrationState *s;
+    const char *value = qdict_get_str(qdict, "value");
 
     d = strtod(value, &ptr);
     switch (*ptr) {
@@ -99,12 +124,11 @@ void do_migrate_set_speed(Monitor *mon, const char *value)
     }
 
     max_throttle = (uint32_t)d;
-    s = migrate_to_fms(current_migration);
 
-    if (s) {
+    s = migrate_to_fms(current_migration);
+    if (s && s->file) {
         qemu_file_set_rate_limit(s->file, max_throttle);
     }
-    
 }
 
 /* amount of nanoseconds we are willing to wait for migration to be down.
@@ -118,10 +142,11 @@ uint64_t migrate_max_downtime(void)
     return max_downtime;
 }
 
-void do_migrate_set_downtime(Monitor *mon, const char *value)
+void do_migrate_set_downtime(Monitor *mon, const QDict *qdict)
 {
     char *ptr;
     double d;
+    const char *value = qdict_get_str(qdict, "value");
 
     d = strtod(value, &ptr);
     if (!strcmp(ptr,"ms")) {
@@ -165,14 +190,15 @@ void do_info_migrate(Monitor *mon)
 
 /* shared migration helpers */
 
-void migrate_fd_monitor_suspend(FdMigrationState *s)
+void migrate_fd_monitor_suspend(FdMigrationState *s, Monitor *mon)
 {
-    s->mon_resume = cur_mon;
-    if (monitor_suspend(cur_mon) == 0)
+    s->mon = mon;
+    if (monitor_suspend(mon) == 0) {
         dprintf("suspending monitor\n");
-    else
-        monitor_printf(cur_mon, "terminal does not allow synchronous "
+    } else {
+        monitor_printf(mon, "terminal does not allow synchronous "
                        "migration, continuing detached\n");
+    }
 }
 
 void migrate_fd_error(FdMigrationState *s)
@@ -189,14 +215,16 @@ void migrate_fd_cleanup(FdMigrationState *s)
     if (s->file) {
         dprintf("closing file\n");
         qemu_fclose(s->file);
+        s->file = NULL;
     }
 
     if (s->fd != -1)
         close(s->fd);
 
     /* Don't resume monitor until we've flushed all of the buffers */
-    if (s->mon_resume)
-        monitor_resume(s->mon_resume);
+    if (s->mon) {
+        monitor_resume(s->mon);
+    }
 
     s->fd = -1;
 }
@@ -239,13 +267,14 @@ void migrate_fd_connect(FdMigrationState *s)
                                       migrate_fd_close);
 
     dprintf("beginning savevm\n");
-    ret = qemu_savevm_state_begin(s->file);
+    ret = qemu_savevm_state_begin(s->mon, s->file, s->mig_state.blk,
+                                  s->mig_state.shared);
     if (ret < 0) {
         dprintf("failed, %d\n", ret);
         migrate_fd_error(s);
         return;
     }
-
+    
     migrate_fd_put_ready(s);
 }
 
@@ -259,15 +288,16 @@ void migrate_fd_put_ready(void *opaque)
     }
 
     dprintf("iterate\n");
-    if (qemu_savevm_state_iterate(s->file) == 1) {
+    if (qemu_savevm_state_iterate(s->mon, s->file) == 1) {
         int state;
         int old_vm_running = vm_running;
 
         dprintf("done iterating\n");
         vm_stop(0);
 
+        qemu_aio_flush();
         bdrv_flush_all();
-        if ((qemu_savevm_state_complete(s->file)) < 0) {
+        if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) {
             if (old_vm_running) {
                 vm_start();
             }
@@ -296,6 +326,7 @@ void migrate_fd_cancel(MigrationState *mig_state)
     dprintf("cancelling migration\n");
 
     s->state = MIG_STATE_CANCELLED;
+    qemu_savevm_state_cancel(s->mon, s->file);
 
     migrate_fd_cleanup(s);
 }