Commit 5bb7910af031cce09cc619b982d39dc889776f65

Authored by aliguori
1 parent 39b65c2e

Introduce UI for live migration

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
@@ -474,7 +474,7 @@ endif #CONFIG_DARWIN_USER @@ -474,7 +474,7 @@ endif #CONFIG_DARWIN_USER
474 ifndef CONFIG_USER_ONLY 474 ifndef CONFIG_USER_ONLY
475 475
476 OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o 476 OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o
477 -OBJS+=fw_cfg.o aio.o buffered_file.o 477 +OBJS+=fw_cfg.o aio.o buffered_file.o migration.o
478 ifdef CONFIG_WIN32 478 ifdef CONFIG_WIN32
479 OBJS+=block-raw-win32.o 479 OBJS+=block-raw-win32.o
480 else 480 else
migration.c 0 → 100644
  1 +/*
  2 + * QEMU live migration
  3 + *
  4 + * Copyright IBM, Corp. 2008
  5 + *
  6 + * Authors:
  7 + * Anthony Liguori <aliguori@us.ibm.com>
  8 + *
  9 + * This work is licensed under the terms of the GNU GPL, version 2. See
  10 + * the COPYING file in the top-level directory.
  11 + *
  12 + */
  13 +
  14 +#include "qemu-common.h"
  15 +#include "migration.h"
  16 +#include "console.h"
  17 +
  18 +/* Migration speed throttling */
  19 +static uint32_t max_throttle = (32 << 20);
  20 +
  21 +static MigrationState *current_migration;
  22 +
  23 +void qemu_start_incoming_migration(const char *uri)
  24 +{
  25 + fprintf(stderr, "unknown migration protocol: %s\n", uri);
  26 +}
  27 +
  28 +void do_migrate(int detach, const char *uri)
  29 +{
  30 + term_printf("unknown migration protocol: %s\n", uri);
  31 +}
  32 +
  33 +void do_migrate_cancel(void)
  34 +{
  35 + MigrationState *s = current_migration;
  36 +
  37 + if (s)
  38 + s->cancel(s);
  39 +}
  40 +
  41 +void do_migrate_set_speed(const char *value)
  42 +{
  43 + double d;
  44 + char *ptr;
  45 +
  46 + d = strtod(value, &ptr);
  47 + switch (*ptr) {
  48 + case 'G': case 'g':
  49 + d *= 1024;
  50 + case 'M': case 'm':
  51 + d *= 1024;
  52 + case 'K': case 'k':
  53 + d *= 1024;
  54 + default:
  55 + break;
  56 + }
  57 +
  58 + max_throttle = (uint32_t)d;
  59 +}
  60 +
  61 +void do_info_migrate(void)
  62 +{
  63 + MigrationState *s = current_migration;
  64 +
  65 + if (s) {
  66 + term_printf("Migration status: ");
  67 + switch (s->get_status(s)) {
  68 + case MIG_STATE_ACTIVE:
  69 + term_printf("active\n");
  70 + break;
  71 + case MIG_STATE_COMPLETED:
  72 + term_printf("completed\n");
  73 + break;
  74 + case MIG_STATE_ERROR:
  75 + term_printf("failed\n");
  76 + break;
  77 + case MIG_STATE_CANCELLED:
  78 + term_printf("cancelled\n");
  79 + break;
  80 + }
  81 + }
  82 +}
  83 +
