These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / migration / qemu-file-unix.c
1 /*
2  * QEMU System Emulator
3  *
4  * Copyright (c) 2003-2008 Fabrice Bellard
5  *
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:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
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
22  * THE SOFTWARE.
23  */
24 #include "qemu/osdep.h"
25 #include "qemu-common.h"
26 #include "qemu/error-report.h"
27 #include "qemu/iov.h"
28 #include "qemu/sockets.h"
29 #include "qemu/coroutine.h"
30 #include "migration/qemu-file.h"
31 #include "migration/qemu-file-internal.h"
32
33 typedef struct QEMUFileSocket {
34     int fd;
35     QEMUFile *file;
36 } QEMUFileSocket;
37
38 static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
39                                     int64_t pos)
40 {
41     QEMUFileSocket *s = opaque;
42     ssize_t len;
43     ssize_t size = iov_size(iov, iovcnt);
44     ssize_t offset = 0;
45     int     err;
46
47     while (size > 0) {
48         len = iov_send(s->fd, iov, iovcnt, offset, size);
49
50         if (len > 0) {
51             size -= len;
52             offset += len;
53         }
54
55         if (size > 0) {
56             if (errno != EAGAIN && errno != EWOULDBLOCK) {
57                 error_report("socket_writev_buffer: Got err=%d for (%zu/%zu)",
58                              errno, (size_t)size, (size_t)len);
59                 /*
60                  * If I've already sent some but only just got the error, I
61                  * could return the amount validly sent so far and wait for the
62                  * next call to report the error, but I'd rather flag the error
63                  * immediately.
64                  */
65                 return -errno;
66             }
67
68             /* Emulate blocking */
69             GPollFD pfd;
70
71             pfd.fd = s->fd;
72             pfd.events = G_IO_OUT | G_IO_ERR;
73             pfd.revents = 0;
74             TFR(err = g_poll(&pfd, 1, -1 /* no timeout */));
75             /* Errors other than EINTR intentionally ignored */
76         }
77      }
78
79     return offset;
80 }
81
82 static int socket_get_fd(void *opaque)
83 {
84     QEMUFileSocket *s = opaque;
85
86     return s->fd;
87 }
88
89 static ssize_t socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
90                                  size_t size)
91 {
92     QEMUFileSocket *s = opaque;
93     ssize_t len;
94
95     for (;;) {
96         len = qemu_recv(s->fd, buf, size, 0);
97         if (len != -1) {
98             break;
99         }
100         if (errno == EAGAIN) {
101             yield_until_fd_readable(s->fd);
102         } else if (errno != EINTR) {
103             break;
104         }
105     }
106
107     if (len == -1) {
108         len = -errno;
109     }
110     return len;
111 }
112
113 static int socket_close(void *opaque)
114 {
115     QEMUFileSocket *s = opaque;
116     closesocket(s->fd);
117     g_free(s);
118     return 0;
119 }
120
121 static int socket_shutdown(void *opaque, bool rd, bool wr)
122 {
123     QEMUFileSocket *s = opaque;
124
125     if (shutdown(s->fd, rd ? (wr ? SHUT_RDWR : SHUT_RD) : SHUT_WR)) {
126         return -errno;
127     } else {
128         return 0;
129     }
130 }
131
132 static int socket_return_close(void *opaque)
133 {
134     QEMUFileSocket *s = opaque;
135     /*
136      * Note: We don't close the socket, that should be done by the forward
137      * path.
138      */
139     g_free(s);
140     return 0;
141 }
142
143 static const QEMUFileOps socket_return_read_ops = {
144     .get_fd          = socket_get_fd,
145     .get_buffer      = socket_get_buffer,
146     .close           = socket_return_close,
147     .shut_down       = socket_shutdown,
148 };
149
150 static const QEMUFileOps socket_return_write_ops = {
151     .get_fd          = socket_get_fd,
152     .writev_buffer   = socket_writev_buffer,
153     .close           = socket_return_close,
154     .shut_down       = socket_shutdown,
155 };
156
157 /*
158  * Give a QEMUFile* off the same socket but data in the opposite
159  * direction.
160  */
161 static QEMUFile *socket_get_return_path(void *opaque)
162 {
163     QEMUFileSocket *forward = opaque;
164     QEMUFileSocket *reverse;
165
166     if (qemu_file_get_error(forward->file)) {
167         /* If the forward file is in error, don't try and open a return */
168         return NULL;
169     }
170
171     reverse = g_malloc0(sizeof(QEMUFileSocket));
172     reverse->fd = forward->fd;
173     /* I don't think there's a better way to tell which direction 'this' is */
174     if (forward->file->ops->get_buffer != NULL) {
175         /* being called from the read side, so we need to be able to write */
176         return qemu_fopen_ops(reverse, &socket_return_write_ops);
177     } else {
178         return qemu_fopen_ops(reverse, &socket_return_read_ops);
179     }
180 }
181
182 static ssize_t unix_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
183                                   int64_t pos)
184 {
185     QEMUFileSocket *s = opaque;
186     ssize_t len, offset;
187     ssize_t size = iov_size(iov, iovcnt);
188     ssize_t total = 0;
189
190     assert(iovcnt > 0);
191     offset = 0;
192     while (size > 0) {
193         /* Find the next start position; skip all full-sized vector elements  */
194         while (offset >= iov[0].iov_len) {
195             offset -= iov[0].iov_len;
196             iov++, iovcnt--;
197         }
198
199         /* skip `offset' bytes from the (now) first element, undo it on exit */
200         assert(iovcnt > 0);
201         iov[0].iov_base += offset;
202         iov[0].iov_len -= offset;
203
204         do {
205             len = writev(s->fd, iov, iovcnt);
206         } while (len == -1 && errno == EINTR);
207         if (len == -1) {
208             return -errno;
209         }
210
211         /* Undo the changes above */
212         iov[0].iov_base -= offset;
213         iov[0].iov_len += offset;
214
215         /* Prepare for the next iteration */
216         offset += len;
217         total += len;
218         size -= len;
219     }
220
221     return total;
222 }
223
224 static ssize_t unix_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
225                               size_t size)
226 {
227     QEMUFileSocket *s = opaque;
228     ssize_t len;
229
230     for (;;) {
231         len = read(s->fd, buf, size);
232         if (len != -1) {
233             break;
234         }
235         if (errno == EAGAIN) {
236             yield_until_fd_readable(s->fd);
237         } else if (errno != EINTR) {
238             break;
239         }
240     }
241
242     if (len == -1) {
243         len = -errno;
244     }
245     return len;
246 }
247
248 static int unix_close(void *opaque)
249 {
250     QEMUFileSocket *s = opaque;
251     close(s->fd);
252     g_free(s);
253     return 0;
254 }
255
256 static const QEMUFileOps unix_read_ops = {
257     .get_fd =     socket_get_fd,
258     .get_buffer = unix_get_buffer,
259     .close =      unix_close
260 };
261
262 static const QEMUFileOps unix_write_ops = {
263     .get_fd =     socket_get_fd,
264     .writev_buffer = unix_writev_buffer,
265     .close =      unix_close
266 };
267
268 QEMUFile *qemu_fdopen(int fd, const char *mode)
269 {
270     QEMUFileSocket *s;
271
272     if (mode == NULL ||
273         (mode[0] != 'r' && mode[0] != 'w') ||
274         mode[1] != 'b' || mode[2] != 0) {
275         fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
276         return NULL;
277     }
278
279     s = g_new0(QEMUFileSocket, 1);
280     s->fd = fd;
281
282     if (mode[0] == 'r') {
283         s->file = qemu_fopen_ops(s, &unix_read_ops);
284     } else {
285         s->file = qemu_fopen_ops(s, &unix_write_ops);
286     }
287     return s->file;
288 }
289
290 static const QEMUFileOps socket_read_ops = {
291     .get_fd          = socket_get_fd,
292     .get_buffer      = socket_get_buffer,
293     .close           = socket_close,
294     .shut_down       = socket_shutdown,
295     .get_return_path = socket_get_return_path
296 };
297
298 static const QEMUFileOps socket_write_ops = {
299     .get_fd          = socket_get_fd,
300     .writev_buffer   = socket_writev_buffer,
301     .close           = socket_close,
302     .shut_down       = socket_shutdown,
303     .get_return_path = socket_get_return_path
304 };
305
306 QEMUFile *qemu_fopen_socket(int fd, const char *mode)
307 {
308     QEMUFileSocket *s;
309
310     if (qemu_file_mode_is_not_valid(mode)) {
311         return NULL;
312     }
313
314     s = g_new0(QEMUFileSocket, 1);
315     s->fd = fd;
316     if (mode[0] == 'w') {
317         qemu_set_block(s->fd);
318         s->file = qemu_fopen_ops(s, &socket_write_ops);
319     } else {
320         s->file = qemu_fopen_ops(s, &socket_read_ops);
321     }
322     return s->file;
323 }