#include "qemu-common.h"
#include "migration.h"
-#include "console.h"
+#include "monitor.h"
#include "buffered_file.h"
#include "sysemu.h"
#include "block.h"
fprintf(stderr, "unknown migration protocol: %s\n", uri);
}
-void do_migrate(int detach, const char *uri)
+void do_migrate(Monitor *mon, int detach, const char *uri)
{
MigrationState *s = NULL;
const char *p;
s = exec_start_outgoing_migration(p, max_throttle, detach);
#endif
else
- term_printf("unknown migration protocol: %s\n", uri);
+ monitor_printf(mon, "unknown migration protocol: %s\n", uri);
if (s == NULL)
- term_printf("migration failed\n");
+ monitor_printf(mon, "migration failed\n");
else {
if (current_migration)
current_migration->release(current_migration);
}
}
-void do_migrate_cancel(void)
+void do_migrate_cancel(Monitor *mon)
{
MigrationState *s = current_migration;
s->cancel(s);
}
-void do_migrate_set_speed(const char *value)
+void do_migrate_set_speed(Monitor *mon, const char *value)
{
double d;
char *ptr;
+ FdMigrationState *s;
d = strtod(value, &ptr);
switch (*ptr) {
}
max_throttle = (uint32_t)d;
+ s = migrate_to_fms(current_migration);
+
+ if (s) {
+ qemu_file_set_rate_limit(s->file, max_throttle);
+ }
+
}
-void do_info_migrate(void)
+void do_info_migrate(Monitor *mon)
{
MigrationState *s = current_migration;
-
+
if (s) {
- term_printf("Migration status: ");
+ monitor_printf(mon, "Migration status: ");
switch (s->get_status(s)) {
case MIG_STATE_ACTIVE:
- term_printf("active\n");
+ monitor_printf(mon, "active\n");
+ monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", ram_bytes_transferred() >> 10);
+ monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", ram_bytes_remaining() >> 10);
+ monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", ram_bytes_total() >> 10);
break;
case MIG_STATE_COMPLETED:
- term_printf("completed\n");
+ monitor_printf(mon, "completed\n");
break;
case MIG_STATE_ERROR:
- term_printf("failed\n");
+ monitor_printf(mon, "failed\n");
break;
case MIG_STATE_CANCELLED:
- term_printf("cancelled\n");
+ monitor_printf(mon, "cancelled\n");
break;
}
}
/* shared migration helpers */
+void migrate_fd_monitor_suspend(FdMigrationState *s)
+{
+ s->mon_resume = cur_mon;
+ if (monitor_suspend(cur_mon) == 0)
+ dprintf("suspending monitor\n");
+ else
+ monitor_printf(cur_mon, "terminal does not allow synchronous "
+ "migration, continuing detached\n");
+}
+
void migrate_fd_error(FdMigrationState *s)
{
dprintf("setting error state\n");
close(s->fd);
/* Don't resume monitor until we've flushed all of the buffers */
- if (s->detach == 2) {
- monitor_resume();
- s->detach = 0;
- }
+ if (s->mon_resume)
+ monitor_resume(s->mon_resume);
s->fd = -1;
}
do {
ret = s->write(s, data, size);
- } while (ret == -1 && ((s->get_error(s)) == EINTR || (s->get_error(s)) == EWOULDBLOCK));
+ } while (ret == -1 && ((s->get_error(s)) == EINTR));
if (ret == -1)
ret = -(s->get_error(s));
dprintf("iterate\n");
if (qemu_savevm_state_iterate(s->file) == 1) {
+ int state;
dprintf("done iterating\n");
vm_stop(0);
bdrv_flush_all();
- qemu_savevm_state_complete(s->file);
- s->state = MIG_STATE_COMPLETED;
+ if ((qemu_savevm_state_complete(s->file)) < 0) {
+ vm_start();
+ state = MIG_STATE_ERROR;
+ } else {
+ state = MIG_STATE_COMPLETED;
+ }
migrate_fd_cleanup(s);
+ s->state = state;
}
}