migration.h 0 → 100644
  1 +/*
  2 + * QEMU live migration
  3 + *
  4 + * Copyright IBM, Corp. 2008
  5 + *
  6 + * Authors:
  7 + * Anthony Liguori <aliguori@us.ibm.com>
  8 + *
  9 + * This work is licensed under the terms of the GNU GPL, version 2. See
  10 + * the COPYING file in the top-level directory.
  11 + *
  12 + */
  13 +
  14 +#ifndef QEMU_MIGRATION_H
  15 +#define QEMU_MIGRATION_H
  16 +
  17 +#define MIG_STATE_ERROR -1
  18 +#define MIG_STATE_COMPLETED 0
  19 +#define MIG_STATE_CANCELLED 1
  20 +#define MIG_STATE_ACTIVE 2
  21 +
  22 +typedef struct MigrationState MigrationState;
  23 +
  24 +struct MigrationState
  25 +{
  26 + /* FIXME: add more accessors to print migration info */
  27 + void (*cancel)(MigrationState *s);
  28 + int (*get_status)(MigrationState *s);
  29 + void (*release)(MigrationState *s);
  30 +};
  31 +
  32 +void qemu_start_incoming_migration(const char *uri);
  33 +
  34 +void do_migrate(int detach, const char *uri);
  35 +
  36 +void do_migrate_cancel(void);
  37 +
  38 +void do_migrate_set_speed(const char *value);
  39 +
  40 +void do_info_migrate(void);
  41 +
  42 +#endif
  43 +
monitor.c
@@ -36,6 +36,7 @@ @@ -36,6 +36,7 @@
36 #include "disas.h" 36 #include "disas.h"
37 #include <dirent.h> 37 #include <dirent.h>
38 #include "qemu-timer.h" 38 #include "qemu-timer.h"
  39 +#include "migration.h"
39 40
40 //#define DEBUG 41 //#define DEBUG
41 //#define DEBUG_COMPLETION 42 //#define DEBUG_COMPLETION
@@ -1454,6 +1455,12 @@ static const term_cmd_t term_cmds[] = { @@ -1454,6 +1455,12 @@ static const term_cmd_t term_cmds[] = {
1454 { "nmi", "i", do_inject_nmi, 1455 { "nmi", "i", do_inject_nmi,
1455 "cpu", "inject an NMI on the given CPU", }, 1456 "cpu", "inject an NMI on the given CPU", },
1456 #endif 1457 #endif
  1458 + { "migrate", "-ds", do_migrate,
  1459 + "[-d] uri", "migrate to URI (using -d to not wait for completion)" },
  1460 + { "migrate_cancel", "", do_migrate_cancel,
  1461 + "", "cancel the current VM migration" },
  1462 + { "migrate_set_speed", "s", do_migrate_set_speed,
  1463 + "value", "set maximum speed (in bytes) for migrations" },
1457 { NULL, NULL, }, 1464 { NULL, NULL, },
1458 }; 1465 };
1459 1466
@@ -1516,6 +1523,7 @@ static const term_cmd_t info_cmds[] = { @@ -1516,6 +1523,7 @@ static const term_cmd_t info_cmds[] = {
1516 { "slirp", "", do_info_slirp, 1523 { "slirp", "", do_info_slirp,
1517 "", "show SLIRP statistics", }, 1524 "", "show SLIRP statistics", },
1518 #endif 1525 #endif
  1526 + { "migrate", "", do_info_migrate, "", "show migration status" },
1519 { NULL, NULL, }, 1527 { NULL, NULL, },
1520 }; 1528 };
1521 1529
qemu_socket.h
@@ -31,5 +31,6 @@ int inet_aton(const char *cp, struct in_addr *ia); @@ -31,5 +31,6 @@ int inet_aton(const char *cp, struct in_addr *ia);
31 #endif /* !_WIN32 */ 31 #endif /* !_WIN32 */
32 32
33 void socket_set_nonblock(int fd); 33 void socket_set_nonblock(int fd);
  34 +int parse_host_port(struct sockaddr_in *saddr, const char *str);
34 35
35 #endif /* QEMU_SOCKET_H */ 36 #endif /* QEMU_SOCKET_H */
@@ -38,6 +38,7 @@ @@ -38,6 +38,7 @@
38 #include "qemu-char.h" 38 #include "qemu-char.h"
39 #include "block.h" 39 #include "block.h"
40 #include "audio/audio.h" 40 #include "audio/audio.h"
  41 +#include "migration.h"
