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 474 ifndef CONFIG_USER_ONLY
475 475  
476 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 478 ifdef CONFIG_WIN32
479 479 OBJS+=block-raw-win32.o
480 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 36 #include "disas.h"
37 37 #include <dirent.h>
38 38 #include "qemu-timer.h"
  39 +#include "migration.h"
39 40  
40 41 //#define DEBUG
41 42 //#define DEBUG_COMPLETION
... ... @@ -1454,6 +1455,12 @@ static const term_cmd_t term_cmds[] = {
1454 1455 { "nmi", "i", do_inject_nmi,
1455 1456 "cpu", "inject an NMI on the given CPU", },
1456 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 1464 { NULL, NULL, },
1458 1465 };
1459 1466  
... ... @@ -1516,6 +1523,7 @@ static const term_cmd_t info_cmds[] = {
1516 1523 { "slirp", "", do_info_slirp,
1517 1524 "", "show SLIRP statistics", },
1518 1525 #endif
  1526 + { "migrate", "", do_info_migrate, "", "show migration status" },
1519 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 31 #endif /* !_WIN32 */
32 32  
33 33 void socket_set_nonblock(int fd);
  34 +int parse_host_port(struct sockaddr_in *saddr, const char *str);
34 35  
35 36 #endif /* QEMU_SOCKET_H */
... ...
... ... @@ -38,6 +38,7 @@
38 38 #include "qemu-char.h"
39 39 #include "block.h"
40 40 #include "audio/audio.h"
  41 +#include "migration.h"
41 42  
42 43 #include <unistd.h>
43 44 #include <fcntl.h>
... ... @@ -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 3368 #ifndef _WIN32
3369 3369 static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
3370 3370 #endif
... ... @@ -6766,6 +6766,8 @@ int qemu_savevm_state(QEMUFile *f)
6766 6766 saved_vm_running = vm_running;
6767 6767 vm_stop(0);
6768 6768  
  6769 + bdrv_flush_all();
  6770 +
6769 6771 ret = qemu_savevm_state_begin(f);
6770 6772 if (ret < 0)
6771 6773 goto out;
... ... @@ -8338,6 +8340,7 @@ enum {
8338 8340 QEMU_OPTION_tb_size,
8339 8341 QEMU_OPTION_icount,
8340 8342 QEMU_OPTION_uuid,
  8343 + QEMU_OPTION_incoming,
8341 8344 };
8342 8345  
8343 8346 typedef struct QEMUOption {
... ... @@ -8450,6 +8453,7 @@ static const QEMUOption qemu_options[] = {
8450 8453 { "startdate", HAS_ARG, QEMU_OPTION_startdate },
8451 8454 { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
8452 8455 { "icount", HAS_ARG, QEMU_OPTION_icount },
  8456 + { "incoming", HAS_ARG, QEMU_OPTION_incoming },
8453 8457 { NULL },
8454 8458 };
8455 8459  
... ... @@ -8742,6 +8746,7 @@ int main(int argc, char **argv)
8742 8746 const char *pid_file = NULL;
8743 8747 VLANState *vlan;
8744 8748 int autostart;
  8749 + const char *incoming = NULL;
8745 8750  
8746 8751 LIST_INIT (&vm_change_state_head);
8747 8752 #ifndef _WIN32
... ... @@ -9349,6 +9354,9 @@ int main(int argc, char **argv)
9349 9354 icount_time_shift = strtol(optarg, NULL, 0);
9350 9355 }
9351 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 9699 if (loadvm)
9692 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 9708 /* XXX: simplify init */
9696 9709 read_passwords();
... ...