Introduce UI for live migration
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 13 Oct 2008 03:12:02 +0000 (03:12 +0000)
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 13 Oct 2008 03:12:02 +0000 (03:12 +0000)
This patch introduces a command line parameter and monitor command for starting
a live migration.  The next patch will provide an example of how to use these
parameters.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5476 c046a42c-6fe2-441c-8c8c-71466251a162

Makefile.target
migration.c [new file with mode: 0644]
migration.h [new file with mode: 0644]
monitor.c
qemu_socket.h
vl.c

index c0af5ecb31eb8fe9b4d36a6082b15b717d3ecec7..a11957dd708297725005da8cd5c4499d3ceb9426 100644 (file)
@@ -474,7 +474,7 @@ endif #CONFIG_DARWIN_USER
 ifndef CONFIG_USER_ONLY
 
 OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o
-OBJS+=fw_cfg.o aio.o buffered_file.o
+OBJS+=fw_cfg.o aio.o buffered_file.o migration.o
 ifdef CONFIG_WIN32
 OBJS+=block-raw-win32.o
 else
diff --git a/migration.c b/migration.c
new file mode 100644 (file)
index 0000000..732fe3f
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * QEMU live migration
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "migration.h"
+#include "console.h"
+
+/* Migration speed throttling */
+static uint32_t max_throttle = (32 << 20);
+
+static MigrationState *current_migration;
+
+void qemu_start_incoming_migration(const char *uri)
+{
+    fprintf(stderr, "unknown migration protocol: %s\n", uri);
+}
+
+void do_migrate(int detach, const char *uri)
+{
+    term_printf("unknown migration protocol: %s\n", uri);
+}
+
+void do_migrate_cancel(void)
+{
+    MigrationState *s = current_migration;
+
+    if (s)
+       s->cancel(s);
+}
+
+void do_migrate_set_speed(const char *value)
+{
+    double d;
+    char *ptr;
+
+    d = strtod(value, &ptr);
+    switch (*ptr) {
+    case 'G': case 'g':
+       d *= 1024;
+    case 'M': case 'm':
+       d *= 1024;
+    case 'K': case 'k':
+       d *= 1024;
+    default:
+       break;
+    }
+
+    max_throttle = (uint32_t)d;
+}
+
+void do_info_migrate(void)
+{
+    MigrationState *s = current_migration;
+    
+    if (s) {
+       term_printf("Migration status: ");
+       switch (s->get_status(s)) {
+       case MIG_STATE_ACTIVE:
+           term_printf("active\n");
+           break;
+       case MIG_STATE_COMPLETED:
+           term_printf("completed\n");
+           break;
+       case MIG_STATE_ERROR:
+           term_printf("failed\n");
+           break;
+       case MIG_STATE_CANCELLED:
+           term_printf("cancelled\n");
+           break;
+       }
+    }
+}
+
diff --git a/migration.h b/migration.h
new file mode 100644 (file)
index 0000000..61f77bd
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * QEMU live migration
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_MIGRATION_H
+#define QEMU_MIGRATION_H
+
+#define MIG_STATE_ERROR                -1
+#define MIG_STATE_COMPLETED    0
+#define MIG_STATE_CANCELLED    1
+#define MIG_STATE_ACTIVE       2
+
+typedef struct MigrationState MigrationState;
+
+struct MigrationState
+{
+    /* FIXME: add more accessors to print migration info */
+    void (*cancel)(MigrationState *s);
+    int (*get_status)(MigrationState *s);
+    void (*release)(MigrationState *s);
+};
+
+void qemu_start_incoming_migration(const char *uri);
+
+void do_migrate(int detach, const char *uri);
+
+void do_migrate_cancel(void);
+
+void do_migrate_set_speed(const char *value);
+
+void do_info_migrate(void);
+
+#endif
+
index dd2e770e685728d677e32569527c5ba1ac872378..4d7c782bca29cb6c3bcffdfd3ae67f424572372f 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -36,6 +36,7 @@
 #include "disas.h"
 #include <dirent.h>
 #include "qemu-timer.h"
