]> git.proxmox.com Git - qemu.git/commitdiff
live migration: Propagate output monitor to callback handler
authorJan Kiszka <jan.kiszka@siemens.com>
Mon, 30 Nov 2009 17:21:21 +0000 (18:21 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Thu, 3 Dec 2009 16:48:53 +0000 (10:48 -0600)
In order to allow proper progress reporting to the monitor that
initiated the migration, forward the monitor reference through the
migration layer down to SaveLiveStateHandler.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
block-migration.c
hw/hw.h
migration-exec.c
migration-fd.c
migration-tcp.c
migration-unix.c
migration.c
migration.h
savevm.c
sysemu.h
vl.c

index 15b76de9bcc4024aae83913b6f0dee9069463ecd..b56be7908c736f96b4fb8d20c2eba2442f7d55eb 100644 (file)
@@ -352,7 +352,7 @@ static void blk_mig_cleanup(void)
     printf("\n");
 }
 
-static int block_save_live(QEMUFile *f, int stage, void *opaque)
+static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
 {
     dprintf("Enter save live stage %d submitted %d transferred %d\n",
             stage, block_mig_state.submitted, block_mig_state.transferred);
diff --git a/hw/hw.h b/hw/hw.h
index 5f34991961e267e3cef24f7370bd022580ed5a34..7b500f4e440525f4d2eb57d49bfbb2489161e1e1 100644 (file)
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -244,7 +244,8 @@ int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence);
 
 typedef void SaveSetParamsHandler(int blk_enable, int shared, void * opaque);
 typedef void SaveStateHandler(QEMUFile *f, void *opaque);
-typedef int SaveLiveStateHandler(QEMUFile *f, int stage, void *opaque);
+typedef int SaveLiveStateHandler(Monitor *mon, QEMUFile *f, int stage,
+                                 void *opaque);
 typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
 
 int register_savevm(const char *idstr,
index c83066959a4e2fc2a8197328cfe6cdc9960933d6..87f645b68cc2288d67fb8032b08e9f6e9634be2d 100644 (file)
@@ -52,7 +52,8 @@ static int exec_close(FdMigrationState *s)
     return 0;
 }
 
-MigrationState *exec_start_outgoing_migration(const char *command,
+MigrationState *exec_start_outgoing_migration(Monitor *mon,
+                                              const char *command,
                                              int64_t bandwidth_limit,
                                              int detach,
                                              int blk,
@@ -88,13 +89,14 @@ MigrationState *exec_start_outgoing_migration(const char *command,
 
     s->mig_state.blk = blk;
     s->mig_state.shared = inc;
-    
+
     s->state = MIG_STATE_ACTIVE;
-    s->mon_resume = NULL;
+    s->mon = NULL;
     s->bandwidth_limit = bandwidth_limit;
 
-    if (!detach)
-        migrate_fd_monitor_suspend(s);
+    if (!detach) {
+        migrate_fd_monitor_suspend(s, mon);
+    }
 
     migrate_fd_connect(s);
     return &s->mig_state;
index 587f9d8e8455b9d7c0401c5e0f0b3679ade3180a..ef7edbc5ecb01dc1e0e9d24521d4bc80785574be 100644 (file)
@@ -82,13 +82,14 @@ MigrationState *fd_start_outgoing_migration(Monitor *mon,
 
     s->mig_state.blk = blk;
     s->mig_state.shared = inc;
-    
+
     s->state = MIG_STATE_ACTIVE;
-    s->mon_resume = NULL;
+    s->mon = NULL;
     s->bandwidth_limit = bandwidth_limit;
 
-    if (!detach)
-        migrate_fd_monitor_suspend(s);
+    if (!detach) {
+        migrate_fd_monitor_suspend(s, mon);
+    }
 
     migrate_fd_connect(s);
     return &s->mig_state;
index efa7c74c67764e6fdefb980766a5452349917e37..b77ed8762148f205bdd31fdd4dcae7f713f7bdb6 100644 (file)
@@ -76,7 +76,8 @@ static void tcp_wait_for_connect(void *opaque)
     }
 }
 
-MigrationState *tcp_start_outgoing_migration(const char *host_port,
+MigrationState *tcp_start_outgoing_migration(Monitor *mon,
+                                             const char *host_port,
                                              int64_t bandwidth_limit,
                                              int detach,
                                             int blk,
@@ -102,7 +103,7 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
     s->mig_state.shared = inc;
 
     s->state = MIG_STATE_ACTIVE;
-    s->mon_resume = NULL;
+    s->mon = NULL;
     s->bandwidth_limit = bandwidth_limit;
     s->fd = socket(PF_INET, SOCK_STREAM, 0);
     if (s->fd == -1) {
@@ -112,8 +113,9 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
 
     socket_set_nonblock(s->fd);
 
-    if (!detach)
-        migrate_fd_monitor_suspend(s);
+    if (!detach) {
+        migrate_fd_monitor_suspend(s, mon);
+    }
 
     do {
         ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr));
index 25cd6d3d2deff9a7281ea6addcaaf0adc2001bbe..7dd787cd91a7cf21acb7b4c05128b877ffaff065 100644 (file)
@@ -75,7 +75,8 @@ static void unix_wait_for_connect(void *opaque)
     }
 }
 
-MigrationState *unix_start_outgoing_migration(const char *path,
+MigrationState *unix_start_outgoing_migration(Monitor *mon,
+                                              const char *path,
                                              int64_t bandwidth_limit,
                                              int detach,
                                              int blk,
@@ -101,7 +102,7 @@ MigrationState *unix_start_outgoing_migration(const char *path,
     s->mig_state.shared = inc;
 
     s->state = MIG_STATE_ACTIVE;
-    s->mon_resume = NULL;
+    s->mon = NULL;
     s->bandwidth_limit = bandwidth_limit;
     s->fd = socket(PF_UNIX, SOCK_STREAM, 0);
     if (s->fd < 0) {
@@ -111,8 +112,9 @@ MigrationState *unix_start_outgoing_migration(const char *path,
 
     socket_set_nonblock(s->fd);
 
-    if (!detach)
-        migrate_fd_monitor_suspend(s);
+    if (!detach) {
+        migrate_fd_monitor_suspend(s, mon);
+    }
 
     do {
         ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr));
index f8a15fb48594f7300131e35f0aba06ac6400e307..f4d30222da53e3652f7db94e620bcd9c7ae94735 100644 (file)
@@ -66,16 +66,16 @@ void do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
     }
 
     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(p, max_throttle, detach, 
+        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))
@@ -190,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)
@@ -221,8 +222,9 @@ void migrate_fd_cleanup(FdMigrationState *s)
         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;
 }
@@ -265,7 +267,7 @@ void migrate_fd_connect(FdMigrationState *s)
                                       migrate_fd_close);
 
     dprintf("beginning savevm\n");
-    ret = qemu_savevm_state_begin(s->file, s->mig_state.blk, 
+    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);
@@ -286,7 +288,7 @@ 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;
 
@@ -295,7 +297,7 @@ void migrate_fd_put_ready(void *opaque)
 
         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();
             }
