blob: 5d04d59688517895185a40ffd16ac34080f5d5d9 [file] [log] [blame]
aliguoria672b462008-11-11 21:33:36 +00001/*
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 */
aliguoria672b462008-11-11 21:33:36 +000024#include <unistd.h>
25#include <fcntl.h>
aliguoria672b462008-11-11 21:33:36 +000026#include <time.h>
27#include <errno.h>
28#include <sys/time.h>
29#include <zlib.h>
30
Juan Quintela71e72a12009-07-27 16:12:56 +020031/* Needed early for CONFIG_BSD etc. */
blueswir1d40cdb12009-03-07 16:52:02 +000032#include "config-host.h"
33
aliguoria672b462008-11-11 21:33:36 +000034#ifndef _WIN32
35#include <sys/times.h>
36#include <sys/wait.h>
37#include <termios.h>
38#include <sys/mman.h>
39#include <sys/ioctl.h>
40#include <sys/resource.h>
41#include <sys/socket.h>
42#include <netinet/in.h>
43#include <net/if.h>
aliguoria672b462008-11-11 21:33:36 +000044#include <arpa/inet.h>
45#include <dirent.h>
46#include <netdb.h>
47#include <sys/select.h>
Juan Quintela71e72a12009-07-27 16:12:56 +020048#ifdef CONFIG_BSD
aliguoria672b462008-11-11 21:33:36 +000049#include <sys/stat.h>
Aurelien Jarnoa167ba52009-11-29 18:00:41 +010050#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
aliguoria672b462008-11-11 21:33:36 +000051#include <libutil.h>
52#else
53#include <util.h>
54#endif
aliguoria672b462008-11-11 21:33:36 +000055#ifdef __linux__
56#include <pty.h>
57#include <malloc.h>
58#include <linux/rtc.h>
59#endif
60#endif
61#endif
62
63#ifdef _WIN32
aliguori49dc7682009-03-08 16:26:59 +000064#include <windows.h>
aliguoria672b462008-11-11 21:33:36 +000065#include <malloc.h>
66#include <sys/timeb.h>
67#include <mmsystem.h>
68#define getopt_long_only getopt_long
69#define memalign(align, size) malloc(size)
70#endif
71
blueswir1511d2b12009-03-07 15:32:56 +000072#include "qemu-common.h"
73#include "hw/hw.h"
Alex Williamson7685ee62010-06-25 11:09:14 -060074#include "hw/qdev.h"
blueswir1511d2b12009-03-07 15:32:56 +000075#include "net.h"
76#include "monitor.h"
77#include "sysemu.h"
78#include "qemu-timer.h"
79#include "qemu-char.h"
blueswir1511d2b12009-03-07 15:32:56 +000080#include "audio/audio.h"
81#include "migration.h"
82#include "qemu_socket.h"
Blue Swirl72cf2d42009-09-12 07:36:22 +000083#include "qemu-queue.h"
Paolo Bonzini2ff68d02011-09-12 16:21:44 +020084#include "qemu-timer.h"
Blue Swirl17a46632011-03-27 16:05:08 +000085#include "cpus.h"
Avi Kivityc5705a72011-12-20 15:59:12 +020086#include "memory.h"
Stefano Stabellinia7ae8352012-01-25 12:24:51 +000087#include "qmp-commands.h"
Juan Quintela517a13c2012-05-21 23:46:44 +020088#include "trace.h"
Peter Maydell08e99e22012-10-30 07:45:12 +000089#include "bitops.h"
blueswir1511d2b12009-03-07 15:32:56 +000090
aliguoria672b462008-11-11 21:33:36 +000091#define SELF_ANNOUNCE_ROUNDS 5
aliguoria672b462008-11-11 21:33:36 +000092
Nolan18995b92009-10-15 16:53:55 -070093#ifndef ETH_P_RARP
Stefan Bergerf8778a72010-04-24 08:54:07 -040094#define ETH_P_RARP 0x8035
Nolan18995b92009-10-15 16:53:55 -070095#endif
96#define ARP_HTYPE_ETH 0x0001
97#define ARP_PTYPE_IP 0x0800
98#define ARP_OP_REQUEST_REV 0x3
99
100static int announce_self_create(uint8_t *buf,
aliguoria672b462008-11-11 21:33:36 +0000101 uint8_t *mac_addr)
102{
Nolan18995b92009-10-15 16:53:55 -0700103 /* 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 */
aliguoria672b462008-11-11 21:33:36 +0000107
Nolan18995b92009-10-15 16:53:55 -0700108 /* 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 */
aliguoria672b462008-11-11 21:33:36 +0000118
Nolan18995b92009-10-15 16:53:55 -0700119 /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
120 memset(buf + 42, 0x00, 18);
aliguoria672b462008-11-11 21:33:36 +0000121
Nolan18995b92009-10-15 16:53:55 -0700122 return 60; /* len (FCS will be added by hardware) */
aliguoria672b462008-11-11 21:33:36 +0000123}
124
Mark McLoughlinf401ca22009-11-25 18:49:32 +0000125static void qemu_announce_self_iter(NICState *nic, void *opaque)
126{
127 uint8_t buf[60];
128 int len;
129
130 len = announce_self_create(buf, nic->conf->macaddr.a);
131
132 qemu_send_packet_raw(&nic->nc, buf, len);
133}
134
135
Gleb Natapoved8b3302009-05-21 17:17:44 +0300136static void qemu_announce_self_once(void *opaque)
aliguoria672b462008-11-11 21:33:36 +0000137{
Gleb Natapoved8b3302009-05-21 17:17:44 +0300138 static int count = SELF_ANNOUNCE_ROUNDS;
139 QEMUTimer *timer = *(QEMUTimer **)opaque;
aliguoria672b462008-11-11 21:33:36 +0000140
Mark McLoughlinf401ca22009-11-25 18:49:32 +0000141 qemu_foreach_nic(qemu_announce_self_iter, NULL);
142
Nolan18995b92009-10-15 16:53:55 -0700143 if (--count) {
144 /* delay 50ms, 150ms, 250ms, ... */
Paolo Bonzini7bd427d2011-03-11 16:47:48 +0100145 qemu_mod_timer(timer, qemu_get_clock_ms(rt_clock) +
Nolan18995b92009-10-15 16:53:55 -0700146 50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);
Gleb Natapoved8b3302009-05-21 17:17:44 +0300147 } else {
148 qemu_del_timer(timer);
149 qemu_free_timer(timer);
150 }
151}
152
153void qemu_announce_self(void)
154{
155 static QEMUTimer *timer;
Paolo Bonzini7bd427d2011-03-11 16:47:48 +0100156 timer = qemu_new_timer_ms(rt_clock, qemu_announce_self_once, &timer);
Gleb Natapoved8b3302009-05-21 17:17:44 +0300157 qemu_announce_self_once(&timer);
aliguoria672b462008-11-11 21:33:36 +0000158}
159
160/***********************************************************/
161/* savevm/loadvm support */
162
163#define IO_BUF_SIZE 32768
164
165struct QEMUFile {
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200166 const QEMUFileOps *ops;
aliguoria672b462008-11-11 21:33:36 +0000167 void *opaque;
168 int is_write;
169
170 int64_t buf_offset; /* start of buffer when writing, end of buffer
171 when reading */
172 int buf_index;
173 int buf_size; /* 0 when writing */
174 uint8_t buf[IO_BUF_SIZE];
175
Juan Quintela3961b4d2011-10-05 01:05:21 +0200176 int last_error;
aliguoria672b462008-11-11 21:33:36 +0000177};
178
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200179typedef struct QEMUFileStdio
aliguoria672b462008-11-11 21:33:36 +0000180{
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200181 FILE *stdio_file;
aliguoria672b462008-11-11 21:33:36 +0000182 QEMUFile *file;
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200183} QEMUFileStdio;
aliguoria672b462008-11-11 21:33:36 +0000184
185typedef struct QEMUFileSocket
186{
187 int fd;
188 QEMUFile *file;
189} QEMUFileSocket;
190
Paolo Bonzini70eb6332012-08-08 10:20:18 +0200191static int socket_get_fd(void *opaque)
192{
193 QEMUFileSocket *s = opaque;
194
195 return s->fd;
196}
197
aliguoria672b462008-11-11 21:33:36 +0000198static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
199{
200 QEMUFileSocket *s = opaque;
201 ssize_t len;
202
Paolo Bonzini595ab6412012-08-07 11:07:59 +0200203 for (;;) {
Blue Swirl00aa0042011-07-23 20:04:29 +0000204 len = qemu_recv(s->fd, buf, size, 0);
Paolo Bonzini595ab6412012-08-07 11:07:59 +0200205 if (len != -1) {
206 break;
207 }
208 if (socket_error() == EAGAIN) {
209 assert(qemu_in_coroutine());
210 qemu_coroutine_yield();
211 } else if (socket_error() != EINTR) {
212 break;
213 }
214 }
aliguoria672b462008-11-11 21:33:36 +0000215
Paolo Bonzini595ab6412012-08-07 11:07:59 +0200216 if (len == -1) {
aliguoria672b462008-11-11 21:33:36 +0000217 len = -socket_error();
Paolo Bonzini595ab6412012-08-07 11:07:59 +0200218 }
aliguoria672b462008-11-11 21:33:36 +0000219 return len;
220}
221
222static int socket_close(void *opaque)
223{
224 QEMUFileSocket *s = opaque;
Paolo Bonziniab52a822012-08-07 10:50:26 +0200225 closesocket(s->fd);
Anthony Liguori7267c092011-08-20 22:09:37 -0500226 g_free(s);
aliguoria672b462008-11-11 21:33:36 +0000227 return 0;
228}
229
Paolo Bonzini70eb6332012-08-08 10:20:18 +0200230static int stdio_get_fd(void *opaque)
231{
232 QEMUFileStdio *s = opaque;
233
234 return fileno(s->stdio_file);
235}
236
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200237static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
aliguoria672b462008-11-11 21:33:36 +0000238{
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200239 QEMUFileStdio *s = opaque;
240 return fwrite(buf, 1, size, s->stdio_file);
aliguoria672b462008-11-11 21:33:36 +0000241}
242
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200243static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
aliguoria672b462008-11-11 21:33:36 +0000244{
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200245 QEMUFileStdio *s = opaque;
246 FILE *fp = s->stdio_file;
Uri Lublin8a67ec42009-06-08 19:27:21 +0300247 int bytes;
248
Paolo Bonzini595ab6412012-08-07 11:07:59 +0200249 for (;;) {
Uri Lublin8a67ec42009-06-08 19:27:21 +0300250 clearerr(fp);
251 bytes = fread(buf, 1, size, fp);
Paolo Bonzini595ab6412012-08-07 11:07:59 +0200252 if (bytes != 0 || !ferror(fp)) {
253 break;
254 }
255 if (errno == EAGAIN) {
256 assert(qemu_in_coroutine());
257 qemu_coroutine_yield();
258 } else if (errno != EINTR) {
259 break;
260 }
261 }
Uri Lublin8a67ec42009-06-08 19:27:21 +0300262 return bytes;
aliguoria672b462008-11-11 21:33:36 +0000263}
264
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200265static int stdio_pclose(void *opaque)
aliguoria672b462008-11-11 21:33:36 +0000266{
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200267 QEMUFileStdio *s = opaque;
Anthony Liguori41ef56e2010-06-02 14:55:25 -0500268 int ret;
269 ret = pclose(s->stdio_file);
Eduardo Habkost26f1af02011-11-10 10:41:44 -0200270 if (ret == -1) {
271 ret = -errno;
272 }
Anthony Liguori7267c092011-08-20 22:09:37 -0500273 g_free(s);
Anthony Liguori41ef56e2010-06-02 14:55:25 -0500274 return ret;
aliguoria672b462008-11-11 21:33:36 +0000275}
276
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200277static int stdio_fclose(void *opaque)
aliguoria672b462008-11-11 21:33:36 +0000278{
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200279 QEMUFileStdio *s = opaque;
Eduardo Habkost0e286702011-11-10 10:41:45 -0200280 int ret = 0;
281 if (fclose(s->stdio_file) == EOF) {
282 ret = -errno;
283 }
Anthony Liguori7267c092011-08-20 22:09:37 -0500284 g_free(s);
Eduardo Habkost0e286702011-11-10 10:41:45 -0200285 return ret;
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200286}
aliguoria672b462008-11-11 21:33:36 +0000287
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200288static const QEMUFileOps stdio_pipe_read_ops = {
Paolo Bonzini70eb6332012-08-08 10:20:18 +0200289 .get_fd = stdio_get_fd,
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200290 .get_buffer = stdio_get_buffer,
291 .close = stdio_pclose
292};
293
294static const QEMUFileOps stdio_pipe_write_ops = {
Paolo Bonzini70eb6332012-08-08 10:20:18 +0200295 .get_fd = stdio_get_fd,
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200296 .put_buffer = stdio_put_buffer,
297 .close = stdio_pclose
298};
299
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200300QEMUFile *qemu_popen(FILE *stdio_file, const char *mode)
301{
302 QEMUFileStdio *s;
303
304 if (stdio_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
aliguoria672b462008-11-11 21:33:36 +0000305 fprintf(stderr, "qemu_popen: Argument validity check failed\n");
306 return NULL;
307 }
308
Anthony Liguori7267c092011-08-20 22:09:37 -0500309 s = g_malloc0(sizeof(QEMUFileStdio));
aliguoria672b462008-11-11 21:33:36 +0000310
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200311 s->stdio_file = stdio_file;
aliguoria672b462008-11-11 21:33:36 +0000312
313 if(mode[0] == 'r') {
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200314 s->file = qemu_fopen_ops(s, &stdio_pipe_read_ops);
aliguoria672b462008-11-11 21:33:36 +0000315 } else {
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200316 s->file = qemu_fopen_ops(s, &stdio_pipe_write_ops);
aliguoria672b462008-11-11 21:33:36 +0000317 }
aliguoria672b462008-11-11 21:33:36 +0000318 return s->file;
319}
320
321QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
322{
323 FILE *popen_file;
324
325 popen_file = popen(command, mode);
326 if(popen_file == NULL) {
327 return NULL;
328 }
329
330 return qemu_popen(popen_file, mode);
331}
332
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200333static const QEMUFileOps stdio_file_read_ops = {
Paolo Bonzini70eb6332012-08-08 10:20:18 +0200334 .get_fd = stdio_get_fd,
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200335 .get_buffer = stdio_get_buffer,
336 .close = stdio_fclose
337};
338
339static const QEMUFileOps stdio_file_write_ops = {
Paolo Bonzini70eb6332012-08-08 10:20:18 +0200340 .get_fd = stdio_get_fd,
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200341 .put_buffer = stdio_put_buffer,
342 .close = stdio_fclose
343};
344
Paolo Bonzini5ac1fad2009-08-18 15:56:25 +0200345QEMUFile *qemu_fdopen(int fd, const char *mode)
346{
347 QEMUFileStdio *s;
348
349 if (mode == NULL ||
350 (mode[0] != 'r' && mode[0] != 'w') ||
351 mode[1] != 'b' || mode[2] != 0) {
352 fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
353 return NULL;
354 }
355
Anthony Liguori7267c092011-08-20 22:09:37 -0500356 s = g_malloc0(sizeof(QEMUFileStdio));
Paolo Bonzini5ac1fad2009-08-18 15:56:25 +0200357 s->stdio_file = fdopen(fd, mode);
358 if (!s->stdio_file)
359 goto fail;
360
361 if(mode[0] == 'r') {
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200362 s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
Paolo Bonzini5ac1fad2009-08-18 15:56:25 +0200363 } else {
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200364 s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
Paolo Bonzini5ac1fad2009-08-18 15:56:25 +0200365 }
366 return s->file;
367
368fail:
Anthony Liguori7267c092011-08-20 22:09:37 -0500369 g_free(s);
Paolo Bonzini5ac1fad2009-08-18 15:56:25 +0200370 return NULL;
371}
372
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200373static const QEMUFileOps socket_read_ops = {
Paolo Bonzini70eb6332012-08-08 10:20:18 +0200374 .get_fd = socket_get_fd,
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200375 .get_buffer = socket_get_buffer,
376 .close = socket_close
377};
378
aliguoria672b462008-11-11 21:33:36 +0000379QEMUFile *qemu_fopen_socket(int fd)
380{
Anthony Liguori7267c092011-08-20 22:09:37 -0500381 QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket));
aliguoria672b462008-11-11 21:33:36 +0000382
aliguoria672b462008-11-11 21:33:36 +0000383 s->fd = fd;
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200384 s->file = qemu_fopen_ops(s, &socket_read_ops);
aliguoria672b462008-11-11 21:33:36 +0000385 return s->file;
386}
387
aliguoria672b462008-11-11 21:33:36 +0000388QEMUFile *qemu_fopen(const char *filename, const char *mode)
389{
390 QEMUFileStdio *s;
391
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200392 if (mode == NULL ||
393 (mode[0] != 'r' && mode[0] != 'w') ||
394 mode[1] != 'b' || mode[2] != 0) {
Blue Swirl090414a2010-03-13 11:36:09 +0000395 fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200396 return NULL;
397 }
398
Anthony Liguori7267c092011-08-20 22:09:37 -0500399 s = g_malloc0(sizeof(QEMUFileStdio));
aliguoria672b462008-11-11 21:33:36 +0000400
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200401 s->stdio_file = fopen(filename, mode);
402 if (!s->stdio_file)
aliguoria672b462008-11-11 21:33:36 +0000403 goto fail;
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +0200404
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200405 if(mode[0] == 'w') {
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200406 s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200407 } else {
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200408 s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
Paolo Bonzini7f79dd22009-08-12 14:17:35 +0200409 }
410 return s->file;
aliguoria672b462008-11-11 21:33:36 +0000411fail:
Anthony Liguori7267c092011-08-20 22:09:37 -0500412 g_free(s);
aliguoria672b462008-11-11 21:33:36 +0000413 return NULL;
414}
415
aliguori178e08a2009-04-05 19:10:55 +0000416static int block_put_buffer(void *opaque, const uint8_t *buf,
aliguoria672b462008-11-11 21:33:36 +0000417 int64_t pos, int size)
418{
Christoph Hellwig45566e92009-07-10 23:11:57 +0200419 bdrv_save_vmstate(opaque, buf, pos, size);
aliguoria672b462008-11-11 21:33:36 +0000420 return size;
421}
422
aliguori178e08a2009-04-05 19:10:55 +0000423static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
aliguoria672b462008-11-11 21:33:36 +0000424{
Christoph Hellwig45566e92009-07-10 23:11:57 +0200425 return bdrv_load_vmstate(opaque, buf, pos, size);
aliguoria672b462008-11-11 21:33:36 +0000426}
427
428static int bdrv_fclose(void *opaque)
429{
Paolo Bonziniad492c92012-06-06 00:04:50 +0200430 return bdrv_flush(opaque);
aliguoria672b462008-11-11 21:33:36 +0000431}
432
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200433static const QEMUFileOps bdrv_read_ops = {
434 .get_buffer = block_get_buffer,
435 .close = bdrv_fclose
436};
437
438static const QEMUFileOps bdrv_write_ops = {
439 .put_buffer = block_put_buffer,
440 .close = bdrv_fclose
441};
442
Christoph Hellwig45566e92009-07-10 23:11:57 +0200443static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
aliguoria672b462008-11-11 21:33:36 +0000444{
aliguoria672b462008-11-11 21:33:36 +0000445 if (is_writable)
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200446 return qemu_fopen_ops(bs, &bdrv_write_ops);
447 return qemu_fopen_ops(bs, &bdrv_read_ops);
aliguoria672b462008-11-11 21:33:36 +0000448}
449
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200450QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)
aliguoria672b462008-11-11 21:33:36 +0000451{
452 QEMUFile *f;
453
Anthony Liguori7267c092011-08-20 22:09:37 -0500454 f = g_malloc0(sizeof(QEMUFile));
aliguoria672b462008-11-11 21:33:36 +0000455
456 f->opaque = opaque;
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200457 f->ops = ops;
aliguoria672b462008-11-11 21:33:36 +0000458 f->is_write = 0;
459
460 return f;
461}
462
Juan Quintela624b9cc2011-10-05 01:02:52 +0200463int qemu_file_get_error(QEMUFile *f)
aliguoria672b462008-11-11 21:33:36 +0000464{
Juan Quintela3961b4d2011-10-05 01:05:21 +0200465 return f->last_error;
aliguoria672b462008-11-11 21:33:36 +0000466}
467
Juan Quintela6f121ff2012-08-30 13:37:56 +0200468static void qemu_file_set_error(QEMUFile *f, int ret)
aliguori4dabe242009-04-05 19:30:51 +0000469{
Juan Quintela3961b4d2011-10-05 01:05:21 +0200470 f->last_error = ret;
aliguori4dabe242009-04-05 19:30:51 +0000471}
472
Eduardo Habkostd82ca912011-11-10 10:41:43 -0200473/** Flushes QEMUFile buffer
474 *
Eduardo Habkostd82ca912011-11-10 10:41:43 -0200475 */
Juan Quintela7311bea2012-08-29 19:08:59 +0200476static int qemu_fflush(QEMUFile *f)
aliguoria672b462008-11-11 21:33:36 +0000477{
Juan Quintela7311bea2012-08-29 19:08:59 +0200478 int ret = 0;
479
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200480 if (!f->ops->put_buffer)
Juan Quintela7311bea2012-08-29 19:08:59 +0200481 return 0;
aliguoria672b462008-11-11 21:33:36 +0000482
483 if (f->is_write && f->buf_index > 0) {
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200484 ret = f->ops->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index);
Juan Quintela7311bea2012-08-29 19:08:59 +0200485 if (ret >= 0) {
aliguoria672b462008-11-11 21:33:36 +0000486 f->buf_offset += f->buf_index;
Juan Quintela7311bea2012-08-29 19:08:59 +0200487 }
aliguoria672b462008-11-11 21:33:36 +0000488 f->buf_index = 0;
489 }
Juan Quintela7311bea2012-08-29 19:08:59 +0200490 return ret;
aliguoria672b462008-11-11 21:33:36 +0000491}
492
493static void qemu_fill_buffer(QEMUFile *f)
494{
495 int len;
Juan Quintela0046c452011-09-30 19:28:45 +0200496 int pending;
aliguoria672b462008-11-11 21:33:36 +0000497
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200498 if (!f->ops->get_buffer)
aliguoria672b462008-11-11 21:33:36 +0000499 return;
500
501 if (f->is_write)
502 abort();
503
Juan Quintela0046c452011-09-30 19:28:45 +0200504 pending = f->buf_size - f->buf_index;
505 if (pending > 0) {
506 memmove(f->buf, f->buf + f->buf_index, pending);
507 }
508 f->buf_index = 0;
509 f->buf_size = pending;
510
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200511 len = f->ops->get_buffer(f->opaque, f->buf + pending, f->buf_offset,
Juan Quintela0046c452011-09-30 19:28:45 +0200512 IO_BUF_SIZE - pending);
aliguoria672b462008-11-11 21:33:36 +0000513 if (len > 0) {
Juan Quintela0046c452011-09-30 19:28:45 +0200514 f->buf_size += len;
aliguoria672b462008-11-11 21:33:36 +0000515 f->buf_offset += len;
Juan Quintelafa39a302011-10-25 19:18:58 +0200516 } else if (len == 0) {
Juan Quintela02c4a052012-08-29 19:36:26 +0200517 qemu_file_set_error(f, -EIO);
aliguoria672b462008-11-11 21:33:36 +0000518 } else if (len != -EAGAIN)
Eduardo Habkostc29110d2011-11-10 10:41:39 -0200519 qemu_file_set_error(f, len);
aliguoria672b462008-11-11 21:33:36 +0000520}
521
Paolo Bonzini70eb6332012-08-08 10:20:18 +0200522int qemu_get_fd(QEMUFile *f)
523{
524 if (f->ops->get_fd) {
525 return f->ops->get_fd(f->opaque);
526 }
527 return -1;
528}
529
Eduardo Habkostd82ca912011-11-10 10:41:43 -0200530/** Closes the file
531 *
532 * Returns negative error value if any error happened on previous operations or
533 * while closing the file. Returns 0 or positive number on success.
534 *
535 * The meaning of return value on success depends on the specific backend
536 * being used.
537 */
538int qemu_fclose(QEMUFile *f)
539{
Juan Quintela29eee862012-08-29 19:14:54 +0200540 int ret;
Juan Quintela7311bea2012-08-29 19:08:59 +0200541 ret = qemu_fflush(f);
Juan Quintela7311bea2012-08-29 19:08:59 +0200542
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200543 if (f->ops->close) {
544 int ret2 = f->ops->close(f->opaque);
Juan Quintela29eee862012-08-29 19:14:54 +0200545 if (ret >= 0) {
546 ret = ret2;
547 }
Juan Quintela7311bea2012-08-29 19:08:59 +0200548 }
Eduardo Habkostd82ca912011-11-10 10:41:43 -0200549 /* If any error was spotted before closing, we should report it
550 * instead of the close() return value.
551 */
552 if (f->last_error) {
553 ret = f->last_error;
554 }
Anthony Liguori7267c092011-08-20 22:09:37 -0500555 g_free(f);
aliguoria672b462008-11-11 21:33:36 +0000556 return ret;
557}
558
Juan Quintelaa2b41352012-09-04 12:45:42 +0200559int qemu_file_put_notify(QEMUFile *f)
aliguoria672b462008-11-11 21:33:36 +0000560{
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200561 return f->ops->put_buffer(f->opaque, NULL, 0, 0);
aliguoria672b462008-11-11 21:33:36 +0000562}
563
564void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
565{
566 int l;
567
Juan Quintelac10682c2012-08-29 19:43:39 +0200568 if (f->last_error) {
569 return;
570 }
571
572 if (f->is_write == 0 && f->buf_index > 0) {
aliguoria672b462008-11-11 21:33:36 +0000573 fprintf(stderr,
574 "Attempted to write to buffer while read buffer is not empty\n");
575 abort();
576 }
577
Juan Quintelac10682c2012-08-29 19:43:39 +0200578 while (size > 0) {
aliguoria672b462008-11-11 21:33:36 +0000579 l = IO_BUF_SIZE - f->buf_index;
580 if (l > size)
581 l = size;
582 memcpy(f->buf + f->buf_index, buf, l);
583 f->is_write = 1;
584 f->buf_index += l;
585 buf += l;
586 size -= l;
Juan Quintela7311bea2012-08-29 19:08:59 +0200587 if (f->buf_index >= IO_BUF_SIZE) {
588 int ret = qemu_fflush(f);
Juan Quintelac10682c2012-08-29 19:43:39 +0200589 if (ret < 0) {
590 qemu_file_set_error(f, ret);
591 break;
592 }
Juan Quintela7311bea2012-08-29 19:08:59 +0200593 }
aliguoria672b462008-11-11 21:33:36 +0000594 }
595}
596
597void qemu_put_byte(QEMUFile *f, int v)
598{
Juan Quintelac10682c2012-08-29 19:43:39 +0200599 if (f->last_error) {
600 return;
601 }
602
603 if (f->is_write == 0 && f->buf_index > 0) {
aliguoria672b462008-11-11 21:33:36 +0000604 fprintf(stderr,
605 "Attempted to write to buffer while read buffer is not empty\n");
606 abort();
607 }
608
609 f->buf[f->buf_index++] = v;
610 f->is_write = 1;
Juan Quintela7311bea2012-08-29 19:08:59 +0200611 if (f->buf_index >= IO_BUF_SIZE) {
612 int ret = qemu_fflush(f);
Juan Quintelac10682c2012-08-29 19:43:39 +0200613 if (ret < 0) {
614 qemu_file_set_error(f, ret);
615 }
Juan Quintela7311bea2012-08-29 19:08:59 +0200616 }
aliguoria672b462008-11-11 21:33:36 +0000617}
618
Juan Quintelac6380722011-10-04 15:28:31 +0200619static void qemu_file_skip(QEMUFile *f, int size)
aliguoria672b462008-11-11 21:33:36 +0000620{
Juan Quintelac6380722011-10-04 15:28:31 +0200621 if (f->buf_index + size <= f->buf_size) {
622 f->buf_index += size;
aliguoria672b462008-11-11 21:33:36 +0000623 }
aliguoria672b462008-11-11 21:33:36 +0000624}
625
Juan Quintelac6380722011-10-04 15:28:31 +0200626static int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset)
Juan Quintela811814b2010-07-26 21:38:43 +0200627{
Juan Quintelac6380722011-10-04 15:28:31 +0200628 int pending;
629 int index;
Juan Quintela811814b2010-07-26 21:38:43 +0200630
Juan Quintelab9ce1452011-10-04 13:55:32 +0200631 if (f->is_write) {
Juan Quintela811814b2010-07-26 21:38:43 +0200632 abort();
Juan Quintela811814b2010-07-26 21:38:43 +0200633 }
Juan Quintela811814b2010-07-26 21:38:43 +0200634
Juan Quintelac6380722011-10-04 15:28:31 +0200635 index = f->buf_index + offset;
636 pending = f->buf_size - index;
637 if (pending < size) {
Juan Quintela811814b2010-07-26 21:38:43 +0200638 qemu_fill_buffer(f);
Juan Quintelac6380722011-10-04 15:28:31 +0200639 index = f->buf_index + offset;
640 pending = f->buf_size - index;
641 }
642
643 if (pending <= 0) {
644 return 0;
645 }
646 if (size > pending) {
647 size = pending;
648 }
649
650 memcpy(buf, f->buf + index, size);
651 return size;
652}
653
654int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
655{
656 int pending = size;
657 int done = 0;
658
659 while (pending > 0) {
660 int res;
661
662 res = qemu_peek_buffer(f, buf, pending, 0);
663 if (res == 0) {
664 return done;
665 }
666 qemu_file_skip(f, res);
667 buf += res;
668 pending -= res;
669 done += res;
670 }
671 return done;
672}
673
674static int qemu_peek_byte(QEMUFile *f, int offset)
675{
676 int index = f->buf_index + offset;
677
678 if (f->is_write) {
679 abort();
680 }
681
682 if (index >= f->buf_size) {
683 qemu_fill_buffer(f);
684 index = f->buf_index + offset;
685 if (index >= f->buf_size) {
Juan Quintela811814b2010-07-26 21:38:43 +0200686 return 0;
Juan Quintelab9ce1452011-10-04 13:55:32 +0200687 }
Juan Quintela811814b2010-07-26 21:38:43 +0200688 }
Juan Quintelac6380722011-10-04 15:28:31 +0200689 return f->buf[index];
Juan Quintela811814b2010-07-26 21:38:43 +0200690}
691
aliguoria672b462008-11-11 21:33:36 +0000692int qemu_get_byte(QEMUFile *f)
693{
Juan Quintela65f3bb32011-10-06 14:29:32 +0200694 int result;
aliguoria672b462008-11-11 21:33:36 +0000695
Juan Quintelac6380722011-10-04 15:28:31 +0200696 result = qemu_peek_byte(f, 0);
697 qemu_file_skip(f, 1);
Juan Quintela65f3bb32011-10-06 14:29:32 +0200698 return result;
aliguoria672b462008-11-11 21:33:36 +0000699}
700
Juan Quintela3aee4be2012-08-29 19:16:56 +0200701static int64_t qemu_ftell(QEMUFile *f)
aliguoria672b462008-11-11 21:33:36 +0000702{
703 return f->buf_offset - f->buf_size + f->buf_index;
704}
705
aliguoria672b462008-11-11 21:33:36 +0000706int qemu_file_rate_limit(QEMUFile *f)
707{
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200708 if (f->ops->rate_limit)
709 return f->ops->rate_limit(f->opaque);
aliguoria672b462008-11-11 21:33:36 +0000710
711 return 0;
712}
713
Michael S. Tsirkin3d002df2010-11-23 19:05:54 +0200714int64_t qemu_file_get_rate_limit(QEMUFile *f)
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +0200715{
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200716 if (f->ops->get_rate_limit)
717 return f->ops->get_rate_limit(f->opaque);
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +0200718
719 return 0;
720}
721
Michael S. Tsirkin3d002df2010-11-23 19:05:54 +0200722int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate)
Glauber Costa19629532009-05-20 18:26:57 -0400723{
Glauber Costa0bb05ea2009-07-14 18:26:51 -0400724 /* any failed or completed migration keeps its state to allow probing of
725 * migration data, but has no associated file anymore */
Paolo Bonzini9229bf32012-08-08 10:15:15 +0200726 if (f && f->ops->set_rate_limit)
727 return f->ops->set_rate_limit(f->opaque, new_rate);
Glauber Costa19629532009-05-20 18:26:57 -0400728
729 return 0;
730}
731
aliguoria672b462008-11-11 21:33:36 +0000732void qemu_put_be16(QEMUFile *f, unsigned int v)
733{
734 qemu_put_byte(f, v >> 8);
735 qemu_put_byte(f, v);
736}
737
738void qemu_put_be32(QEMUFile *f, unsigned int v)
739{
740 qemu_put_byte(f, v >> 24);
741 qemu_put_byte(f, v >> 16);
742 qemu_put_byte(f, v >> 8);
743 qemu_put_byte(f, v);
744}
745
746void qemu_put_be64(QEMUFile *f, uint64_t v)
747{
748 qemu_put_be32(f, v >> 32);
749 qemu_put_be32(f, v);
750}
751
752unsigned int qemu_get_be16(QEMUFile *f)
753{
754 unsigned int v;
755 v = qemu_get_byte(f) << 8;
756 v |= qemu_get_byte(f);
757 return v;
758}
759
760unsigned int qemu_get_be32(QEMUFile *f)
761{
762 unsigned int v;
763 v = qemu_get_byte(f) << 24;
764 v |= qemu_get_byte(f) << 16;
765 v |= qemu_get_byte(f) << 8;
766 v |= qemu_get_byte(f);
767 return v;
768}
769
770uint64_t qemu_get_be64(QEMUFile *f)
771{
772 uint64_t v;
773 v = (uint64_t)qemu_get_be32(f) << 32;
774 v |= qemu_get_be32(f);
775 return v;
776}
777
Paolo Bonzini2ff68d02011-09-12 16:21:44 +0200778
779/* timer */
780
781void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
782{
783 uint64_t expire_time;
784
785 expire_time = qemu_timer_expire_time_ns(ts);
786 qemu_put_be64(f, expire_time);
787}
788
789void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
790{
791 uint64_t expire_time;
792
793 expire_time = qemu_get_be64(f);
794 if (expire_time != -1) {
795 qemu_mod_timer_ns(ts, expire_time);
796 } else {
797 qemu_del_timer(ts);
798 }
799}
800
801
Gerd Hoffmanncdae5cf2010-11-01 15:51:54 +0100802/* bool */
803
804static int get_bool(QEMUFile *f, void *pv, size_t size)
805{
806 bool *v = pv;
807 *v = qemu_get_byte(f);
808 return 0;
809}
810
811static void put_bool(QEMUFile *f, void *pv, size_t size)
812{
813 bool *v = pv;
814 qemu_put_byte(f, *v);
815}
816
817const VMStateInfo vmstate_info_bool = {
818 .name = "bool",
819 .get = get_bool,
820 .put = put_bool,
821};
822
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200823/* 8 bit int */
824
825static int get_int8(QEMUFile *f, void *pv, size_t size)
826{
827 int8_t *v = pv;
828 qemu_get_s8s(f, v);
829 return 0;
830}
831
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200832static void put_int8(QEMUFile *f, void *pv, size_t size)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200833{
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200834 int8_t *v = pv;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200835 qemu_put_s8s(f, v);
836}
837
838const VMStateInfo vmstate_info_int8 = {
839 .name = "int8",
840 .get = get_int8,
841 .put = put_int8,
842};
843
844/* 16 bit int */
845
846static int get_int16(QEMUFile *f, void *pv, size_t size)
847{
848 int16_t *v = pv;
849 qemu_get_sbe16s(f, v);
850 return 0;
851}
852
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200853static void put_int16(QEMUFile *f, void *pv, size_t size)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200854{
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200855 int16_t *v = pv;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200856 qemu_put_sbe16s(f, v);
857}
858
859const VMStateInfo vmstate_info_int16 = {
860 .name = "int16",
861 .get = get_int16,
862 .put = put_int16,
863};
864
865/* 32 bit int */
866
867static int get_int32(QEMUFile *f, void *pv, size_t size)
868{
869 int32_t *v = pv;
870 qemu_get_sbe32s(f, v);
871 return 0;
872}
873
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200874static void put_int32(QEMUFile *f, void *pv, size_t size)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200875{
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200876 int32_t *v = pv;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200877 qemu_put_sbe32s(f, v);
878}
879
880const VMStateInfo vmstate_info_int32 = {
881 .name = "int32",
882 .get = get_int32,
883 .put = put_int32,
884};
885
Juan Quintela82501662009-08-20 19:42:32 +0200886/* 32 bit int. See that the received value is the same than the one
887 in the field */
888
889static int get_int32_equal(QEMUFile *f, void *pv, size_t size)
890{
891 int32_t *v = pv;
892 int32_t v2;
893 qemu_get_sbe32s(f, &v2);
894
895 if (*v == v2)
896 return 0;
897 return -EINVAL;
898}
899
900const VMStateInfo vmstate_info_int32_equal = {
901 .name = "int32 equal",
902 .get = get_int32_equal,
903 .put = put_int32,
904};
905
Juan Quintela0a031e02009-08-20 19:42:37 +0200906/* 32 bit int. See that the received value is the less or the same
907 than the one in the field */
908
909static int get_int32_le(QEMUFile *f, void *pv, size_t size)
910{
911 int32_t *old = pv;
912 int32_t new;
913 qemu_get_sbe32s(f, &new);
914
915 if (*old <= new)
916 return 0;
917 return -EINVAL;
918}
919
920const VMStateInfo vmstate_info_int32_le = {
921 .name = "int32 equal",
922 .get = get_int32_le,
923 .put = put_int32,
924};
925
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200926/* 64 bit int */
927
928static int get_int64(QEMUFile *f, void *pv, size_t size)
929{
930 int64_t *v = pv;
931 qemu_get_sbe64s(f, v);
932 return 0;
933}
934
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200935static void put_int64(QEMUFile *f, void *pv, size_t size)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200936{
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200937 int64_t *v = pv;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200938 qemu_put_sbe64s(f, v);
939}
940
941const VMStateInfo vmstate_info_int64 = {
942 .name = "int64",
943 .get = get_int64,
944 .put = put_int64,
945};
946
947/* 8 bit unsigned int */
948
949static int get_uint8(QEMUFile *f, void *pv, size_t size)
950{
951 uint8_t *v = pv;
952 qemu_get_8s(f, v);
953 return 0;
954}
955
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200956static void put_uint8(QEMUFile *f, void *pv, size_t size)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200957{
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200958 uint8_t *v = pv;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200959 qemu_put_8s(f, v);
960}
961
962const VMStateInfo vmstate_info_uint8 = {
963 .name = "uint8",
964 .get = get_uint8,
965 .put = put_uint8,
966};
967
968/* 16 bit unsigned int */
969
970static int get_uint16(QEMUFile *f, void *pv, size_t size)
971{
972 uint16_t *v = pv;
973 qemu_get_be16s(f, v);
974 return 0;
975}
976
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200977static void put_uint16(QEMUFile *f, void *pv, size_t size)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200978{
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200979 uint16_t *v = pv;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200980 qemu_put_be16s(f, v);
981}
982
983const VMStateInfo vmstate_info_uint16 = {
984 .name = "uint16",
985 .get = get_uint16,
986 .put = put_uint16,
987};
988
989/* 32 bit unsigned int */
990
991static int get_uint32(QEMUFile *f, void *pv, size_t size)
992{
993 uint32_t *v = pv;
994 qemu_get_be32s(f, v);
995 return 0;
996}
997
Juan Quintela84e2e3e2009-09-29 22:48:20 +0200998static void put_uint32(QEMUFile *f, void *pv, size_t size)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +0200999{
Juan Quintela84e2e3e2009-09-29 22:48:20 +02001000 uint32_t *v = pv;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001001 qemu_put_be32s(f, v);
1002}
1003
1004const VMStateInfo vmstate_info_uint32 = {
1005 .name = "uint32",
1006 .get = get_uint32,
1007 .put = put_uint32,
1008};
1009
Juan Quintela9122a8f2011-03-10 12:33:48 +01001010/* 32 bit uint. See that the received value is the same than the one
1011 in the field */
1012
1013static int get_uint32_equal(QEMUFile *f, void *pv, size_t size)
1014{
1015 uint32_t *v = pv;
1016 uint32_t v2;
1017 qemu_get_be32s(f, &v2);
1018
1019 if (*v == v2) {
1020 return 0;
1021 }
1022 return -EINVAL;
1023}
1024
1025const VMStateInfo vmstate_info_uint32_equal = {
1026 .name = "uint32 equal",
1027 .get = get_uint32_equal,
1028 .put = put_uint32,
1029};
1030
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001031/* 64 bit unsigned int */
1032
1033static int get_uint64(QEMUFile *f, void *pv, size_t size)
1034{
1035 uint64_t *v = pv;
1036 qemu_get_be64s(f, v);
1037 return 0;
1038}
1039
Juan Quintela84e2e3e2009-09-29 22:48:20 +02001040static void put_uint64(QEMUFile *f, void *pv, size_t size)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001041{
Juan Quintela84e2e3e2009-09-29 22:48:20 +02001042 uint64_t *v = pv;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001043 qemu_put_be64s(f, v);
1044}
1045
1046const VMStateInfo vmstate_info_uint64 = {
1047 .name = "uint64",
1048 .get = get_uint64,
1049 .put = put_uint64,
1050};
1051
Juan Quintela80cd83e2009-09-10 03:04:36 +02001052/* 8 bit int. See that the received value is the same than the one
1053 in the field */
1054
1055static int get_uint8_equal(QEMUFile *f, void *pv, size_t size)
1056{
1057 uint8_t *v = pv;
1058 uint8_t v2;
1059 qemu_get_8s(f, &v2);
1060
1061 if (*v == v2)
1062 return 0;
1063 return -EINVAL;
1064}
1065
1066const VMStateInfo vmstate_info_uint8_equal = {
Juan Quintelaaa1cce62009-10-15 19:16:06 +02001067 .name = "uint8 equal",
Juan Quintela80cd83e2009-09-10 03:04:36 +02001068 .get = get_uint8_equal,
1069 .put = put_uint8,
1070};
1071
Juan Quinteladc3b83a2009-10-15 23:16:13 +02001072/* 16 bit unsigned int int. See that the received value is the same than the one
1073 in the field */
1074
1075static int get_uint16_equal(QEMUFile *f, void *pv, size_t size)
1076{
1077 uint16_t *v = pv;
1078 uint16_t v2;
1079 qemu_get_be16s(f, &v2);
1080
1081 if (*v == v2)
1082 return 0;
1083 return -EINVAL;
1084}
1085
1086const VMStateInfo vmstate_info_uint16_equal = {
1087 .name = "uint16 equal",
1088 .get = get_uint16_equal,
1089 .put = put_uint16,
1090};
1091
Juan Quinteladde04632009-08-20 19:42:26 +02001092/* timers */
1093
1094static int get_timer(QEMUFile *f, void *pv, size_t size)
1095{
1096 QEMUTimer *v = pv;
1097 qemu_get_timer(f, v);
1098 return 0;
1099}
1100
Juan Quintela84e2e3e2009-09-29 22:48:20 +02001101static void put_timer(QEMUFile *f, void *pv, size_t size)
Juan Quinteladde04632009-08-20 19:42:26 +02001102{
Juan Quintela84e2e3e2009-09-29 22:48:20 +02001103 QEMUTimer *v = pv;
Juan Quinteladde04632009-08-20 19:42:26 +02001104 qemu_put_timer(f, v);
1105}
1106
1107const VMStateInfo vmstate_info_timer = {
1108 .name = "timer",
1109 .get = get_timer,
1110 .put = put_timer,
1111};
1112
Juan Quintela6f67c502009-08-20 19:42:35 +02001113/* uint8_t buffers */
1114
1115static int get_buffer(QEMUFile *f, void *pv, size_t size)
1116{
1117 uint8_t *v = pv;
1118 qemu_get_buffer(f, v, size);
1119 return 0;
1120}
1121
Juan Quintela84e2e3e2009-09-29 22:48:20 +02001122static void put_buffer(QEMUFile *f, void *pv, size_t size)
Juan Quintela6f67c502009-08-20 19:42:35 +02001123{
Juan Quintela84e2e3e2009-09-29 22:48:20 +02001124 uint8_t *v = pv;
Juan Quintela6f67c502009-08-20 19:42:35 +02001125 qemu_put_buffer(f, v, size);
1126}
1127
1128const VMStateInfo vmstate_info_buffer = {
1129 .name = "buffer",
1130 .get = get_buffer,
1131 .put = put_buffer,
1132};
1133
Juan Quintela76507c72009-10-19 15:46:28 +02001134/* unused buffers: space that was used for some fields that are
Stefan Weil61cc8702011-04-13 22:45:22 +02001135 not useful anymore */
Juan Quintela76507c72009-10-19 15:46:28 +02001136
1137static int get_unused_buffer(QEMUFile *f, void *pv, size_t size)
1138{
Jan Kiszka21174c32009-12-02 12:36:35 +01001139 uint8_t buf[1024];
1140 int block_len;
1141
1142 while (size > 0) {
1143 block_len = MIN(sizeof(buf), size);
1144 size -= block_len;
1145 qemu_get_buffer(f, buf, block_len);
1146 }
1147 return 0;
Juan Quintela76507c72009-10-19 15:46:28 +02001148}
1149
1150static void put_unused_buffer(QEMUFile *f, void *pv, size_t size)
1151{
Jan Kiszka21174c32009-12-02 12:36:35 +01001152 static const uint8_t buf[1024];
1153 int block_len;
1154
1155 while (size > 0) {
1156 block_len = MIN(sizeof(buf), size);
1157 size -= block_len;
1158 qemu_put_buffer(f, buf, block_len);
1159 }
Juan Quintela76507c72009-10-19 15:46:28 +02001160}
1161
1162const VMStateInfo vmstate_info_unused_buffer = {
1163 .name = "unused_buffer",
1164 .get = get_unused_buffer,
1165 .put = put_unused_buffer,
1166};
1167
Peter Maydell08e99e22012-10-30 07:45:12 +00001168/* bitmaps (as defined by bitmap.h). Note that size here is the size
1169 * of the bitmap in bits. The on-the-wire format of a bitmap is 64
1170 * bit words with the bits in big endian order. The in-memory format
1171 * is an array of 'unsigned long', which may be either 32 or 64 bits.
1172 */
1173/* This is the number of 64 bit words sent over the wire */
1174#define BITS_TO_U64S(nr) DIV_ROUND_UP(nr, 64)
1175static int get_bitmap(QEMUFile *f, void *pv, size_t size)
1176{
1177 unsigned long *bmp = pv;
1178 int i, idx = 0;
1179 for (i = 0; i < BITS_TO_U64S(size); i++) {
1180 uint64_t w = qemu_get_be64(f);
1181 bmp[idx++] = w;
1182 if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) {
1183 bmp[idx++] = w >> 32;
1184 }
1185 }
1186 return 0;
1187}
1188
1189static void put_bitmap(QEMUFile *f, void *pv, size_t size)
1190{
1191 unsigned long *bmp = pv;
1192 int i, idx = 0;
1193 for (i = 0; i < BITS_TO_U64S(size); i++) {
1194 uint64_t w = bmp[idx++];
1195 if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) {
1196 w |= ((uint64_t)bmp[idx++]) << 32;
1197 }
1198 qemu_put_be64(f, w);
1199 }
1200}
1201
1202const VMStateInfo vmstate_info_bitmap = {
1203 .name = "bitmap",
1204 .get = get_bitmap,
1205 .put = put_bitmap,
1206};
1207
Alex Williamson7685ee62010-06-25 11:09:14 -06001208typedef struct CompatEntry {
1209 char idstr[256];
1210 int instance_id;
1211} CompatEntry;
1212
aliguoria672b462008-11-11 21:33:36 +00001213typedef struct SaveStateEntry {
Blue Swirl72cf2d42009-09-12 07:36:22 +00001214 QTAILQ_ENTRY(SaveStateEntry) entry;
aliguoria672b462008-11-11 21:33:36 +00001215 char idstr[256];
1216 int instance_id;
Jan Kiszka4d2ffa02010-05-15 13:32:40 +02001217 int alias_id;
aliguoria672b462008-11-11 21:33:36 +00001218 int version_id;
1219 int section_id;
Juan Quintela22ea40f2012-06-26 17:19:10 +02001220 SaveVMHandlers *ops;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001221 const VMStateDescription *vmsd;
aliguoria672b462008-11-11 21:33:36 +00001222 void *opaque;
Alex Williamson7685ee62010-06-25 11:09:14 -06001223 CompatEntry *compat;
Cam Macdonell24312962010-07-26 18:11:00 -06001224 int no_migrate;
Stefano Stabellinia7ae8352012-01-25 12:24:51 +00001225 int is_ram;
aliguoria672b462008-11-11 21:33:36 +00001226} SaveStateEntry;
1227
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +02001228
Blue Swirl72cf2d42009-09-12 07:36:22 +00001229static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers =
1230 QTAILQ_HEAD_INITIALIZER(savevm_handlers);
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001231static int global_section_id;
aliguoria672b462008-11-11 21:33:36 +00001232
Juan Quintela8718e992009-09-01 02:12:31 +02001233static int calculate_new_instance_id(const char *idstr)
1234{
1235 SaveStateEntry *se;
1236 int instance_id = 0;
1237
Blue Swirl72cf2d42009-09-12 07:36:22 +00001238 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
Juan Quintela8718e992009-09-01 02:12:31 +02001239 if (strcmp(idstr, se->idstr) == 0
1240 && instance_id <= se->instance_id) {
1241 instance_id = se->instance_id + 1;
1242 }
1243 }
1244 return instance_id;
1245}
1246
Alex Williamson7685ee62010-06-25 11:09:14 -06001247static int calculate_compat_instance_id(const char *idstr)
1248{
1249 SaveStateEntry *se;
1250 int instance_id = 0;
1251
1252 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1253 if (!se->compat)
1254 continue;
1255
1256 if (strcmp(idstr, se->compat->idstr) == 0
1257 && instance_id <= se->compat->instance_id) {
1258 instance_id = se->compat->instance_id + 1;
1259 }
1260 }
1261 return instance_id;
1262}
1263
aliguoria672b462008-11-11 21:33:36 +00001264/* TODO: Individual devices generally have very little idea about the rest
1265 of the system, so instance_id should be removed/replaced.
1266 Meanwhile pass -1 as instance_id if you do not already have a clearly
1267 distinguishing id for all instances of your device class. */
Alex Williamson0be71e32010-06-25 11:09:07 -06001268int register_savevm_live(DeviceState *dev,
1269 const char *idstr,
aliguoria672b462008-11-11 21:33:36 +00001270 int instance_id,
1271 int version_id,
Juan Quintela7908c782012-06-26 18:46:10 +02001272 SaveVMHandlers *ops,
aliguoria672b462008-11-11 21:33:36 +00001273 void *opaque)
1274{
Juan Quintela8718e992009-09-01 02:12:31 +02001275 SaveStateEntry *se;
aliguoria672b462008-11-11 21:33:36 +00001276
Anthony Liguori7267c092011-08-20 22:09:37 -05001277 se = g_malloc0(sizeof(SaveStateEntry));
aliguoria672b462008-11-11 21:33:36 +00001278 se->version_id = version_id;
1279 se->section_id = global_section_id++;
Juan Quintela7908c782012-06-26 18:46:10 +02001280 se->ops = ops;
aliguoria672b462008-11-11 21:33:36 +00001281 se->opaque = opaque;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001282 se->vmsd = NULL;
Cam Macdonell24312962010-07-26 18:11:00 -06001283 se->no_migrate = 0;
Stefano Stabellinia7ae8352012-01-25 12:24:51 +00001284 /* if this is a live_savem then set is_ram */
Juan Quintela16310a32012-06-28 15:31:37 +02001285 if (ops->save_live_setup != NULL) {
Stefano Stabellinia7ae8352012-01-25 12:24:51 +00001286 se->is_ram = 1;
1287 }
aliguoria672b462008-11-11 21:33:36 +00001288
Anthony Liguori09e5ab62012-02-03 12:28:43 -06001289 if (dev) {
1290 char *id = qdev_get_dev_path(dev);
Alex Williamson7685ee62010-06-25 11:09:14 -06001291 if (id) {
1292 pstrcpy(se->idstr, sizeof(se->idstr), id);
1293 pstrcat(se->idstr, sizeof(se->idstr), "/");
Anthony Liguori7267c092011-08-20 22:09:37 -05001294 g_free(id);
Alex Williamson7685ee62010-06-25 11:09:14 -06001295
Anthony Liguori7267c092011-08-20 22:09:37 -05001296 se->compat = g_malloc0(sizeof(CompatEntry));
Alex Williamson7685ee62010-06-25 11:09:14 -06001297 pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), idstr);
1298 se->compat->instance_id = instance_id == -1 ?
1299 calculate_compat_instance_id(idstr) : instance_id;
1300 instance_id = -1;
1301 }
1302 }
1303 pstrcat(se->idstr, sizeof(se->idstr), idstr);
1304
Juan Quintela8718e992009-09-01 02:12:31 +02001305 if (instance_id == -1) {
Alex Williamson7685ee62010-06-25 11:09:14 -06001306 se->instance_id = calculate_new_instance_id(se->idstr);
Juan Quintela8718e992009-09-01 02:12:31 +02001307 } else {
1308 se->instance_id = instance_id;
aliguoria672b462008-11-11 21:33:36 +00001309 }
Alex Williamson7685ee62010-06-25 11:09:14 -06001310 assert(!se->compat || se->instance_id == 0);
Juan Quintela8718e992009-09-01 02:12:31 +02001311 /* add at the end of list */
Blue Swirl72cf2d42009-09-12 07:36:22 +00001312 QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
aliguoria672b462008-11-11 21:33:36 +00001313 return 0;
1314}
1315
Alex Williamson0be71e32010-06-25 11:09:07 -06001316int register_savevm(DeviceState *dev,
1317 const char *idstr,
aliguoria672b462008-11-11 21:33:36 +00001318 int instance_id,
1319 int version_id,
1320 SaveStateHandler *save_state,
1321 LoadStateHandler *load_state,
1322 void *opaque)
1323{
Juan Quintela7908c782012-06-26 18:46:10 +02001324 SaveVMHandlers *ops = g_malloc0(sizeof(SaveVMHandlers));
1325 ops->save_state = save_state;
1326 ops->load_state = load_state;
Alex Williamson0be71e32010-06-25 11:09:07 -06001327 return register_savevm_live(dev, idstr, instance_id, version_id,
Juan Quintela7908c782012-06-26 18:46:10 +02001328 ops, opaque);
aliguoria672b462008-11-11 21:33:36 +00001329}
1330
Alex Williamson0be71e32010-06-25 11:09:07 -06001331void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque)
aliguori41bd13a2009-04-17 17:10:59 +00001332{
Juan Quintela8718e992009-09-01 02:12:31 +02001333 SaveStateEntry *se, *new_se;
Alex Williamson7685ee62010-06-25 11:09:14 -06001334 char id[256] = "";
1335
Anthony Liguori09e5ab62012-02-03 12:28:43 -06001336 if (dev) {
1337 char *path = qdev_get_dev_path(dev);
Alex Williamson7685ee62010-06-25 11:09:14 -06001338 if (path) {
1339 pstrcpy(id, sizeof(id), path);
1340 pstrcat(id, sizeof(id), "/");
Anthony Liguori7267c092011-08-20 22:09:37 -05001341 g_free(path);
Alex Williamson7685ee62010-06-25 11:09:14 -06001342 }
1343 }
1344 pstrcat(id, sizeof(id), idstr);
aliguori41bd13a2009-04-17 17:10:59 +00001345
Blue Swirl72cf2d42009-09-12 07:36:22 +00001346 QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
Alex Williamson7685ee62010-06-25 11:09:14 -06001347 if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {
Blue Swirl72cf2d42009-09-12 07:36:22 +00001348 QTAILQ_REMOVE(&savevm_handlers, se, entry);
Alex Williamson69e58af2010-07-21 08:35:31 -06001349 if (se->compat) {
Anthony Liguori7267c092011-08-20 22:09:37 -05001350 g_free(se->compat);
Alex Williamson69e58af2010-07-21 08:35:31 -06001351 }
Juan Quintela22ea40f2012-06-26 17:19:10 +02001352 g_free(se->ops);
Anthony Liguori7267c092011-08-20 22:09:37 -05001353 g_free(se);
aliguori41bd13a2009-04-17 17:10:59 +00001354 }
aliguori41bd13a2009-04-17 17:10:59 +00001355 }
1356}
1357
Alex Williamson0be71e32010-06-25 11:09:07 -06001358int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
Jan Kiszka4d2ffa02010-05-15 13:32:40 +02001359 const VMStateDescription *vmsd,
1360 void *opaque, int alias_id,
1361 int required_for_version)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001362{
Juan Quintela8718e992009-09-01 02:12:31 +02001363 SaveStateEntry *se;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001364
Jan Kiszka4d2ffa02010-05-15 13:32:40 +02001365 /* If this triggers, alias support can be dropped for the vmsd. */
1366 assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id);
1367
Anthony Liguori7267c092011-08-20 22:09:37 -05001368 se = g_malloc0(sizeof(SaveStateEntry));
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001369 se->version_id = vmsd->version_id;
1370 se->section_id = global_section_id++;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001371 se->opaque = opaque;
1372 se->vmsd = vmsd;
Jan Kiszka4d2ffa02010-05-15 13:32:40 +02001373 se->alias_id = alias_id;
Gerd Hoffmann2837c8e2011-07-08 10:44:35 +02001374 se->no_migrate = vmsd->unmigratable;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001375
Anthony Liguori09e5ab62012-02-03 12:28:43 -06001376 if (dev) {
1377 char *id = qdev_get_dev_path(dev);
Alex Williamson7685ee62010-06-25 11:09:14 -06001378 if (id) {
1379 pstrcpy(se->idstr, sizeof(se->idstr), id);
1380 pstrcat(se->idstr, sizeof(se->idstr), "/");
Anthony Liguori7267c092011-08-20 22:09:37 -05001381 g_free(id);
Alex Williamson7685ee62010-06-25 11:09:14 -06001382
Anthony Liguori7267c092011-08-20 22:09:37 -05001383 se->compat = g_malloc0(sizeof(CompatEntry));
Alex Williamson7685ee62010-06-25 11:09:14 -06001384 pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name);
1385 se->compat->instance_id = instance_id == -1 ?
1386 calculate_compat_instance_id(vmsd->name) : instance_id;
1387 instance_id = -1;
1388 }
1389 }
1390 pstrcat(se->idstr, sizeof(se->idstr), vmsd->name);
1391
Juan Quintela8718e992009-09-01 02:12:31 +02001392 if (instance_id == -1) {
Alex Williamson7685ee62010-06-25 11:09:14 -06001393 se->instance_id = calculate_new_instance_id(se->idstr);
Juan Quintela8718e992009-09-01 02:12:31 +02001394 } else {
1395 se->instance_id = instance_id;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001396 }
Alex Williamson7685ee62010-06-25 11:09:14 -06001397 assert(!se->compat || se->instance_id == 0);
Juan Quintela8718e992009-09-01 02:12:31 +02001398 /* add at the end of list */
Blue Swirl72cf2d42009-09-12 07:36:22 +00001399 QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001400 return 0;
1401}
1402
Alex Williamson0be71e32010-06-25 11:09:07 -06001403int vmstate_register(DeviceState *dev, int instance_id,
1404 const VMStateDescription *vmsd, void *opaque)
Jan Kiszka4d2ffa02010-05-15 13:32:40 +02001405{
Alex Williamson0be71e32010-06-25 11:09:07 -06001406 return vmstate_register_with_alias_id(dev, instance_id, vmsd,
1407 opaque, -1, 0);
Jan Kiszka4d2ffa02010-05-15 13:32:40 +02001408}
1409
Alex Williamson0be71e32010-06-25 11:09:07 -06001410void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
1411 void *opaque)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001412{
Juan Quintela1eb75382009-09-10 03:04:29 +02001413 SaveStateEntry *se, *new_se;
1414
Blue Swirl72cf2d42009-09-12 07:36:22 +00001415 QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
Juan Quintela1eb75382009-09-10 03:04:29 +02001416 if (se->vmsd == vmsd && se->opaque == opaque) {
Blue Swirl72cf2d42009-09-12 07:36:22 +00001417 QTAILQ_REMOVE(&savevm_handlers, se, entry);
Alex Williamson69e58af2010-07-21 08:35:31 -06001418 if (se->compat) {
Anthony Liguori7267c092011-08-20 22:09:37 -05001419 g_free(se->compat);
Alex Williamson69e58af2010-07-21 08:35:31 -06001420 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001421 g_free(se);
Juan Quintela1eb75382009-09-10 03:04:29 +02001422 }
1423 }
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001424}
1425
Juan Quintela811814b2010-07-26 21:38:43 +02001426static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
1427 void *opaque);
1428static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
1429 void *opaque);
1430
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001431int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
1432 void *opaque, int version_id)
1433{
1434 VMStateField *field = vmsd->fields;
Juan Quintela811814b2010-07-26 21:38:43 +02001435 int ret;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001436
1437 if (version_id > vmsd->version_id) {
1438 return -EINVAL;
1439 }
1440 if (version_id < vmsd->minimum_version_id_old) {
1441 return -EINVAL;
1442 }
1443 if (version_id < vmsd->minimum_version_id) {
1444 return vmsd->load_state_old(f, opaque, version_id);
1445 }
Juan Quintelafd4d52d2009-09-10 03:04:31 +02001446 if (vmsd->pre_load) {
1447 int ret = vmsd->pre_load(opaque);
1448 if (ret)
1449 return ret;
1450 }
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001451 while(field->name) {
Juan Quintelaf11f6a52009-09-29 22:49:07 +02001452 if ((field->field_exists &&
1453 field->field_exists(opaque, version_id)) ||
1454 (!field->field_exists &&
1455 field->version_id <= version_id)) {
Juan Quintelaf752a6a2009-08-20 19:42:27 +02001456 void *base_addr = opaque + field->offset;
Juan Quintela811814b2010-07-26 21:38:43 +02001457 int i, n_elems = 1;
Juan Quintelae61a1e02009-12-02 12:36:38 +01001458 int size = field->size;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001459
Juan Quintelae61a1e02009-12-02 12:36:38 +01001460 if (field->flags & VMS_VBUFFER) {
1461 size = *(int32_t *)(opaque+field->size_offset);
Juan Quintela33599e22009-12-02 12:36:43 +01001462 if (field->flags & VMS_MULTIPLY) {
1463 size *= field->size;
1464 }
Juan Quintelae61a1e02009-12-02 12:36:38 +01001465 }
Juan Quintelaf752a6a2009-08-20 19:42:27 +02001466 if (field->flags & VMS_ARRAY) {
1467 n_elems = field->num;
Juan Quintelad6698282009-10-16 11:27:17 +02001468 } else if (field->flags & VMS_VARRAY_INT32) {
1469 n_elems = *(int32_t *)(opaque+field->num_offset);
Juan Quintelaa624b082011-03-10 12:33:50 +01001470 } else if (field->flags & VMS_VARRAY_UINT32) {
1471 n_elems = *(uint32_t *)(opaque+field->num_offset);
Juan Quintelabdb49412009-10-16 11:35:18 +02001472 } else if (field->flags & VMS_VARRAY_UINT16) {
1473 n_elems = *(uint16_t *)(opaque+field->num_offset);
Juan Quintela82fa39b2011-03-10 12:33:49 +01001474 } else if (field->flags & VMS_VARRAY_UINT8) {
1475 n_elems = *(uint8_t *)(opaque+field->num_offset);
Juan Quinteladde04632009-08-20 19:42:26 +02001476 }
Juan Quintelaf752a6a2009-08-20 19:42:27 +02001477 if (field->flags & VMS_POINTER) {
Juan Quintelae61a1e02009-12-02 12:36:38 +01001478 base_addr = *(void **)base_addr + field->start;
Juan Quintelaf752a6a2009-08-20 19:42:27 +02001479 }
1480 for (i = 0; i < n_elems; i++) {
Juan Quintelae61a1e02009-12-02 12:36:38 +01001481 void *addr = base_addr + size * i;
Juan Quintelaec245e22009-08-20 19:42:29 +02001482
Juan Quintela19df4382009-09-29 22:48:41 +02001483 if (field->flags & VMS_ARRAY_OF_POINTER) {
1484 addr = *(void **)addr;
1485 }
Juan Quintelaec245e22009-08-20 19:42:29 +02001486 if (field->flags & VMS_STRUCT) {
Juan Quintelafa3aad22009-08-28 15:28:25 +02001487 ret = vmstate_load_state(f, field->vmsd, addr, field->vmsd->version_id);
Juan Quintelaec245e22009-08-20 19:42:29 +02001488 } else {
Juan Quintelae61a1e02009-12-02 12:36:38 +01001489 ret = field->info->get(f, addr, size);
Juan Quintelaec245e22009-08-20 19:42:29 +02001490
1491 }
Juan Quintelaf752a6a2009-08-20 19:42:27 +02001492 if (ret < 0) {
1493 return ret;
1494 }
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001495 }
1496 }
1497 field++;
1498 }
Juan Quintela811814b2010-07-26 21:38:43 +02001499 ret = vmstate_subsection_load(f, vmsd, opaque);
1500 if (ret != 0) {
1501 return ret;
1502 }
Juan Quintela752ff2f2009-09-10 03:04:30 +02001503 if (vmsd->post_load) {
Juan Quintelae59fb372009-09-29 22:48:21 +02001504 return vmsd->post_load(opaque, version_id);
Juan Quintela752ff2f2009-09-10 03:04:30 +02001505 }
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001506 return 0;
1507}
1508
1509void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
Juan Quintela84e2e3e2009-09-29 22:48:20 +02001510 void *opaque)
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001511{
1512 VMStateField *field = vmsd->fields;
1513
Juan Quintela8fb07912009-09-10 03:04:32 +02001514 if (vmsd->pre_save) {
1515 vmsd->pre_save(opaque);
1516 }
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001517 while(field->name) {
Juan Quintelaf11f6a52009-09-29 22:49:07 +02001518 if (!field->field_exists ||
1519 field->field_exists(opaque, vmsd->version_id)) {
1520 void *base_addr = opaque + field->offset;
1521 int i, n_elems = 1;
Juan Quintelae61a1e02009-12-02 12:36:38 +01001522 int size = field->size;
Juan Quinteladde04632009-08-20 19:42:26 +02001523
Juan Quintelae61a1e02009-12-02 12:36:38 +01001524 if (field->flags & VMS_VBUFFER) {
1525 size = *(int32_t *)(opaque+field->size_offset);
Juan Quintela33599e22009-12-02 12:36:43 +01001526 if (field->flags & VMS_MULTIPLY) {
1527 size *= field->size;
1528 }
Juan Quintelae61a1e02009-12-02 12:36:38 +01001529 }
Juan Quintelaf11f6a52009-09-29 22:49:07 +02001530 if (field->flags & VMS_ARRAY) {
1531 n_elems = field->num;
Juan Quintelad6698282009-10-16 11:27:17 +02001532 } else if (field->flags & VMS_VARRAY_INT32) {
1533 n_elems = *(int32_t *)(opaque+field->num_offset);
Amos Kong1329d182012-03-13 14:05:36 +08001534 } else if (field->flags & VMS_VARRAY_UINT32) {
1535 n_elems = *(uint32_t *)(opaque+field->num_offset);
Juan Quintelabdb49412009-10-16 11:35:18 +02001536 } else if (field->flags & VMS_VARRAY_UINT16) {
1537 n_elems = *(uint16_t *)(opaque+field->num_offset);
Juan Quintelab7844212011-03-15 15:53:25 +01001538 } else if (field->flags & VMS_VARRAY_UINT8) {
1539 n_elems = *(uint8_t *)(opaque+field->num_offset);
Juan Quintelaf11f6a52009-09-29 22:49:07 +02001540 }
1541 if (field->flags & VMS_POINTER) {
Juan Quintelae61a1e02009-12-02 12:36:38 +01001542 base_addr = *(void **)base_addr + field->start;
Juan Quintelaf11f6a52009-09-29 22:49:07 +02001543 }
1544 for (i = 0; i < n_elems; i++) {
Juan Quintelae61a1e02009-12-02 12:36:38 +01001545 void *addr = base_addr + size * i;
Juan Quintelaec245e22009-08-20 19:42:29 +02001546
Juan Quintela85953872009-12-02 12:36:37 +01001547 if (field->flags & VMS_ARRAY_OF_POINTER) {
1548 addr = *(void **)addr;
1549 }
Juan Quintelaf11f6a52009-09-29 22:49:07 +02001550 if (field->flags & VMS_STRUCT) {
1551 vmstate_save_state(f, field->vmsd, addr);
1552 } else {
Juan Quintelae61a1e02009-12-02 12:36:38 +01001553 field->info->put(f, addr, size);
Juan Quintelaf11f6a52009-09-29 22:49:07 +02001554 }
Juan Quintelaec245e22009-08-20 19:42:29 +02001555 }
Juan Quintelaf752a6a2009-08-20 19:42:27 +02001556 }
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001557 field++;
1558 }
Juan Quintela811814b2010-07-26 21:38:43 +02001559 vmstate_subsection_save(f, vmsd, opaque);
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001560}
1561
Juan Quintela4082be42009-08-20 19:42:24 +02001562static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
1563{
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001564 if (!se->vmsd) { /* Old style */
Juan Quintela22ea40f2012-06-26 17:19:10 +02001565 return se->ops->load_state(f, se->opaque, version_id);
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001566 }
1567 return vmstate_load_state(f, se->vmsd, se->opaque, version_id);
Juan Quintela4082be42009-08-20 19:42:24 +02001568}
1569
Alex Williamsondc912122011-01-11 14:39:43 -07001570static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
Juan Quintela4082be42009-08-20 19:42:24 +02001571{
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001572 if (!se->vmsd) { /* Old style */
Juan Quintela22ea40f2012-06-26 17:19:10 +02001573 se->ops->save_state(f, se->opaque);
Alex Williamsondc912122011-01-11 14:39:43 -07001574 return;
Juan Quintela9ed7d6a2009-08-20 19:42:25 +02001575 }
1576 vmstate_save_state(f,se->vmsd, se->opaque);
Juan Quintela4082be42009-08-20 19:42:24 +02001577}
1578
aliguoria672b462008-11-11 21:33:36 +00001579#define QEMU_VM_FILE_MAGIC 0x5145564d
1580#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
1581#define QEMU_VM_FILE_VERSION 0x00000003
1582
1583#define QEMU_VM_EOF 0x00
1584#define QEMU_VM_SECTION_START 0x01
1585#define QEMU_VM_SECTION_PART 0x02
1586#define QEMU_VM_SECTION_END 0x03
1587#define QEMU_VM_SECTION_FULL 0x04
Juan Quintela811814b2010-07-26 21:38:43 +02001588#define QEMU_VM_SUBSECTION 0x05
aliguoria672b462008-11-11 21:33:36 +00001589
Luiz Capitulinoe1c37d02011-12-05 14:48:01 -02001590bool qemu_savevm_state_blocked(Error **errp)
Alex Williamsondc912122011-01-11 14:39:43 -07001591{
1592 SaveStateEntry *se;
1593
1594 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1595 if (se->no_migrate) {
Luiz Capitulinoe1c37d02011-12-05 14:48:01 -02001596 error_set(errp, QERR_MIGRATION_NOT_SUPPORTED, se->idstr);
Alex Williamsondc912122011-01-11 14:39:43 -07001597 return true;
1598 }
1599 }
1600 return false;
1601}
1602
Isaku Yamahata6607ae22012-06-19 18:43:09 +03001603int qemu_savevm_state_begin(QEMUFile *f,
1604 const MigrationParams *params)
aliguoria672b462008-11-11 21:33:36 +00001605{
1606 SaveStateEntry *se;
Juan Quintela39346382011-09-22 11:02:14 +02001607 int ret;
aliguoria672b462008-11-11 21:33:36 +00001608
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +02001609 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
Juan Quintela22ea40f2012-06-26 17:19:10 +02001610 if (!se->ops || !se->ops->set_params) {
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +02001611 continue;
Isaku Yamahata6607ae22012-06-19 18:43:09 +03001612 }
Juan Quintela22ea40f2012-06-26 17:19:10 +02001613 se->ops->set_params(params, se->opaque);
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +02001614 }
1615
aliguoria672b462008-11-11 21:33:36 +00001616 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1617 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1618
Blue Swirl72cf2d42009-09-12 07:36:22 +00001619 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
aliguoria672b462008-11-11 21:33:36 +00001620 int len;
1621
Juan Quintelad1315aa2012-06-28 15:11:57 +02001622 if (!se->ops || !se->ops->save_live_setup) {
aliguoria672b462008-11-11 21:33:36 +00001623 continue;
Juan Quintela22ea40f2012-06-26 17:19:10 +02001624 }
Juan Quintela6bd68782012-06-27 10:59:15 +02001625 if (se->ops && se->ops->is_active) {
1626 if (!se->ops->is_active(se->opaque)) {
1627 continue;
1628 }
1629 }
aliguoria672b462008-11-11 21:33:36 +00001630 /* Section type */
1631 qemu_put_byte(f, QEMU_VM_SECTION_START);
1632 qemu_put_be32(f, se->section_id);
1633
1634 /* ID string */
1635 len = strlen(se->idstr);
1636 qemu_put_byte(f, len);
1637 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1638
1639 qemu_put_be32(f, se->instance_id);
1640 qemu_put_be32(f, se->version_id);
1641
Juan Quintelad1315aa2012-06-28 15:11:57 +02001642 ret = se->ops->save_live_setup(f, se->opaque);
Juan Quintela29757252011-10-19 15:22:18 +02001643 if (ret < 0) {
Luiz Capitulino539de122011-12-05 14:06:56 -02001644 qemu_savevm_state_cancel(f);
Juan Quintela29757252011-10-19 15:22:18 +02001645 return ret;
1646 }
aliguoria672b462008-11-11 21:33:36 +00001647 }
Juan Quintela624b9cc2011-10-05 01:02:52 +02001648 ret = qemu_file_get_error(f);
Juan Quintela39346382011-09-22 11:02:14 +02001649 if (ret != 0) {
Luiz Capitulino539de122011-12-05 14:06:56 -02001650 qemu_savevm_state_cancel(f);
Jan Kiszka4ec7fcc2009-11-30 18:21:21 +01001651 }
aliguoria672b462008-11-11 21:33:36 +00001652
Juan Quintela39346382011-09-22 11:02:14 +02001653 return ret;
1654
aliguoria672b462008-11-11 21:33:36 +00001655}
1656
Juan Quintela39346382011-09-22 11:02:14 +02001657/*
Dong Xu Wang07f35072011-11-22 18:06:26 +08001658 * this function has three return values:
Juan Quintela39346382011-09-22 11:02:14 +02001659 * negative: there was one error, and we have -errno.
1660 * 0 : We haven't finished, caller have to go again
1661 * 1 : We have finished, we can go to complete phase
1662 */
Luiz Capitulino539de122011-12-05 14:06:56 -02001663int qemu_savevm_state_iterate(QEMUFile *f)
aliguoria672b462008-11-11 21:33:36 +00001664{
1665 SaveStateEntry *se;
1666 int ret = 1;
1667
Blue Swirl72cf2d42009-09-12 07:36:22 +00001668 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
Juan Quintela16310a32012-06-28 15:31:37 +02001669 if (!se->ops || !se->ops->save_live_iterate) {
aliguoria672b462008-11-11 21:33:36 +00001670 continue;
Juan Quintela22ea40f2012-06-26 17:19:10 +02001671 }
Juan Quintela6bd68782012-06-27 10:59:15 +02001672 if (se->ops && se->ops->is_active) {
1673 if (!se->ops->is_active(se->opaque)) {
1674 continue;
1675 }
1676 }
Juan Quintelaaac844e2012-05-22 00:38:26 +02001677 if (qemu_file_rate_limit(f)) {
1678 return 0;
1679 }
Juan Quintela517a13c2012-05-21 23:46:44 +02001680 trace_savevm_section_start();
aliguoria672b462008-11-11 21:33:36 +00001681 /* Section type */
1682 qemu_put_byte(f, QEMU_VM_SECTION_PART);
1683 qemu_put_be32(f, se->section_id);
1684
Juan Quintela16310a32012-06-28 15:31:37 +02001685 ret = se->ops->save_live_iterate(f, se->opaque);
Juan Quintela517a13c2012-05-21 23:46:44 +02001686 trace_savevm_section_end(se->section_id);
1687
Juan Quintela29757252011-10-19 15:22:18 +02001688 if (ret <= 0) {
Jan Kiszka90697be2009-12-01 15:19:55 +01001689 /* Do not proceed to the next vmstate before this one reported
1690 completion of the current stage. This serializes the migration
1691 and reduces the probability that a faster changing state is
1692 synchronized over and over again. */
1693 break;
1694 }
aliguoria672b462008-11-11 21:33:36 +00001695 }
Juan Quintela39346382011-09-22 11:02:14 +02001696 if (ret != 0) {
1697 return ret;
Jan Kiszka4ec7fcc2009-11-30 18:21:21 +01001698 }
Juan Quintela624b9cc2011-10-05 01:02:52 +02001699 ret = qemu_file_get_error(f);
Juan Quintela39346382011-09-22 11:02:14 +02001700 if (ret != 0) {
Luiz Capitulino539de122011-12-05 14:06:56 -02001701 qemu_savevm_state_cancel(f);
Juan Quintela39346382011-09-22 11:02:14 +02001702 }
1703 return ret;
aliguoria672b462008-11-11 21:33:36 +00001704}
1705
Luiz Capitulino539de122011-12-05 14:06:56 -02001706int qemu_savevm_state_complete(QEMUFile *f)
aliguoria672b462008-11-11 21:33:36 +00001707{
1708 SaveStateEntry *se;
Juan Quintela29757252011-10-19 15:22:18 +02001709 int ret;
aliguoria672b462008-11-11 21:33:36 +00001710
Jan Kiszkaea375f92010-03-01 19:10:30 +01001711 cpu_synchronize_all_states();
1712
Blue Swirl72cf2d42009-09-12 07:36:22 +00001713 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
Juan Quintela16310a32012-06-28 15:31:37 +02001714 if (!se->ops || !se->ops->save_live_complete) {
aliguoria672b462008-11-11 21:33:36 +00001715 continue;
Juan Quintela22ea40f2012-06-26 17:19:10 +02001716 }
Juan Quintela6bd68782012-06-27 10:59:15 +02001717 if (se->ops && se->ops->is_active) {
1718 if (!se->ops->is_active(se->opaque)) {
1719 continue;
1720 }
1721 }
Juan Quintela517a13c2012-05-21 23:46:44 +02001722 trace_savevm_section_start();
aliguoria672b462008-11-11 21:33:36 +00001723 /* Section type */
1724 qemu_put_byte(f, QEMU_VM_SECTION_END);
1725 qemu_put_be32(f, se->section_id);
1726
Juan Quintela16310a32012-06-28 15:31:37 +02001727 ret = se->ops->save_live_complete(f, se->opaque);
Juan Quintela517a13c2012-05-21 23:46:44 +02001728 trace_savevm_section_end(se->section_id);
Juan Quintela29757252011-10-19 15:22:18 +02001729 if (ret < 0) {
1730 return ret;
1731 }
aliguoria672b462008-11-11 21:33:36 +00001732 }
1733
Blue Swirl72cf2d42009-09-12 07:36:22 +00001734 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
aliguoria672b462008-11-11 21:33:36 +00001735 int len;
1736
Juan Quintela22ea40f2012-06-26 17:19:10 +02001737 if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
aliguoria672b462008-11-11 21:33:36 +00001738 continue;
Juan Quintela22ea40f2012-06-26 17:19:10 +02001739 }
Juan Quintela517a13c2012-05-21 23:46:44 +02001740 trace_savevm_section_start();
aliguoria672b462008-11-11 21:33:36 +00001741 /* Section type */
1742 qemu_put_byte(f, QEMU_VM_SECTION_FULL);
1743 qemu_put_be32(f, se->section_id);
1744
1745 /* ID string */
1746 len = strlen(se->idstr);
1747 qemu_put_byte(f, len);
1748 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1749
1750 qemu_put_be32(f, se->instance_id);
1751 qemu_put_be32(f, se->version_id);
1752
Alex Williamsondc912122011-01-11 14:39:43 -07001753 vmstate_save(f, se);
Juan Quintela517a13c2012-05-21 23:46:44 +02001754 trace_savevm_section_end(se->section_id);
aliguoria672b462008-11-11 21:33:36 +00001755 }
1756
1757 qemu_put_byte(f, QEMU_VM_EOF);
1758
Juan Quintela624b9cc2011-10-05 01:02:52 +02001759 return qemu_file_get_error(f);
aliguoria672b462008-11-11 21:33:36 +00001760}
1761
Luiz Capitulino539de122011-12-05 14:06:56 -02001762void qemu_savevm_state_cancel(QEMUFile *f)
Jan Kiszka4ec7fcc2009-11-30 18:21:21 +01001763{
1764 SaveStateEntry *se;
1765
1766 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
Juan Quintela9b5bfab2012-06-26 19:26:41 +02001767 if (se->ops && se->ops->cancel) {
1768 se->ops->cancel(se->opaque);
Jan Kiszka4ec7fcc2009-11-30 18:21:21 +01001769 }
1770 }
1771}
1772
Luiz Capitulinoe1c37d02011-12-05 14:48:01 -02001773static int qemu_savevm_state(QEMUFile *f)
aliguoria672b462008-11-11 21:33:36 +00001774{
aliguoria672b462008-11-11 21:33:36 +00001775 int ret;
Isaku Yamahata6607ae22012-06-19 18:43:09 +03001776 MigrationParams params = {
1777 .blk = 0,
1778 .shared = 0
1779 };
aliguoria672b462008-11-11 21:33:36 +00001780
Luiz Capitulinoe1c37d02011-12-05 14:48:01 -02001781 if (qemu_savevm_state_blocked(NULL)) {
Alex Williamsondc912122011-01-11 14:39:43 -07001782 ret = -EINVAL;
1783 goto out;
1784 }
1785
Isaku Yamahata6607ae22012-06-19 18:43:09 +03001786 ret = qemu_savevm_state_begin(f, &params);
aliguoria672b462008-11-11 21:33:36 +00001787 if (ret < 0)
1788 goto out;
1789
1790 do {
Luiz Capitulino539de122011-12-05 14:06:56 -02001791 ret = qemu_savevm_state_iterate(f);
aliguoria672b462008-11-11 21:33:36 +00001792 if (ret < 0)
1793 goto out;
1794 } while (ret == 0);
1795
Luiz Capitulino539de122011-12-05 14:06:56 -02001796 ret = qemu_savevm_state_complete(f);
aliguoria672b462008-11-11 21:33:36 +00001797
1798out:
Juan Quintela39346382011-09-22 11:02:14 +02001799 if (ret == 0) {
Juan Quintela624b9cc2011-10-05 01:02:52 +02001800 ret = qemu_file_get_error(f);
Juan Quintela39346382011-09-22 11:02:14 +02001801 }
aliguoria672b462008-11-11 21:33:36 +00001802
aliguoria672b462008-11-11 21:33:36 +00001803 return ret;
1804}
1805
Stefano Stabellinia7ae8352012-01-25 12:24:51 +00001806static int qemu_save_device_state(QEMUFile *f)
1807{
1808 SaveStateEntry *se;
1809
1810 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1811 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1812
1813 cpu_synchronize_all_states();
1814
1815 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1816 int len;
1817
1818 if (se->is_ram) {
1819 continue;
1820 }
Juan Quintela22ea40f2012-06-26 17:19:10 +02001821 if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
Stefano Stabellinia7ae8352012-01-25 12:24:51 +00001822 continue;
1823 }
1824
1825 /* Section type */
1826 qemu_put_byte(f, QEMU_VM_SECTION_FULL);
1827 qemu_put_be32(f, se->section_id);
1828
1829 /* ID string */
1830 len = strlen(se->idstr);
1831 qemu_put_byte(f, len);
1832 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1833
1834 qemu_put_be32(f, se->instance_id);
1835 qemu_put_be32(f, se->version_id);
1836
1837 vmstate_save(f, se);
1838 }
1839
1840 qemu_put_byte(f, QEMU_VM_EOF);
1841
1842 return qemu_file_get_error(f);
1843}
1844
aliguoria672b462008-11-11 21:33:36 +00001845static SaveStateEntry *find_se(const char *idstr, int instance_id)
1846{
1847 SaveStateEntry *se;
1848
Blue Swirl72cf2d42009-09-12 07:36:22 +00001849 QTAILQ_FOREACH(se, &savevm_handlers, entry) {
aliguoria672b462008-11-11 21:33:36 +00001850 if (!strcmp(se->idstr, idstr) &&
Jan Kiszka4d2ffa02010-05-15 13:32:40 +02001851 (instance_id == se->instance_id ||
1852 instance_id == se->alias_id))
aliguoria672b462008-11-11 21:33:36 +00001853 return se;
Alex Williamson7685ee62010-06-25 11:09:14 -06001854 /* Migrating from an older version? */
1855 if (strstr(se->idstr, idstr) && se->compat) {
1856 if (!strcmp(se->compat->idstr, idstr) &&
1857 (instance_id == se->compat->instance_id ||
1858 instance_id == se->alias_id))
1859 return se;
1860 }
aliguoria672b462008-11-11 21:33:36 +00001861 }
1862 return NULL;
1863}
1864
Juan Quintela811814b2010-07-26 21:38:43 +02001865static const VMStateDescription *vmstate_get_subsection(const VMStateSubsection *sub, char *idstr)
1866{
1867 while(sub && sub->needed) {
1868 if (strcmp(idstr, sub->vmsd->name) == 0) {
1869 return sub->vmsd;
1870 }
1871 sub++;
1872 }
1873 return NULL;
1874}
1875
1876static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
1877 void *opaque)
1878{
Juan Quintelac6380722011-10-04 15:28:31 +02001879 while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) {
Juan Quintela811814b2010-07-26 21:38:43 +02001880 char idstr[256];
1881 int ret;
Juan Quintelac6380722011-10-04 15:28:31 +02001882 uint8_t version_id, len, size;
Juan Quintela811814b2010-07-26 21:38:43 +02001883 const VMStateDescription *sub_vmsd;
1884
Juan Quintelac6380722011-10-04 15:28:31 +02001885 len = qemu_peek_byte(f, 1);
1886 if (len < strlen(vmsd->name) + 1) {
1887 /* subsection name has be be "section_name/a" */
1888 return 0;
1889 }
1890 size = qemu_peek_buffer(f, (uint8_t *)idstr, len, 2);
1891 if (size != len) {
1892 return 0;
1893 }
1894 idstr[size] = 0;
Juan Quintela811814b2010-07-26 21:38:43 +02001895
Juan Quintelac6380722011-10-04 15:28:31 +02001896 if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) {
1897 /* it don't have a valid subsection name */
1898 return 0;
1899 }
Juan Quintela3da9eeb2011-09-30 19:46:43 +02001900 sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr);
Juan Quintela811814b2010-07-26 21:38:43 +02001901 if (sub_vmsd == NULL) {
1902 return -ENOENT;
1903 }
Juan Quintelac6380722011-10-04 15:28:31 +02001904 qemu_file_skip(f, 1); /* subsection */
1905 qemu_file_skip(f, 1); /* len */
1906 qemu_file_skip(f, len); /* idstr */
1907 version_id = qemu_get_be32(f);
1908
Juan Quintela811814b2010-07-26 21:38:43 +02001909 ret = vmstate_load_state(f, sub_vmsd, opaque, version_id);
1910 if (ret) {
1911 return ret;
1912 }
1913 }
1914 return 0;
1915}
1916
1917static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
1918 void *opaque)
1919{
1920 const VMStateSubsection *sub = vmsd->subsections;
1921
1922 while (sub && sub->needed) {
1923 if (sub->needed(opaque)) {
1924 const VMStateDescription *vmsd = sub->vmsd;
1925 uint8_t len;
1926
1927 qemu_put_byte(f, QEMU_VM_SUBSECTION);
1928 len = strlen(vmsd->name);
1929 qemu_put_byte(f, len);
1930 qemu_put_buffer(f, (uint8_t *)vmsd->name, len);
1931 qemu_put_be32(f, vmsd->version_id);
1932 vmstate_save_state(f, vmsd, opaque);
1933 }
1934 sub++;
1935 }
1936}
1937
aliguoria672b462008-11-11 21:33:36 +00001938typedef struct LoadStateEntry {
Blue Swirl72cf2d42009-09-12 07:36:22 +00001939 QLIST_ENTRY(LoadStateEntry) entry;
aliguoria672b462008-11-11 21:33:36 +00001940 SaveStateEntry *se;
1941 int section_id;
1942 int version_id;
aliguoria672b462008-11-11 21:33:36 +00001943} LoadStateEntry;
1944
aliguoria672b462008-11-11 21:33:36 +00001945int qemu_loadvm_state(QEMUFile *f)
1946{
Blue Swirl72cf2d42009-09-12 07:36:22 +00001947 QLIST_HEAD(, LoadStateEntry) loadvm_handlers =
1948 QLIST_HEAD_INITIALIZER(loadvm_handlers);
Juan Quintelaf4dbb8d2009-09-01 02:12:33 +02001949 LoadStateEntry *le, *new_le;
aliguoria672b462008-11-11 21:33:36 +00001950 uint8_t section_type;
1951 unsigned int v;
1952 int ret;
1953
Luiz Capitulinoe1c37d02011-12-05 14:48:01 -02001954 if (qemu_savevm_state_blocked(NULL)) {
Alex Williamsondc912122011-01-11 14:39:43 -07001955 return -EINVAL;
1956 }
1957
aliguoria672b462008-11-11 21:33:36 +00001958 v = qemu_get_be32(f);
1959 if (v != QEMU_VM_FILE_MAGIC)
1960 return -EINVAL;
1961
1962 v = qemu_get_be32(f);
Juan Quintelabbfe1402009-09-10 03:04:24 +02001963 if (v == QEMU_VM_FILE_VERSION_COMPAT) {
1964 fprintf(stderr, "SaveVM v2 format is obsolete and don't work anymore\n");
1965 return -ENOTSUP;
1966 }
aliguoria672b462008-11-11 21:33:36 +00001967 if (v != QEMU_VM_FILE_VERSION)
1968 return -ENOTSUP;
1969
1970 while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
1971 uint32_t instance_id, version_id, section_id;
aliguoria672b462008-11-11 21:33:36 +00001972 SaveStateEntry *se;
1973 char idstr[257];
1974 int len;
1975
1976 switch (section_type) {
1977 case QEMU_VM_SECTION_START:
1978 case QEMU_VM_SECTION_FULL:
1979 /* Read section start */
1980 section_id = qemu_get_be32(f);
1981 len = qemu_get_byte(f);
1982 qemu_get_buffer(f, (uint8_t *)idstr, len);
1983 idstr[len] = 0;
1984 instance_id = qemu_get_be32(f);
1985 version_id = qemu_get_be32(f);
1986
1987 /* Find savevm section */
1988 se = find_se(idstr, instance_id);
1989 if (se == NULL) {
1990 fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
1991 ret = -EINVAL;
1992 goto out;
1993 }
1994
1995 /* Validate version */
1996 if (version_id > se->version_id) {
1997 fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
1998 version_id, idstr, se->version_id);
1999 ret = -EINVAL;
2000 goto out;
2001 }
2002
2003 /* Add entry */
Anthony Liguori7267c092011-08-20 22:09:37 -05002004 le = g_malloc0(sizeof(*le));
aliguoria672b462008-11-11 21:33:36 +00002005
2006 le->se = se;
2007 le->section_id = section_id;
2008 le->version_id = version_id;
Blue Swirl72cf2d42009-09-12 07:36:22 +00002009 QLIST_INSERT_HEAD(&loadvm_handlers, le, entry);
aliguoria672b462008-11-11 21:33:36 +00002010
Juan Quintela4082be42009-08-20 19:42:24 +02002011 ret = vmstate_load(f, le->se, le->version_id);
Juan Quintelab5a22e42009-08-20 19:42:23 +02002012 if (ret < 0) {
2013 fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
2014 instance_id, idstr);
2015 goto out;
2016 }
aliguoria672b462008-11-11 21:33:36 +00002017 break;
2018 case QEMU_VM_SECTION_PART:
2019 case QEMU_VM_SECTION_END:
2020 section_id = qemu_get_be32(f);
2021
Blue Swirl72cf2d42009-09-12 07:36:22 +00002022 QLIST_FOREACH(le, &loadvm_handlers, entry) {
Juan Quintelaf4dbb8d2009-09-01 02:12:33 +02002023 if (le->section_id == section_id) {
2024 break;
2025 }
2026 }
aliguoria672b462008-11-11 21:33:36 +00002027 if (le == NULL) {
2028 fprintf(stderr, "Unknown savevm section %d\n", section_id);
2029 ret = -EINVAL;
2030 goto out;
2031 }
2032
Juan Quintela4082be42009-08-20 19:42:24 +02002033 ret = vmstate_load(f, le->se, le->version_id);
Juan Quintelab5a22e42009-08-20 19:42:23 +02002034 if (ret < 0) {
2035 fprintf(stderr, "qemu: warning: error while loading state section id %d\n",
2036 section_id);
2037 goto out;
2038 }
aliguoria672b462008-11-11 21:33:36 +00002039 break;
2040 default:
2041 fprintf(stderr, "Unknown savevm section type %d\n", section_type);
2042 ret = -EINVAL;
2043 goto out;
2044 }
2045 }
2046
Jan Kiszkaea375f92010-03-01 19:10:30 +01002047 cpu_synchronize_all_post_init();
2048
aliguoria672b462008-11-11 21:33:36 +00002049 ret = 0;
2050
2051out:
Blue Swirl72cf2d42009-09-12 07:36:22 +00002052 QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {
2053 QLIST_REMOVE(le, entry);
Anthony Liguori7267c092011-08-20 22:09:37 -05002054 g_free(le);
aliguoria672b462008-11-11 21:33:36 +00002055 }
2056
Juan Quintela42802d42011-10-05 01:14:46 +02002057 if (ret == 0) {
2058 ret = qemu_file_get_error(f);
Juan Quintela624b9cc2011-10-05 01:02:52 +02002059 }
aliguoria672b462008-11-11 21:33:36 +00002060
2061 return ret;
2062}
2063
aliguoria672b462008-11-11 21:33:36 +00002064static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
2065 const char *name)
2066{
2067 QEMUSnapshotInfo *sn_tab, *sn;
2068 int nb_sns, i, ret;
2069
2070 ret = -ENOENT;
2071 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
2072 if (nb_sns < 0)
2073 return ret;
2074 for(i = 0; i < nb_sns; i++) {
2075 sn = &sn_tab[i];
2076 if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
2077 *sn_info = *sn;
2078 ret = 0;
2079 break;
2080 }
2081 }
Anthony Liguori7267c092011-08-20 22:09:37 -05002082 g_free(sn_tab);
aliguoria672b462008-11-11 21:33:36 +00002083 return ret;
2084}
2085
Kevin Wolfcb499fb2009-11-03 17:34:37 +01002086/*
2087 * Deletes snapshots of a given name in all opened images.
2088 */
2089static int del_existing_snapshots(Monitor *mon, const char *name)
2090{
2091 BlockDriverState *bs;
Kevin Wolfcb499fb2009-11-03 17:34:37 +01002092 QEMUSnapshotInfo sn1, *snapshot = &sn1;
2093 int ret;
2094
Markus Armbrusterdbc13592010-06-02 18:55:21 +02002095 bs = NULL;
2096 while ((bs = bdrv_next(bs))) {
Kevin Wolfcb499fb2009-11-03 17:34:37 +01002097 if (bdrv_can_snapshot(bs) &&
2098 bdrv_snapshot_find(bs, snapshot, name) >= 0)
2099 {
2100 ret = bdrv_snapshot_delete(bs, name);
2101 if (ret < 0) {
2102 monitor_printf(mon,
2103 "Error while deleting snapshot on '%s'\n",
2104 bdrv_get_device_name(bs));
2105 return -1;
2106 }
2107 }
2108 }
2109
2110 return 0;
2111}
2112
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002113void do_savevm(Monitor *mon, const QDict *qdict)
aliguoria672b462008-11-11 21:33:36 +00002114{
2115 BlockDriverState *bs, *bs1;
2116 QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
Kevin Wolfcb499fb2009-11-03 17:34:37 +01002117 int ret;
aliguoria672b462008-11-11 21:33:36 +00002118 QEMUFile *f;
2119 int saved_vm_running;
Kevin Wolfc2c9a462011-11-16 11:35:54 +01002120 uint64_t vm_state_size;
aliguoria672b462008-11-11 21:33:36 +00002121#ifdef _WIN32
2122 struct _timeb tb;
Miguel Di Ciurcio Filho7d631a12010-08-04 14:55:49 -03002123 struct tm *ptm;
aliguoria672b462008-11-11 21:33:36 +00002124#else
2125 struct timeval tv;
Miguel Di Ciurcio Filho7d631a12010-08-04 14:55:49 -03002126 struct tm tm;
aliguoria672b462008-11-11 21:33:36 +00002127#endif
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002128 const char *name = qdict_get_try_str(qdict, "name");
aliguoria672b462008-11-11 21:33:36 +00002129
Miguel Di Ciurcio Filhofeeee5a2010-06-08 10:40:55 -03002130 /* Verify if there is a device that doesn't support snapshots and is writable */
Markus Armbrusterdbc13592010-06-02 18:55:21 +02002131 bs = NULL;
2132 while ((bs = bdrv_next(bs))) {
Miguel Di Ciurcio Filhofeeee5a2010-06-08 10:40:55 -03002133
Markus Armbruster07b70bf2011-08-03 15:08:11 +02002134 if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
Miguel Di Ciurcio Filhofeeee5a2010-06-08 10:40:55 -03002135 continue;
2136 }
2137
2138 if (!bdrv_can_snapshot(bs)) {
2139 monitor_printf(mon, "Device '%s' is writable but does not support snapshots.\n",
2140 bdrv_get_device_name(bs));
2141 return;
2142 }
2143 }
2144
Markus Armbrusterf9092b12010-06-25 10:33:39 +02002145 bs = bdrv_snapshots();
aliguoria672b462008-11-11 21:33:36 +00002146 if (!bs) {
aliguori376253e2009-03-05 23:01:23 +00002147 monitor_printf(mon, "No block device can accept snapshots\n");
aliguoria672b462008-11-11 21:33:36 +00002148 return;
2149 }
aliguoria672b462008-11-11 21:33:36 +00002150
Luiz Capitulino13548692011-07-29 15:36:43 -03002151 saved_vm_running = runstate_is_running();
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002152 vm_stop(RUN_STATE_SAVE_VM);
aliguoria672b462008-11-11 21:33:36 +00002153
Kevin Wolfcb499fb2009-11-03 17:34:37 +01002154 memset(sn, 0, sizeof(*sn));
aliguoria672b462008-11-11 21:33:36 +00002155
2156 /* fill auxiliary fields */
2157#ifdef _WIN32
2158 _ftime(&tb);
2159 sn->date_sec = tb.time;
2160 sn->date_nsec = tb.millitm * 1000000;
2161#else
2162 gettimeofday(&tv, NULL);
2163 sn->date_sec = tv.tv_sec;
2164 sn->date_nsec = tv.tv_usec * 1000;
2165#endif
Paolo Bonzini74475452011-03-11 16:47:48 +01002166 sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
aliguoria672b462008-11-11 21:33:36 +00002167
Miguel Di Ciurcio Filho7d631a12010-08-04 14:55:49 -03002168 if (name) {
2169 ret = bdrv_snapshot_find(bs, old_sn, name);
2170 if (ret >= 0) {
2171 pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
2172 pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
2173 } else {
2174 pstrcpy(sn->name, sizeof(sn->name), name);
2175 }
2176 } else {
2177#ifdef _WIN32
Stefan Weil55dd9ff2012-04-12 22:33:12 +02002178 time_t t = tb.time;
2179 ptm = localtime(&t);
Miguel Di Ciurcio Filho7d631a12010-08-04 14:55:49 -03002180 strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", ptm);
2181#else
Blue Swirld7d9b522010-09-09 19:13:04 +00002182 /* cast below needed for OpenBSD where tv_sec is still 'long' */
2183 localtime_r((const time_t *)&tv.tv_sec, &tm);
Miguel Di Ciurcio Filho7d631a12010-08-04 14:55:49 -03002184 strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", &tm);
2185#endif
2186 }
2187
Kevin Wolfcb499fb2009-11-03 17:34:37 +01002188 /* Delete old snapshots of the same name */
Marcelo Tosattif139a412010-01-20 14:26:34 -02002189 if (name && del_existing_snapshots(mon, name) < 0) {
Kevin Wolfcb499fb2009-11-03 17:34:37 +01002190 goto the_end;
2191 }
2192
aliguoria672b462008-11-11 21:33:36 +00002193 /* save the VM state */
Christoph Hellwig45566e92009-07-10 23:11:57 +02002194 f = qemu_fopen_bdrv(bs, 1);
aliguoria672b462008-11-11 21:33:36 +00002195 if (!f) {
aliguori376253e2009-03-05 23:01:23 +00002196 monitor_printf(mon, "Could not open VM state file\n");
aliguoria672b462008-11-11 21:33:36 +00002197 goto the_end;
2198 }
Luiz Capitulinoe1c37d02011-12-05 14:48:01 -02002199 ret = qemu_savevm_state(f);
aliguori2d22b182008-12-11 21:06:49 +00002200 vm_state_size = qemu_ftell(f);
aliguoria672b462008-11-11 21:33:36 +00002201 qemu_fclose(f);
2202 if (ret < 0) {
aliguori376253e2009-03-05 23:01:23 +00002203 monitor_printf(mon, "Error %d while writing VM\n", ret);
aliguoria672b462008-11-11 21:33:36 +00002204 goto the_end;
2205 }
2206
2207 /* create the snapshots */
2208
Markus Armbrusterdbc13592010-06-02 18:55:21 +02002209 bs1 = NULL;
2210 while ((bs1 = bdrv_next(bs1))) {
Miguel Di Ciurcio Filhofeeee5a2010-06-08 10:40:55 -03002211 if (bdrv_can_snapshot(bs1)) {
aliguori2d22b182008-12-11 21:06:49 +00002212 /* Write VM state size only to the image that contains the state */
2213 sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
aliguoria672b462008-11-11 21:33:36 +00002214 ret = bdrv_snapshot_create(bs1, sn);
2215 if (ret < 0) {
aliguori376253e2009-03-05 23:01:23 +00002216 monitor_printf(mon, "Error while creating snapshot on '%s'\n",
2217 bdrv_get_device_name(bs1));
aliguoria672b462008-11-11 21:33:36 +00002218 }
2219 }
2220 }
2221
2222 the_end:
2223 if (saved_vm_running)
2224 vm_start();
2225}
2226
Stefano Stabellinia7ae8352012-01-25 12:24:51 +00002227void qmp_xen_save_devices_state(const char *filename, Error **errp)
2228{
2229 QEMUFile *f;
2230 int saved_vm_running;
2231 int ret;
2232
2233 saved_vm_running = runstate_is_running();
2234 vm_stop(RUN_STATE_SAVE_VM);
2235
2236 f = qemu_fopen(filename, "wb");
2237 if (!f) {
2238 error_set(errp, QERR_OPEN_FILE_FAILED, filename);
2239 goto the_end;
2240 }
2241 ret = qemu_save_device_state(f);
2242 qemu_fclose(f);
2243 if (ret < 0) {
2244 error_set(errp, QERR_IO_ERROR);
2245 }
2246
2247 the_end:
2248 if (saved_vm_running)
2249 vm_start();
Stefano Stabellinia7ae8352012-01-25 12:24:51 +00002250}
2251
Markus Armbruster03cd4652010-02-17 16:24:10 +01002252int load_vmstate(const char *name)
aliguoria672b462008-11-11 21:33:36 +00002253{
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002254 BlockDriverState *bs, *bs_vm_state;
aliguori2d22b182008-12-11 21:06:49 +00002255 QEMUSnapshotInfo sn;
aliguoria672b462008-11-11 21:33:36 +00002256 QEMUFile *f;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002257 int ret;
aliguoria672b462008-11-11 21:33:36 +00002258
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002259 bs_vm_state = bdrv_snapshots();
2260 if (!bs_vm_state) {
2261 error_report("No block device supports snapshots");
2262 return -ENOTSUP;
2263 }
2264
2265 /* Don't even try to load empty VM states */
2266 ret = bdrv_snapshot_find(bs_vm_state, &sn, name);
2267 if (ret < 0) {
2268 return ret;
2269 } else if (sn.vm_state_size == 0) {
Kevin Wolfe11480d2011-03-01 10:48:12 +01002270 error_report("This is a disk-only snapshot. Revert to it offline "
2271 "using qemu-img.");
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002272 return -EINVAL;
2273 }
2274
2275 /* Verify if there is any device that doesn't support snapshots and is
2276 writable and check if the requested snapshot is available too. */
Markus Armbrusterdbc13592010-06-02 18:55:21 +02002277 bs = NULL;
2278 while ((bs = bdrv_next(bs))) {
Miguel Di Ciurcio Filhofeeee5a2010-06-08 10:40:55 -03002279
Markus Armbruster07b70bf2011-08-03 15:08:11 +02002280 if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
Miguel Di Ciurcio Filhofeeee5a2010-06-08 10:40:55 -03002281 continue;
2282 }
2283
2284 if (!bdrv_can_snapshot(bs)) {
2285 error_report("Device '%s' is writable but does not support snapshots.",
2286 bdrv_get_device_name(bs));
2287 return -ENOTSUP;
2288 }
Miguel Di Ciurcio Filhofeeee5a2010-06-08 10:40:55 -03002289
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002290 ret = bdrv_snapshot_find(bs, &sn, name);
2291 if (ret < 0) {
2292 error_report("Device '%s' does not have the requested snapshot '%s'",
2293 bdrv_get_device_name(bs), name);
2294 return ret;
2295 }
aliguoria672b462008-11-11 21:33:36 +00002296 }
2297
2298 /* Flush all IO requests so they don't interfere with the new state. */
Stefan Hajnoczi922453b2011-11-30 12:23:43 +00002299 bdrv_drain_all();
aliguoria672b462008-11-11 21:33:36 +00002300
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002301 bs = NULL;
2302 while ((bs = bdrv_next(bs))) {
2303 if (bdrv_can_snapshot(bs)) {
2304 ret = bdrv_snapshot_goto(bs, name);
aliguoria672b462008-11-11 21:33:36 +00002305 if (ret < 0) {
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002306 error_report("Error %d while activating snapshot '%s' on '%s'",
2307 ret, name, bdrv_get_device_name(bs));
2308 return ret;
aliguoria672b462008-11-11 21:33:36 +00002309 }
2310 }
2311 }
2312
aliguoria672b462008-11-11 21:33:36 +00002313 /* restore the VM state */
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002314 f = qemu_fopen_bdrv(bs_vm_state, 0);
aliguoria672b462008-11-11 21:33:36 +00002315 if (!f) {
Markus Armbruster1ecda022010-02-18 17:25:24 +01002316 error_report("Could not open VM state file");
Juan Quintela05f24012009-08-20 19:42:22 +02002317 return -EINVAL;
aliguoria672b462008-11-11 21:33:36 +00002318 }
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002319
Jan Kiszka5a8a49d2011-06-14 18:29:45 +02002320 qemu_system_reset(VMRESET_SILENT);
aliguoria672b462008-11-11 21:33:36 +00002321 ret = qemu_loadvm_state(f);
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002322
aliguoria672b462008-11-11 21:33:36 +00002323 qemu_fclose(f);
2324 if (ret < 0) {
Markus Armbruster1ecda022010-02-18 17:25:24 +01002325 error_report("Error %d while loading VM state", ret);
Juan Quintela05f24012009-08-20 19:42:22 +02002326 return ret;
aliguoria672b462008-11-11 21:33:36 +00002327 }
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002328
Juan Quintela05f24012009-08-20 19:42:22 +02002329 return 0;
Juan Quintela7b630342009-08-20 19:42:20 +02002330}
2331
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002332void do_delvm(Monitor *mon, const QDict *qdict)
aliguoria672b462008-11-11 21:33:36 +00002333{
2334 BlockDriverState *bs, *bs1;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002335 int ret;
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002336 const char *name = qdict_get_str(qdict, "name");
aliguoria672b462008-11-11 21:33:36 +00002337
Markus Armbrusterf9092b12010-06-25 10:33:39 +02002338 bs = bdrv_snapshots();
aliguoria672b462008-11-11 21:33:36 +00002339 if (!bs) {
aliguori376253e2009-03-05 23:01:23 +00002340 monitor_printf(mon, "No block device supports snapshots\n");
aliguoria672b462008-11-11 21:33:36 +00002341 return;
2342 }
2343
Markus Armbrusterdbc13592010-06-02 18:55:21 +02002344 bs1 = NULL;
2345 while ((bs1 = bdrv_next(bs1))) {
Miguel Di Ciurcio Filhofeeee5a2010-06-08 10:40:55 -03002346 if (bdrv_can_snapshot(bs1)) {
aliguoria672b462008-11-11 21:33:36 +00002347 ret = bdrv_snapshot_delete(bs1, name);
2348 if (ret < 0) {
2349 if (ret == -ENOTSUP)
aliguori376253e2009-03-05 23:01:23 +00002350 monitor_printf(mon,
2351 "Snapshots not supported on device '%s'\n",
2352 bdrv_get_device_name(bs1));
aliguoria672b462008-11-11 21:33:36 +00002353 else
aliguori376253e2009-03-05 23:01:23 +00002354 monitor_printf(mon, "Error %d while deleting snapshot on "
2355 "'%s'\n", ret, bdrv_get_device_name(bs1));
aliguoria672b462008-11-11 21:33:36 +00002356 }
2357 }
2358 }
2359}
2360
aliguori376253e2009-03-05 23:01:23 +00002361void do_info_snapshots(Monitor *mon)
aliguoria672b462008-11-11 21:33:36 +00002362{
2363 BlockDriverState *bs, *bs1;
Miguel Di Ciurcio Filhof9209912010-08-04 14:55:48 -03002364 QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
2365 int nb_sns, i, ret, available;
2366 int total;
2367 int *available_snapshots;
aliguoria672b462008-11-11 21:33:36 +00002368 char buf[256];
2369
Markus Armbrusterf9092b12010-06-25 10:33:39 +02002370 bs = bdrv_snapshots();
aliguoria672b462008-11-11 21:33:36 +00002371 if (!bs) {
aliguori376253e2009-03-05 23:01:23 +00002372 monitor_printf(mon, "No available block device supports snapshots\n");
aliguoria672b462008-11-11 21:33:36 +00002373 return;
2374 }
aliguoria672b462008-11-11 21:33:36 +00002375
2376 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
2377 if (nb_sns < 0) {
aliguori376253e2009-03-05 23:01:23 +00002378 monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
aliguoria672b462008-11-11 21:33:36 +00002379 return;
2380 }
Miguel Di Ciurcio Filhof9209912010-08-04 14:55:48 -03002381
2382 if (nb_sns == 0) {
2383 monitor_printf(mon, "There is no snapshot available.\n");
2384 return;
aliguoria672b462008-11-11 21:33:36 +00002385 }
Miguel Di Ciurcio Filhof9209912010-08-04 14:55:48 -03002386
Anthony Liguori7267c092011-08-20 22:09:37 -05002387 available_snapshots = g_malloc0(sizeof(int) * nb_sns);
Miguel Di Ciurcio Filhof9209912010-08-04 14:55:48 -03002388 total = 0;
2389 for (i = 0; i < nb_sns; i++) {
2390 sn = &sn_tab[i];
2391 available = 1;
2392 bs1 = NULL;
2393
2394 while ((bs1 = bdrv_next(bs1))) {
2395 if (bdrv_can_snapshot(bs1) && bs1 != bs) {
2396 ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str);
2397 if (ret < 0) {
2398 available = 0;
2399 break;
2400 }
2401 }
2402 }
2403
2404 if (available) {
2405 available_snapshots[total] = i;
2406 total++;
2407 }
2408 }
2409
2410 if (total > 0) {
2411 monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
2412 for (i = 0; i < total; i++) {
2413 sn = &sn_tab[available_snapshots[i]];
2414 monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
2415 }
2416 } else {
2417 monitor_printf(mon, "There is no suitable snapshot available\n");
2418 }
2419
Anthony Liguori7267c092011-08-20 22:09:37 -05002420 g_free(sn_tab);
2421 g_free(available_snapshots);
Miguel Di Ciurcio Filhof9209912010-08-04 14:55:48 -03002422
aliguoria672b462008-11-11 21:33:36 +00002423}
Avi Kivityc5705a72011-12-20 15:59:12 +02002424
2425void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
2426{
Avi Kivity1ddde082012-01-08 13:18:19 +02002427 qemu_ram_set_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK,
Avi Kivityc5705a72011-12-20 15:59:12 +02002428 memory_region_name(mr), dev);
2429}
2430
2431void vmstate_unregister_ram(MemoryRegion *mr, DeviceState *dev)
2432{
2433 /* Nothing do to while the implementation is in RAMBlock */
2434}
2435
2436void vmstate_register_ram_global(MemoryRegion *mr)
2437{
2438 vmstate_register_ram(mr, NULL);
2439}
Orit Wasserman302dfbe2012-08-06 21:42:52 +03002440
2441/*
2442 page = zrun nzrun
2443 | zrun nzrun page
2444
2445 zrun = length
2446
2447 nzrun = length byte...
2448
2449 length = uleb128 encoded integer
2450 */
2451int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,
2452 uint8_t *dst, int dlen)
2453{
2454 uint32_t zrun_len = 0, nzrun_len = 0;
2455 int d = 0, i = 0;
2456 long res, xor;
2457 uint8_t *nzrun_start = NULL;
2458
2459 g_assert(!(((uintptr_t)old_buf | (uintptr_t)new_buf | slen) %
2460 sizeof(long)));
2461
2462 while (i < slen) {
2463 /* overflow */
2464 if (d + 2 > dlen) {
2465 return -1;
2466 }
2467
2468 /* not aligned to sizeof(long) */
2469 res = (slen - i) % sizeof(long);
2470 while (res && old_buf[i] == new_buf[i]) {
2471 zrun_len++;
2472 i++;
2473 res--;
2474 }
2475
2476 /* word at a time for speed */
2477 if (!res) {
2478 while (i < slen &&
2479 (*(long *)(old_buf + i)) == (*(long *)(new_buf + i))) {
2480 i += sizeof(long);
2481 zrun_len += sizeof(long);
2482 }
2483
2484 /* go over the rest */
2485 while (i < slen && old_buf[i] == new_buf[i]) {
2486 zrun_len++;
2487 i++;
2488 }
2489 }
2490
2491 /* buffer unchanged */
2492 if (zrun_len == slen) {
2493 return 0;
2494 }
2495
2496 /* skip last zero run */
2497 if (i == slen) {
2498 return d;
2499 }
2500
2501 d += uleb128_encode_small(dst + d, zrun_len);
2502
2503 zrun_len = 0;
2504 nzrun_start = new_buf + i;
2505
2506 /* overflow */
2507 if (d + 2 > dlen) {
2508 return -1;
2509 }
2510 /* not aligned to sizeof(long) */
2511 res = (slen - i) % sizeof(long);
2512 while (res && old_buf[i] != new_buf[i]) {
2513 i++;
2514 nzrun_len++;
2515 res--;
2516 }
2517
2518 /* word at a time for speed, use of 32-bit long okay */
2519 if (!res) {
2520 /* truncation to 32-bit long okay */
Alexander Grafa5b71722012-08-14 12:53:18 +02002521 long mask = (long)0x0101010101010101ULL;
Orit Wasserman302dfbe2012-08-06 21:42:52 +03002522 while (i < slen) {
2523 xor = *(long *)(old_buf + i) ^ *(long *)(new_buf + i);
2524 if ((xor - mask) & ~xor & (mask << 7)) {
2525 /* found the end of an nzrun within the current long */
2526 while (old_buf[i] != new_buf[i]) {
2527 nzrun_len++;
2528 i++;
2529 }
2530 break;
2531 } else {
2532 i += sizeof(long);
2533 nzrun_len += sizeof(long);
2534 }
2535 }
2536 }
2537
2538 d += uleb128_encode_small(dst + d, nzrun_len);
2539 /* overflow */
2540 if (d + nzrun_len > dlen) {
2541 return -1;
2542 }
2543 memcpy(dst + d, nzrun_start, nzrun_len);
2544 d += nzrun_len;
2545 nzrun_len = 0;
2546 }
2547
2548 return d;
2549}
2550
2551int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen)
2552{
2553 int i = 0, d = 0;
2554 int ret;
2555 uint32_t count = 0;
2556
2557 while (i < slen) {
2558
2559 /* zrun */
2560 if ((slen - i) < 2) {
2561 return -1;
2562 }
2563
2564 ret = uleb128_decode_small(src + i, &count);
2565 if (ret < 0 || (i && !count)) {
2566 return -1;
2567 }
2568 i += ret;
2569 d += count;
2570
2571 /* overflow */
2572 if (d > dlen) {
2573 return -1;
2574 }
2575
2576 /* nzrun */
2577 if ((slen - i) < 2) {
2578 return -1;
2579 }
2580
2581 ret = uleb128_decode_small(src + i, &count);
2582 if (ret < 0 || !count) {
2583 return -1;
2584 }
2585 i += ret;
2586
2587 /* overflow */
2588 if (d + count > dlen || i + count > slen) {
2589 return -1;
2590 }
2591
2592 memcpy(dst + d, src + i, count);
2593 d += count;
2594 i += count;
2595 }
2596
2597 return d;
2598}