@@ -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);
@@ -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,
@@ -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;
@@ -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;
@@ -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));
@@ -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));
@@ -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);
}
@@ -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);
@@ -1236,7 +1236,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;
@@ -1268,18 +1269,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;
@@ -1292,21 +1293,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;
@@ -1318,7 +1319,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) {
@@ -1350,18 +1351,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;
@@ -1371,17 +1372,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))
@@ -1670,7 +1671,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) {
@@ -61,11 +61,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);
@@ -2928,7 +2928,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;
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> --- block-migration.c | 2 +- hw/hw.h | 3 ++- migration-exec.c | 12 +++++++----- migration-fd.c | 9 +++++---- migration-tcp.c | 10 ++++++---- migration-unix.c | 10 ++++++---- migration.c | 30 ++++++++++++++++-------------- migration.h | 13 ++++++++----- savevm.c | 31 ++++++++++++++++--------------- sysemu.h | 10 +++++----- vl.c | 2 +- 11 files changed, 73 insertions(+), 59 deletions(-)