blob: e344fe8d59dc08a6e3254618fd482e6ced402125 [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' Turner7a78db72013-12-14 11:46:01 +010078#include "qemu/timer.h"
David 'Digit' Turnere7216d82013-12-15 00:51:13 +010079#include "sysemu/char.h"
David 'Digit' Turner34c48ff2013-12-15 00:25:03 +010080#include "sysemu/blockdev.h"
David 'Digit' Turnere1e03df2013-12-15 00:42:21 +010081#include "block/block.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070082#include "audio/audio.h"
David 'Digit' Turner28a09b62013-12-15 00:16:00 +010083#include "migration/migration.h"
David 'Digit' Turnerd0edecb2013-12-17 09:32:26 +010084#include "qemu/sockets.h"
David 'Digit' Turner031d6552013-12-15 00:52:36 +010085#include "qemu/queue.h"
David 'Digit' Turner28a09b62013-12-15 00:16:00 +010086#include "migration/qemu-file.h"
Tim Baverstock622b8f42010-12-07 11:36:59 +000087#include "android/snapshot.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070088
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070089
90#define SELF_ANNOUNCE_ROUNDS 5
David 'Digit' Turner986acc92011-05-10 16:50:01 +020091
92#ifndef ETH_P_RARP
93#define ETH_P_RARP 0x8035
94#endif
95#define ARP_HTYPE_ETH 0x0001
96#define ARP_PTYPE_IP 0x0800
97#define ARP_OP_REQUEST_REV 0x3
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070098
David 'Digit' Turner5973c772011-05-10 07:06:00 +020099static int announce_self_create(uint8_t *buf,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700100 uint8_t *mac_addr)
101{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200102 /* Ethernet header. */
103 memset(buf, 0xff, 6); /* destination MAC addr */
104 memcpy(buf + 6, mac_addr, 6); /* source MAC addr */
105 *(uint16_t *)(buf + 12) = htons(ETH_P_RARP); /* ethertype */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700106
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200107 /* RARP header. */
108 *(uint16_t *)(buf + 14) = htons(ARP_HTYPE_ETH); /* hardware addr space */
109 *(uint16_t *)(buf + 16) = htons(ARP_PTYPE_IP); /* protocol addr space */
110 *(buf + 18) = 6; /* hardware addr length (ethernet) */
111 *(buf + 19) = 4; /* protocol addr length (IPv4) */
112 *(uint16_t *)(buf + 20) = htons(ARP_OP_REQUEST_REV); /* opcode */
113 memcpy(buf + 22, mac_addr, 6); /* source hw addr */
114 memset(buf + 28, 0x00, 4); /* source protocol addr */
115 memcpy(buf + 32, mac_addr, 6); /* target hw addr */
116 memset(buf + 38, 0x00, 4); /* target protocol addr */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700117
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200118 /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
119 memset(buf + 42, 0x00, 18);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700120
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200121 return 60; /* len (FCS will be added by hardware) */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700122}
123
124static void qemu_announce_self_once(void *opaque)
125{
126 int i, len;
127 VLANState *vlan;
128 VLANClientState *vc;
129 uint8_t buf[256];
130 static int count = SELF_ANNOUNCE_ROUNDS;
131 QEMUTimer *timer = *(QEMUTimer **)opaque;
132
133 for (i = 0; i < MAX_NICS; i++) {
134 if (!nd_table[i].used)
135 continue;
136 len = announce_self_create(buf, nd_table[i].macaddr);
137 vlan = nd_table[i].vlan;
138 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
139 vc->receive(vc, buf, len);
140 }
141 }
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200142 if (--count) {
143 /* delay 50ms, 150ms, 250ms, ... */
144 qemu_mod_timer(timer, qemu_get_clock_ms(rt_clock) +
145 50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700146 } else {
147 qemu_del_timer(timer);
148 qemu_free_timer(timer);
149 }
150}
151
152void qemu_announce_self(void)
153{
154 static QEMUTimer *timer;
David 'Digit' Turner5973c772011-05-10 07:06:00 +0200155 timer = qemu_new_timer_ms(rt_clock, qemu_announce_self_once, &timer);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700156 qemu_announce_self_once(&timer);
157}
158
159/***********************************************************/
160/* savevm/loadvm support */
161
162#define IO_BUF_SIZE 32768
163
164struct QEMUFile {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100165 const QEMUFileOps* ops;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700166 void *opaque;
167 int is_write;
168
169 int64_t buf_offset; /* start of buffer when writing, end of buffer
170 when reading */
171 int buf_index;
172 int buf_size; /* 0 when writing */
173 uint8_t buf[IO_BUF_SIZE];
174
175 int has_error;
176};
177
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200178typedef struct QEMUFileStdio
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700179{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200180 FILE *stdio_file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700181 QEMUFile *file;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200182} QEMUFileStdio;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700183
184typedef struct QEMUFileSocket
185{
186 int fd;
187 QEMUFile *file;
188} QEMUFileSocket;
189
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100190static int socket_get_fd(void *opaque)
191{
192 QEMUFileSocket *s = opaque;
193
194 return s->fd;
195}
196
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200197static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700198{
199 QEMUFileSocket *s = opaque;
200 ssize_t len;
201
202 do {
203 len = recv(s->fd, (void *)buf, size, 0);
204 } while (len == -1 && socket_error() == EINTR);
205
206 if (len == -1)
207 len = -socket_error();
208
209 return len;
210}
211
212static int file_socket_close(void *opaque)
213{
214 QEMUFileSocket *s = opaque;
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100215 if (s->fd >= 0)
216 socket_close(s->fd);
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100217 g_free(s);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700218 return 0;
219}
220
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100221static int stdio_get_fd(void* opaque)
222{
223 QEMUFileStdio *s = opaque;
224 return fileno(s->stdio_file);
225}
226
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200227static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700228{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200229 QEMUFileStdio *s = opaque;
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100230 fseek(s->stdio_file, pos, SEEK_SET);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200231 return fwrite(buf, 1, size, s->stdio_file);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700232}
233
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200234static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700235{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200236 QEMUFileStdio *s = opaque;
237 FILE *fp = s->stdio_file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700238 int bytes;
239
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100240 fseek(s->stdio_file, pos, SEEK_SET);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700241 do {
242 clearerr(fp);
243 bytes = fread(buf, 1, size, fp);
244 } while ((bytes == 0) && ferror(fp) && (errno == EINTR));
245 return bytes;
246}
247
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200248static int stdio_pclose(void *opaque)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700249{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200250 QEMUFileStdio *s = opaque;
251 int ret;
252 ret = pclose(s->stdio_file);
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100253 g_free(s);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200254 return ret;
255}
256
257static int stdio_fclose(void *opaque)
258{
259 QEMUFileStdio *s = opaque;
260 fclose(s->stdio_file);
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100261 g_free(s);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700262 return 0;
263}
264
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100265static const QEMUFileOps stdio_pipe_read_ops = {
266 .get_fd = stdio_get_fd,
267 .get_buffer = stdio_get_buffer,
268 .close = stdio_pclose
269};
270
271static const QEMUFileOps stdio_pipe_write_ops = {
272 .get_fd = stdio_get_fd,
273 .put_buffer = stdio_put_buffer,
274 .close = stdio_pclose
275};
276
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200277QEMUFile *qemu_popen(FILE *stdio_file, const char *mode)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700278{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200279 QEMUFileStdio *s;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700280
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200281 if (stdio_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700282 fprintf(stderr, "qemu_popen: Argument validity check failed\n");
283 return NULL;
284 }
285
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100286 s = g_malloc0(sizeof(QEMUFileStdio));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700287
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200288 s->stdio_file = stdio_file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700289
290 if(mode[0] == 'r') {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100291 s->file = qemu_fopen_ops(s, &stdio_pipe_read_ops);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700292 } else {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100293 s->file = qemu_fopen_ops(s, &stdio_pipe_write_ops);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700294 }
295 return s->file;
296}
297
298QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
299{
300 FILE *popen_file;
301
302 popen_file = popen(command, mode);
303 if(popen_file == NULL) {
304 return NULL;
305 }
306
307 return qemu_popen(popen_file, mode);
308}
309
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100310int qemu_get_fd(QEMUFile *f)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700311{
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100312 if (f->ops->get_fd)
313 return f->ops->get_fd(f->opaque);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700314
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100315 return -1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700316}
317
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100318static const QEMUFileOps stdio_file_read_ops = {
319 .get_fd = stdio_get_fd,
320 .get_buffer = stdio_get_buffer,
321 .close = stdio_fclose
322};
323
324static const QEMUFileOps stdio_file_write_ops = {
325 .get_fd = stdio_get_fd,
326 .put_buffer = stdio_put_buffer,
327 .close = stdio_fclose
328};
329
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200330QEMUFile *qemu_fdopen(int fd, const char *mode)
331{
332 QEMUFileStdio *s;
333
334 if (mode == NULL ||
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100335 (mode[0] != 'r' && mode[0] != 'w') ||
336 mode[1] != 'b' || mode[2] != 0) {
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200337 fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
338 return NULL;
339 }
340
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100341 s = g_malloc0(sizeof(QEMUFileStdio));
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200342 s->stdio_file = fdopen(fd, mode);
343 if (!s->stdio_file)
344 goto fail;
345
346 if(mode[0] == 'r') {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100347 s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200348 } else {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100349 s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200350 }
351 return s->file;
352
353fail:
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100354 g_free(s);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200355 return NULL;
356}
357
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100358static const QEMUFileOps socket_read_ops = {
359 .get_fd = socket_get_fd,
360 .get_buffer = socket_get_buffer,
361 .close = file_socket_close
362};
363
364static const QEMUFileOps socket_write_ops = {
365 .get_fd = socket_get_fd,
366 .close = file_socket_close
367};
368
369QEMUFile *qemu_fopen_socket(int fd, const char* mode)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700370{
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100371 QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700372
373 s->fd = fd;
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100374 if (mode[0] == 'r')
375 s->file = qemu_fopen_ops(s, &socket_read_ops);
376 else
377 s->file = qemu_fopen_ops(s, &socket_write_ops);
378
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700379 return s->file;
380}
381
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100382bool qemu_file_mode_is_not_valid(const char *mode)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700383{
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100384 if (mode == NULL ||
385 (mode[0] != 'r' && mode[0] != 'w') ||
386 mode[1] != 'b' || mode[2] != 0) {
387 fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
388 return true;
389 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700390
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100391 return false;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700392}
393
394QEMUFile *qemu_fopen(const char *filename, const char *mode)
395{
396 QEMUFileStdio *s;
397
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100398 if (qemu_file_mode_is_not_valid(mode)) {
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200399 return NULL;
400 }
401
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100402 s = g_malloc0(sizeof(QEMUFileStdio));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700403
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200404 s->stdio_file = fopen(filename, mode);
405 if (!s->stdio_file)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700406 goto fail;
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +0200407
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200408 if(mode[0] == 'w') {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100409 s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200410 } else {
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100411 s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200412 }
413 return s->file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700414fail:
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100415 g_free(s);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700416 return NULL;
417}
418
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700419static int block_put_buffer(void *opaque, const uint8_t *buf,
420 int64_t pos, int size)
421{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200422 bdrv_save_vmstate(opaque, buf, pos, size);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700423 return size;
424}
425
426static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
427{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200428 return bdrv_load_vmstate(opaque, buf, pos, size);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700429}
430
431static int bdrv_fclose(void *opaque)
432{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700433 return 0;
434}
435
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100436static const QEMUFileOps bdrv_file_read_ops = {
437 .get_buffer = block_get_buffer,
438 .close = bdrv_fclose,
439};
440
441static const QEMUFileOps bdrv_file_write_opts = {
442 .put_buffer = block_put_buffer,
443 .close = bdrv_fclose,
444};
445
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200446static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700447{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700448 if (is_writable)
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100449 return qemu_fopen_ops(bs, &bdrv_file_write_opts);
450 else
451 return qemu_fopen_ops(bs, &bdrv_file_read_ops);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700452}
453
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100454QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps* file_ops)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700455{
456 QEMUFile *f;
457
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100458 f = g_malloc0(sizeof(QEMUFile));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700459
460 f->opaque = opaque;
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100461 f->ops = file_ops;
462 f->is_write = (file_ops->put_buffer != NULL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700463
464 return f;
465}
466
467int qemu_file_has_error(QEMUFile *f)
468{
469 return f->has_error;
470}
471
472void qemu_file_set_error(QEMUFile *f)
473{
474 f->has_error = 1;
475}
476
477void qemu_fflush(QEMUFile *f)
478{
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100479 if (!f->ops->put_buffer)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700480 return;
481
482 if (f->is_write && f->buf_index > 0) {
483 int len;
484
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100485 len = f->ops->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700486 if (len > 0)
487 f->buf_offset += f->buf_index;
488 else
489 f->has_error = 1;
490 f->buf_index = 0;
491 }
492}
493
494static void qemu_fill_buffer(QEMUFile *f)
495{
496 int len;
497
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100498 if (!f->ops->get_buffer)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700499 return;
500
501 if (f->is_write)
502 abort();
503
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100504 len = f->ops->get_buffer(f->opaque, f->buf, f->buf_offset, IO_BUF_SIZE);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700505 if (len > 0) {
506 f->buf_index = 0;
507 f->buf_size = len;
508 f->buf_offset += len;
509 } else if (len != -EAGAIN)
510 f->has_error = 1;
511}
512
513int qemu_fclose(QEMUFile *f)
514{
515 int ret = 0;
516 qemu_fflush(f);
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100517 if (f->ops->close)
518 ret = f->ops->close(f->opaque);
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100519 g_free(f);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700520 return ret;
521}
522
523void qemu_file_put_notify(QEMUFile *f)
524{
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100525 f->ops->put_buffer(f->opaque, NULL, 0, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700526}
527
528void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
529{
530 int l;
531
532 if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
533 fprintf(stderr,
534 "Attempted to write to buffer while read buffer is not empty\n");
535 abort();
536 }
537
538 while (!f->has_error && size > 0) {
539 l = IO_BUF_SIZE - f->buf_index;
540 if (l > size)
541 l = size;
542 memcpy(f->buf + f->buf_index, buf, l);
543 f->is_write = 1;
544 f->buf_index += l;
545 buf += l;
546 size -= l;
547 if (f->buf_index >= IO_BUF_SIZE)
548 qemu_fflush(f);
549 }
550}
551
552void qemu_put_byte(QEMUFile *f, int v)
553{
554 if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
555 fprintf(stderr,
556 "Attempted to write to buffer while read buffer is not empty\n");
557 abort();
558 }
559
560 f->buf[f->buf_index++] = v;
561 f->is_write = 1;
562 if (f->buf_index >= IO_BUF_SIZE)
563 qemu_fflush(f);
564}
565
566int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
567{
568 int size, l;
569
570 if (f->is_write)
571 abort();
572
573 size = size1;
574 while (size > 0) {
575 l = f->buf_size - f->buf_index;
576 if (l == 0) {
577 qemu_fill_buffer(f);
578 l = f->buf_size - f->buf_index;
579 if (l == 0)
580 break;
581 }
582 if (l > size)
583 l = size;
584 memcpy(buf, f->buf + f->buf_index, l);
585 f->buf_index += l;
586 buf += l;
587 size -= l;
588 }
589 return size1 - size;
590}
591
592int qemu_get_byte(QEMUFile *f)
593{
594 if (f->is_write)
595 abort();
596
597 if (f->buf_index >= f->buf_size) {
598 qemu_fill_buffer(f);
599 if (f->buf_index >= f->buf_size)
600 return 0;
601 }
602 return f->buf[f->buf_index++];
603}
604
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +0200605#ifdef CONFIG_ANDROID
606void qemu_put_string(QEMUFile *f, const char* str)
607{
608 /* We will encode NULL and the empty string in the same way */
609 int slen;
610 if (str == NULL) {
611 str = "";
612 }
613 slen = strlen(str);
614 qemu_put_be32(f, slen);
615 qemu_put_buffer(f, (const uint8_t*)str, slen);
616}
617
618char* qemu_get_string(QEMUFile *f)
619{
620 int slen = qemu_get_be32(f);
621 char* str;
622 if (slen == 0)
623 return NULL;
624
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100625 str = g_malloc(slen+1);
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +0200626 if (qemu_get_buffer(f, (uint8_t*)str, slen) != slen) {
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100627 g_free(str);
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +0200628 return NULL;
629 }
630 str[slen] = '\0';
631 return str;
632}
633#endif
634
635
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700636int64_t qemu_ftell(QEMUFile *f)
637{
638 return f->buf_offset - f->buf_size + f->buf_index;
639}
640
641int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
642{
643 if (whence == SEEK_SET) {
644 /* nothing to do */
645 } else if (whence == SEEK_CUR) {
646 pos += qemu_ftell(f);
647 } else {
648 /* SEEK_END not supported */
649 return -1;
650 }
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100651 if (f->ops->put_buffer) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700652 qemu_fflush(f);
653 f->buf_offset = pos;
654 } else {
655 f->buf_offset = pos;
656 f->buf_index = 0;
657 f->buf_size = 0;
658 }
659 return pos;
660}
661
662int qemu_file_rate_limit(QEMUFile *f)
663{
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100664 if (f->ops->rate_limit)
665 return f->ops->rate_limit(f->opaque);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700666
667 return 0;
668}
669
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200670int64_t qemu_file_get_rate_limit(QEMUFile *f)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700671{
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100672 if (f->ops->get_rate_limit)
673 return f->ops->get_rate_limit(f->opaque);
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200674
675 return 0;
676}
677
678int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate)
679{
680 /* any failed or completed migration keeps its state to allow probing of
681 * migration data, but has no associated file anymore */
David 'Digit' Turner0e051542014-01-23 02:41:42 +0100682 if (f && f->ops->set_rate_limit)
683 return f->ops->set_rate_limit(f->opaque, new_rate);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700684
685 return 0;
686}
687
688void qemu_put_be16(QEMUFile *f, unsigned int v)
689{
690 qemu_put_byte(f, v >> 8);
691 qemu_put_byte(f, v);
692}
693
694void qemu_put_be32(QEMUFile *f, unsigned int v)
695{
696 qemu_put_byte(f, v >> 24);
697 qemu_put_byte(f, v >> 16);
698 qemu_put_byte(f, v >> 8);
699 qemu_put_byte(f, v);
700}
701
702void qemu_put_be64(QEMUFile *f, uint64_t v)
703{
704 qemu_put_be32(f, v >> 32);
705 qemu_put_be32(f, v);
706}
707
708unsigned int qemu_get_be16(QEMUFile *f)
709{
710 unsigned int v;
711 v = qemu_get_byte(f) << 8;
712 v |= qemu_get_byte(f);
713 return v;
714}
715
716unsigned int qemu_get_be32(QEMUFile *f)
717{
718 unsigned int v;
719 v = qemu_get_byte(f) << 24;
720 v |= qemu_get_byte(f) << 16;
721 v |= qemu_get_byte(f) << 8;
722 v |= qemu_get_byte(f);
723 return v;
724}
725
726uint64_t qemu_get_be64(QEMUFile *f)
727{
728 uint64_t v;
729 v = (uint64_t)qemu_get_be32(f) << 32;
730 v |= qemu_get_be32(f);
731 return v;
732}
733
734void qemu_put_struct(QEMUFile* f, const QField* fields, const void* s)
735{
736 const QField* qf = fields;
737
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100738 /* Iterate over struct fields */
739 while (qf->type != Q_FIELD_END) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700740 uint8_t* p = (uint8_t*)s + qf->offset;
741
742 switch (qf->type) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700743 case Q_FIELD_BYTE:
744 qemu_put_byte(f, p[0]);
745 break;
746 case Q_FIELD_INT16:
747 qemu_put_be16(f, ((uint16_t*)p)[0]);
748 break;
749 case Q_FIELD_INT32:
750 qemu_put_be32(f, ((uint32_t*)p)[0]);
751 break;
752 case Q_FIELD_INT64:
753 qemu_put_be64(f, ((uint64_t*)p)[0]);
754 break;
755 case Q_FIELD_BUFFER:
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100756 if (qf[1].type != Q_FIELD_BUFFER_SIZE ||
757 qf[2].type != Q_FIELD_BUFFER_SIZE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700758 {
759 fprintf(stderr, "%s: invalid QFIELD_BUFFER item passed as argument. aborting\n",
760 __FUNCTION__ );
761 exit(1);
762 }
763 else
764 {
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100765 uint32_t size = ((uint32_t)qf[1].offset << 16) | (uint32_t)qf[2].offset;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700766
767 qemu_put_buffer(f, p, size);
768 qf += 2;
769 }
770 break;
771 default:
772 fprintf(stderr, "%s: invalid fields list passed as argument. aborting\n", __FUNCTION__);
773 exit(1);
774 }
775 qf++;
776 }
777}
778
779int qemu_get_struct(QEMUFile* f, const QField* fields, void* s)
780{
781 const QField* qf = fields;
782
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100783 /* Iterate over struct fields */
784 while (qf->type != Q_FIELD_END) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700785 uint8_t* p = (uint8_t*)s + qf->offset;
786
787 switch (qf->type) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700788 case Q_FIELD_BYTE:
789 p[0] = qemu_get_byte(f);
790 break;
791 case Q_FIELD_INT16:
792 ((uint16_t*)p)[0] = qemu_get_be16(f);
793 break;
794 case Q_FIELD_INT32:
795 ((uint32_t*)p)[0] = qemu_get_be32(f);
796 break;
797 case Q_FIELD_INT64:
798 ((uint64_t*)p)[0] = qemu_get_be64(f);
799 break;
800 case Q_FIELD_BUFFER:
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100801 if (qf[1].type != Q_FIELD_BUFFER_SIZE ||
802 qf[2].type != Q_FIELD_BUFFER_SIZE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700803 {
804 fprintf(stderr, "%s: invalid QFIELD_BUFFER item passed as argument.\n",
805 __FUNCTION__ );
806 return -1;
807 }
808 else
809 {
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100810 uint32_t size = ((uint32_t)qf[1].offset << 16) | (uint32_t)qf[2].offset;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700811 int ret = qemu_get_buffer(f, p, size);
812
813 if (ret != size) {
814 fprintf(stderr, "%s: not enough bytes to load structure\n", __FUNCTION__);
815 return -1;
816 }
817 qf += 2;
818 }
819 break;
820 default:
821 fprintf(stderr, "%s: invalid fields list passed as argument. aborting\n", __FUNCTION__);
822 exit(1);
823 }
824 qf++;
825 }
826 return 0;
827}
828
Ot ten Thije871da2a2010-09-20 10:29:22 +0100829/* write a float to file */
830void qemu_put_float(QEMUFile *f, float v)
831{
832 uint8_t *bytes = (uint8_t*) &v;
833 qemu_put_buffer(f, bytes, sizeof(float));
834}
835
836/* read a float from file */
837float qemu_get_float(QEMUFile *f)
838{
839 uint8_t bytes[sizeof(float)];
840 qemu_get_buffer(f, bytes, sizeof(float));
841
842 return *((float*) bytes);
843}
844
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700845typedef struct SaveStateEntry {
846 char idstr[256];
847 int instance_id;
848 int version_id;
849 int section_id;
850 SaveLiveStateHandler *save_live_state;
851 SaveStateHandler *save_state;
852 LoadStateHandler *load_state;
853 void *opaque;
854 struct SaveStateEntry *next;
855} SaveStateEntry;
856
857static SaveStateEntry *first_se;
858
859/* TODO: Individual devices generally have very little idea about the rest
860 of the system, so instance_id should be removed/replaced.
861 Meanwhile pass -1 as instance_id if you do not already have a clearly
862 distinguishing id for all instances of your device class. */
863int register_savevm_live(const char *idstr,
864 int instance_id,
865 int version_id,
866 SaveLiveStateHandler *save_live_state,
867 SaveStateHandler *save_state,
868 LoadStateHandler *load_state,
869 void *opaque)
870{
871 SaveStateEntry *se, **pse;
872 static int global_section_id;
873
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100874 se = g_malloc(sizeof(SaveStateEntry));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700875 pstrcpy(se->idstr, sizeof(se->idstr), idstr);
876 se->instance_id = (instance_id == -1) ? 0 : instance_id;
877 se->version_id = version_id;
878 se->section_id = global_section_id++;
879 se->save_live_state = save_live_state;
880 se->save_state = save_state;
881 se->load_state = load_state;
882 se->opaque = opaque;
883 se->next = NULL;
884
885 /* add at the end of list */
886 pse = &first_se;
887 while (*pse != NULL) {
888 if (instance_id == -1
889 && strcmp(se->idstr, (*pse)->idstr) == 0
890 && se->instance_id <= (*pse)->instance_id)
891 se->instance_id = (*pse)->instance_id + 1;
892 pse = &(*pse)->next;
893 }
894 *pse = se;
895 return 0;
896}
897
898int register_savevm(const char *idstr,
899 int instance_id,
900 int version_id,
901 SaveStateHandler *save_state,
902 LoadStateHandler *load_state,
903 void *opaque)
904{
905 return register_savevm_live(idstr, instance_id, version_id,
906 NULL, save_state, load_state, opaque);
907}
908
909void unregister_savevm(const char *idstr, void *opaque)
910{
911 SaveStateEntry **pse;
912
913 pse = &first_se;
914 while (*pse != NULL) {
915 if (strcmp((*pse)->idstr, idstr) == 0 && (*pse)->opaque == opaque) {
916 SaveStateEntry *next = (*pse)->next;
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100917 g_free(*pse);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700918 *pse = next;
919 continue;
920 }
921 pse = &(*pse)->next;
922 }
923}
924
925#define QEMU_VM_FILE_MAGIC 0x5145564d
926#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +0200927#define QEMU_VM_FILE_VERSION 0x00000004
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700928
929#define QEMU_VM_EOF 0x00
930#define QEMU_VM_SECTION_START 0x01
931#define QEMU_VM_SECTION_PART 0x02
932#define QEMU_VM_SECTION_END 0x03
933#define QEMU_VM_SECTION_FULL 0x04
934
935int qemu_savevm_state_begin(QEMUFile *f)
936{
937 SaveStateEntry *se;
938
939 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
940 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
941
942 for (se = first_se; se != NULL; se = se->next) {
943 int len;
944
945 if (se->save_live_state == NULL)
946 continue;
947
948 /* Section type */
949 qemu_put_byte(f, QEMU_VM_SECTION_START);
950 qemu_put_be32(f, se->section_id);
951
952 /* ID string */
953 len = strlen(se->idstr);
954 qemu_put_byte(f, len);
955 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
956
957 qemu_put_be32(f, se->instance_id);
958 qemu_put_be32(f, se->version_id);
959
960 se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
961 }
962
963 if (qemu_file_has_error(f))
964 return -EIO;
965
966 return 0;
967}
968
969int qemu_savevm_state_iterate(QEMUFile *f)
970{
971 SaveStateEntry *se;
972 int ret = 1;
973
974 for (se = first_se; se != NULL; se = se->next) {
975 if (se->save_live_state == NULL)
976 continue;
977
978 /* Section type */
979 qemu_put_byte(f, QEMU_VM_SECTION_PART);
980 qemu_put_be32(f, se->section_id);
981
982 ret &= !!se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque);
983 }
984
985 if (ret)
986 return 1;
987
988 if (qemu_file_has_error(f))
989 return -EIO;
990
991 return 0;
992}
993
994int qemu_savevm_state_complete(QEMUFile *f)
995{
996 SaveStateEntry *se;
997
998 for (se = first_se; se != NULL; se = se->next) {
999 if (se->save_live_state == NULL)
1000 continue;
1001
1002 /* Section type */
1003 qemu_put_byte(f, QEMU_VM_SECTION_END);
1004 qemu_put_be32(f, se->section_id);
1005
1006 se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);
1007 }
1008
1009 for(se = first_se; se != NULL; se = se->next) {
1010 int len;
1011
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001012 if (se->save_state == NULL)
1013 continue;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001014
1015 /* Section type */
1016 qemu_put_byte(f, QEMU_VM_SECTION_FULL);
1017 qemu_put_be32(f, se->section_id);
1018
1019 /* ID string */
1020 len = strlen(se->idstr);
1021 qemu_put_byte(f, len);
1022 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1023
1024 qemu_put_be32(f, se->instance_id);
1025 qemu_put_be32(f, se->version_id);
1026
1027 se->save_state(f, se->opaque);
1028 }
1029
1030 qemu_put_byte(f, QEMU_VM_EOF);
1031
1032 if (qemu_file_has_error(f))
1033 return -EIO;
1034
1035 return 0;
1036}
1037
1038int qemu_savevm_state(QEMUFile *f)
1039{
1040 int saved_vm_running;
1041 int ret;
1042
1043 saved_vm_running = vm_running;
1044 vm_stop(0);
1045
1046 bdrv_flush_all();
1047
1048 ret = qemu_savevm_state_begin(f);
1049 if (ret < 0)
1050 goto out;
1051
1052 do {
1053 ret = qemu_savevm_state_iterate(f);
1054 if (ret < 0)
1055 goto out;
1056 } while (ret == 0);
1057
1058 ret = qemu_savevm_state_complete(f);
1059
1060out:
1061 if (qemu_file_has_error(f))
1062 ret = -EIO;
1063
1064 if (!ret && saved_vm_running)
1065 vm_start();
1066
1067 return ret;
1068}
1069
1070static SaveStateEntry *find_se(const char *idstr, int instance_id)
1071{
1072 SaveStateEntry *se;
1073
1074 for(se = first_se; se != NULL; se = se->next) {
1075 if (!strcmp(se->idstr, idstr) &&
1076 instance_id == se->instance_id)
1077 return se;
1078 }
1079 return NULL;
1080}
1081
1082typedef struct LoadStateEntry {
1083 SaveStateEntry *se;
1084 int section_id;
1085 int version_id;
1086 struct LoadStateEntry *next;
1087} LoadStateEntry;
1088
1089static int qemu_loadvm_state_v2(QEMUFile *f)
1090{
1091 SaveStateEntry *se;
1092 int len, ret, instance_id, record_len, version_id;
1093 int64_t total_len, end_pos, cur_pos;
1094 char idstr[256];
1095
1096 total_len = qemu_get_be64(f);
1097 end_pos = total_len + qemu_ftell(f);
1098 for(;;) {
1099 if (qemu_ftell(f) >= end_pos)
1100 break;
1101 len = qemu_get_byte(f);
1102 qemu_get_buffer(f, (uint8_t *)idstr, len);
1103 idstr[len] = '\0';
1104 instance_id = qemu_get_be32(f);
1105 version_id = qemu_get_be32(f);
1106 record_len = qemu_get_be32(f);
1107 cur_pos = qemu_ftell(f);
1108 se = find_se(idstr, instance_id);
1109 if (!se) {
1110 fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
1111 instance_id, idstr);
1112 } else {
1113 ret = se->load_state(f, se->opaque, version_id);
1114 if (ret < 0) {
1115 fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
1116 instance_id, idstr);
1117 return ret;
1118 }
1119 }
1120 /* always seek to exact end of record */
1121 qemu_fseek(f, cur_pos + record_len, SEEK_SET);
1122 }
1123
1124 if (qemu_file_has_error(f))
1125 return -EIO;
1126
1127 return 0;
1128}
1129
1130int qemu_loadvm_state(QEMUFile *f)
1131{
1132 LoadStateEntry *first_le = NULL;
1133 uint8_t section_type;
1134 unsigned int v;
1135 int ret;
1136
1137 v = qemu_get_be32(f);
1138 if (v != QEMU_VM_FILE_MAGIC)
1139 return -EINVAL;
1140
1141 v = qemu_get_be32(f);
1142 if (v == QEMU_VM_FILE_VERSION_COMPAT)
1143 return qemu_loadvm_state_v2(f);
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +02001144 if (v < QEMU_VM_FILE_VERSION) {
1145 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 -07001146 return -ENOTSUP;
David 'Digit' Turner3e92c2d2011-10-11 03:02:41 +02001147 } else if (v > QEMU_VM_FILE_VERSION) {
1148 fprintf(stderr, "Snapshot format %d is more recent than the emulator, please update your Android SDK Tools.\n", v);
1149 return -ENOTSUP;
1150 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001151
1152 while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
1153 uint32_t instance_id, version_id, section_id;
1154 LoadStateEntry *le;
1155 SaveStateEntry *se;
1156 char idstr[257];
1157 int len;
1158
1159 switch (section_type) {
1160 case QEMU_VM_SECTION_START:
1161 case QEMU_VM_SECTION_FULL:
1162 /* Read section start */
1163 section_id = qemu_get_be32(f);
1164 len = qemu_get_byte(f);
1165 qemu_get_buffer(f, (uint8_t *)idstr, len);
1166 idstr[len] = 0;
1167 instance_id = qemu_get_be32(f);
1168 version_id = qemu_get_be32(f);
1169
1170 /* Find savevm section */
1171 se = find_se(idstr, instance_id);
1172 if (se == NULL) {
1173 fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
1174 ret = -EINVAL;
1175 goto out;
1176 }
1177
1178 /* Validate version */
1179 if (version_id > se->version_id) {
1180 fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
1181 version_id, idstr, se->version_id);
1182 ret = -EINVAL;
1183 goto out;
1184 }
1185
1186 /* Add entry */
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001187 le = g_malloc0(sizeof(*le));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001188
1189 le->se = se;
1190 le->section_id = section_id;
1191 le->version_id = version_id;
1192 le->next = first_le;
1193 first_le = le;
1194
Vladimir Chtchetkined0e28722011-10-05 14:25:07 -07001195 if (le->se->load_state(f, le->se->opaque, le->version_id)) {
1196 fprintf(stderr, "savevm: unable to load section %s\n", idstr);
1197 ret = -EINVAL;
1198 goto out;
1199 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001200 break;
1201 case QEMU_VM_SECTION_PART:
1202 case QEMU_VM_SECTION_END:
1203 section_id = qemu_get_be32(f);
1204
1205 for (le = first_le; le && le->section_id != section_id; le = le->next);
1206 if (le == NULL) {
1207 fprintf(stderr, "Unknown savevm section %d\n", section_id);
1208 ret = -EINVAL;
1209 goto out;
1210 }
1211
1212 le->se->load_state(f, le->se->opaque, le->version_id);
1213 break;
1214 default:
1215 fprintf(stderr, "Unknown savevm section type %d\n", section_type);
1216 ret = -EINVAL;
1217 goto out;
1218 }
1219 }
1220
1221 ret = 0;
1222
1223out:
1224 while (first_le) {
1225 LoadStateEntry *le = first_le;
1226 first_le = first_le->next;
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001227 g_free(le);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001228 }
1229
1230 if (qemu_file_has_error(f))
1231 ret = -EIO;
1232
1233 return ret;
1234}
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001235#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001236static BlockDriverState *get_bs_snapshots(void)
1237{
1238 BlockDriverState *bs;
1239 int i;
1240
1241 if (bs_snapshots)
1242 return bs_snapshots;
1243 for(i = 0; i <= nb_drives; i++) {
1244 bs = drives_table[i].bdrv;
1245 if (bdrv_can_snapshot(bs))
1246 goto ok;
1247 }
1248 return NULL;
1249 ok:
1250 bs_snapshots = bs;
1251 return bs;
1252}
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001253#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001254static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
1255 const char *name)
1256{
1257 QEMUSnapshotInfo *sn_tab, *sn;
1258 int nb_sns, i, ret;
1259
1260 ret = -ENOENT;
1261 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1262 if (nb_sns < 0)
1263 return ret;
1264 for(i = 0; i < nb_sns; i++) {
1265 sn = &sn_tab[i];
1266 if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
1267 *sn_info = *sn;
1268 ret = 0;
1269 break;
1270 }
1271 }
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001272 g_free(sn_tab);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001273 return ret;
1274}
1275
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001276void do_savevm(Monitor *err, const char *name)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001277{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001278 BlockDriverState *bs, *bs1;
1279 QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001280 int must_delete, ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001281 BlockDriverInfo bdi1, *bdi = &bdi1;
1282 QEMUFile *f;
1283 int saved_vm_running;
1284 uint32_t vm_state_size;
1285#ifdef _WIN32
1286 struct _timeb tb;
1287#else
1288 struct timeval tv;
1289#endif
1290
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001291 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001292 if (!bs) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001293 monitor_printf(err, "No block device can accept snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001294 return;
1295 }
1296
1297 /* ??? Should this occur after vm_stop? */
1298 qemu_aio_flush();
1299
1300 saved_vm_running = vm_running;
1301 vm_stop(0);
1302
1303 must_delete = 0;
1304 if (name) {
1305 ret = bdrv_snapshot_find(bs, old_sn, name);
1306 if (ret >= 0) {
1307 must_delete = 1;
1308 }
1309 }
1310 memset(sn, 0, sizeof(*sn));
1311 if (must_delete) {
1312 pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
1313 pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
1314 } else {
1315 if (name)
1316 pstrcpy(sn->name, sizeof(sn->name), name);
1317 }
1318
1319 /* fill auxiliary fields */
1320#ifdef _WIN32
1321 _ftime(&tb);
1322 sn->date_sec = tb.time;
1323 sn->date_nsec = tb.millitm * 1000000;
1324#else
1325 gettimeofday(&tv, NULL);
1326 sn->date_sec = tv.tv_sec;
1327 sn->date_nsec = tv.tv_usec * 1000;
1328#endif
David 'Digit' Turner5973c772011-05-10 07:06:00 +02001329 sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001330
1331 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001332 monitor_printf(err, "Device %s does not support VM state snapshots\n",
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001333 bdrv_get_device_name(bs));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001334 goto the_end;
1335 }
1336
1337 /* save the VM state */
David 'Digit' Turner986acc92011-05-10 16:50:01 +02001338 f = qemu_fopen_bdrv(bs, 1);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001339 if (!f) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001340 monitor_printf(err, "Could not open VM state file\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001341 goto the_end;
1342 }
1343 ret = qemu_savevm_state(f);
1344 vm_state_size = qemu_ftell(f);
1345 qemu_fclose(f);
1346 if (ret < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001347 monitor_printf(err, "Error %d while writing VM\n", ret);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001348 goto the_end;
1349 }
1350
1351 /* create the snapshots */
1352
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001353 bs1 = NULL;
1354 while ((bs1 = bdrv_next(bs1))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001355 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001356 if (must_delete) {
1357 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
1358 if (ret < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001359 monitor_printf(err,
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001360 "Error while deleting snapshot on '%s'\n",
1361 bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001362 }
1363 }
1364 /* Write VM state size only to the image that contains the state */
1365 sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
1366 ret = bdrv_snapshot_create(bs1, sn);
1367 if (ret < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001368 monitor_printf(err, "Error while creating snapshot on '%s'\n",
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001369 bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001370 }
1371 }
1372 }
1373
1374 the_end:
1375 if (saved_vm_running)
1376 vm_start();
1377}
1378
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001379void do_loadvm(Monitor *err, const char *name)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001380{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001381 BlockDriverState *bs, *bs1;
1382 BlockDriverInfo bdi1, *bdi = &bdi1;
1383 QEMUSnapshotInfo sn;
1384 QEMUFile *f;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001385 int ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001386 int saved_vm_running;
1387
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001388 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001389 if (!bs) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001390 monitor_printf(err, "No block device supports snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001391 return;
1392 }
1393
1394 /* Flush all IO requests so they don't interfere with the new state. */
1395 qemu_aio_flush();
1396
1397 saved_vm_running = vm_running;
1398 vm_stop(0);
1399
Vladimir Chtchetkine05e07482012-02-03 10:02:50 -08001400 bs1 = bs;
1401 do {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001402 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001403 ret = bdrv_snapshot_goto(bs1, name);
1404 if (ret < 0) {
1405 if (bs != bs1)
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001406 monitor_printf(err, "Warning: ");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001407 switch(ret) {
1408 case -ENOTSUP:
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001409 monitor_printf(err,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001410 "Snapshots not supported on device '%s'\n",
1411 bdrv_get_device_name(bs1));
1412 break;
1413 case -ENOENT:
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001414 monitor_printf(err, "Could not find snapshot '%s' on "
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001415 "device '%s'\n",
1416 name, bdrv_get_device_name(bs1));
1417 break;
1418 default:
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001419 monitor_printf(err, "Error %d while activating snapshot on"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001420 " '%s'\n", ret, bdrv_get_device_name(bs1));
1421 break;
1422 }
1423 /* fatal on snapshot block device */
1424 if (bs == bs1)
1425 goto the_end;
1426 }
1427 }
Vladimir Chtchetkine05e07482012-02-03 10:02:50 -08001428 } while ((bs1 = bdrv_next(bs)));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001429
1430 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001431 monitor_printf(err, "Device %s does not support VM state snapshots\n",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001432 bdrv_get_device_name(bs));
1433 return;
1434 }
1435
1436 /* Don't even try to load empty VM states */
1437 ret = bdrv_snapshot_find(bs, &sn, name);
1438 if ((ret >= 0) && (sn.vm_state_size == 0))
1439 goto the_end;
1440
1441 /* restore the VM state */
David 'Digit' Turner986acc92011-05-10 16:50:01 +02001442 f = qemu_fopen_bdrv(bs, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001443 if (!f) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001444 monitor_printf(err, "Could not open VM state file\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001445 goto the_end;
1446 }
1447 ret = qemu_loadvm_state(f);
1448 qemu_fclose(f);
1449 if (ret < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001450 monitor_printf(err, "Error %d while loading VM state\n", ret);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001451 }
1452 the_end:
1453 if (saved_vm_running)
1454 vm_start();
1455}
1456
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001457void do_delvm(Monitor *err, const char *name)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001458{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001459 BlockDriverState *bs, *bs1;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001460 int ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001461
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001462 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001463 if (!bs) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001464 monitor_printf(err, "No block device supports snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001465 return;
1466 }
1467
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001468 bs1 = NULL;
1469 while ((bs1 = bdrv_next(bs1))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001470 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001471 ret = bdrv_snapshot_delete(bs1, name);
1472 if (ret < 0) {
1473 if (ret == -ENOTSUP)
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001474 monitor_printf(err,
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001475 "Snapshots not supported on device '%s'\n",
1476 bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001477 else
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001478 monitor_printf(err, "Error %d while deleting snapshot on "
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001479 "'%s'\n", ret, bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001480 }
1481 }
1482 }
1483}
1484
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001485void do_info_snapshots(Monitor* out, Monitor* err)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001486{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001487 BlockDriverState *bs, *bs1;
1488 QEMUSnapshotInfo *sn_tab, *sn;
1489 int nb_sns, i;
1490 char buf[256];
1491
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001492 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001493 if (!bs) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001494 monitor_printf(err, "No available block device supports snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001495 return;
1496 }
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001497 monitor_printf(out, "Snapshot devices:");
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001498 bs1 = NULL;
1499 while ((bs1 = bdrv_next(bs1))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001500 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001501 if (bs == bs1)
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001502 monitor_printf(out, " %s", bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001503 }
1504 }
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001505 monitor_printf(out, "\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001506
1507 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1508 if (nb_sns < 0) {
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001509 monitor_printf(err, "bdrv_snapshot_list: error %d\n", nb_sns);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001510 return;
1511 }
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001512 monitor_printf(out, "Snapshot list (from %s):\n",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001513 bdrv_get_device_name(bs));
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001514 monitor_printf(out, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001515 for(i = 0; i < nb_sns; i++) {
1516 sn = &sn_tab[i];
David 'Digit' Turner95a83ce2011-05-10 17:31:15 +02001517 monitor_printf(out, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001518 }
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +01001519 g_free(sn_tab);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001520}