master
c 116 lines 2.69 KB
Raw
1 /*
2 * QEMU live migration via generic fd
3 *
4 * Copyright Red Hat, Inc. 2009-2016
5 *
6 * Authors:
7 * Chris Lalancette <clalance@redhat.com>
8 * Daniel P. Berrange <berrange@redhat.com>
9 *
10 * This work is licensed under the terms of the GNU GPL, version 2. See
11 * the COPYING file in the top-level directory.
12 *
13 * Contributions after 2012-01-13 are licensed under the terms of the
14 * GNU GPL, version 2 or (at your option) any later version.
15 */
16
17 #include "qemu/osdep.h"
18 #include "channel.h"
19 #include "fd.h"
20 #include "file.h"
21 #include "migration.h"
22 #include "monitor/monitor.h"
23 #include "qemu/error-report.h"
24 #include "qemu/sockets.h"
25 #include "io/channel-util.h"
26 #include "trace.h"
27 #include "qapi/error.h"
28
29 static bool fd_is_pipe(int fd)
30 {
31 struct stat statbuf;
32
33 if (fstat(fd, &statbuf) == -1) {
34 return false;
35 }
36
37 return S_ISFIFO(statbuf.st_mode);
38 }
39
40 static bool migration_fd_valid(int fd)
41 {
42 if (fd_is_socket(fd)) {
43 return true;
44 }
45
46 if (fd_is_pipe(fd)) {
47 return true;
48 }
49
50 return false;
51 }
52
53 QIOChannel *fd_connect_outgoing(MigrationState *s, const char *fdname,
54 Error **errp)
55 {
56 QIOChannel *ioc = NULL;
57 int fd = monitor_get_fd(monitor_cur(), fdname, errp);
58 if (fd == -1) {
59 goto out;
60 }
61
62 if (!migration_fd_valid(fd)) {
63 error_setg(errp, "fd: migration to a file is not supported."
64 " Use file: instead.");
65 goto out;
66 }
67
68 trace_migration_fd_outgoing(fd);
69 ioc = qio_channel_new_fd(fd, errp);
70 if (!ioc) {
71 close(fd);
72 goto out;
73 }
74
75 qio_channel_set_name(ioc, "migration-fd-outgoing");
76 out:
77 return ioc;
78 }
79
80 static gboolean fd_accept_incoming_migration(QIOChannel *ioc,
81 GIOCondition condition,
82 gpointer opaque)
83 {
84 migration_channel_process_incoming(ioc);
85 object_unref(OBJECT(ioc));
86 return G_SOURCE_REMOVE;
87 }
88
89 void fd_connect_incoming(const char *fdname, Error **errp)
90 {
91 QIOChannel *ioc;
92 int fd = monitor_fd_param(monitor_cur(), fdname, errp);
93 if (fd == -1) {
94 return;
95 }
96
97 if (!migration_fd_valid(fd)) {
98 error_setg(errp, "fd: migration to a file is not supported."
99 " Use file: instead.");
100 return;
101 }
102
103 trace_migration_fd_incoming(fd);
104
105 ioc = qio_channel_new_fd(fd, errp);
106 if (!ioc) {
107 close(fd);
108 return;
109 }
110
111 qio_channel_set_name(ioc, "migration-fd-incoming");
112 qio_channel_add_watch_full(ioc, G_IO_IN,
113 fd_accept_incoming_migration,
114 NULL, NULL,
115 g_main_context_get_thread_default());
116 }