@@ -324,7 +326,7 @@ void migrate_fd_cancel(MigrationState *mig_state)
     dprintf("cancelling migration\n");
 
     s->state = MIG_STATE_CANCELLED;
-    qemu_savevm_state_cancel(s->file);
+    qemu_savevm_state_cancel(s->mon, s->file);
 
     migrate_fd_cleanup(s);
 }
index 56adf05e6f87425219fa71bafdc193f5a8d492b0..3f2b3df2bd5ac190793b11ed057fef06596ad617 100644 (file)
@@ -42,7 +42,7 @@ struct FdMigrationState
     int64_t bandwidth_limit;
     QEMUFile *file;
     int fd;
-    Monitor *mon_resume;
+    Monitor *mon;
     int state;
     int (*get_error)(struct FdMigrationState*);
     int (*close)(struct FdMigrationState*);
@@ -66,7 +66,8 @@ void do_info_migrate(Monitor *mon);
 
 int exec_start_incoming_migration(const char *host_port);
 
-MigrationState *exec_start_outgoing_migration(const char *host_port,
+MigrationState *exec_start_outgoing_migration(Monitor *mon,
+                                              const char *host_port,
                                              int64_t bandwidth_limit,
                                              int detach,
                                              int blk,
@@ -74,7 +75,8 @@ MigrationState *exec_start_outgoing_migration(const char *host_port,
 
 int tcp_start_incoming_migration(const char *host_port);
 
-MigrationState *tcp_start_outgoing_migration(const char *host_port,
+MigrationState *tcp_start_outgoing_migration(Monitor *mon,
+                                             const char *host_port,
                                             int64_t bandwidth_limit,
                                             int detach,
                                             int blk,
@@ -82,7 +84,8 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
 
 int unix_start_incoming_migration(const char *path);
 
-MigrationState *unix_start_outgoing_migration(const char *path,
+MigrationState *unix_start_outgoing_migration(Monitor *mon,
+                                              const char *path,
                                              int64_t bandwidth_limit,
                                              int detach,
                                              int blk,
@@ -97,7 +100,7 @@ MigrationState *fd_start_outgoing_migration(Monitor *mon,
                                            int blk,
                                            int inc);
 
-void migrate_fd_monitor_suspend(FdMigrationState *s);
+void migrate_fd_monitor_suspend(FdMigrationState *s, Monitor *mon);
 
 void migrate_fd_error(FdMigrationState *s);
 
index 9a7a78ecc649b596446ef476ae17b183f8f7107d..db44ed607b4d9ea44e6ca92b6f409f1f398276f5 100644 (file)
--- a/savevm.c
+++ b/savevm.c
@@ -1264,7 +1264,8 @@ static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
 #define QEMU_VM_SECTION_END          0x03
 #define QEMU_VM_SECTION_FULL         0x04
 
-int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared)
+int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
+                            int shared)
 {
     SaveStateEntry *se;
 
@@ -1296,18 +1297,18 @@ int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared)
         qemu_put_be32(f, se->instance_id);
         qemu_put_be32(f, se->version_id);
 
-        se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
+        se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque);
     }
 
     if (qemu_file_has_error(f)) {
-        qemu_savevm_state_cancel(f);
+        qemu_savevm_state_cancel(mon, f);
         return -EIO;
     }
 
     return 0;
 }
 
-int qemu_savevm_state_iterate(QEMUFile *f)
+int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
 {
     SaveStateEntry *se;
     int ret = 1;
@@ -1320,21 +1321,21 @@ int qemu_savevm_state_iterate(QEMUFile *f)
         qemu_put_byte(f, QEMU_VM_SECTION_PART);
         qemu_put_be32(f, se->section_id);
 
-        ret &= !!se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque);
+        ret &= !!se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque);
     }
 
     if (ret)
         return 1;
 
     if (qemu_file_has_error(f)) {
-        qemu_savevm_state_cancel(f);
+        qemu_savevm_state_cancel(mon, f);
         return -EIO;
     }
 
     return 0;
 }
 
