blob: 2ce7770cfab7aa2e0a164670f616d30887278ef2 [file] [log] [blame]
aliguori065e2812008-11-11 16:46:33 +00001/*
2 * QEMU live migration
3 *
4 * Copyright IBM, Corp. 2008
5 * Copyright Dell MessageOne 2008
6 *
7 * Authors:
8 * Anthony Liguori <aliguori@us.ibm.com>
9 * Charles Duffy <charles_duffy@messageone.com>
10 *
11 * This work is licensed under the terms of the GNU GPL, version 2. See
12 * the COPYING file in the top-level directory.
13 *
Paolo Bonzini6b620ca2012-01-13 17:44:23 +010014 * Contributions after 2012-01-13 are licensed under the terms of the
15 * GNU GPL, version 2 or (at your option) any later version.
aliguori065e2812008-11-11 16:46:33 +000016 */
17
18#include "qemu-common.h"
19#include "qemu_socket.h"
20#include "migration.h"
21#include "qemu-char.h"
aliguori065e2812008-11-11 16:46:33 +000022#include "buffered_file.h"
23#include "block.h"
Blue Swirl0ffbba32010-06-04 20:01:07 +000024#include <sys/types.h>
25#include <sys/wait.h>
aliguori065e2812008-11-11 16:46:33 +000026
27//#define DEBUG_MIGRATION_EXEC
28
29#ifdef DEBUG_MIGRATION_EXEC
malcd0f2c4c2010-02-07 02:03:50 +030030#define DPRINTF(fmt, ...) \
aliguori065e2812008-11-11 16:46:33 +000031 do { printf("migration-exec: " fmt, ## __VA_ARGS__); } while (0)
32#else
malcd0f2c4c2010-02-07 02:03:50 +030033#define DPRINTF(fmt, ...) \
aliguori065e2812008-11-11 16:46:33 +000034 do { } while (0)
35#endif
36
Juan Quintela22f00a42010-05-11 15:56:35 +020037static int file_errno(MigrationState *s)
aliguori065e2812008-11-11 16:46:33 +000038{
39 return errno;
40}
41
Juan Quintela22f00a42010-05-11 15:56:35 +020042static int file_write(MigrationState *s, const void * buf, size_t size)
aliguori065e2812008-11-11 16:46:33 +000043{
44 return write(s->fd, buf, size);
45}
46
Juan Quintela22f00a42010-05-11 15:56:35 +020047static int exec_close(MigrationState *s)
aliguori065e2812008-11-11 16:46:33 +000048{
Anthony Liguori41ef56e2010-06-02 14:55:25 -050049 int ret = 0;
malcd0f2c4c2010-02-07 02:03:50 +030050 DPRINTF("exec_close\n");
Paolo Bonzini6c360132012-09-27 13:30:15 +020051 ret = qemu_fclose(s->opaque);
52 s->opaque = NULL;
53 s->fd = -1;
54 if (ret >= 0 && !(WIFEXITED(ret) && WEXITSTATUS(ret) == 0)) {
55 /* close succeeded, but non-zero exit code: */
56 ret = -EIO; /* fake errno value */
aliguori065e2812008-11-11 16:46:33 +000057 }
Anthony Liguori41ef56e2010-06-02 14:55:25 -050058 return ret;
aliguori065e2812008-11-11 16:46:33 +000059}
60
Paolo Bonzinif37afb52012-10-02 10:02:46 +020061void exec_start_outgoing_migration(MigrationState *s, const char *command, Error **errp)
aliguori065e2812008-11-11 16:46:33 +000062{
aliguori065e2812008-11-11 16:46:33 +000063 FILE *f;
64
aliguori065e2812008-11-11 16:46:33 +000065 f = popen(command, "w");
66 if (f == NULL) {
Paolo Bonzinif37afb52012-10-02 10:02:46 +020067 error_setg_errno(errp, errno, "failed to popen the migration target");
68 return;
aliguori065e2812008-11-11 16:46:33 +000069 }
70
71 s->fd = fileno(f);
Paolo Bonzinif37afb52012-10-02 10:02:46 +020072 assert(s->fd != -1);
Chris Lalancette90750002009-08-05 17:07:35 +020073 socket_set_nonblock(s->fd);
aliguori065e2812008-11-11 16:46:33 +000074
75 s->opaque = qemu_popen(f, "w");
76
aliguori8ad9fa52008-11-12 22:29:11 +000077 s->close = exec_close;
aliguori065e2812008-11-11 16:46:33 +000078 s->get_error = file_errno;
79 s->write = file_write;
aliguori065e2812008-11-11 16:46:33 +000080
81 migrate_fd_connect(s);
aliguori065e2812008-11-11 16:46:33 +000082}
83
Chris Lalancette8a43b1e2009-05-25 16:38:23 +020084static void exec_accept_incoming_migration(void *opaque)
aliguori065e2812008-11-11 16:46:33 +000085{
Chris Lalancette8a43b1e2009-05-25 16:38:23 +020086 QEMUFile *f = opaque;
aliguori065e2812008-11-11 16:46:33 +000087
Paolo Bonzinid263a202012-08-08 10:21:26 +020088 qemu_set_fd_handler2(qemu_get_fd(f), NULL, NULL, NULL, NULL);
Paolo Bonzinia6ef2902012-08-07 10:49:13 +020089 process_incoming_migration(f);
aliguori065e2812008-11-11 16:46:33 +000090 qemu_fclose(f);
Chris Lalancette8a43b1e2009-05-25 16:38:23 +020091}
92
Paolo Bonzini43eaae22012-10-02 18:21:18 +020093void exec_start_incoming_migration(const char *command, Error **errp)
Chris Lalancette8a43b1e2009-05-25 16:38:23 +020094{
95 QEMUFile *f;
96
malcd0f2c4c2010-02-07 02:03:50 +030097 DPRINTF("Attempting to start an incoming migration\n");
Chris Lalancette8a43b1e2009-05-25 16:38:23 +020098 f = qemu_popen_cmd(command, "r");
99 if(f == NULL) {
Paolo Bonzini43eaae22012-10-02 18:21:18 +0200100 error_setg_errno(errp, errno, "failed to popen the migration source");
101 return;
Chris Lalancette8a43b1e2009-05-25 16:38:23 +0200102 }
103
Paolo Bonzinid263a202012-08-08 10:21:26 +0200104 qemu_set_fd_handler2(qemu_get_fd(f), NULL,
Juan Quintela1c39e2a2010-03-11 17:55:38 +0100105 exec_accept_incoming_migration, NULL, f);
aliguori065e2812008-11-11 16:46:33 +0000106}