41 42
42 #include <unistd.h> 43 #include <unistd.h>
43 #include <fcntl.h> 44 #include <fcntl.h>
@@ -3364,7 +3365,6 @@ static void udp_chr_update_read_handler(CharDriverState *chr) @@ -3364,7 +3365,6 @@ static void udp_chr_update_read_handler(CharDriverState *chr)
3364 } 3365 }
3365 } 3366 }
3366 3367
3367 -int parse_host_port(struct sockaddr_in *saddr, const char *str);  
3368 #ifndef _WIN32 3368 #ifndef _WIN32
3369 static int parse_unix_path(struct sockaddr_un *uaddr, const char *str); 3369 static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
3370 #endif 3370 #endif
@@ -6766,6 +6766,8 @@ int qemu_savevm_state(QEMUFile *f) @@ -6766,6 +6766,8 @@ int qemu_savevm_state(QEMUFile *f)
6766 saved_vm_running = vm_running; 6766 saved_vm_running = vm_running;
6767 vm_stop(0); 6767 vm_stop(0);
6768 6768
  6769 + bdrv_flush_all();
  6770 +
6769 ret = qemu_savevm_state_begin(f); 6771 ret = qemu_savevm_state_begin(f);
6770 if (ret < 0) 6772 if (ret < 0)
6771 goto out; 6773 goto out;
@@ -8338,6 +8340,7 @@ enum { @@ -8338,6 +8340,7 @@ enum {
8338 QEMU_OPTION_tb_size, 8340 QEMU_OPTION_tb_size,
8339 QEMU_OPTION_icount, 8341 QEMU_OPTION_icount,
8340 QEMU_OPTION_uuid, 8342 QEMU_OPTION_uuid,
  8343 + QEMU_OPTION_incoming,
8341 }; 8344 };
8342 8345
8343 typedef struct QEMUOption { 8346 typedef struct QEMUOption {
@@ -8450,6 +8453,7 @@ static const QEMUOption qemu_options[] = { @@ -8450,6 +8453,7 @@ static const QEMUOption qemu_options[] = {
8450 { "startdate", HAS_ARG, QEMU_OPTION_startdate }, 8453 { "startdate", HAS_ARG, QEMU_OPTION_startdate },
8451 { "tb-size", HAS_ARG, QEMU_OPTION_tb_size }, 8454 { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
8452 { "icount", HAS_ARG, QEMU_OPTION_icount }, 8455 { "icount", HAS_ARG, QEMU_OPTION_icount },
  8456 + { "incoming", HAS_ARG, QEMU_OPTION_incoming },
8453 { NULL }, 8457 { NULL },
8454 }; 8458 };
8455 8459
@@ -8742,6 +8746,7 @@ int main(int argc, char **argv) @@ -8742,6 +8746,7 @@ int main(int argc, char **argv)
8742 const char *pid_file = NULL; 8746 const char *pid_file = NULL;
8743 VLANState *vlan; 8747 VLANState *vlan;
8744 int autostart; 8748 int autostart;
  8749 + const char *incoming = NULL;
8745 8750
8746 LIST_INIT (&vm_change_state_head); 8751 LIST_INIT (&vm_change_state_head);
8747 #ifndef _WIN32 8752 #ifndef _WIN32
@@ -9349,6 +9354,9 @@ int main(int argc, char **argv) @@ -9349,6 +9354,9 @@ int main(int argc, char **argv)
9349 icount_time_shift = strtol(optarg, NULL, 0); 9354 icount_time_shift = strtol(optarg, NULL, 0);
9350 } 9355 }
9351 break; 9356 break;
  9357 + case QEMU_OPTION_incoming:
  9358 + incoming = optarg;
  9359 + break;
9352 } 9360 }
9353 } 9361 }
9354 } 9362 }
@@ -9691,6 +9699,11 @@ int main(int argc, char **argv) @@ -9691,6 +9699,11 @@ int main(int argc, char **argv)
9691 if (loadvm) 9699 if (loadvm)
9692 do_loadvm(loadvm); 9700 do_loadvm(loadvm);
9693 9701
  9702 + if (incoming) {
  9703 + autostart = 0; /* fixme how to deal with -daemonize */
  9704 + qemu_start_incoming_migration(incoming);
  9705 + }
  9706 +
9694 { 9707 {
9695 /* XXX: simplify init */ 9708 /* XXX: simplify init */
9696 read_passwords(); 9709 read_passwords();