-int qemu_savevm_state_complete(QEMUFile *f)
+int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
 {
     SaveStateEntry *se;
 
@@ -1346,7 +1347,7 @@ int qemu_savevm_state_complete(QEMUFile *f)
         qemu_put_byte(f, QEMU_VM_SECTION_END);
         qemu_put_be32(f, se->section_id);
 
-        se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);
+        se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);
     }
 
     QTAILQ_FOREACH(se, &savevm_handlers, entry) {
@@ -1378,18 +1379,18 @@ int qemu_savevm_state_complete(QEMUFile *f)
     return 0;
 }
 
-void qemu_savevm_state_cancel(QEMUFile *f)
+void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f)
 {
     SaveStateEntry *se;
 
     QTAILQ_FOREACH(se, &savevm_handlers, entry) {
         if (se->save_live_state) {
-            se->save_live_state(f, -1, se->opaque);
+            se->save_live_state(mon, f, -1, se->opaque);
         }
     }
 }
 
-int qemu_savevm_state(QEMUFile *f)
+static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
 {
     int saved_vm_running;
     int ret;
@@ -1399,17 +1400,17 @@ int qemu_savevm_state(QEMUFile *f)
 
     bdrv_flush_all();
 
-    ret = qemu_savevm_state_begin(f, 0, 0);
+    ret = qemu_savevm_state_begin(mon, f, 0, 0);
     if (ret < 0)
         goto out;
 
     do {
-        ret = qemu_savevm_state_iterate(f);
+        ret = qemu_savevm_state_iterate(mon, f);
         if (ret < 0)
             goto out;
     } while (ret == 0);
 
-    ret = qemu_savevm_state_complete(f);
+    ret = qemu_savevm_state_complete(mon, f);
 
 out:
     if (qemu_file_has_error(f))
@@ -1698,7 +1699,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
         monitor_printf(mon, "Could not open VM state file\n");
         goto the_end;
     }
-    ret = qemu_savevm_state(f);
+    ret = qemu_savevm_state(mon, f);
     vm_state_size = qemu_ftell(f);
     qemu_fclose(f);
     if (ret < 0) {
index 0149bd16c23fe6fb44225dbff6a75e8c3aceb59b..e7819de9a777c863c535ebf59346196789bb8624 100644 (file)
--- a/sysemu.h
+++ b/sysemu.h
@@ -62,11 +62,11 @@ void qemu_announce_self(void);
 
 void main_loop_wait(int timeout);
 
-int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared);
-int qemu_savevm_state_iterate(QEMUFile *f);
-int qemu_savevm_state_complete(QEMUFile *f);
-void qemu_savevm_state_cancel(QEMUFile *f);
-int qemu_savevm_state(QEMUFile *f);
+int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
+                            int shared);
+int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f);
+int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f);
+void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f);
 int qemu_loadvm_state(QEMUFile *f);
 
 void qemu_errors_to_file(FILE *fp);
diff --git a/vl.c b/vl.c
index f6c655b8de5e71780d93a14c5bf70f75f9cb1ff3..e9b75c9b8651b5aff1f2c818ec0003ad804fa672 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -2927,7 +2927,7 @@ uint64_t ram_bytes_total(void)
     return last_ram_offset;
 }
 
-static int ram_save_live(QEMUFile *f, int stage, void *opaque)
+static int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
 {
     ram_addr_t addr;
     uint64_t bytes_transferred_last;