blob: 69f56b96969c2f1f57098ad8736ad99f48643824 [file] [log] [blame]
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001/*
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 <unistd.h>
25#include <fcntl.h>
26#include <signal.h>
27#include <time.h>
28#include <errno.h>
29#include <sys/time.h>
30#include <zlib.h>
31
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070032/* Needed early for CONFIG_BSD etc. */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070033#include "config-host.h"
34
35#ifndef _WIN32
36#include <sys/times.h>
37#include <sys/wait.h>
38#include <termios.h>
39#include <sys/mman.h>
40#include <sys/ioctl.h>
41#include <sys/resource.h>
42#include <sys/socket.h>
43#include <netinet/in.h>
44#include <net/if.h>
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070045#include <arpa/inet.h>
46#include <dirent.h>
47#include <netdb.h>
48#include <sys/select.h>
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070049#ifdef CONFIG_BSD
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070050#include <sys/stat.h>
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +010051#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070052#include <libutil.h>
53#else
54#include <util.h>
55#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070056#ifdef __linux__
57#include <pty.h>
58#include <malloc.h>
59#include <linux/rtc.h>
60#endif
61#endif
62#endif
63
64#ifdef _WIN32
65#include <windows.h>
66#include <malloc.h>
67#include <sys/timeb.h>
68#include <mmsystem.h>
69#define getopt_long_only getopt_long
70#define memalign(align, size) malloc(size)
71#endif
72
73#include "qemu-common.h"
74#include "hw/hw.h"
David 'Digit' Turnercc330d42013-12-14 23:26:42 +010075#include "net/net.h"
David 'Digit' Turner6af67652013-12-14 23:49:32 +010076#include "monitor/monitor.h"
David 'Digit' Turner34c48ff2013-12-15 00:25:03 +010077#include "sysemu/sysemu.h"
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +010078#include "qemu/iov.h"
David 'Digit' Turner7a78db72013-12-14 11:46:01 +010079#include "qemu/timer.h"
David 'Digit' Turnere7216d82013-12-15 00:51:13 +010080#include "sysemu/char.h"
David 'Digit' Turner34c48ff2013-12-15 00:25:03 +010081#include "sysemu/blockdev.h"
David 'Digit' Turnere1e03df2013-12-15 00:42:21 +010082#include "block/block.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070083#include "audio/audio.h"
David 'Digit' Turner28a09b62013-12-15 00:16:00 +010084#include "migration/migration.h"
David 'Digit' Turnerd0edecb2013-12-17 09:32:26 +010085#include "qemu/sockets.h"
David 'Digit' Turner031d6552013-12-15 00:52:36 +010086#include "qemu/queue.h"
David 'Digit' Turner28a09b62013-12-15 00:16:00 +010087#include "migration/qemu-file.h"
Tim Baverstock622b8f42010-12-07 11:36:59 +000088#include "android/snapshot.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070089
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070090
91#define SELF_ANNOUNCE_ROUNDS 5
David 'Digit' Turner986acc92011-05-10 16:50:01 +020092
93#ifndef ETH_P_RARP
94#define ETH_P_RARP 0x8035
95#endif
96#define ARP_HTYPE_ETH 0x0001
97#define ARP_PTYPE_IP 0x0800
98#define ARP_OP_REQUEST_REV 0x3
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070099
David 'Digit' Turner5973c772011-05-10 07:06:00 +0200100static int announce_self_create(uint8_t *buf,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700101 uint8_t *mac_addr)
102{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200103 /* Ethernet header. */
104 memset(buf, 0xff, 6); /* destination MAC addr */
105 memcpy(buf + 6, mac_addr, 6); /* source MAC addr */
106 *(uint16_t *)(buf + 12) = htons(ETH_P_RARP); /* ethertype */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700107
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200108 /* RARP header. */
109 *(uint16_t *)(buf + 14) = htons(ARP_HTYPE_ETH); /* hardware addr space */
110 *(uint16_t *)(buf + 16) = htons(ARP_PTYPE_IP); /* protocol addr space */
111 *(buf + 18) = 6; /* hardware addr length (ethernet) */
112 *(buf + 19) = 4; /* protocol addr length (IPv4) */
113 *(uint16_t *)(buf + 20) = htons(ARP_OP_REQUEST_REV); /* opcode */
114 memcpy(buf + 22, mac_addr, 6); /* source hw addr */
115 memset(buf + 28, 0x00, 4); /* source protocol addr */
116 memcpy(buf + 32, mac_addr, 6); /* target hw addr */
117 memset(buf + 38, 0x00, 4); /* target protocol addr */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700118
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200119 /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
120 memset(buf + 42, 0x00, 18);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700121
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200122 return 60; /* len (FCS will be added by hardware) */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700123}
124
125static void qemu_announce_self_once(void *opaque)
126{
127 int i, len;
128 VLANState *vlan;
129 VLANClientState *vc;
130 uint8_t buf[256];
131 static int count = SELF_ANNOUNCE_ROUNDS;
132 QEMUTimer *timer = *(QEMUTimer **)opaque;
133
134 for (i = 0; i < MAX_NICS; i++) {
135 if (!nd_table[i].used)
136 continue;
137 len = announce_self_create(buf, nd_table[i].macaddr);
138 vlan = nd_table[i].vlan;
139 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
140 vc->receive(vc, buf, len);
141 }
142 }
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200143 if (--count) {
144 /* delay 50ms, 150ms, 250ms, ... */
David 'Digit' Turnerdcda9492014-02-16 15:13:55 +0100145 timer_mod(timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) +
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200146 50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700147 } else {
David 'Digit' Turnerdcda9492014-02-16 15:13:55 +0100148 timer_del(timer);
149 timer_free(timer);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700150 }
151}
152
153void qemu_announce_self(void)
154{
155 static QEMUTimer *timer;
David 'Digit' Turnerdcda9492014-02-16 15:13:55 +0100156 timer = timer_new_ms(QEMU_CLOCK_REALTIME, qemu_announce_self_once, &timer);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700157 qemu_announce_self_once(&timer);
158}
159
160/***********************************************************/
161/* savevm/loadvm support */
162
David 'Digit' Turner1365eb22014-02-16 22:23:26 +0100163void yield_until_fd_readable(int fd);
164
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700165#define IO_BUF_SIZE 32768
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100166#define MAX_IOV_SIZE MIN(IOV_MAX, 64)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700167
168struct QEMUFile {
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100169 const QEMUFileOps *ops;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700170 void *opaque;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700171
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100172 int64_t bytes_xfer;
173 int64_t xfer_limit;
174
175 int64_t pos; /* start of buffer when writing, end of buffer
176 when reading */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700177 int buf_index;
178 int buf_size; /* 0 when writing */
179 uint8_t buf[IO_BUF_SIZE];
180
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100181 struct iovec iov[MAX_IOV_SIZE];
182 unsigned int iovcnt;
183
184 int last_error;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700185};
186
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200187typedef struct QEMUFileStdio
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700188{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200189 FILE *stdio_file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700190 QEMUFile *file;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200191} QEMUFileStdio;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700192
193typedef struct QEMUFileSocket
194{
195 int fd;
196 QEMUFile *file;
197} QEMUFileSocket;
198
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100199static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
200 int64_t pos)
201{
202 QEMUFileSocket *s = opaque;
203 ssize_t len;
204 ssize_t size = iov_size(iov, iovcnt);
205
206 len = iov_send(s->fd, iov, iovcnt, 0, size);
207 if (len < size) {
208 len = -socket_error();
209 }
210 return len;
211}
212
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100213static int socket_get_fd(void *opaque)
214{
215 QEMUFileSocket *s = opaque;
216
217 return s->fd;
218}
219
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200220static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700221{
222 QEMUFileSocket *s = opaque;
223 ssize_t len;
224
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100225 for (;;) {
226 len = qemu_recv(s->fd, buf, size, 0);
227 if (len != -1) {
228 break;
229 }
230#ifndef CONFIG_ANDROID
231 if (socket_error() == EAGAIN) {
232 yield_until_fd_readable(s->fd);
233 } else if (socket_error() != EINTR) {
234 break;
235 }
236#else
237 if (socket_error() != EINTR)
238 break;
239#endif
240 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700241
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100242 if (len == -1) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700243 len = -socket_error();
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100244 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700245 return len;
246}
247
248static int file_socket_close(void *opaque)
249{
250 QEMUFileSocket *s = opaque;
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100251 if (s->fd >= 0)
252 socket_close(s->fd);
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100253 g_free(s);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700254 return 0;
255}
256
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100257static int stdio_get_fd(void *opaque)
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100258{
259 QEMUFileStdio *s = opaque;
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100260
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100261 return fileno(s->stdio_file);
262}
263
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200264static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700265{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200266 QEMUFileStdio *s = opaque;
267 return fwrite(buf, 1, size, s->stdio_file);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700268}
269
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200270static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700271{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200272 QEMUFileStdio *s = opaque;
273 FILE *fp = s->stdio_file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700274 int bytes;
275
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100276 for (;;) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700277 clearerr(fp);
278 bytes = fread(buf, 1, size, fp);
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100279 if (bytes != 0 || !ferror(fp)) {
280 break;
281 }
282#ifndef CONFIG_ANDROID
283 if (errno == EAGAIN) {
284 yield_until_fd_readable(fileno(fp));
285 } else if (errno != EINTR) {
286 break;
287 }
288#else
289 if (errno != EINTR)
290 break;
291#endif
292 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700293 return bytes;
294}
295
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200296static int stdio_pclose(void *opaque)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700297{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200298 QEMUFileStdio *s = opaque;
299 int ret;
300 ret = pclose(s->stdio_file);
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100301 if (ret == -1) {
302 ret = -errno;
303 } else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
304 /* close succeeded, but non-zero exit code: */
305 ret = -EIO; /* fake errno value */
306 }
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100307 g_free(s);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200308 return ret;
309}
310
311static int stdio_fclose(void *opaque)
312{
313 QEMUFileStdio *s = opaque;
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100314 int ret = 0;
315
316 if (s->file->ops->put_buffer || s->file->ops->writev_buffer) {
317 int fd = fileno(s->stdio_file);
318 struct stat st;
319
320 ret = fstat(fd, &st);
321 if (ret == 0 && S_ISREG(st.st_mode)) {
322 /*
323 * If the file handle is a regular file make sure the
324 * data is flushed to disk before signaling success.
325 */
326 ret = fsync(fd);
327 if (ret != 0) {
328 ret = -errno;
329 return ret;
330 }
331 }
332 }
333 if (fclose(s->stdio_file) == EOF) {
334 ret = -errno;
335 }
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100336 g_free(s);
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100337 return ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700338}
339
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100340static const QEMUFileOps stdio_pipe_read_ops = {
341 .get_fd = stdio_get_fd,
342 .get_buffer = stdio_get_buffer,
343 .close = stdio_pclose
344};
345
346static const QEMUFileOps stdio_pipe_write_ops = {
347 .get_fd = stdio_get_fd,
348 .put_buffer = stdio_put_buffer,
349 .close = stdio_pclose
350};
351
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100352QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700353{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100354 FILE *stdio_file;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200355 QEMUFileStdio *s;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700356
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100357 if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700358 fprintf(stderr, "qemu_popen: Argument validity check failed\n");
359 return NULL;
360 }
361
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100362 stdio_file = popen(command, mode);
363 if (stdio_file == NULL) {
364 return NULL;
365 }
366
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100367 s = g_malloc0(sizeof(QEMUFileStdio));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700368
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200369 s->stdio_file = stdio_file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700370
371 if(mode[0] == 'r') {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100372 s->file = qemu_fopen_ops(s, &stdio_pipe_read_ops);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700373 } else {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100374 s->file = qemu_fopen_ops(s, &stdio_pipe_write_ops);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700375 }
376 return s->file;
377}
378
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100379static const QEMUFileOps stdio_file_read_ops = {
380 .get_fd = stdio_get_fd,
381 .get_buffer = stdio_get_buffer,
382 .close = stdio_fclose
383};
384
385static const QEMUFileOps stdio_file_write_ops = {
386 .get_fd = stdio_get_fd,
387 .put_buffer = stdio_put_buffer,
388 .close = stdio_fclose
389};
390
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100391static ssize_t unix_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
392 int64_t pos)
393{
394 QEMUFileSocket *s = opaque;
395 ssize_t len, offset;
396 ssize_t size = iov_size(iov, iovcnt);
397 ssize_t total = 0;
398
399 assert(iovcnt > 0);
400 offset = 0;
401 while (size > 0) {
402 /* Find the next start position; skip all full-sized vector elements */
403 while (offset >= iov[0].iov_len) {
404 offset -= iov[0].iov_len;
405 iov++, iovcnt--;
406 }
407
408 /* skip `offset' bytes from the (now) first element, undo it on exit */
409 assert(iovcnt > 0);
410 iov[0].iov_base += offset;
411 iov[0].iov_len -= offset;
412
413 do {
414 len = writev(s->fd, iov, iovcnt);
415 } while (len == -1 && errno == EINTR);
416 if (len == -1) {
417 return -errno;
418 }
419
420 /* Undo the changes above */
421 iov[0].iov_base -= offset;
422 iov[0].iov_len += offset;
423
424 /* Prepare for the next iteration */
425 offset += len;
426 total += len;
427 size -= len;
428 }
429
430 return total;
431}
432
433static int unix_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
434{
435 QEMUFileSocket *s = opaque;
436 ssize_t len;
437
438 for (;;) {
439 len = read(s->fd, buf, size);
440 if (len != -1) {
441 break;
442 }
443 if (errno == EAGAIN) {
444 yield_until_fd_readable(s->fd);
445 } else if (errno != EINTR) {
446 break;
447 }
448 }
449
450 if (len == -1) {
451 len = -errno;
452 }
453 return len;
454}
455
456static int unix_close(void *opaque)
457{
458 QEMUFileSocket *s = opaque;
459 close(s->fd);
460 g_free(s);
461 return 0;
462}
463
464static const QEMUFileOps unix_read_ops = {
465 .get_fd = socket_get_fd,
466 .get_buffer = unix_get_buffer,
467 .close = unix_close
468};
469
470static const QEMUFileOps unix_write_ops = {
471 .get_fd = socket_get_fd,
472 .writev_buffer = unix_writev_buffer,
473 .close = unix_close
474};
475
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200476QEMUFile *qemu_fdopen(int fd, const char *mode)
477{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100478 QEMUFileSocket *s;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200479
480 if (mode == NULL ||
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100481 (mode[0] != 'r' && mode[0] != 'w') ||
482 mode[1] != 'b' || mode[2] != 0) {
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200483 fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
484 return NULL;
485 }
486
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100487 s = g_malloc0(sizeof(QEMUFileSocket));
488 s->fd = fd;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200489
490 if(mode[0] == 'r') {
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100491 s->file = qemu_fopen_ops(s, &unix_read_ops);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200492 } else {
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100493 s->file = qemu_fopen_ops(s, &unix_write_ops);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200494 }
495 return s->file;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200496}
497
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100498static const QEMUFileOps socket_read_ops = {
499 .get_fd = socket_get_fd,
500 .get_buffer = socket_get_buffer,
501 .close = file_socket_close
502};
503
504static const QEMUFileOps socket_write_ops = {
505 .get_fd = socket_get_fd,
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100506 .writev_buffer = socket_writev_buffer,
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100507 .close = file_socket_close
508};
509
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100510bool qemu_file_mode_is_not_valid(const char *mode)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700511{
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100512 if (mode == NULL ||
513 (mode[0] != 'r' && mode[0] != 'w') ||
514 mode[1] != 'b' || mode[2] != 0) {
515 fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
516 return true;
517 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700518
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100519 return false;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700520}
521
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100522QEMUFile *qemu_fopen_socket(int fd, const char *mode)
523{
524 QEMUFileSocket *s;
525
526 if (qemu_file_mode_is_not_valid(mode)) {
527 return NULL;
528 }
529
530 s = g_malloc0(sizeof(QEMUFileSocket));
531 s->fd = fd;
532 if (mode[0] == 'w') {
533 qemu_set_block(s->fd);
534 s->file = qemu_fopen_ops(s, &socket_write_ops);
535 } else {
536 s->file = qemu_fopen_ops(s, &socket_read_ops);
537 }
538 return s->file;
539}
540
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700541QEMUFile *qemu_fopen(const char *filename, const char *mode)
542{
543 QEMUFileStdio *s;
544
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100545 if (qemu_file_mode_is_not_valid(mode)) {
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200546 return NULL;
547 }
548
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100549 s = g_malloc0(sizeof(QEMUFileStdio));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700550
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200551 s->stdio_file = fopen(filename, mode);
552 if (!s->stdio_file)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700553 goto fail;
David 'Digit' Turnerc0052462014-02-25 18:39:29 +0100554
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200555 if(mode[0] == 'w') {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100556 s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200557 } else {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100558 s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200559 }
560 return s->file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700561fail:
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100562 g_free(s);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700563 return NULL;
564}
565
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100566#ifndef CONFIG_ANDROID
567// TODO(digit): Once bdrv_writev_vmstate() is implemented.
568static ssize_t block_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
569 int64_t pos)
570{
571 int ret;
572 QEMUIOVector qiov;
573
574 qemu_iovec_init_external(&qiov, iov, iovcnt);
575 ret = bdrv_writev_vmstate(opaque, &qiov, pos);
576 if (ret < 0) {
577 return ret;
578 }
579
580 return qiov.size;
581}
582#endif
583
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700584static int block_put_buffer(void *opaque, const uint8_t *buf,
585 int64_t pos, int size)
586{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200587 bdrv_save_vmstate(opaque, buf, pos, size);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700588 return size;
589}
590
591static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
592{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200593 return bdrv_load_vmstate(opaque, buf, pos, size);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700594}
595
596static int bdrv_fclose(void *opaque)
597{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100598 // TODO(digit): bdrv_flush() should return error code.
599 bdrv_flush(opaque);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700600 return 0;
601}
602
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100603static const QEMUFileOps bdrv_read_ops = {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100604 .get_buffer = block_get_buffer,
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100605 .close = bdrv_fclose
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100606};
607
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100608static const QEMUFileOps bdrv_write_ops = {
609 .put_buffer = block_put_buffer,
610 //.writev_buffer = block_writev_buffer,
611 .close = bdrv_fclose
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100612};
613
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200614static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700615{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700616 if (is_writable)
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100617 return qemu_fopen_ops(bs, &bdrv_write_ops);
618 return qemu_fopen_ops(bs, &bdrv_read_ops);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700619}
620
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100621QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700622{
623 QEMUFile *f;
624
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100625 f = g_malloc0(sizeof(QEMUFile));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700626
627 f->opaque = opaque;
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100628 f->ops = ops;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700629 return f;
630}
631
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100632/*
633 * Get last error for stream f
634 *
635 * Return negative error value if there has been an error on previous
636 * operations, return 0 if no error happened.
637 *
638 */
639int qemu_file_get_error(QEMUFile *f)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700640{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100641 return f->last_error;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700642}
643
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100644void qemu_file_set_error(QEMUFile *f, int ret)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700645{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100646 if (f->last_error == 0) {
647 f->last_error = ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700648 }
649}
650
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100651static inline bool qemu_file_is_writable(QEMUFile *f)
652{
653 return f->ops->writev_buffer || f->ops->put_buffer;
654}
655
656/**
657 * Flushes QEMUFile buffer
658 *
659 * If there is writev_buffer QEMUFileOps it uses it otherwise uses
660 * put_buffer ops.
661 */
662void qemu_fflush(QEMUFile *f)
663{
664 ssize_t ret = 0;
665
666 if (!qemu_file_is_writable(f)) {
667 return;
668 }
669
670 if (f->ops->writev_buffer) {
671 if (f->iovcnt > 0) {
672 ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos);
673 }
674 } else {
675 if (f->buf_index > 0) {
676 ret = f->ops->put_buffer(f->opaque, f->buf, f->pos, f->buf_index);
677 }
678 }
679 if (ret >= 0) {
680 f->pos += ret;
681 }
682 f->buf_index = 0;
683 f->iovcnt = 0;
684 if (ret < 0) {
685 qemu_file_set_error(f, ret);
686 }
687}
688
689#ifndef CONFIG_ANDROID
690// TODO(digit).
691void ram_control_before_iterate(QEMUFile *f, uint64_t flags)
692{
693 int ret = 0;
694
695 if (f->ops->before_ram_iterate) {
696 ret = f->ops->before_ram_iterate(f, f->opaque, flags);
697 if (ret < 0) {
698 qemu_file_set_error(f, ret);
699 }
700 }
701}
702
703void ram_control_after_iterate(QEMUFile *f, uint64_t flags)
704{
705 int ret = 0;
706
707 if (f->ops->after_ram_iterate) {
708 ret = f->ops->after_ram_iterate(f, f->opaque, flags);
709 if (ret < 0) {
710 qemu_file_set_error(f, ret);
711 }
712 }
713}
714
715void ram_control_load_hook(QEMUFile *f, uint64_t flags)
716{
717 int ret = -EINVAL;
718
719 if (f->ops->hook_ram_load) {
720 ret = f->ops->hook_ram_load(f, f->opaque, flags);
721 if (ret < 0) {
722 qemu_file_set_error(f, ret);
723 }
724 } else {
725 qemu_file_set_error(f, ret);
726 }
727}
728
729size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
730 ram_addr_t offset, size_t size, int *bytes_sent)
731{
732 if (f->ops->save_page) {
733 int ret = f->ops->save_page(f, f->opaque, block_offset,
734 offset, size, bytes_sent);
735
736 if (ret != RAM_SAVE_CONTROL_DELAYED) {
737 if (bytes_sent && *bytes_sent > 0) {
738 qemu_update_position(f, *bytes_sent);
739 } else if (ret < 0) {
740 qemu_file_set_error(f, ret);
741 }
742 }
743
744 return ret;
745 }
746
747 return RAM_SAVE_CONTROL_NOT_SUPP;
748}
749#endif // !CONFIG_ANDROID
750
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700751static void qemu_fill_buffer(QEMUFile *f)
752{
753 int len;
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100754 int pending;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700755
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100756 assert(!qemu_file_is_writable(f));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700757
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100758 pending = f->buf_size - f->buf_index;
759 if (pending > 0) {
760 memmove(f->buf, f->buf + f->buf_index, pending);
761 }
762 f->buf_index = 0;
763 f->buf_size = pending;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700764
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100765 len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos,
766 IO_BUF_SIZE - pending);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700767 if (len > 0) {
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100768 f->buf_size += len;
769 f->pos += len;
770 } else if (len == 0) {
771 qemu_file_set_error(f, -EIO);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700772 } else if (len != -EAGAIN)
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100773 qemu_file_set_error(f, len);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700774}
775
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100776int qemu_get_fd(QEMUFile *f)
777{
778 if (f->ops->get_fd) {
779 return f->ops->get_fd(f->opaque);
780 }
781 return -1;
782}
783
784void qemu_update_position(QEMUFile *f, size_t size)
785{
786 f->pos += size;
787}
788
789/** Closes the file
790 *
791 * Returns negative error value if any error happened on previous operations or
792 * while closing the file. Returns 0 or positive number on success.
793 *
794 * The meaning of return value on success depends on the specific backend
795 * being used.
796 */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700797int qemu_fclose(QEMUFile *f)
798{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100799 int ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700800 qemu_fflush(f);
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100801 ret = qemu_file_get_error(f);
802
803 if (f->ops->close) {
804 int ret2 = f->ops->close(f->opaque);
805 if (ret >= 0) {
806 ret = ret2;
807 }
808 }
809 /* If any error was spotted before closing, we should report it
810 * instead of the close() return value.
811 */
812 if (f->last_error) {
813 ret = f->last_error;
814 }
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100815 g_free(f);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700816 return ret;
817}
818
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100819static void add_to_iovec(QEMUFile *f, const uint8_t *buf, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700820{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100821 /* check for adjacent buffer and coalesce them */
822 if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base +
823 f->iov[f->iovcnt - 1].iov_len) {
824 f->iov[f->iovcnt - 1].iov_len += size;
825 } else {
826 f->iov[f->iovcnt].iov_base = (uint8_t *)buf;
827 f->iov[f->iovcnt++].iov_len = size;
828 }
829
830 if (f->iovcnt >= MAX_IOV_SIZE) {
831 qemu_fflush(f);
832 }
833}
834
835void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size)
836{
837 if (!f->ops->writev_buffer) {
838 qemu_put_buffer(f, buf, size);
839 return;
840 }
841
842 if (f->last_error) {
843 return;
844 }
845
846 f->bytes_xfer += size;
847 add_to_iovec(f, buf, size);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700848}
849
850void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
851{
852 int l;
853
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100854 if (f->last_error) {
855 return;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700856 }
857
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100858 while (size > 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700859 l = IO_BUF_SIZE - f->buf_index;
860 if (l > size)
861 l = size;
862 memcpy(f->buf + f->buf_index, buf, l);
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100863 f->bytes_xfer += l;
864 if (f->ops->writev_buffer) {
865 add_to_iovec(f, f->buf + f->buf_index, l);
866 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700867 f->buf_index += l;
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100868 if (f->buf_index == IO_BUF_SIZE) {
869 qemu_fflush(f);
870 }
871 if (qemu_file_get_error(f)) {
872 break;
873 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700874 buf += l;
875 size -= l;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700876 }
877}
878
879void qemu_put_byte(QEMUFile *f, int v)
880{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100881 if (f->last_error) {
882 return;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700883 }
884
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100885 f->buf[f->buf_index] = v;
886 f->bytes_xfer++;
887 if (f->ops->writev_buffer) {
888 add_to_iovec(f, f->buf + f->buf_index, 1);
889 }
890 f->buf_index++;
891 if (f->buf_index == IO_BUF_SIZE) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700892 qemu_fflush(f);
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100893 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700894}
895
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100896static void qemu_file_skip(QEMUFile *f, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700897{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100898 if (f->buf_index + size <= f->buf_size) {
899 f->buf_index += size;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700900 }
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100901}
902
903static int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset)
904{
905 int pending;
906 int index;
907
908 assert(!qemu_file_is_writable(f));
909
910 index = f->buf_index + offset;
911 pending = f->buf_size - index;
912 if (pending < size) {
913 qemu_fill_buffer(f);
914 index = f->buf_index + offset;
915 pending = f->buf_size - index;
916 }
917
918 if (pending <= 0) {
919 return 0;
920 }
921 if (size > pending) {
922 size = pending;
923 }
924
925 memcpy(buf, f->buf + index, size);
926 return size;
927}
928
929int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
930{
931 int pending = size;
932 int done = 0;
933
934 while (pending > 0) {
935 int res;
936
937 res = qemu_peek_buffer(f, buf, pending, 0);
938 if (res == 0) {
939 return done;
940 }
941 qemu_file_skip(f, res);
942 buf += res;
943 pending -= res;
944 done += res;
945 }
946 return done;
947}
948
949static int qemu_peek_byte(QEMUFile *f, int offset)
950{
951 int index = f->buf_index + offset;
952
953 assert(!qemu_file_is_writable(f));
954
955 if (index >= f->buf_size) {
956 qemu_fill_buffer(f);
957 index = f->buf_index + offset;
958 if (index >= f->buf_size) {
959 return 0;
960 }
961 }
962 return f->buf[index];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700963}
964
965int qemu_get_byte(QEMUFile *f)
966{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100967 int result;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700968
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +0100969 result = qemu_peek_byte(f, 0);
970 qemu_file_skip(f, 1);
971 return result;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700972}
973
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +0200974#ifdef CONFIG_ANDROID
975void qemu_put_string(QEMUFile *f, const char* str)
976{
977 /* We will encode NULL and the empty string in the same way */
978 int slen;
979 if (str == NULL) {
980 str = "";
981 }
982 slen = strlen(str);
983 qemu_put_be32(f, slen);
984 qemu_put_buffer(f, (const uint8_t*)str, slen);
985}
986
987char* qemu_get_string(QEMUFile *f)
988{
989 int slen = qemu_get_be32(f);
990 char* str;
991 if (slen == 0)
992 return NULL;
993
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100994 str = g_malloc(slen+1);
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +0200995 if (qemu_get_buffer(f, (uint8_t*)str, slen) != slen) {
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100996 g_free(str);
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +0200997 return NULL;
998 }
999 str[slen] = '\0';
1000 return str;
1001}
1002#endif
1003
1004
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001005int64_t qemu_ftell(QEMUFile *f)
1006{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001007 qemu_fflush(f);
1008 return f->pos;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001009}
1010
1011int qemu_file_rate_limit(QEMUFile *f)
1012{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001013 if (qemu_file_get_error(f)) {
1014 return 1;
1015 }
1016 if (f->xfer_limit > 0 && f->bytes_xfer > f->xfer_limit) {
1017 return 1;
1018 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001019 return 0;
1020}
1021
David 'Digit' Turner986acc92011-05-10 16:50:01 +02001022int64_t qemu_file_get_rate_limit(QEMUFile *f)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001023{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001024 return f->xfer_limit;
David 'Digit' Turner986acc92011-05-10 16:50:01 +02001025}
1026
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001027void qemu_file_set_rate_limit(QEMUFile *f, int64_t limit)
David 'Digit' Turner986acc92011-05-10 16:50:01 +02001028{
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001029 f->xfer_limit = limit;
1030}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001031
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001032void qemu_file_reset_rate_limit(QEMUFile *f)
1033{
1034 f->bytes_xfer = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001035}
1036
1037void qemu_put_be16(QEMUFile *f, unsigned int v)
1038{
1039 qemu_put_byte(f, v >> 8);
1040 qemu_put_byte(f, v);
1041}
1042
1043void qemu_put_be32(QEMUFile *f, unsigned int v)
1044{
1045 qemu_put_byte(f, v >> 24);
1046 qemu_put_byte(f, v >> 16);
1047 qemu_put_byte(f, v >> 8);
1048 qemu_put_byte(f, v);
1049}
1050
1051void qemu_put_be64(QEMUFile *f, uint64_t v)
1052{
1053 qemu_put_be32(f, v >> 32);
1054 qemu_put_be32(f, v);
1055}
1056
1057unsigned int qemu_get_be16(QEMUFile *f)
1058{
1059 unsigned int v;
1060 v = qemu_get_byte(f) << 8;
1061 v |= qemu_get_byte(f);
1062 return v;
1063}
1064
1065unsigned int qemu_get_be32(QEMUFile *f)
1066{
1067 unsigned int v;
1068 v = qemu_get_byte(f) << 24;
1069 v |= qemu_get_byte(f) << 16;
1070 v |= qemu_get_byte(f) << 8;
1071 v |= qemu_get_byte(f);
1072 return v;
1073}
1074
1075uint64_t qemu_get_be64(QEMUFile *f)
1076{
1077 uint64_t v;
1078 v = (uint64_t)qemu_get_be32(f) << 32;
1079 v |= qemu_get_be32(f);
1080 return v;
1081}
1082
David 'Digit' Turnerdcda9492014-02-16 15:13:55 +01001083
1084/* timer */
1085
1086void timer_put(QEMUFile *f, QEMUTimer *ts)
1087{
1088 uint64_t expire_time;
1089
1090 expire_time = timer_expire_time_ns(ts);
1091 qemu_put_be64(f, expire_time);
1092}
1093
1094void timer_get(QEMUFile *f, QEMUTimer *ts)
1095{
1096 uint64_t expire_time;
1097
1098 expire_time = qemu_get_be64(f);
1099 if (expire_time != -1) {
1100 timer_mod_ns(ts, expire_time);
1101 } else {
1102 timer_del(ts);
1103 }
1104}
1105
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001106void qemu_put_struct(QEMUFile* f, const QField* fields, const void* s)
1107{
1108 const QField* qf = fields;
1109
Ot ten Thije7fd67eb2010-07-29 10:26:01 +01001110 /* Iterate over struct fields */
1111 while (qf->type != Q_FIELD_END) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001112 uint8_t* p = (uint8_t*)s + qf->offset;
1113
1114 switch (qf->type) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001115 case Q_FIELD_BYTE:
1116 qemu_put_byte(f, p[0]);
1117 break;
1118 case Q_FIELD_INT16:
1119 qemu_put_be16(f, ((uint16_t*)p)[0]);
1120 break;
1121 case Q_FIELD_INT32:
1122 qemu_put_be32(f, ((uint32_t*)p)[0]);
1123 break;
1124 case Q_FIELD_INT64:
1125 qemu_put_be64(f, ((uint64_t*)p)[0]);
1126 break;
1127 case Q_FIELD_BUFFER:
Ot ten Thije7fd67eb2010-07-29 10:26:01 +01001128 if (qf[1].type != Q_FIELD_BUFFER_SIZE ||
1129 qf[2].type != Q_FIELD_BUFFER_SIZE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001130 {
1131 fprintf(stderr, "%s: invalid QFIELD_BUFFER item passed as argument. aborting\n",
1132 __FUNCTION__ );
1133 exit(1);
1134 }
1135 else
1136 {
Ot ten Thije7fd67eb2010-07-29 10:26:01 +01001137 uint32_t size = ((uint32_t)qf[1].offset << 16) | (uint32_t)qf[2].offset;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001138
1139 qemu_put_buffer(f, p, size);
1140 qf += 2;
1141 }
1142 break;
1143 default:
1144 fprintf(stderr, "%s: invalid fields list passed as argument. aborting\n", __FUNCTION__);
1145 exit(1);
1146 }
1147 qf++;
1148 }
1149}
1150
1151int qemu_get_struct(QEMUFile* f, const QField* fields, void* s)
1152{
1153 const QField* qf = fields;
1154
Ot ten Thije7fd67eb2010-07-29 10:26:01 +01001155 /* Iterate over struct fields */
1156 while (qf->type != Q_FIELD_END) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001157 uint8_t* p = (uint8_t*)s + qf->offset;
1158
1159 switch (qf->type) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001160 case Q_FIELD_BYTE:
1161 p[0] = qemu_get_byte(f);
1162 break;
1163 case Q_FIELD_INT16:
1164 ((uint16_t*)p)[0] = qemu_get_be16(f);
1165 break;
1166 case Q_FIELD_INT32:
1167 ((uint32_t*)p)[0] = qemu_get_be32(f);
1168 break;
1169 case Q_FIELD_INT64:
1170 ((uint64_t*)p)[0] = qemu_get_be64(f);
1171 break;
1172 case Q_FIELD_BUFFER:
Ot ten Thije7fd67eb2010-07-29 10:26:01 +01001173 if (qf[1].type != Q_FIELD_BUFFER_SIZE ||
1174 qf[2].type != Q_FIELD_BUFFER_SIZE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001175 {
1176 fprintf(stderr, "%s: invalid QFIELD_BUFFER item passed as argument.\n",
1177 __FUNCTION__ );
1178 return -1;
1179 }
1180 else
1181 {
Ot ten Thije7fd67eb2010-07-29 10:26:01 +01001182 uint32_t size = ((uint32_t)qf[1].offset << 16) | (uint32_t)qf[2].offset;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001183 int ret = qemu_get_buffer(f, p, size);
1184
1185 if (ret != size) {
1186 fprintf(stderr, "%s: not enough bytes to load structure\n", __FUNCTION__);
1187 return -1;
1188 }
1189 qf += 2;
1190 }
1191 break;
1192 default:
1193 fprintf(stderr, "%s: invalid fields list passed as argument. aborting\n", __FUNCTION__);
1194 exit(1);
1195 }
1196 qf++;
1197 }
1198 return 0;
1199}
1200
Ot ten Thije871da2a2010-09-20 10:29:22 +01001201/* write a float to file */
1202void qemu_put_float(QEMUFile *f, float v)
1203{
1204 uint8_t *bytes = (uint8_t*) &v;
1205 qemu_put_buffer(f, bytes, sizeof(float));
1206}
1207
1208/* read a float from file */
1209float qemu_get_float(QEMUFile *f)
1210{
1211 uint8_t bytes[sizeof(float)];
1212 qemu_get_buffer(f, bytes, sizeof(float));
1213
1214 return *((float*) bytes);
1215}
1216
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001217typedef struct SaveStateEntry {
1218 char idstr[256];
1219 int instance_id;
1220 int version_id;
1221 int section_id;
1222 SaveLiveStateHandler *save_live_state;
1223 SaveStateHandler *save_state;
1224 LoadStateHandler *load_state;
1225 void *opaque;
1226 struct SaveStateEntry *next;
1227} SaveStateEntry;
1228
1229static SaveStateEntry *first_se;
1230
1231/* TODO: Individual devices generally have very little idea about the rest
1232 of the system, so instance_id should be removed/replaced.
1233 Meanwhile pass -1 as instance_id if you do not already have a clearly
1234 distinguishing id for all instances of your device class. */
1235int register_savevm_live(const char *idstr,
1236 int instance_id,
1237 int version_id,
1238 SaveLiveStateHandler *save_live_state,
1239 SaveStateHandler *save_state,
1240 LoadStateHandler *load_state,
1241 void *opaque)
1242{
1243 SaveStateEntry *se, **pse;
1244 static int global_section_id;
1245
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001246 se = g_malloc(sizeof(SaveStateEntry));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001247 pstrcpy(se->idstr, sizeof(se->idstr), idstr);
1248 se->instance_id = (instance_id == -1) ? 0 : instance_id;
1249 se->version_id = version_id;
1250 se->section_id = global_section_id++;
1251 se->save_live_state = save_live_state;
1252 se->save_state = save_state;
1253 se->load_state = load_state;
1254 se->opaque = opaque;
1255 se->next = NULL;
1256
1257 /* add at the end of list */
1258 pse = &first_se;
1259 while (*pse != NULL) {
1260 if (instance_id == -1
1261 && strcmp(se->idstr, (*pse)->idstr) == 0
1262 && se->instance_id <= (*pse)->instance_id)
1263 se->instance_id = (*pse)->instance_id + 1;
1264 pse = &(*pse)->next;
1265 }
1266 *pse = se;
1267 return 0;
1268}
1269
1270int register_savevm(const char *idstr,
1271 int instance_id,
1272 int version_id,
1273 SaveStateHandler *save_state,
1274 LoadStateHandler *load_state,
1275 void *opaque)
1276{
1277 return register_savevm_live(idstr, instance_id, version_id,
1278 NULL, save_state, load_state, opaque);
1279}
1280
1281void unregister_savevm(const char *idstr, void *opaque)
1282{
1283 SaveStateEntry **pse;
1284
1285 pse = &first_se;
1286 while (*pse != NULL) {
1287 if (strcmp((*pse)->idstr, idstr) == 0 && (*pse)->opaque == opaque) {
1288 SaveStateEntry *next = (*pse)->next;
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001289 g_free(*pse);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001290 *pse = next;
1291 continue;
1292 }
1293 pse = &(*pse)->next;
1294 }
1295}
1296
1297#define QEMU_VM_FILE_MAGIC 0x5145564d
1298#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +02001299#define QEMU_VM_FILE_VERSION 0x00000004
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001300
1301#define QEMU_VM_EOF 0x00
1302#define QEMU_VM_SECTION_START 0x01
1303#define QEMU_VM_SECTION_PART 0x02
1304#define QEMU_VM_SECTION_END 0x03
1305#define QEMU_VM_SECTION_FULL 0x04
1306
1307int qemu_savevm_state_begin(QEMUFile *f)
1308{
1309 SaveStateEntry *se;
1310
1311 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1312 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1313
1314 for (se = first_se; se != NULL; se = se->next) {
1315 int len;
1316
1317 if (se->save_live_state == NULL)
1318 continue;
1319
1320 /* Section type */
1321 qemu_put_byte(f, QEMU_VM_SECTION_START);
1322 qemu_put_be32(f, se->section_id);
1323
1324 /* ID string */
1325 len = strlen(se->idstr);
1326 qemu_put_byte(f, len);
1327 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1328
1329 qemu_put_be32(f, se->instance_id);
1330 qemu_put_be32(f, se->version_id);
1331
1332 se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
1333 }
1334
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001335 return qemu_file_get_error(f);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001336}
1337
1338int qemu_savevm_state_iterate(QEMUFile *f)
1339{
1340 SaveStateEntry *se;
1341 int ret = 1;
1342
1343 for (se = first_se; se != NULL; se = se->next) {
1344 if (se->save_live_state == NULL)
1345 continue;
1346
1347 /* Section type */
1348 qemu_put_byte(f, QEMU_VM_SECTION_PART);
1349 qemu_put_be32(f, se->section_id);
1350
1351 ret &= !!se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque);
1352 }
1353
1354 if (ret)
1355 return 1;
1356
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001357 return qemu_file_get_error(f);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001358}
1359
1360int qemu_savevm_state_complete(QEMUFile *f)
1361{
1362 SaveStateEntry *se;
1363
1364 for (se = first_se; se != NULL; se = se->next) {
1365 if (se->save_live_state == NULL)
1366 continue;
1367
1368 /* Section type */
1369 qemu_put_byte(f, QEMU_VM_SECTION_END);
1370 qemu_put_be32(f, se->section_id);
1371
1372 se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);
1373 }
1374
1375 for(se = first_se; se != NULL; se = se->next) {
1376 int len;
1377
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001378 if (se->save_state == NULL)
1379 continue;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001380
1381 /* Section type */
1382 qemu_put_byte(f, QEMU_VM_SECTION_FULL);
1383 qemu_put_be32(f, se->section_id);
1384
1385 /* ID string */
1386 len = strlen(se->idstr);
1387 qemu_put_byte(f, len);
1388 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1389
1390 qemu_put_be32(f, se->instance_id);
1391 qemu_put_be32(f, se->version_id);
1392
1393 se->save_state(f, se->opaque);
1394 }
1395
1396 qemu_put_byte(f, QEMU_VM_EOF);
1397
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001398 return qemu_file_get_error(f);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001399}
1400
1401int qemu_savevm_state(QEMUFile *f)
1402{
1403 int saved_vm_running;
1404 int ret;
1405
1406 saved_vm_running = vm_running;
1407 vm_stop(0);
1408
1409 bdrv_flush_all();
1410
1411 ret = qemu_savevm_state_begin(f);
1412 if (ret < 0)
1413 goto out;
1414
1415 do {
1416 ret = qemu_savevm_state_iterate(f);
1417 if (ret < 0)
1418 goto out;
1419 } while (ret == 0);
1420
1421 ret = qemu_savevm_state_complete(f);
1422
1423out:
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001424 ret = qemu_file_get_error(f);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001425
1426 if (!ret && saved_vm_running)
1427 vm_start();
1428
1429 return ret;
1430}
1431
1432static SaveStateEntry *find_se(const char *idstr, int instance_id)
1433{
1434 SaveStateEntry *se;
1435
1436 for(se = first_se; se != NULL; se = se->next) {
1437 if (!strcmp(se->idstr, idstr) &&
1438 instance_id == se->instance_id)
1439 return se;
1440 }
1441 return NULL;
1442}
1443
1444typedef struct LoadStateEntry {
1445 SaveStateEntry *se;
1446 int section_id;
1447 int version_id;
1448 struct LoadStateEntry *next;
1449} LoadStateEntry;
1450
1451static int qemu_loadvm_state_v2(QEMUFile *f)
1452{
1453 SaveStateEntry *se;
1454 int len, ret, instance_id, record_len, version_id;
1455 int64_t total_len, end_pos, cur_pos;
1456 char idstr[256];
1457
1458 total_len = qemu_get_be64(f);
1459 end_pos = total_len + qemu_ftell(f);
1460 for(;;) {
1461 if (qemu_ftell(f) >= end_pos)
1462 break;
1463 len = qemu_get_byte(f);
1464 qemu_get_buffer(f, (uint8_t *)idstr, len);
1465 idstr[len] = '\0';
1466 instance_id = qemu_get_be32(f);
1467 version_id = qemu_get_be32(f);
1468 record_len = qemu_get_be32(f);
1469 cur_pos = qemu_ftell(f);
1470 se = find_se(idstr, instance_id);
1471 if (!se) {
1472 fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
1473 instance_id, idstr);
1474 } else {
1475 ret = se->load_state(f, se->opaque, version_id);
1476 if (ret < 0) {
1477 fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
1478 instance_id, idstr);
1479 return ret;
1480 }
1481 }
1482 /* always seek to exact end of record */
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001483 qemu_file_skip(f, cur_pos + record_len - qemu_ftell(f));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001484 }
1485
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001486 return qemu_file_get_error(f);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001487}
1488
1489int qemu_loadvm_state(QEMUFile *f)
1490{
1491 LoadStateEntry *first_le = NULL;
1492 uint8_t section_type;
1493 unsigned int v;
1494 int ret;
1495
1496 v = qemu_get_be32(f);
1497 if (v != QEMU_VM_FILE_MAGIC)
1498 return -EINVAL;
1499
1500 v = qemu_get_be32(f);
1501 if (v == QEMU_VM_FILE_VERSION_COMPAT)
1502 return qemu_loadvm_state_v2(f);
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +02001503 if (v < QEMU_VM_FILE_VERSION) {
1504 fprintf(stderr, "Snapshot format %d is too old for this version of the emulator, please create a new one.\n", v);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001505 return -ENOTSUP;
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +02001506 } else if (v > QEMU_VM_FILE_VERSION) {
1507 fprintf(stderr, "Snapshot format %d is more recent than the emulator, please update your Android SDK Tools.\n", v);
1508 return -ENOTSUP;
1509 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001510
1511 while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
1512 uint32_t instance_id, version_id, section_id;
1513 LoadStateEntry *le;
1514 SaveStateEntry *se;
1515 char idstr[257];
1516 int len;
1517
1518 switch (section_type) {
1519 case QEMU_VM_SECTION_START:
1520 case QEMU_VM_SECTION_FULL:
1521 /* Read section start */
1522 section_id = qemu_get_be32(f);
1523 len = qemu_get_byte(f);
1524 qemu_get_buffer(f, (uint8_t *)idstr, len);
1525 idstr[len] = 0;
1526 instance_id = qemu_get_be32(f);
1527 version_id = qemu_get_be32(f);
1528
1529 /* Find savevm section */
1530 se = find_se(idstr, instance_id);
1531 if (se == NULL) {
1532 fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
1533 ret = -EINVAL;
1534 goto out;
1535 }
1536
1537 /* Validate version */
1538 if (version_id > se->version_id) {
1539 fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
1540 version_id, idstr, se->version_id);
1541 ret = -EINVAL;
1542 goto out;
1543 }
1544
1545 /* Add entry */
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001546 le = g_malloc0(sizeof(*le));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001547
1548 le->se = se;
1549 le->section_id = section_id;
1550 le->version_id = version_id;
1551 le->next = first_le;
1552 first_le = le;
1553
Vladimir Chtchetkined0e28722011-10-05 14:25:07 -07001554 if (le->se->load_state(f, le->se->opaque, le->version_id)) {
1555 fprintf(stderr, "savevm: unable to load section %s\n", idstr);
1556 ret = -EINVAL;
1557 goto out;
1558 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001559 break;
1560 case QEMU_VM_SECTION_PART:
1561 case QEMU_VM_SECTION_END:
1562 section_id = qemu_get_be32(f);
1563
1564 for (le = first_le; le && le->section_id != section_id; le = le->next);
1565 if (le == NULL) {
1566 fprintf(stderr, "Unknown savevm section %d\n", section_id);
1567 ret = -EINVAL;
1568 goto out;
1569 }
1570
1571 le->se->load_state(f, le->se->opaque, le->version_id);
1572 break;
1573 default:
1574 fprintf(stderr, "Unknown savevm section type %d\n", section_type);
1575 ret = -EINVAL;
1576 goto out;
1577 }
1578 }
1579
1580 ret = 0;
1581
1582out:
1583 while (first_le) {
1584 LoadStateEntry *le = first_le;
1585 first_le = first_le->next;
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001586 g_free(le);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001587 }
1588
David 'Digit' Turnerc79de3c2014-01-23 04:17:24 +01001589 if (qemu_file_get_error(f))
1590 ret = qemu_file_get_error(f);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001591
1592 return ret;
1593}
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001594#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001595static BlockDriverState *get_bs_snapshots(void)
1596{
1597 BlockDriverState *bs;
1598 int i;
1599
1600 if (bs_snapshots)
1601 return bs_snapshots;
1602 for(i = 0; i <= nb_drives; i++) {
1603 bs = drives_table[i].bdrv;
1604 if (bdrv_can_snapshot(bs))
1605 goto ok;
1606 }
1607 return NULL;
1608 ok:
1609 bs_snapshots = bs;
1610 return bs;
1611}
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001612#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001613static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
1614 const char *name)
1615{
1616 QEMUSnapshotInfo *sn_tab, *sn;
1617 int nb_sns, i, ret;
1618
1619 ret = -ENOENT;
1620 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1621 if (nb_sns < 0)
1622 return ret;
1623 for(i = 0; i < nb_sns; i++) {
1624 sn = &sn_tab[i];
1625 if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
1626 *sn_info = *sn;
1627 ret = 0;
1628 break;
1629 }
1630 }
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001631 g_free(sn_tab);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001632 return ret;
1633}
1634
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001635void do_savevm(Monitor *err, const char *name)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001636{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001637 BlockDriverState *bs, *bs1;
1638 QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001639 int must_delete, ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001640 BlockDriverInfo bdi1, *bdi = &bdi1;
1641 QEMUFile *f;
1642 int saved_vm_running;
1643 uint32_t vm_state_size;
1644#ifdef _WIN32
1645 struct _timeb tb;
1646#else
1647 struct timeval tv;
1648#endif
1649
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001650 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001651 if (!bs) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001652 monitor_printf(err, "No block device can accept snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001653 return;
1654 }
1655
1656 /* ??? Should this occur after vm_stop? */
1657 qemu_aio_flush();
1658
1659 saved_vm_running = vm_running;
1660 vm_stop(0);
1661
1662 must_delete = 0;
1663 if (name) {
1664 ret = bdrv_snapshot_find(bs, old_sn, name);
1665 if (ret >= 0) {
1666 must_delete = 1;
1667 }
1668 }
1669 memset(sn, 0, sizeof(*sn));
1670 if (must_delete) {
1671 pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
1672 pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
1673 } else {
1674 if (name)
1675 pstrcpy(sn->name, sizeof(sn->name), name);
1676 }
1677
1678 /* fill auxiliary fields */
1679#ifdef _WIN32
1680 _ftime(&tb);
1681 sn->date_sec = tb.time;
1682 sn->date_nsec = tb.millitm * 1000000;
1683#else
1684 gettimeofday(&tv, NULL);
1685 sn->date_sec = tv.tv_sec;
1686 sn->date_nsec = tv.tv_usec * 1000;
1687#endif
David 'Digit' Turnerdcda9492014-02-16 15:13:55 +01001688 sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001689
1690 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001691 monitor_printf(err, "Device %s does not support VM state snapshots\n",
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001692 bdrv_get_device_name(bs));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001693 goto the_end;
1694 }
1695
1696 /* save the VM state */
David 'Digit' Turner986acc92011-05-10 16:50:01 +02001697 f = qemu_fopen_bdrv(bs, 1);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001698 if (!f) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001699 monitor_printf(err, "Could not open VM state file\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001700 goto the_end;
1701 }
1702 ret = qemu_savevm_state(f);
1703 vm_state_size = qemu_ftell(f);
1704 qemu_fclose(f);
1705 if (ret < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001706 monitor_printf(err, "Error %d while writing VM\n", ret);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001707 goto the_end;
1708 }
1709
1710 /* create the snapshots */
1711
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001712 bs1 = NULL;
1713 while ((bs1 = bdrv_next(bs1))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001714 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001715 if (must_delete) {
1716 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
1717 if (ret < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001718 monitor_printf(err,
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001719 "Error while deleting snapshot on '%s'\n",
1720 bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001721 }
1722 }
1723 /* Write VM state size only to the image that contains the state */
1724 sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
1725 ret = bdrv_snapshot_create(bs1, sn);
1726 if (ret < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001727 monitor_printf(err, "Error while creating snapshot on '%s'\n",
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001728 bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001729 }
1730 }
1731 }
1732
1733 the_end:
1734 if (saved_vm_running)
1735 vm_start();
1736}
1737
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001738void do_loadvm(Monitor *err, const char *name)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001739{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001740 BlockDriverState *bs, *bs1;
1741 BlockDriverInfo bdi1, *bdi = &bdi1;
1742 QEMUSnapshotInfo sn;
1743 QEMUFile *f;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001744 int ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001745 int saved_vm_running;
1746
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001747 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001748 if (!bs) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001749 monitor_printf(err, "No block device supports snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001750 return;
1751 }
1752
1753 /* Flush all IO requests so they don't interfere with the new state. */
1754 qemu_aio_flush();
1755
1756 saved_vm_running = vm_running;
1757 vm_stop(0);
1758
Vladimir Chtchetkine05e07482012-02-03 10:02:50 -08001759 bs1 = bs;
1760 do {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001761 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001762 ret = bdrv_snapshot_goto(bs1, name);
1763 if (ret < 0) {
1764 if (bs != bs1)
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001765 monitor_printf(err, "Warning: ");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001766 switch(ret) {
1767 case -ENOTSUP:
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001768 monitor_printf(err,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001769 "Snapshots not supported on device '%s'\n",
1770 bdrv_get_device_name(bs1));
1771 break;
1772 case -ENOENT:
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001773 monitor_printf(err, "Could not find snapshot '%s' on "
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001774 "device '%s'\n",
1775 name, bdrv_get_device_name(bs1));
1776 break;
1777 default:
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001778 monitor_printf(err, "Error %d while activating snapshot on"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001779 " '%s'\n", ret, bdrv_get_device_name(bs1));
1780 break;
1781 }
1782 /* fatal on snapshot block device */
1783 if (bs == bs1)
1784 goto the_end;
1785 }
1786 }
Vladimir Chtchetkine05e07482012-02-03 10:02:50 -08001787 } while ((bs1 = bdrv_next(bs)));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001788
1789 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001790 monitor_printf(err, "Device %s does not support VM state snapshots\n",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001791 bdrv_get_device_name(bs));
1792 return;
1793 }
1794
1795 /* Don't even try to load empty VM states */
1796 ret = bdrv_snapshot_find(bs, &sn, name);
1797 if ((ret >= 0) && (sn.vm_state_size == 0))
1798 goto the_end;
1799
1800 /* restore the VM state */
David 'Digit' Turner986acc92011-05-10 16:50:01 +02001801 f = qemu_fopen_bdrv(bs, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001802 if (!f) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001803 monitor_printf(err, "Could not open VM state file\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001804 goto the_end;
1805 }
1806 ret = qemu_loadvm_state(f);
1807 qemu_fclose(f);
1808 if (ret < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001809 monitor_printf(err, "Error %d while loading VM state\n", ret);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001810 }
1811 the_end:
1812 if (saved_vm_running)
1813 vm_start();
1814}
1815
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001816void do_delvm(Monitor *err, const char *name)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001817{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001818 BlockDriverState *bs, *bs1;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001819 int ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001820
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001821 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001822 if (!bs) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001823 monitor_printf(err, "No block device supports snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001824 return;
1825 }
1826
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001827 bs1 = NULL;
1828 while ((bs1 = bdrv_next(bs1))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001829 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001830 ret = bdrv_snapshot_delete(bs1, name);
1831 if (ret < 0) {
1832 if (ret == -ENOTSUP)
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001833 monitor_printf(err,
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001834 "Snapshots not supported on device '%s'\n",
1835 bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001836 else
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001837 monitor_printf(err, "Error %d while deleting snapshot on "
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001838 "'%s'\n", ret, bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001839 }
1840 }
1841 }
1842}
1843
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001844void do_info_snapshots(Monitor* out, Monitor* err)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001845{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001846 BlockDriverState *bs, *bs1;
1847 QEMUSnapshotInfo *sn_tab, *sn;
1848 int nb_sns, i;
1849 char buf[256];
1850
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001851 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001852 if (!bs) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001853 monitor_printf(err, "No available block device supports snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001854 return;
1855 }
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001856 monitor_printf(out, "Snapshot devices:");
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001857 bs1 = NULL;
1858 while ((bs1 = bdrv_next(bs1))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001859 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001860 if (bs == bs1)
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001861 monitor_printf(out, " %s", bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001862 }
1863 }
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001864 monitor_printf(out, "\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001865
1866 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1867 if (nb_sns < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001868 monitor_printf(err, "bdrv_snapshot_list: error %d\n", nb_sns);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001869 return;
1870 }
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001871 monitor_printf(out, "Snapshot list (from %s):\n",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001872 bdrv_get_device_name(bs));
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001873 monitor_printf(out, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001874 for(i = 0; i < nb_sns; i++) {
1875 sn = &sn_tab[i];
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001876 monitor_printf(out, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001877 }
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001878 g_free(sn_tab);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001879}