+#include "migration.h"
 
 //#define DEBUG
 //#define DEBUG_COMPLETION
@@ -1454,6 +1455,12 @@ static const term_cmd_t term_cmds[] = {
     { "nmi", "i", do_inject_nmi,
       "cpu", "inject an NMI on the given CPU", },
 #endif
+    { "migrate", "-ds", do_migrate,
+      "[-d] uri", "migrate to URI (using -d to not wait for completion)" },
+    { "migrate_cancel", "", do_migrate_cancel,
+      "", "cancel the current VM migration" },
+    { "migrate_set_speed", "s", do_migrate_set_speed,
+      "value", "set maximum speed (in bytes) for migrations" },
     { NULL, NULL, },
 };
 
@@ -1516,6 +1523,7 @@ static const term_cmd_t info_cmds[] = {
     { "slirp", "", do_info_slirp,
       "", "show SLIRP statistics", },
 #endif
+    { "migrate", "", do_info_migrate, "", "show migration status" },
     { NULL, NULL, },
 };
 
index ef2d88bfe9c9267c3de0fa3632534c79e256119a..f8817bf86b6627354b9d6364e12e41a79dba5964 100644 (file)
@@ -31,5 +31,6 @@ int inet_aton(const char *cp, struct in_addr *ia);
 #endif /* !_WIN32 */
 
 void socket_set_nonblock(int fd);
+int parse_host_port(struct sockaddr_in *saddr, const char *str);
 
 #endif /* QEMU_SOCKET_H */
diff --git a/vl.c b/vl.c
index c31f972aa0d5a6a053e023cc217145eb7e31ead6..190a408014e40a8cc4ca78343b70675678adc8d4 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -38,6 +38,7 @@
 #include "qemu-char.h"
 #include "block.h"
 #include "audio/audio.h"
+#include "migration.h"
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -3364,7 +3365,6 @@ static void udp_chr_update_read_handler(CharDriverState *chr)
     }
 }
 
-int parse_host_port(struct sockaddr_in *saddr, const char *str);
 #ifndef _WIN32
 static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
 #endif
@@ -6766,6 +6766,8 @@ int qemu_savevm_state(QEMUFile *f)
     saved_vm_running = vm_running;
     vm_stop(0);
 
+    bdrv_flush_all();
+
     ret = qemu_savevm_state_begin(f);
     if (ret < 0)
         goto out;
@@ -8338,6 +8340,7 @@ enum {
     QEMU_OPTION_tb_size,
     QEMU_OPTION_icount,
     QEMU_OPTION_uuid,
+    QEMU_OPTION_incoming,
 };
 
 typedef struct QEMUOption {
@@ -8450,6 +8453,7 @@ static const QEMUOption qemu_options[] = {
     { "startdate", HAS_ARG, QEMU_OPTION_startdate },
     { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
     { "icount", HAS_ARG, QEMU_OPTION_icount },
+    { "incoming", HAS_ARG, QEMU_OPTION_incoming },
     { NULL },
 };
 
@@ -8742,6 +8746,7 @@ int main(int argc, char **argv)
     const char *pid_file = NULL;
     VLANState *vlan;
     int autostart;
+    const char *incoming = NULL;
 
     LIST_INIT (&vm_change_state_head);
 #ifndef _WIN32
@@ -9349,6 +9354,9 @@ int main(int argc, char **argv)
                     icount_time_shift = strtol(optarg, NULL, 0);
                 }
                 break;
+            case QEMU_OPTION_incoming:
+                incoming = optarg;
+                break;
             }
         }
     }
@@ -9691,6 +9699,11 @@ int main(int argc, char **argv)
     if (loadvm)
         do_loadvm(loadvm);
 
+    if (incoming) {
+        autostart = 0; /* fixme how to deal with -daemonize */
+        qemu_start_incoming_migration(incoming);
+    }
+
     {
         /* XXX: simplify init */
         read_passwords();