2 * QEMU migration support
4 * Copyright (C) 2007 Anthony Liguori <anthony@codemonkey.ws>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 #include "qemu_socket.h"
30 #define MIN_FINALIZE_SIZE (200 << 10)
32 typedef struct MigrationState
38 int last_updated_pages
;
43 char buffer
[TARGET_PAGE_SIZE
+ 4];
48 int (*release
)(void *opaque
);
51 static uint32_t max_throttle
= (32 << 20);
52 static MigrationState
*current_migration
;
54 /* QEMUFile migration implementation */
56 static void migrate_put_buffer(void *opaque
, const uint8_t *buf
, int64_t pos
, int size
)
58 MigrationState
*s
= opaque
;
64 while (offset
< size
) {
67 len
= write(s
->fd
, buf
+ offset
, size
- offset
);
69 if (errno
== EAGAIN
|| errno
== EINTR
)
71 term_printf("migration: write failed (%s)\n", strerror(errno
));
74 } else if (len
== 0) {
75 term_printf("migration: other side closed connection\n");
84 static void migrate_close(void *opaque
)
86 MigrationState
*s
= opaque
;
88 if (s
->release
&& s
->release(s
->opaque
))
92 current_migration
= NULL
;
95 /* Outgoing migration routines */
97 static void migrate_finish(MigrationState
*s
)
101 int *has_error
= s
->has_error
;
103 fcntl(s
->fd
, F_SETFL
, 0);
106 f
= qemu_fopen(s
, migrate_put_buffer
, NULL
, migrate_close
);
110 ret
= qemu_live_savevm_state(f
);
113 if (ret
!= 0 || *has_error
) {
114 term_printf("Migration failed! ret=%d error=%d\n", ret
, *has_error
);
119 qemu_free(has_error
);
120 cpu_physical_memory_set_dirty_tracking(0);
123 static int migrate_write_buffer(MigrationState
*s
)
128 if (s
->n_buffer
!= sizeof(s
->buffer
)) {
131 len
= write(s
->fd
, s
->buffer
+ s
->n_buffer
, sizeof(s
->buffer
) - s
->n_buffer
);
145 s
->throttle_count
+= len
;
147 if (s
->n_buffer
!= sizeof(s
->buffer
))
151 if (s
->throttle_count
> max_throttle
) {
153 qemu_set_fd_handler2(s
->fd
, NULL
, NULL
, NULL
, NULL
);
160 static int migrate_check_convergence(MigrationState
*s
)
165 for (addr
= 0; addr
< phys_ram_size
; addr
+= TARGET_PAGE_SIZE
) {
167 if (kvm_allowed
&& (addr
>=0xa0000) && (addr
<0xc0000)) /* do not access video-addresses */
170 if (cpu_physical_memory_get_dirty(addr
, MIGRATION_DIRTY_FLAG
))
174 return ((dirty_count
* TARGET_PAGE_SIZE
) < MIN_FINALIZE_SIZE
);
177 static void migrate_write(void *opaque
)
179 MigrationState
*s
= opaque
;
181 if (migrate_write_buffer(s
))
184 if (migrate_check_convergence(s
) || *s
->has_error
) {
185 qemu_del_timer(s
->timer
);
186 qemu_free_timer(s
->timer
);
187 qemu_set_fd_handler2(s
->fd
, NULL
, NULL
, NULL
, NULL
);
192 while (s
->addr
< phys_ram_size
) {
194 if (kvm_allowed
&& (s
->addr
>=0xa0000) && (s
->addr
<0xc0000)) /* do not access video-addresses */
198 if (cpu_physical_memory_get_dirty(s
->addr
, MIGRATION_DIRTY_FLAG
)) {
199 uint32_t value
= cpu_to_be32(s
->addr
);
201 memcpy(s
->buffer
, &value
, 4);
202 memcpy(s
->buffer
+ 4, phys_ram_base
+ s
->addr
, TARGET_PAGE_SIZE
);
205 cpu_physical_memory_reset_dirty(s
->addr
, s
->addr
+ TARGET_PAGE_SIZE
, MIGRATION_DIRTY_FLAG
);
207 s
->addr
+= TARGET_PAGE_SIZE
;
211 if (migrate_write_buffer(s
))
214 s
->addr
+= TARGET_PAGE_SIZE
;
217 s
->last_updated_pages
= s
->updated_pages
;
218 s
->updated_pages
= 0;
223 static void migrate_reset_throttle(void *opaque
)
225 MigrationState
*s
= opaque
;
227 s
->bps
= s
->throttle_count
;
231 qemu_set_fd_handler2(s
->fd
, NULL
, NULL
, migrate_write
, s
);
233 s
->throttle_count
= 0;
234 qemu_mod_timer(s
->timer
, qemu_get_clock(rt_clock
) + 1000);
237 static int start_migration(MigrationState
*s
)
239 uint32_t value
= cpu_to_be32(phys_ram_size
);
240 target_phys_addr_t addr
;
243 while (offset
!= 4) {
244 ssize_t len
= write(s
->fd
, ((char *)&value
) + offset
, 4 - offset
);
245 if (len
== -1 && errno
== EINTR
)
254 fcntl(s
->fd
, F_SETFL
, O_NONBLOCK
);
256 for (addr
= 0; addr
< phys_ram_size
; addr
+= TARGET_PAGE_SIZE
) {
258 if (kvm_allowed
&& (addr
>=0xa0000) && (addr
<0xc0000)) /* do not access video-addresses */
261 if (!cpu_physical_memory_get_dirty(addr
, MIGRATION_DIRTY_FLAG
))
262 cpu_physical_memory_set_dirty(addr
);
265 cpu_physical_memory_set_dirty_tracking(1);
269 s
->updated_pages
= 0;
270 s
->last_updated_pages
= 0;
271 s
->n_buffer
= sizeof(s
->buffer
);
272 s
->timer
= qemu_new_timer(rt_clock
, migrate_reset_throttle
, s
);
274 qemu_mod_timer(s
->timer
, qemu_get_clock(rt_clock
));
275 qemu_set_fd_handler2(s
->fd
, NULL
, NULL
, migrate_write
, s
);
278 static MigrationState
*migration_init_fd(int detach
, int fd
)
282 s
= qemu_mallocz(sizeof(MigrationState
));
284 term_printf("Allocation error\n");
289 s
->has_error
= qemu_mallocz(sizeof(int));
290 if (s
->has_error
== NULL
) {
291 term_printf("malloc failed (for has_error)\n");
296 current_migration
= s
;
298 if (start_migration(s
) == -1) {
299 term_printf("Could not start migration\n");
309 typedef struct MigrationCmdState
315 static int cmd_release(void *opaque
)
317 MigrationCmdState
*c
= opaque
;
323 ret
= waitpid(c
->pid
, &status
, 0);
324 if (ret
== -1 && errno
== EINTR
)
328 term_printf("migration: waitpid failed (%s)\n", strerror(errno
));
331 /* FIXME: check and uncomment
332 * if (WIFEXITED(status))
333 * status = WEXITSTATUS(status);
338 static MigrationState
*migration_init_cmd(int detach
, const char *command
, char **argv
)
345 if (pipe(fds
) == -1) {
346 term_printf("pipe() (%s)\n", strerror(errno
));
354 term_printf("fork error (%s)\n", strerror(errno
));
359 dup2(fds
[0], STDIN_FILENO
);
360 execvp(command
, argv
);
365 for (i
= 0; argv
[i
]; i
++)
369 s
= migration_init_fd(detach
, fds
[1]);
371 MigrationCmdState
*c
= qemu_mallocz(sizeof(*c
));
374 s
->release
= cmd_release
;
381 static MigrationState
*migration_init_exec(int detach
, const char *command
)
385 argv
= qemu_mallocz(sizeof(char *) * 4);
386 argv
[0] = strdup("sh");
387 argv
[1] = strdup("-c");
388 argv
[2] = strdup(command
);
391 return migration_init_cmd(detach
, "/bin/sh", argv
);
394 static MigrationState
*migration_init_ssh(int detach
, const char *host
)
396 int qemu_argc
, daemonize
= 0, argc
, i
;
397 char **qemu_argv
, **argv
;
398 const char *incoming
= NULL
;
400 qemu_get_launch_info(&qemu_argc
, &qemu_argv
, &daemonize
, &incoming
);
402 argc
= 3 + qemu_argc
;
408 argv
= qemu_mallocz(sizeof(char *) * (argc
+ 1));
409 argv
[0] = strdup("ssh");
410 argv
[1] = strdup("-XC");
411 argv
[2] = strdup(host
);
413 for (i
= 0; i
< qemu_argc
; i
++)
414 argv
[3 + i
] = strdup(qemu_argv
[i
]);
417 argv
[3 + i
++] = strdup("-daemonize");
419 argv
[3 + i
++] = strdup("-incoming");
420 argv
[3 + i
++] = strdup("stdio");
425 return migration_init_cmd(detach
, "ssh", argv
);
428 static int tcp_release(void *opaque
)
430 MigrationState
*s
= opaque
;
435 len
= read(s
->fd
, &status
, 1);
436 if (len
== -1 && errno
== EINTR
)
441 return (len
!= 1 || status
!= 0);
444 static MigrationState
*migration_init_tcp(int detach
, const char *host
)
447 struct sockaddr_in addr
;
450 fd
= socket(PF_INET
, SOCK_STREAM
, 0);
452 term_printf("socket() failed %s\n", strerror(errno
));
456 addr
.sin_family
= AF_INET
;
457 if (parse_host_port(&addr
, host
) == -1) {
458 term_printf("parse_host_port() FAILED for %s\n", host
);
463 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
)) == -1) {
464 term_printf("connect() failed %s\n", strerror(errno
));
469 s
= migration_init_fd(detach
, fd
);
472 s
->release
= tcp_release
;
477 /* Incoming migration */
479 static int migrate_incoming_fd(int fd
)
482 QEMUFile
*f
= qemu_fopen_fd(fd
);
484 extern void qemu_announce_self(void);
486 if (qemu_get_be32(f
) != phys_ram_size
)
491 addr
= qemu_get_be32(f
);
494 l
= qemu_get_buffer(f
, phys_ram_base
+ addr
, TARGET_PAGE_SIZE
);
495 if (l
!= TARGET_PAGE_SIZE
)
502 ret
= qemu_live_loadvm_state(f
);
508 static int migrate_incoming_tcp(const char *host
)
510 struct sockaddr_in addr
;
511 socklen_t addrlen
= sizeof(addr
);
518 addr
.sin_family
= AF_INET
;
519 if (parse_host_port(&addr
, host
) == -1) {
520 fprintf(stderr
, "parse_host_port() failed for %s\n", host
);
525 fd
= socket(PF_INET
, SOCK_STREAM
, 0);
527 perror("socket failed");
532 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &reuse
, sizeof(reuse
)) == -1) {
533 perror("setsockopt() failed");
538 if (bind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
)) == -1) {
539 perror("bind() failed");
544 if (listen(fd
, 1) == -1) {
545 perror("listen() failed");
551 sfd
= accept(fd
, (struct sockaddr
*)&addr
, &addrlen
);
555 perror("accept() failed");
560 rc
= migrate_incoming_fd(sfd
);
563 fprintf(stderr
, "migrate_incoming_fd failed (rc=%d)\n", rc
);
568 len
= write(sfd
, &status
, 1);
569 if (len
== -1 && errno
== EAGAIN
)
585 int migrate_incoming(const char *device
)
590 if (strcmp(device
, "stdio") == 0)
591 ret
= migrate_incoming_fd(STDIN_FILENO
);
592 else if (strstart(device
, "tcp://", &ptr
)) {
595 end
= strchr(host
, '/');
597 ret
= migrate_incoming_tcp(host
);
607 /* Migration monitor command */
610 1) audit all error paths
613 void do_migrate(int detach
, const char *uri
)
617 if (strstart(uri
, "exec:", &ptr
)) {
618 char *command
= urldecode(ptr
);
619 migration_init_exec(detach
, command
);
621 } else if (strstart(uri
, "ssh://", &ptr
)) {
625 end
= strchr(host
, '/');
627 migration_init_ssh(detach
, host
);
629 } else if (strstart(uri
, "tcp://", &ptr
)) {
633 end
= strchr(host
, '/');
636 if (migration_init_tcp(detach
, host
) == NULL
)
637 term_printf("migration failed (migration_init_tcp for %s failed)\n", host
);
640 term_printf("Unknown migration protocol '%s'\n", uri
);
645 void do_migrate_set_speed(const char *value
)
650 d
= strtod(value
, &ptr
);
662 max_throttle
= (uint32_t)d
;
665 void do_info_migration(void)
667 MigrationState
*s
= current_migration
;
670 term_printf("Migration active\n");
671 if (s
->bps
< (1 << 20))
672 term_printf("Transfer rate %3.1f kb/s\n",
673 (double)s
->bps
/ 1024);
675 term_printf("Transfer rate %3.1f mb/s\n",
676 (double)s
->bps
/ (1024 * 1024));
677 term_printf("Iteration %d\n", s
->iteration
);
678 term_printf("Transferred %d/%d pages\n", s
->updated_pages
, phys_ram_size
>> TARGET_PAGE_BITS
);
680 term_printf("Last iteration found %d dirty pages\n", s
->last_updated_pages
);
682 term_printf("Migration inactive\n");
684 term_printf("Maximum migration speed is ");
685 if (max_throttle
< (1 << 20))
686 term_printf("%3.1f kb/s\n", (double)max_throttle
/ 1024);
688 term_printf("%3.1f mb/s\n", (double)max_throttle
/ (1024 * 1024));
691 void do_migrate_cancel(void)
693 MigrationState
*s
= current_migration
;