Statistics
| Branch: | Revision:

root / savevm.c @ 1b902f7d

History | View | Annotate | Download (58.6 kB)

1 a672b469 aliguori
/*
2 a672b469 aliguori
 * QEMU System Emulator
3 a672b469 aliguori
 *
4 a672b469 aliguori
 * Copyright (c) 2003-2008 Fabrice Bellard
5 a672b469 aliguori
 *
6 a672b469 aliguori
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 a672b469 aliguori
 * of this software and associated documentation files (the "Software"), to deal
8 a672b469 aliguori
 * in the Software without restriction, including without limitation the rights
9 a672b469 aliguori
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 a672b469 aliguori
 * copies of the Software, and to permit persons to whom the Software is
11 a672b469 aliguori
 * furnished to do so, subject to the following conditions:
12 a672b469 aliguori
 *
13 a672b469 aliguori
 * The above copyright notice and this permission notice shall be included in
14 a672b469 aliguori
 * all copies or substantial portions of the Software.
15 a672b469 aliguori
 *
16 a672b469 aliguori
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 a672b469 aliguori
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 a672b469 aliguori
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 a672b469 aliguori
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 a672b469 aliguori
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 a672b469 aliguori
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 a672b469 aliguori
 * THE SOFTWARE.
23 a672b469 aliguori
 */
24 a672b469 aliguori
#include <unistd.h>
25 a672b469 aliguori
#include <fcntl.h>
26 a672b469 aliguori
#include <time.h>
27 a672b469 aliguori
#include <errno.h>
28 a672b469 aliguori
#include <sys/time.h>
29 a672b469 aliguori
#include <zlib.h>
30 a672b469 aliguori
31 71e72a19 Juan Quintela
/* Needed early for CONFIG_BSD etc. */
32 d40cdb10 blueswir1
#include "config-host.h"
33 d40cdb10 blueswir1
34 a672b469 aliguori
#ifndef _WIN32
35 a672b469 aliguori
#include <sys/times.h>
36 a672b469 aliguori
#include <sys/wait.h>
37 a672b469 aliguori
#include <termios.h>
38 a672b469 aliguori
#include <sys/mman.h>
39 a672b469 aliguori
#include <sys/ioctl.h>
40 a672b469 aliguori
#include <sys/resource.h>
41 a672b469 aliguori
#include <sys/socket.h>
42 a672b469 aliguori
#include <netinet/in.h>
43 a672b469 aliguori
#include <net/if.h>
44 a672b469 aliguori
#include <arpa/inet.h>
45 a672b469 aliguori
#include <dirent.h>
46 a672b469 aliguori
#include <netdb.h>
47 a672b469 aliguori
#include <sys/select.h>
48 71e72a19 Juan Quintela
#ifdef CONFIG_BSD
49 a672b469 aliguori
#include <sys/stat.h>
50 a167ba50 Aurelien Jarno
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
51 a672b469 aliguori
#include <libutil.h>
52 a672b469 aliguori
#else
53 a672b469 aliguori
#include <util.h>
54 a672b469 aliguori
#endif
55 a672b469 aliguori
#ifdef __linux__
56 a672b469 aliguori
#include <pty.h>
57 a672b469 aliguori
#include <malloc.h>
58 a672b469 aliguori
#include <linux/rtc.h>
59 a672b469 aliguori
#endif
60 a672b469 aliguori
#endif
61 a672b469 aliguori
#endif
62 a672b469 aliguori
63 a672b469 aliguori
#ifdef _WIN32
64 49dc768d aliguori
#include <windows.h>
65 a672b469 aliguori
#include <malloc.h>
66 a672b469 aliguori
#include <sys/timeb.h>
67 a672b469 aliguori
#include <mmsystem.h>
68 a672b469 aliguori
#define getopt_long_only getopt_long
69 a672b469 aliguori
#define memalign(align, size) malloc(size)
70 a672b469 aliguori
#endif
71 a672b469 aliguori
72 511d2b14 blueswir1
#include "qemu-common.h"
73 511d2b14 blueswir1
#include "hw/hw.h"
74 7685ee6a Alex Williamson
#include "hw/qdev.h"
75 511d2b14 blueswir1
#include "net.h"
76 511d2b14 blueswir1
#include "monitor.h"
77 511d2b14 blueswir1
#include "sysemu.h"
78 511d2b14 blueswir1
#include "qemu-timer.h"
79 511d2b14 blueswir1
#include "qemu-char.h"
80 511d2b14 blueswir1
#include "audio/audio.h"
81 511d2b14 blueswir1
#include "migration.h"
82 511d2b14 blueswir1
#include "qemu_socket.h"
83 72cf2d4f Blue Swirl
#include "qemu-queue.h"
84 2ff68d07 Paolo Bonzini
#include "qemu-timer.h"
85 17a4663e Blue Swirl
#include "cpus.h"
86 c5705a77 Avi Kivity
#include "memory.h"
87 a7ae8355 Stefano Stabellini
#include "qmp-commands.h"
88 511d2b14 blueswir1
89 a672b469 aliguori
#define SELF_ANNOUNCE_ROUNDS 5
90 a672b469 aliguori
91 18995b98 Nolan
#ifndef ETH_P_RARP
92 f8778a77 Stefan Berger
#define ETH_P_RARP 0x8035
93 18995b98 Nolan
#endif
94 18995b98 Nolan
#define ARP_HTYPE_ETH 0x0001
95 18995b98 Nolan
#define ARP_PTYPE_IP 0x0800
96 18995b98 Nolan
#define ARP_OP_REQUEST_REV 0x3
97 18995b98 Nolan
98 18995b98 Nolan
static int announce_self_create(uint8_t *buf,
99 a672b469 aliguori
                                uint8_t *mac_addr)
100 a672b469 aliguori
{
101 18995b98 Nolan
    /* Ethernet header. */
102 18995b98 Nolan
    memset(buf, 0xff, 6);         /* destination MAC addr */
103 18995b98 Nolan
    memcpy(buf + 6, mac_addr, 6); /* source MAC addr */
104 18995b98 Nolan
    *(uint16_t *)(buf + 12) = htons(ETH_P_RARP); /* ethertype */
105 18995b98 Nolan
106 18995b98 Nolan
    /* RARP header. */
107 18995b98 Nolan
    *(uint16_t *)(buf + 14) = htons(ARP_HTYPE_ETH); /* hardware addr space */
108 18995b98 Nolan
    *(uint16_t *)(buf + 16) = htons(ARP_PTYPE_IP); /* protocol addr space */
109 18995b98 Nolan
    *(buf + 18) = 6; /* hardware addr length (ethernet) */
110 18995b98 Nolan
    *(buf + 19) = 4; /* protocol addr length (IPv4) */
111 18995b98 Nolan
    *(uint16_t *)(buf + 20) = htons(ARP_OP_REQUEST_REV); /* opcode */
112 18995b98 Nolan
    memcpy(buf + 22, mac_addr, 6); /* source hw addr */
113 18995b98 Nolan
    memset(buf + 28, 0x00, 4);     /* source protocol addr */
114 18995b98 Nolan
    memcpy(buf + 32, mac_addr, 6); /* target hw addr */
115 18995b98 Nolan
    memset(buf + 38, 0x00, 4);     /* target protocol addr */
116 18995b98 Nolan
117 18995b98 Nolan
    /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
118 18995b98 Nolan
    memset(buf + 42, 0x00, 18);
119 18995b98 Nolan
120 18995b98 Nolan
    return 60; /* len (FCS will be added by hardware) */
121 a672b469 aliguori
}
122 a672b469 aliguori
123 f401ca22 Mark McLoughlin
static void qemu_announce_self_iter(NICState *nic, void *opaque)
124 a672b469 aliguori
{
125 18995b98 Nolan
    uint8_t buf[60];
126 f401ca22 Mark McLoughlin
    int len;
127 f401ca22 Mark McLoughlin
128 f401ca22 Mark McLoughlin
    len = announce_self_create(buf, nic->conf->macaddr.a);
129 f401ca22 Mark McLoughlin
130 f401ca22 Mark McLoughlin
    qemu_send_packet_raw(&nic->nc, buf, len);
131 f401ca22 Mark McLoughlin
}
132 f401ca22 Mark McLoughlin
133 f401ca22 Mark McLoughlin
134 f401ca22 Mark McLoughlin
static void qemu_announce_self_once(void *opaque)
135 f401ca22 Mark McLoughlin
{
136 ed8b330b Gleb Natapov
    static int count = SELF_ANNOUNCE_ROUNDS;
137 ed8b330b Gleb Natapov
    QEMUTimer *timer = *(QEMUTimer **)opaque;
138 a672b469 aliguori
139 f401ca22 Mark McLoughlin
    qemu_foreach_nic(qemu_announce_self_iter, NULL);
140 f401ca22 Mark McLoughlin
141 18995b98 Nolan
    if (--count) {
142 18995b98 Nolan
        /* delay 50ms, 150ms, 250ms, ... */
143 7bd427d8 Paolo Bonzini
        qemu_mod_timer(timer, qemu_get_clock_ms(rt_clock) +
144 18995b98 Nolan
                       50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);
145 ed8b330b Gleb Natapov
    } else {
146 ed8b330b Gleb Natapov
            qemu_del_timer(timer);
147 ed8b330b Gleb Natapov
            qemu_free_timer(timer);
148 ed8b330b Gleb Natapov
    }
149 ed8b330b Gleb Natapov
}
150 ed8b330b Gleb Natapov
151 ed8b330b Gleb Natapov
void qemu_announce_self(void)
152 ed8b330b Gleb Natapov
{
153 ed8b330b Gleb Natapov
        static QEMUTimer *timer;
154 7bd427d8 Paolo Bonzini
        timer = qemu_new_timer_ms(rt_clock, qemu_announce_self_once, &timer);
155 ed8b330b Gleb Natapov
        qemu_announce_self_once(&timer);
156 a672b469 aliguori
}
157 a672b469 aliguori
158 a672b469 aliguori
/***********************************************************/
159 a672b469 aliguori
/* savevm/loadvm support */
160 a672b469 aliguori
161 a672b469 aliguori
#define IO_BUF_SIZE 32768
162 a672b469 aliguori
163 a672b469 aliguori
struct QEMUFile {
164 a672b469 aliguori
    QEMUFilePutBufferFunc *put_buffer;
165 a672b469 aliguori
    QEMUFileGetBufferFunc *get_buffer;
166 a672b469 aliguori
    QEMUFileCloseFunc *close;
167 a672b469 aliguori
    QEMUFileRateLimit *rate_limit;
168 19629537 Glauber Costa
    QEMUFileSetRateLimit *set_rate_limit;
169 c163b5ca lirans@il.ibm.com
    QEMUFileGetRateLimit *get_rate_limit;
170 a672b469 aliguori
    void *opaque;
171 a672b469 aliguori
    int is_write;
172 a672b469 aliguori
173 a672b469 aliguori
    int64_t buf_offset; /* start of buffer when writing, end of buffer
174 a672b469 aliguori
                           when reading */
175 a672b469 aliguori
    int buf_index;
176 a672b469 aliguori
    int buf_size; /* 0 when writing */
177 a672b469 aliguori
    uint8_t buf[IO_BUF_SIZE];
178 a672b469 aliguori
179 3961b4dd Juan Quintela
    int last_error;
180 a672b469 aliguori
};
181 a672b469 aliguori
182 7f79dd28 Paolo Bonzini
typedef struct QEMUFileStdio
183 a672b469 aliguori
{
184 7f79dd28 Paolo Bonzini
    FILE *stdio_file;
185 a672b469 aliguori
    QEMUFile *file;
186 7f79dd28 Paolo Bonzini
} QEMUFileStdio;
187 a672b469 aliguori
188 a672b469 aliguori
typedef struct QEMUFileSocket
189 a672b469 aliguori
{
190 a672b469 aliguori
    int fd;
191 a672b469 aliguori
    QEMUFile *file;
192 a672b469 aliguori
} QEMUFileSocket;
193 a672b469 aliguori
194 a672b469 aliguori
static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
195 a672b469 aliguori
{
196 a672b469 aliguori
    QEMUFileSocket *s = opaque;
197 a672b469 aliguori
    ssize_t len;
198 a672b469 aliguori
199 a672b469 aliguori
    do {
200 00aa0040 Blue Swirl
        len = qemu_recv(s->fd, buf, size, 0);
201 a672b469 aliguori
    } while (len == -1 && socket_error() == EINTR);
202 a672b469 aliguori
203 a672b469 aliguori
    if (len == -1)
204 a672b469 aliguori
        len = -socket_error();
205 a672b469 aliguori
206 a672b469 aliguori
    return len;
207 a672b469 aliguori
}
208 a672b469 aliguori
209 a672b469 aliguori
static int socket_close(void *opaque)
210 a672b469 aliguori
{
211 a672b469 aliguori
    QEMUFileSocket *s = opaque;
212 7267c094 Anthony Liguori
    g_free(s);
213 a672b469 aliguori
    return 0;
214 a672b469 aliguori
}
215 a672b469 aliguori
216 7f79dd28 Paolo Bonzini
static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
217 a672b469 aliguori
{
218 7f79dd28 Paolo Bonzini
    QEMUFileStdio *s = opaque;
219 7f79dd28 Paolo Bonzini
    return fwrite(buf, 1, size, s->stdio_file);
220 a672b469 aliguori
}
221 a672b469 aliguori
222 7f79dd28 Paolo Bonzini
static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
223 a672b469 aliguori
{
224 7f79dd28 Paolo Bonzini
    QEMUFileStdio *s = opaque;
225 7f79dd28 Paolo Bonzini
    FILE *fp = s->stdio_file;
226 8a67ec4d Uri Lublin
    int bytes;
227 8a67ec4d Uri Lublin
228 8a67ec4d Uri Lublin
    do {
229 8a67ec4d Uri Lublin
        clearerr(fp);
230 8a67ec4d Uri Lublin
        bytes = fread(buf, 1, size, fp);
231 8a67ec4d Uri Lublin
    } while ((bytes == 0) && ferror(fp) && (errno == EINTR));
232 8a67ec4d Uri Lublin
    return bytes;
233 a672b469 aliguori
}
234 a672b469 aliguori
235 7f79dd28 Paolo Bonzini
static int stdio_pclose(void *opaque)
236 7f79dd28 Paolo Bonzini
{
237 7f79dd28 Paolo Bonzini
    QEMUFileStdio *s = opaque;
238 41ef56e6 Anthony Liguori
    int ret;
239 41ef56e6 Anthony Liguori
    ret = pclose(s->stdio_file);
240 26f1af0a Eduardo Habkost
    if (ret == -1) {
241 26f1af0a Eduardo Habkost
        ret = -errno;
242 26f1af0a Eduardo Habkost
    }
243 7267c094 Anthony Liguori
    g_free(s);
244 41ef56e6 Anthony Liguori
    return ret;
245 7f79dd28 Paolo Bonzini
}
246 7f79dd28 Paolo Bonzini
247 7f79dd28 Paolo Bonzini
static int stdio_fclose(void *opaque)
248 a672b469 aliguori
{
249 7f79dd28 Paolo Bonzini
    QEMUFileStdio *s = opaque;
250 0e286705 Eduardo Habkost
    int ret = 0;
251 0e286705 Eduardo Habkost
    if (fclose(s->stdio_file) == EOF) {
252 0e286705 Eduardo Habkost
        ret = -errno;
253 0e286705 Eduardo Habkost
    }
254 7267c094 Anthony Liguori
    g_free(s);
255 0e286705 Eduardo Habkost
    return ret;
256 a672b469 aliguori
}
257 a672b469 aliguori
258 7f79dd28 Paolo Bonzini
QEMUFile *qemu_popen(FILE *stdio_file, const char *mode)
259 a672b469 aliguori
{
260 7f79dd28 Paolo Bonzini
    QEMUFileStdio *s;
261 a672b469 aliguori
262 7f79dd28 Paolo Bonzini
    if (stdio_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
263 a672b469 aliguori
        fprintf(stderr, "qemu_popen: Argument validity check failed\n");
264 a672b469 aliguori
        return NULL;
265 a672b469 aliguori
    }
266 a672b469 aliguori
267 7267c094 Anthony Liguori
    s = g_malloc0(sizeof(QEMUFileStdio));
268 a672b469 aliguori
269 7f79dd28 Paolo Bonzini
    s->stdio_file = stdio_file;
270 a672b469 aliguori
271 a672b469 aliguori
    if(mode[0] == 'r') {
272 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_pclose, 
273 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
274 a672b469 aliguori
    } else {
275 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_pclose, 
276 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
277 a672b469 aliguori
    }
278 a672b469 aliguori
    return s->file;
279 a672b469 aliguori
}
280 a672b469 aliguori
281 a672b469 aliguori
QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
282 a672b469 aliguori
{
283 a672b469 aliguori
    FILE *popen_file;
284 a672b469 aliguori
285 a672b469 aliguori
    popen_file = popen(command, mode);
286 a672b469 aliguori
    if(popen_file == NULL) {
287 a672b469 aliguori
        return NULL;
288 a672b469 aliguori
    }
289 a672b469 aliguori
290 a672b469 aliguori
    return qemu_popen(popen_file, mode);
291 a672b469 aliguori
}
292 a672b469 aliguori
293 7f79dd28 Paolo Bonzini
int qemu_stdio_fd(QEMUFile *f)
294 8a43b1ea Chris Lalancette
{
295 7f79dd28 Paolo Bonzini
    QEMUFileStdio *p;
296 8a43b1ea Chris Lalancette
    int fd;
297 8a43b1ea Chris Lalancette
298 7f79dd28 Paolo Bonzini
    p = (QEMUFileStdio *)f->opaque;
299 7f79dd28 Paolo Bonzini
    fd = fileno(p->stdio_file);
300 8a43b1ea Chris Lalancette
301 8a43b1ea Chris Lalancette
    return fd;
302 8a43b1ea Chris Lalancette
}
303 8a43b1ea Chris Lalancette
304 5ac1fad3 Paolo Bonzini
QEMUFile *qemu_fdopen(int fd, const char *mode)
305 5ac1fad3 Paolo Bonzini
{
306 5ac1fad3 Paolo Bonzini
    QEMUFileStdio *s;
307 5ac1fad3 Paolo Bonzini
308 5ac1fad3 Paolo Bonzini
    if (mode == NULL ||
309 5ac1fad3 Paolo Bonzini
        (mode[0] != 'r' && mode[0] != 'w') ||
310 5ac1fad3 Paolo Bonzini
        mode[1] != 'b' || mode[2] != 0) {
311 5ac1fad3 Paolo Bonzini
        fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
312 5ac1fad3 Paolo Bonzini
        return NULL;
313 5ac1fad3 Paolo Bonzini
    }
314 5ac1fad3 Paolo Bonzini
315 7267c094 Anthony Liguori
    s = g_malloc0(sizeof(QEMUFileStdio));
316 5ac1fad3 Paolo Bonzini
    s->stdio_file = fdopen(fd, mode);
317 5ac1fad3 Paolo Bonzini
    if (!s->stdio_file)
318 5ac1fad3 Paolo Bonzini
        goto fail;
319 5ac1fad3 Paolo Bonzini
320 5ac1fad3 Paolo Bonzini
    if(mode[0] == 'r') {
321 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_fclose, 
322 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
323 5ac1fad3 Paolo Bonzini
    } else {
324 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_fclose, 
325 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
326 5ac1fad3 Paolo Bonzini
    }
327 5ac1fad3 Paolo Bonzini
    return s->file;
328 5ac1fad3 Paolo Bonzini
329 5ac1fad3 Paolo Bonzini
fail:
330 7267c094 Anthony Liguori
    g_free(s);
331 5ac1fad3 Paolo Bonzini
    return NULL;
332 5ac1fad3 Paolo Bonzini
}
333 5ac1fad3 Paolo Bonzini
334 a672b469 aliguori
QEMUFile *qemu_fopen_socket(int fd)
335 a672b469 aliguori
{
336 7267c094 Anthony Liguori
    QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket));
337 a672b469 aliguori
338 a672b469 aliguori
    s->fd = fd;
339 c163b5ca lirans@il.ibm.com
    s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, 
340 c163b5ca lirans@il.ibm.com
                             NULL, NULL, NULL);
341 a672b469 aliguori
    return s->file;
342 a672b469 aliguori
}
343 a672b469 aliguori
344 a672b469 aliguori
static int file_put_buffer(void *opaque, const uint8_t *buf,
345 a672b469 aliguori
                            int64_t pos, int size)
346 a672b469 aliguori
{
347 a672b469 aliguori
    QEMUFileStdio *s = opaque;
348 7f79dd28 Paolo Bonzini
    fseek(s->stdio_file, pos, SEEK_SET);
349 5fdb3aa1 Kirill A. Shutemov
    return fwrite(buf, 1, size, s->stdio_file);
350 a672b469 aliguori
}
351 a672b469 aliguori
352 a672b469 aliguori
static int file_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
353 a672b469 aliguori
{
354 a672b469 aliguori
    QEMUFileStdio *s = opaque;
355 7f79dd28 Paolo Bonzini
    fseek(s->stdio_file, pos, SEEK_SET);
356 7f79dd28 Paolo Bonzini
    return fread(buf, 1, size, s->stdio_file);
357 a672b469 aliguori
}
358 a672b469 aliguori
359 a672b469 aliguori
QEMUFile *qemu_fopen(const char *filename, const char *mode)
360 a672b469 aliguori
{
361 a672b469 aliguori
    QEMUFileStdio *s;
362 a672b469 aliguori
363 7f79dd28 Paolo Bonzini
    if (mode == NULL ||
364 7f79dd28 Paolo Bonzini
        (mode[0] != 'r' && mode[0] != 'w') ||
365 7f79dd28 Paolo Bonzini
        mode[1] != 'b' || mode[2] != 0) {
366 090414a3 Blue Swirl
        fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
367 7f79dd28 Paolo Bonzini
        return NULL;
368 7f79dd28 Paolo Bonzini
    }
369 7f79dd28 Paolo Bonzini
370 7267c094 Anthony Liguori
    s = g_malloc0(sizeof(QEMUFileStdio));
371 a672b469 aliguori
372 7f79dd28 Paolo Bonzini
    s->stdio_file = fopen(filename, mode);
373 7f79dd28 Paolo Bonzini
    if (!s->stdio_file)
374 a672b469 aliguori
        goto fail;
375 c163b5ca lirans@il.ibm.com
    
376 7f79dd28 Paolo Bonzini
    if(mode[0] == 'w') {
377 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, file_put_buffer, NULL, stdio_fclose, 
378 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
379 7f79dd28 Paolo Bonzini
    } else {
380 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, NULL, file_get_buffer, stdio_fclose, 
381 c163b5ca lirans@il.ibm.com
                               NULL, NULL, NULL);
382 7f79dd28 Paolo Bonzini
    }
383 7f79dd28 Paolo Bonzini
    return s->file;
384 a672b469 aliguori
fail:
385 7267c094 Anthony Liguori
    g_free(s);
386 a672b469 aliguori
    return NULL;
387 a672b469 aliguori
}
388 a672b469 aliguori
389 178e08a5 aliguori
static int block_put_buffer(void *opaque, const uint8_t *buf,
390 a672b469 aliguori
                           int64_t pos, int size)
391 a672b469 aliguori
{
392 45566e9c Christoph Hellwig
    bdrv_save_vmstate(opaque, buf, pos, size);
393 a672b469 aliguori
    return size;
394 a672b469 aliguori
}
395 a672b469 aliguori
396 178e08a5 aliguori
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
397 a672b469 aliguori
{
398 45566e9c Christoph Hellwig
    return bdrv_load_vmstate(opaque, buf, pos, size);
399 a672b469 aliguori
}
400 a672b469 aliguori
401 a672b469 aliguori
static int bdrv_fclose(void *opaque)
402 a672b469 aliguori
{
403 a672b469 aliguori
    return 0;
404 a672b469 aliguori
}
405 a672b469 aliguori
406 45566e9c Christoph Hellwig
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
407 a672b469 aliguori
{
408 a672b469 aliguori
    if (is_writable)
409 c163b5ca lirans@il.ibm.com
        return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose, 
410 c163b5ca lirans@il.ibm.com
                              NULL, NULL, NULL);
411 c163b5ca lirans@il.ibm.com
    return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclose, NULL, NULL, NULL);
412 a672b469 aliguori
}
413 a672b469 aliguori
414 a672b469 aliguori
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
415 a672b469 aliguori
                         QEMUFileGetBufferFunc *get_buffer,
416 a672b469 aliguori
                         QEMUFileCloseFunc *close,
417 19629537 Glauber Costa
                         QEMUFileRateLimit *rate_limit,
418 c163b5ca lirans@il.ibm.com
                         QEMUFileSetRateLimit *set_rate_limit,
419 c163b5ca lirans@il.ibm.com
                         QEMUFileGetRateLimit *get_rate_limit)
420 a672b469 aliguori
{
421 a672b469 aliguori
    QEMUFile *f;
422 a672b469 aliguori
423 7267c094 Anthony Liguori
    f = g_malloc0(sizeof(QEMUFile));
424 a672b469 aliguori
425 a672b469 aliguori
    f->opaque = opaque;
426 a672b469 aliguori
    f->put_buffer = put_buffer;
427 a672b469 aliguori
    f->get_buffer = get_buffer;
428 a672b469 aliguori
    f->close = close;
429 a672b469 aliguori
    f->rate_limit = rate_limit;
430 19629537 Glauber Costa
    f->set_rate_limit = set_rate_limit;
431 c163b5ca lirans@il.ibm.com
    f->get_rate_limit = get_rate_limit;
432 a672b469 aliguori
    f->is_write = 0;
433 a672b469 aliguori
434 a672b469 aliguori
    return f;
435 a672b469 aliguori
}
436 a672b469 aliguori
437 624b9cc2 Juan Quintela
int qemu_file_get_error(QEMUFile *f)
438 a672b469 aliguori
{
439 3961b4dd Juan Quintela
    return f->last_error;
440 a672b469 aliguori
}
441 a672b469 aliguori
442 dcd1d224 Juan Quintela
void qemu_file_set_error(QEMUFile *f, int ret)
443 4dabe248 aliguori
{
444 3961b4dd Juan Quintela
    f->last_error = ret;
445 4dabe248 aliguori
}
446 4dabe248 aliguori
447 d82ca915 Eduardo Habkost
/** Sets last_error conditionally
448 d82ca915 Eduardo Habkost
 *
449 d82ca915 Eduardo Habkost
 * Sets last_error only if ret is negative _and_ no error
450 d82ca915 Eduardo Habkost
 * was set before.
451 d82ca915 Eduardo Habkost
 */
452 d82ca915 Eduardo Habkost
static void qemu_file_set_if_error(QEMUFile *f, int ret)
453 d82ca915 Eduardo Habkost
{
454 d82ca915 Eduardo Habkost
    if (ret < 0 && !f->last_error) {
455 d82ca915 Eduardo Habkost
        qemu_file_set_error(f, ret);
456 d82ca915 Eduardo Habkost
    }
457 d82ca915 Eduardo Habkost
}
458 d82ca915 Eduardo Habkost
459 d82ca915 Eduardo Habkost
/** Flushes QEMUFile buffer
460 d82ca915 Eduardo Habkost
 *
461 d82ca915 Eduardo Habkost
 * In case of error, last_error is set.
462 d82ca915 Eduardo Habkost
 */
463 a672b469 aliguori
void qemu_fflush(QEMUFile *f)
464 a672b469 aliguori
{
465 a672b469 aliguori
    if (!f->put_buffer)
466 a672b469 aliguori
        return;
467 a672b469 aliguori
468 a672b469 aliguori
    if (f->is_write && f->buf_index > 0) {
469 a672b469 aliguori
        int len;
470 a672b469 aliguori
471 a672b469 aliguori
        len = f->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index);
472 a672b469 aliguori
        if (len > 0)
473 a672b469 aliguori
            f->buf_offset += f->buf_index;
474 a672b469 aliguori
        else
475 c29110d5 Eduardo Habkost
            qemu_file_set_error(f, -EINVAL);
476 a672b469 aliguori
        f->buf_index = 0;
477 a672b469 aliguori
    }
478 a672b469 aliguori
}
479 a672b469 aliguori
480 a672b469 aliguori
static void qemu_fill_buffer(QEMUFile *f)
481 a672b469 aliguori
{
482 a672b469 aliguori
    int len;
483 0046c45b Juan Quintela
    int pending;
484 a672b469 aliguori
485 a672b469 aliguori
    if (!f->get_buffer)
486 a672b469 aliguori
        return;
487 a672b469 aliguori
488 a672b469 aliguori
    if (f->is_write)
489 a672b469 aliguori
        abort();
490 a672b469 aliguori
491 0046c45b Juan Quintela
    pending = f->buf_size - f->buf_index;
492 0046c45b Juan Quintela
    if (pending > 0) {
493 0046c45b Juan Quintela
        memmove(f->buf, f->buf + f->buf_index, pending);
494 0046c45b Juan Quintela
    }
495 0046c45b Juan Quintela
    f->buf_index = 0;
496 0046c45b Juan Quintela
    f->buf_size = pending;
497 0046c45b Juan Quintela
498 0046c45b Juan Quintela
    len = f->get_buffer(f->opaque, f->buf + pending, f->buf_offset,
499 0046c45b Juan Quintela
                        IO_BUF_SIZE - pending);
500 a672b469 aliguori
    if (len > 0) {
501 0046c45b Juan Quintela
        f->buf_size += len;
502 a672b469 aliguori
        f->buf_offset += len;
503 fa39a30f Juan Quintela
    } else if (len == 0) {
504 fa39a30f Juan Quintela
        f->last_error = -EIO;
505 a672b469 aliguori
    } else if (len != -EAGAIN)
506 c29110d5 Eduardo Habkost
        qemu_file_set_error(f, len);
507 a672b469 aliguori
}
508 a672b469 aliguori
509 d82ca915 Eduardo Habkost
/** Calls close function and set last_error if needed
510 d82ca915 Eduardo Habkost
 *
511 d82ca915 Eduardo Habkost
 * Internal function. qemu_fflush() must be called before this.
512 d82ca915 Eduardo Habkost
 *
513 d82ca915 Eduardo Habkost
 * Returns f->close() return value, or 0 if close function is not set.
514 d82ca915 Eduardo Habkost
 */
515 d82ca915 Eduardo Habkost
static int qemu_close(QEMUFile *f)
516 a672b469 aliguori
{
517 a672b469 aliguori
    int ret = 0;
518 d82ca915 Eduardo Habkost
    if (f->close) {
519 a672b469 aliguori
        ret = f->close(f->opaque);
520 d82ca915 Eduardo Habkost
        qemu_file_set_if_error(f, ret);
521 d82ca915 Eduardo Habkost
    }
522 d82ca915 Eduardo Habkost
    return ret;
523 d82ca915 Eduardo Habkost
}
524 d82ca915 Eduardo Habkost
525 d82ca915 Eduardo Habkost
/** Closes the file
526 d82ca915 Eduardo Habkost
 *
527 d82ca915 Eduardo Habkost
 * Returns negative error value if any error happened on previous operations or
528 d82ca915 Eduardo Habkost
 * while closing the file. Returns 0 or positive number on success.
529 d82ca915 Eduardo Habkost
 *
530 d82ca915 Eduardo Habkost
 * The meaning of return value on success depends on the specific backend
531 d82ca915 Eduardo Habkost
 * being used.
532 d82ca915 Eduardo Habkost
 */
533 d82ca915 Eduardo Habkost
int qemu_fclose(QEMUFile *f)
534 d82ca915 Eduardo Habkost
{
535 d82ca915 Eduardo Habkost
    int ret;
536 d82ca915 Eduardo Habkost
    qemu_fflush(f);
537 d82ca915 Eduardo Habkost
    ret = qemu_close(f);
538 d82ca915 Eduardo Habkost
    /* If any error was spotted before closing, we should report it
539 d82ca915 Eduardo Habkost
     * instead of the close() return value.
540 d82ca915 Eduardo Habkost
     */
541 d82ca915 Eduardo Habkost
    if (f->last_error) {
542 d82ca915 Eduardo Habkost
        ret = f->last_error;
543 d82ca915 Eduardo Habkost
    }
544 7267c094 Anthony Liguori
    g_free(f);
545 a672b469 aliguori
    return ret;
546 a672b469 aliguori
}
547 a672b469 aliguori
548 a672b469 aliguori
void qemu_file_put_notify(QEMUFile *f)
549 a672b469 aliguori
{
550 a672b469 aliguori
    f->put_buffer(f->opaque, NULL, 0, 0);
551 a672b469 aliguori
}
552 a672b469 aliguori
553 a672b469 aliguori
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
554 a672b469 aliguori
{
555 a672b469 aliguori
    int l;
556 a672b469 aliguori
557 3961b4dd Juan Quintela
    if (!f->last_error && f->is_write == 0 && f->buf_index > 0) {
558 a672b469 aliguori
        fprintf(stderr,
559 a672b469 aliguori
                "Attempted to write to buffer while read buffer is not empty\n");
560 a672b469 aliguori
        abort();
561 a672b469 aliguori
    }
562 a672b469 aliguori
563 3961b4dd Juan Quintela
    while (!f->last_error && size > 0) {
564 a672b469 aliguori
        l = IO_BUF_SIZE - f->buf_index;
565 a672b469 aliguori
        if (l > size)
566 a672b469 aliguori
            l = size;
567 a672b469 aliguori
        memcpy(f->buf + f->buf_index, buf, l);
568 a672b469 aliguori
        f->is_write = 1;
569 a672b469 aliguori
        f->buf_index += l;
570 a672b469 aliguori
        buf += l;
571 a672b469 aliguori
        size -= l;
572 a672b469 aliguori
        if (f->buf_index >= IO_BUF_SIZE)
573 a672b469 aliguori
            qemu_fflush(f);
574 a672b469 aliguori
    }
575 a672b469 aliguori
}
576 a672b469 aliguori
577 a672b469 aliguori
void qemu_put_byte(QEMUFile *f, int v)
578 a672b469 aliguori
{
579 3961b4dd Juan Quintela
    if (!f->last_error && f->is_write == 0 && f->buf_index > 0) {
580 a672b469 aliguori
        fprintf(stderr,
581 a672b469 aliguori
                "Attempted to write to buffer while read buffer is not empty\n");
582 a672b469 aliguori
        abort();
583 a672b469 aliguori
    }
584 a672b469 aliguori
585 a672b469 aliguori
    f->buf[f->buf_index++] = v;
586 a672b469 aliguori
    f->is_write = 1;
587 a672b469 aliguori
    if (f->buf_index >= IO_BUF_SIZE)
588 a672b469 aliguori
        qemu_fflush(f);
589 a672b469 aliguori
}
590 a672b469 aliguori
591 c6380724 Juan Quintela
static void qemu_file_skip(QEMUFile *f, int size)
592 a672b469 aliguori
{
593 c6380724 Juan Quintela
    if (f->buf_index + size <= f->buf_size) {
594 c6380724 Juan Quintela
        f->buf_index += size;
595 c6380724 Juan Quintela
    }
596 c6380724 Juan Quintela
}
597 c6380724 Juan Quintela
598 c6380724 Juan Quintela
static int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset)
599 a672b469 aliguori
{
600 c6380724 Juan Quintela
    int pending;
601 c6380724 Juan Quintela
    int index;
602 a672b469 aliguori
603 b9ce1454 Juan Quintela
    if (f->is_write) {
604 a672b469 aliguori
        abort();
605 b9ce1454 Juan Quintela
    }
606 a672b469 aliguori
607 c6380724 Juan Quintela
    index = f->buf_index + offset;
608 c6380724 Juan Quintela
    pending = f->buf_size - index;
609 c6380724 Juan Quintela
    if (pending < size) {
610 c6380724 Juan Quintela
        qemu_fill_buffer(f);
611 c6380724 Juan Quintela
        index = f->buf_index + offset;
612 c6380724 Juan Quintela
        pending = f->buf_size - index;
613 c6380724 Juan Quintela
    }
614 c6380724 Juan Quintela
615 c6380724 Juan Quintela
    if (pending <= 0) {
616 c6380724 Juan Quintela
        return 0;
617 c6380724 Juan Quintela
    }
618 c6380724 Juan Quintela
    if (size > pending) {
619 c6380724 Juan Quintela
        size = pending;
620 c6380724 Juan Quintela
    }
621 c6380724 Juan Quintela
622 c6380724 Juan Quintela
    memcpy(buf, f->buf + index, size);
623 c6380724 Juan Quintela
    return size;
624 c6380724 Juan Quintela
}
625 c6380724 Juan Quintela
626 c6380724 Juan Quintela
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
627 c6380724 Juan Quintela
{
628 c6380724 Juan Quintela
    int pending = size;
629 c6380724 Juan Quintela
    int done = 0;
630 c6380724 Juan Quintela
631 c6380724 Juan Quintela
    while (pending > 0) {
632 c6380724 Juan Quintela
        int res;
633 c6380724 Juan Quintela
634 c6380724 Juan Quintela
        res = qemu_peek_buffer(f, buf, pending, 0);
635 c6380724 Juan Quintela
        if (res == 0) {
636 c6380724 Juan Quintela
            return done;
637 a672b469 aliguori
        }
638 c6380724 Juan Quintela
        qemu_file_skip(f, res);
639 c6380724 Juan Quintela
        buf += res;
640 c6380724 Juan Quintela
        pending -= res;
641 c6380724 Juan Quintela
        done += res;
642 a672b469 aliguori
    }
643 c6380724 Juan Quintela
    return done;
644 a672b469 aliguori
}
645 a672b469 aliguori
646 c6380724 Juan Quintela
static int qemu_peek_byte(QEMUFile *f, int offset)
647 811814bd Juan Quintela
{
648 c6380724 Juan Quintela
    int index = f->buf_index + offset;
649 c6380724 Juan Quintela
650 b9ce1454 Juan Quintela
    if (f->is_write) {
651 811814bd Juan Quintela
        abort();
652 b9ce1454 Juan Quintela
    }
653 811814bd Juan Quintela
654 c6380724 Juan Quintela
    if (index >= f->buf_size) {
655 811814bd Juan Quintela
        qemu_fill_buffer(f);
656 c6380724 Juan Quintela
        index = f->buf_index + offset;
657 c6380724 Juan Quintela
        if (index >= f->buf_size) {
658 811814bd Juan Quintela
            return 0;
659 b9ce1454 Juan Quintela
        }
660 811814bd Juan Quintela
    }
661 c6380724 Juan Quintela
    return f->buf[index];
662 811814bd Juan Quintela
}
663 811814bd Juan Quintela
664 a672b469 aliguori
int qemu_get_byte(QEMUFile *f)
665 a672b469 aliguori
{
666 65f3bb3d Juan Quintela
    int result;
667 a672b469 aliguori
668 c6380724 Juan Quintela
    result = qemu_peek_byte(f, 0);
669 c6380724 Juan Quintela
    qemu_file_skip(f, 1);
670 65f3bb3d Juan Quintela
    return result;
671 a672b469 aliguori
}
672 a672b469 aliguori
673 a672b469 aliguori
int64_t qemu_ftell(QEMUFile *f)
674 a672b469 aliguori
{
675 a672b469 aliguori
    return f->buf_offset - f->buf_size + f->buf_index;
676 a672b469 aliguori
}
677 a672b469 aliguori
678 a672b469 aliguori
int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
679 a672b469 aliguori
{
680 a672b469 aliguori
    if (whence == SEEK_SET) {
681 a672b469 aliguori
        /* nothing to do */
682 a672b469 aliguori
    } else if (whence == SEEK_CUR) {
683 a672b469 aliguori
        pos += qemu_ftell(f);
684 a672b469 aliguori
    } else {
685 a672b469 aliguori
        /* SEEK_END not supported */
686 a672b469 aliguori
        return -1;
687 a672b469 aliguori
    }
688 a672b469 aliguori
    if (f->put_buffer) {
689 a672b469 aliguori
        qemu_fflush(f);
690 a672b469 aliguori
        f->buf_offset = pos;
691 a672b469 aliguori
    } else {
692 a672b469 aliguori
        f->buf_offset = pos;
693 a672b469 aliguori
        f->buf_index = 0;
694 a672b469 aliguori
        f->buf_size = 0;
695 a672b469 aliguori
    }
696 a672b469 aliguori
    return pos;
697 a672b469 aliguori
}
698 a672b469 aliguori
699 a672b469 aliguori
int qemu_file_rate_limit(QEMUFile *f)
700 a672b469 aliguori
{
701 a672b469 aliguori
    if (f->rate_limit)
702 a672b469 aliguori
        return f->rate_limit(f->opaque);
703 a672b469 aliguori
704 a672b469 aliguori
    return 0;
705 a672b469 aliguori
}
706 a672b469 aliguori
707 3d002df3 Michael S. Tsirkin
int64_t qemu_file_get_rate_limit(QEMUFile *f)
708 c163b5ca lirans@il.ibm.com
{
709 c163b5ca lirans@il.ibm.com
    if (f->get_rate_limit)
710 c163b5ca lirans@il.ibm.com
        return f->get_rate_limit(f->opaque);
711 c163b5ca lirans@il.ibm.com
712 c163b5ca lirans@il.ibm.com
    return 0;
713 c163b5ca lirans@il.ibm.com
}
714 c163b5ca lirans@il.ibm.com
715 3d002df3 Michael S. Tsirkin
int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate)
716 19629537 Glauber Costa
{
717 0bb05eaf Glauber Costa
    /* any failed or completed migration keeps its state to allow probing of
718 0bb05eaf Glauber Costa
     * migration data, but has no associated file anymore */
719 0bb05eaf Glauber Costa
    if (f && f->set_rate_limit)
720 19629537 Glauber Costa
        return f->set_rate_limit(f->opaque, new_rate);
721 19629537 Glauber Costa
722 19629537 Glauber Costa
    return 0;
723 19629537 Glauber Costa
}
724 19629537 Glauber Costa
725 a672b469 aliguori
void qemu_put_be16(QEMUFile *f, unsigned int v)
726 a672b469 aliguori
{
727 a672b469 aliguori
    qemu_put_byte(f, v >> 8);
728 a672b469 aliguori
    qemu_put_byte(f, v);
729 a672b469 aliguori
}
730 a672b469 aliguori
731 a672b469 aliguori
void qemu_put_be32(QEMUFile *f, unsigned int v)
732 a672b469 aliguori
{
733 a672b469 aliguori
    qemu_put_byte(f, v >> 24);
734 a672b469 aliguori
    qemu_put_byte(f, v >> 16);
735 a672b469 aliguori
    qemu_put_byte(f, v >> 8);
736 a672b469 aliguori
    qemu_put_byte(f, v);
737 a672b469 aliguori
}
738 a672b469 aliguori
739 a672b469 aliguori
void qemu_put_be64(QEMUFile *f, uint64_t v)
740 a672b469 aliguori
{
741 a672b469 aliguori
    qemu_put_be32(f, v >> 32);
742 a672b469 aliguori
    qemu_put_be32(f, v);
743 a672b469 aliguori
}
744 a672b469 aliguori
745 a672b469 aliguori
unsigned int qemu_get_be16(QEMUFile *f)
746 a672b469 aliguori
{
747 a672b469 aliguori
    unsigned int v;
748 a672b469 aliguori
    v = qemu_get_byte(f) << 8;
749 a672b469 aliguori
    v |= qemu_get_byte(f);
750 a672b469 aliguori
    return v;
751 a672b469 aliguori
}
752 a672b469 aliguori
753 a672b469 aliguori
unsigned int qemu_get_be32(QEMUFile *f)
754 a672b469 aliguori
{
755 a672b469 aliguori
    unsigned int v;
756 a672b469 aliguori
    v = qemu_get_byte(f) << 24;
757 a672b469 aliguori
    v |= qemu_get_byte(f) << 16;
758 a672b469 aliguori
    v |= qemu_get_byte(f) << 8;
759 a672b469 aliguori
    v |= qemu_get_byte(f);
760 a672b469 aliguori
    return v;
761 a672b469 aliguori
}
762 a672b469 aliguori
763 a672b469 aliguori
uint64_t qemu_get_be64(QEMUFile *f)
764 a672b469 aliguori
{
765 a672b469 aliguori
    uint64_t v;
766 a672b469 aliguori
    v = (uint64_t)qemu_get_be32(f) << 32;
767 a672b469 aliguori
    v |= qemu_get_be32(f);
768 a672b469 aliguori
    return v;
769 a672b469 aliguori
}
770 a672b469 aliguori
771 2ff68d07 Paolo Bonzini
772 2ff68d07 Paolo Bonzini
/* timer */
773 2ff68d07 Paolo Bonzini
774 2ff68d07 Paolo Bonzini
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
775 2ff68d07 Paolo Bonzini
{
776 2ff68d07 Paolo Bonzini
    uint64_t expire_time;
777 2ff68d07 Paolo Bonzini
778 2ff68d07 Paolo Bonzini
    expire_time = qemu_timer_expire_time_ns(ts);
779 2ff68d07 Paolo Bonzini
    qemu_put_be64(f, expire_time);
780 2ff68d07 Paolo Bonzini
}
781 2ff68d07 Paolo Bonzini
782 2ff68d07 Paolo Bonzini
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
783 2ff68d07 Paolo Bonzini
{
784 2ff68d07 Paolo Bonzini
    uint64_t expire_time;
785 2ff68d07 Paolo Bonzini
786 2ff68d07 Paolo Bonzini
    expire_time = qemu_get_be64(f);
787 2ff68d07 Paolo Bonzini
    if (expire_time != -1) {
788 2ff68d07 Paolo Bonzini
        qemu_mod_timer_ns(ts, expire_time);
789 2ff68d07 Paolo Bonzini
    } else {
790 2ff68d07 Paolo Bonzini
        qemu_del_timer(ts);
791 2ff68d07 Paolo Bonzini
    }
792 2ff68d07 Paolo Bonzini
}
793 2ff68d07 Paolo Bonzini
794 2ff68d07 Paolo Bonzini
795 cdae5cfb Gerd Hoffmann
/* bool */
796 cdae5cfb Gerd Hoffmann
797 cdae5cfb Gerd Hoffmann
static int get_bool(QEMUFile *f, void *pv, size_t size)
798 cdae5cfb Gerd Hoffmann
{
799 cdae5cfb Gerd Hoffmann
    bool *v = pv;
800 cdae5cfb Gerd Hoffmann
    *v = qemu_get_byte(f);
801 cdae5cfb Gerd Hoffmann
    return 0;
802 cdae5cfb Gerd Hoffmann
}
803 cdae5cfb Gerd Hoffmann
804 cdae5cfb Gerd Hoffmann
static void put_bool(QEMUFile *f, void *pv, size_t size)
805 cdae5cfb Gerd Hoffmann
{
806 cdae5cfb Gerd Hoffmann
    bool *v = pv;
807 cdae5cfb Gerd Hoffmann
    qemu_put_byte(f, *v);
808 cdae5cfb Gerd Hoffmann
}
809 cdae5cfb Gerd Hoffmann
810 cdae5cfb Gerd Hoffmann
const VMStateInfo vmstate_info_bool = {
811 cdae5cfb Gerd Hoffmann
    .name = "bool",
812 cdae5cfb Gerd Hoffmann
    .get  = get_bool,
813 cdae5cfb Gerd Hoffmann
    .put  = put_bool,
814 cdae5cfb Gerd Hoffmann
};
815 cdae5cfb Gerd Hoffmann
816 9ed7d6ae Juan Quintela
/* 8 bit int */
817 9ed7d6ae Juan Quintela
818 9ed7d6ae Juan Quintela
static int get_int8(QEMUFile *f, void *pv, size_t size)
819 9ed7d6ae Juan Quintela
{
820 9ed7d6ae Juan Quintela
    int8_t *v = pv;
821 9ed7d6ae Juan Quintela
    qemu_get_s8s(f, v);
822 9ed7d6ae Juan Quintela
    return 0;
823 9ed7d6ae Juan Quintela
}
824 9ed7d6ae Juan Quintela
825 84e2e3eb Juan Quintela
static void put_int8(QEMUFile *f, void *pv, size_t size)
826 9ed7d6ae Juan Quintela
{
827 84e2e3eb Juan Quintela
    int8_t *v = pv;
828 9ed7d6ae Juan Quintela
    qemu_put_s8s(f, v);
829 9ed7d6ae Juan Quintela
}
830 9ed7d6ae Juan Quintela
831 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_int8 = {
832 9ed7d6ae Juan Quintela
    .name = "int8",
833 9ed7d6ae Juan Quintela
    .get  = get_int8,
834 9ed7d6ae Juan Quintela
    .put  = put_int8,
835 9ed7d6ae Juan Quintela
};
836 9ed7d6ae Juan Quintela
837 9ed7d6ae Juan Quintela
/* 16 bit int */
838 9ed7d6ae Juan Quintela
839 9ed7d6ae Juan Quintela
static int get_int16(QEMUFile *f, void *pv, size_t size)
840 9ed7d6ae Juan Quintela
{
841 9ed7d6ae Juan Quintela
    int16_t *v = pv;
842 9ed7d6ae Juan Quintela
    qemu_get_sbe16s(f, v);
843 9ed7d6ae Juan Quintela
    return 0;
844 9ed7d6ae Juan Quintela
}
845 9ed7d6ae Juan Quintela
846 84e2e3eb Juan Quintela
static void put_int16(QEMUFile *f, void *pv, size_t size)
847 9ed7d6ae Juan Quintela
{
848 84e2e3eb Juan Quintela
    int16_t *v = pv;
849 9ed7d6ae Juan Quintela
    qemu_put_sbe16s(f, v);
850 9ed7d6ae Juan Quintela
}
851 9ed7d6ae Juan Quintela
852 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_int16 = {
853 9ed7d6ae Juan Quintela
    .name = "int16",
854 9ed7d6ae Juan Quintela
    .get  = get_int16,
855 9ed7d6ae Juan Quintela
    .put  = put_int16,
856 9ed7d6ae Juan Quintela
};
857 9ed7d6ae Juan Quintela
858 9ed7d6ae Juan Quintela
/* 32 bit int */
859 9ed7d6ae Juan Quintela
860 9ed7d6ae Juan Quintela
static int get_int32(QEMUFile *f, void *pv, size_t size)
861 9ed7d6ae Juan Quintela
{
862 9ed7d6ae Juan Quintela
    int32_t *v = pv;
863 9ed7d6ae Juan Quintela
    qemu_get_sbe32s(f, v);
864 9ed7d6ae Juan Quintela
    return 0;
865 9ed7d6ae Juan Quintela
}
866 9ed7d6ae Juan Quintela
867 84e2e3eb Juan Quintela
static void put_int32(QEMUFile *f, void *pv, size_t size)
868 9ed7d6ae Juan Quintela
{
869 84e2e3eb Juan Quintela
    int32_t *v = pv;
870 9ed7d6ae Juan Quintela
    qemu_put_sbe32s(f, v);
871 9ed7d6ae Juan Quintela
}
872 9ed7d6ae Juan Quintela
873 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_int32 = {
874 9ed7d6ae Juan Quintela
    .name = "int32",
875 9ed7d6ae Juan Quintela
    .get  = get_int32,
876 9ed7d6ae Juan Quintela
    .put  = put_int32,
877 9ed7d6ae Juan Quintela
};
878 9ed7d6ae Juan Quintela
879 82501660 Juan Quintela
/* 32 bit int. See that the received value is the same than the one
880 82501660 Juan Quintela
   in the field */
881 82501660 Juan Quintela
882 82501660 Juan Quintela
static int get_int32_equal(QEMUFile *f, void *pv, size_t size)
883 82501660 Juan Quintela
{
884 82501660 Juan Quintela
    int32_t *v = pv;
885 82501660 Juan Quintela
    int32_t v2;
886 82501660 Juan Quintela
    qemu_get_sbe32s(f, &v2);
887 82501660 Juan Quintela
888 82501660 Juan Quintela
    if (*v == v2)
889 82501660 Juan Quintela
        return 0;
890 82501660 Juan Quintela
    return -EINVAL;
891 82501660 Juan Quintela
}
892 82501660 Juan Quintela
893 82501660 Juan Quintela
const VMStateInfo vmstate_info_int32_equal = {
894 82501660 Juan Quintela
    .name = "int32 equal",
895 82501660 Juan Quintela
    .get  = get_int32_equal,
896 82501660 Juan Quintela
    .put  = put_int32,
897 82501660 Juan Quintela
};
898 82501660 Juan Quintela
899 0a031e0a Juan Quintela
/* 32 bit int. See that the received value is the less or the same
900 0a031e0a Juan Quintela
   than the one in the field */
901 0a031e0a Juan Quintela
902 0a031e0a Juan Quintela
static int get_int32_le(QEMUFile *f, void *pv, size_t size)
903 0a031e0a Juan Quintela
{
904 0a031e0a Juan Quintela
    int32_t *old = pv;
905 0a031e0a Juan Quintela
    int32_t new;
906 0a031e0a Juan Quintela
    qemu_get_sbe32s(f, &new);
907 0a031e0a Juan Quintela
908 0a031e0a Juan Quintela
    if (*old <= new)
909 0a031e0a Juan Quintela
        return 0;
910 0a031e0a Juan Quintela
    return -EINVAL;
911 0a031e0a Juan Quintela
}
912 0a031e0a Juan Quintela
913 0a031e0a Juan Quintela
const VMStateInfo vmstate_info_int32_le = {
914 0a031e0a Juan Quintela
    .name = "int32 equal",
915 0a031e0a Juan Quintela
    .get  = get_int32_le,
916 0a031e0a Juan Quintela
    .put  = put_int32,
917 0a031e0a Juan Quintela
};
918 0a031e0a Juan Quintela
919 9ed7d6ae Juan Quintela
/* 64 bit int */
920 9ed7d6ae Juan Quintela
921 9ed7d6ae Juan Quintela
static int get_int64(QEMUFile *f, void *pv, size_t size)
922 9ed7d6ae Juan Quintela
{
923 9ed7d6ae Juan Quintela
    int64_t *v = pv;
924 9ed7d6ae Juan Quintela
    qemu_get_sbe64s(f, v);
925 9ed7d6ae Juan Quintela
    return 0;
926 9ed7d6ae Juan Quintela
}
927 9ed7d6ae Juan Quintela
928 84e2e3eb Juan Quintela
static void put_int64(QEMUFile *f, void *pv, size_t size)
929 9ed7d6ae Juan Quintela
{
930 84e2e3eb Juan Quintela
    int64_t *v = pv;
931 9ed7d6ae Juan Quintela
    qemu_put_sbe64s(f, v);
932 9ed7d6ae Juan Quintela
}
933 9ed7d6ae Juan Quintela
934 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_int64 = {
935 9ed7d6ae Juan Quintela
    .name = "int64",
936 9ed7d6ae Juan Quintela
    .get  = get_int64,
937 9ed7d6ae Juan Quintela
    .put  = put_int64,
938 9ed7d6ae Juan Quintela
};
939 9ed7d6ae Juan Quintela
940 9ed7d6ae Juan Quintela
/* 8 bit unsigned int */
941 9ed7d6ae Juan Quintela
942 9ed7d6ae Juan Quintela
static int get_uint8(QEMUFile *f, void *pv, size_t size)
943 9ed7d6ae Juan Quintela
{
944 9ed7d6ae Juan Quintela
    uint8_t *v = pv;
945 9ed7d6ae Juan Quintela
    qemu_get_8s(f, v);
946 9ed7d6ae Juan Quintela
    return 0;
947 9ed7d6ae Juan Quintela
}
948 9ed7d6ae Juan Quintela
949 84e2e3eb Juan Quintela
static void put_uint8(QEMUFile *f, void *pv, size_t size)
950 9ed7d6ae Juan Quintela
{
951 84e2e3eb Juan Quintela
    uint8_t *v = pv;
952 9ed7d6ae Juan Quintela
    qemu_put_8s(f, v);
953 9ed7d6ae Juan Quintela
}
954 9ed7d6ae Juan Quintela
955 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_uint8 = {
956 9ed7d6ae Juan Quintela
    .name = "uint8",
957 9ed7d6ae Juan Quintela
    .get  = get_uint8,
958 9ed7d6ae Juan Quintela
    .put  = put_uint8,
959 9ed7d6ae Juan Quintela
};
960 9ed7d6ae Juan Quintela
961 9ed7d6ae Juan Quintela
/* 16 bit unsigned int */
962 9ed7d6ae Juan Quintela
963 9ed7d6ae Juan Quintela
static int get_uint16(QEMUFile *f, void *pv, size_t size)
964 9ed7d6ae Juan Quintela
{
965 9ed7d6ae Juan Quintela
    uint16_t *v = pv;
966 9ed7d6ae Juan Quintela
    qemu_get_be16s(f, v);
967 9ed7d6ae Juan Quintela
    return 0;
968 9ed7d6ae Juan Quintela
}
969 9ed7d6ae Juan Quintela
970 84e2e3eb Juan Quintela
static void put_uint16(QEMUFile *f, void *pv, size_t size)
971 9ed7d6ae Juan Quintela
{
972 84e2e3eb Juan Quintela
    uint16_t *v = pv;
973 9ed7d6ae Juan Quintela
    qemu_put_be16s(f, v);
974 9ed7d6ae Juan Quintela
}
975 9ed7d6ae Juan Quintela
976 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_uint16 = {
977 9ed7d6ae Juan Quintela
    .name = "uint16",
978 9ed7d6ae Juan Quintela
    .get  = get_uint16,
979 9ed7d6ae Juan Quintela
    .put  = put_uint16,
980 9ed7d6ae Juan Quintela
};
981 9ed7d6ae Juan Quintela
982 9ed7d6ae Juan Quintela
/* 32 bit unsigned int */
983 9ed7d6ae Juan Quintela
984 9ed7d6ae Juan Quintela
static int get_uint32(QEMUFile *f, void *pv, size_t size)
985 9ed7d6ae Juan Quintela
{
986 9ed7d6ae Juan Quintela
    uint32_t *v = pv;
987 9ed7d6ae Juan Quintela
    qemu_get_be32s(f, v);
988 9ed7d6ae Juan Quintela
    return 0;
989 9ed7d6ae Juan Quintela
}
990 9ed7d6ae Juan Quintela
991 84e2e3eb Juan Quintela
static void put_uint32(QEMUFile *f, void *pv, size_t size)
992 9ed7d6ae Juan Quintela
{
993 84e2e3eb Juan Quintela
    uint32_t *v = pv;
994 9ed7d6ae Juan Quintela
    qemu_put_be32s(f, v);
995 9ed7d6ae Juan Quintela
}
996 9ed7d6ae Juan Quintela
997 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_uint32 = {
998 9ed7d6ae Juan Quintela
    .name = "uint32",
999 9ed7d6ae Juan Quintela
    .get  = get_uint32,
1000 9ed7d6ae Juan Quintela
    .put  = put_uint32,
1001 9ed7d6ae Juan Quintela
};
1002 9ed7d6ae Juan Quintela
1003 9122a8fe Juan Quintela
/* 32 bit uint. See that the received value is the same than the one
1004 9122a8fe Juan Quintela
   in the field */
1005 9122a8fe Juan Quintela
1006 9122a8fe Juan Quintela
static int get_uint32_equal(QEMUFile *f, void *pv, size_t size)
1007 9122a8fe Juan Quintela
{
1008 9122a8fe Juan Quintela
    uint32_t *v = pv;
1009 9122a8fe Juan Quintela
    uint32_t v2;
1010 9122a8fe Juan Quintela
    qemu_get_be32s(f, &v2);
1011 9122a8fe Juan Quintela
1012 9122a8fe Juan Quintela
    if (*v == v2) {
1013 9122a8fe Juan Quintela
        return 0;
1014 9122a8fe Juan Quintela
    }
1015 9122a8fe Juan Quintela
    return -EINVAL;
1016 9122a8fe Juan Quintela
}
1017 9122a8fe Juan Quintela
1018 9122a8fe Juan Quintela
const VMStateInfo vmstate_info_uint32_equal = {
1019 9122a8fe Juan Quintela
    .name = "uint32 equal",
1020 9122a8fe Juan Quintela
    .get  = get_uint32_equal,
1021 9122a8fe Juan Quintela
    .put  = put_uint32,
1022 9122a8fe Juan Quintela
};
1023 9122a8fe Juan Quintela
1024 9ed7d6ae Juan Quintela
/* 64 bit unsigned int */
1025 9ed7d6ae Juan Quintela
1026 9ed7d6ae Juan Quintela
static int get_uint64(QEMUFile *f, void *pv, size_t size)
1027 9ed7d6ae Juan Quintela
{
1028 9ed7d6ae Juan Quintela
    uint64_t *v = pv;
1029 9ed7d6ae Juan Quintela
    qemu_get_be64s(f, v);
1030 9ed7d6ae Juan Quintela
    return 0;
1031 9ed7d6ae Juan Quintela
}
1032 9ed7d6ae Juan Quintela
1033 84e2e3eb Juan Quintela
static void put_uint64(QEMUFile *f, void *pv, size_t size)
1034 9ed7d6ae Juan Quintela
{
1035 84e2e3eb Juan Quintela
    uint64_t *v = pv;
1036 9ed7d6ae Juan Quintela
    qemu_put_be64s(f, v);
1037 9ed7d6ae Juan Quintela
}
1038 9ed7d6ae Juan Quintela
1039 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_uint64 = {
1040 9ed7d6ae Juan Quintela
    .name = "uint64",
1041 9ed7d6ae Juan Quintela
    .get  = get_uint64,
1042 9ed7d6ae Juan Quintela
    .put  = put_uint64,
1043 9ed7d6ae Juan Quintela
};
1044 9ed7d6ae Juan Quintela
1045 80cd83e7 Juan Quintela
/* 8 bit int. See that the received value is the same than the one
1046 80cd83e7 Juan Quintela
   in the field */
1047 80cd83e7 Juan Quintela
1048 80cd83e7 Juan Quintela
static int get_uint8_equal(QEMUFile *f, void *pv, size_t size)
1049 80cd83e7 Juan Quintela
{
1050 80cd83e7 Juan Quintela
    uint8_t *v = pv;
1051 80cd83e7 Juan Quintela
    uint8_t v2;
1052 80cd83e7 Juan Quintela
    qemu_get_8s(f, &v2);
1053 80cd83e7 Juan Quintela
1054 80cd83e7 Juan Quintela
    if (*v == v2)
1055 80cd83e7 Juan Quintela
        return 0;
1056 80cd83e7 Juan Quintela
    return -EINVAL;
1057 80cd83e7 Juan Quintela
}
1058 80cd83e7 Juan Quintela
1059 80cd83e7 Juan Quintela
const VMStateInfo vmstate_info_uint8_equal = {
1060 aa1cce69 Juan Quintela
    .name = "uint8 equal",
1061 80cd83e7 Juan Quintela
    .get  = get_uint8_equal,
1062 80cd83e7 Juan Quintela
    .put  = put_uint8,
1063 80cd83e7 Juan Quintela
};
1064 80cd83e7 Juan Quintela
1065 dc3b83a0 Juan Quintela
/* 16 bit unsigned int int. See that the received value is the same than the one
1066 dc3b83a0 Juan Quintela
   in the field */
1067 dc3b83a0 Juan Quintela
1068 dc3b83a0 Juan Quintela
static int get_uint16_equal(QEMUFile *f, void *pv, size_t size)
1069 dc3b83a0 Juan Quintela
{
1070 dc3b83a0 Juan Quintela
    uint16_t *v = pv;
1071 dc3b83a0 Juan Quintela
    uint16_t v2;
1072 dc3b83a0 Juan Quintela
    qemu_get_be16s(f, &v2);
1073 dc3b83a0 Juan Quintela
1074 dc3b83a0 Juan Quintela
    if (*v == v2)
1075 dc3b83a0 Juan Quintela
        return 0;
1076 dc3b83a0 Juan Quintela
    return -EINVAL;
1077 dc3b83a0 Juan Quintela
}
1078 dc3b83a0 Juan Quintela
1079 dc3b83a0 Juan Quintela
const VMStateInfo vmstate_info_uint16_equal = {
1080 dc3b83a0 Juan Quintela
    .name = "uint16 equal",
1081 dc3b83a0 Juan Quintela
    .get  = get_uint16_equal,
1082 dc3b83a0 Juan Quintela
    .put  = put_uint16,
1083 dc3b83a0 Juan Quintela
};
1084 dc3b83a0 Juan Quintela
1085 dde0463b Juan Quintela
/* timers  */
1086 dde0463b Juan Quintela
1087 dde0463b Juan Quintela
static int get_timer(QEMUFile *f, void *pv, size_t size)
1088 dde0463b Juan Quintela
{
1089 dde0463b Juan Quintela
    QEMUTimer *v = pv;
1090 dde0463b Juan Quintela
    qemu_get_timer(f, v);
1091 dde0463b Juan Quintela
    return 0;
1092 dde0463b Juan Quintela
}
1093 dde0463b Juan Quintela
1094 84e2e3eb Juan Quintela
static void put_timer(QEMUFile *f, void *pv, size_t size)
1095 dde0463b Juan Quintela
{
1096 84e2e3eb Juan Quintela
    QEMUTimer *v = pv;
1097 dde0463b Juan Quintela
    qemu_put_timer(f, v);
1098 dde0463b Juan Quintela
}
1099 dde0463b Juan Quintela
1100 dde0463b Juan Quintela
const VMStateInfo vmstate_info_timer = {
1101 dde0463b Juan Quintela
    .name = "timer",
1102 dde0463b Juan Quintela
    .get  = get_timer,
1103 dde0463b Juan Quintela
    .put  = put_timer,
1104 dde0463b Juan Quintela
};
1105 dde0463b Juan Quintela
1106 6f67c50f Juan Quintela
/* uint8_t buffers */
1107 6f67c50f Juan Quintela
1108 6f67c50f Juan Quintela
static int get_buffer(QEMUFile *f, void *pv, size_t size)
1109 6f67c50f Juan Quintela
{
1110 6f67c50f Juan Quintela
    uint8_t *v = pv;
1111 6f67c50f Juan Quintela
    qemu_get_buffer(f, v, size);
1112 6f67c50f Juan Quintela
    return 0;
1113 6f67c50f Juan Quintela
}
1114 6f67c50f Juan Quintela
1115 84e2e3eb Juan Quintela
static void put_buffer(QEMUFile *f, void *pv, size_t size)
1116 6f67c50f Juan Quintela
{
1117 84e2e3eb Juan Quintela
    uint8_t *v = pv;
1118 6f67c50f Juan Quintela
    qemu_put_buffer(f, v, size);
1119 6f67c50f Juan Quintela
}
1120 6f67c50f Juan Quintela
1121 6f67c50f Juan Quintela
const VMStateInfo vmstate_info_buffer = {
1122 6f67c50f Juan Quintela
    .name = "buffer",
1123 6f67c50f Juan Quintela
    .get  = get_buffer,
1124 6f67c50f Juan Quintela
    .put  = put_buffer,
1125 6f67c50f Juan Quintela
};
1126 6f67c50f Juan Quintela
1127 76507c75 Juan Quintela
/* unused buffers: space that was used for some fields that are
1128 61cc8701 Stefan Weil
   not useful anymore */
1129 76507c75 Juan Quintela
1130 76507c75 Juan Quintela
static int get_unused_buffer(QEMUFile *f, void *pv, size_t size)
1131 76507c75 Juan Quintela
{
1132 21174c34 Jan Kiszka
    uint8_t buf[1024];
1133 21174c34 Jan Kiszka
    int block_len;
1134 21174c34 Jan Kiszka
1135 21174c34 Jan Kiszka
    while (size > 0) {
1136 21174c34 Jan Kiszka
        block_len = MIN(sizeof(buf), size);
1137 21174c34 Jan Kiszka
        size -= block_len;
1138 21174c34 Jan Kiszka
        qemu_get_buffer(f, buf, block_len);
1139 21174c34 Jan Kiszka
    }
1140 21174c34 Jan Kiszka
   return 0;
1141 76507c75 Juan Quintela
}
1142 76507c75 Juan Quintela
1143 76507c75 Juan Quintela
static void put_unused_buffer(QEMUFile *f, void *pv, size_t size)
1144 76507c75 Juan Quintela
{
1145 21174c34 Jan Kiszka
    static const uint8_t buf[1024];
1146 21174c34 Jan Kiszka
    int block_len;
1147 21174c34 Jan Kiszka
1148 21174c34 Jan Kiszka
    while (size > 0) {
1149 21174c34 Jan Kiszka
        block_len = MIN(sizeof(buf), size);
1150 21174c34 Jan Kiszka
        size -= block_len;
1151 21174c34 Jan Kiszka
        qemu_put_buffer(f, buf, block_len);
1152 21174c34 Jan Kiszka
    }
1153 76507c75 Juan Quintela
}
1154 76507c75 Juan Quintela
1155 76507c75 Juan Quintela
const VMStateInfo vmstate_info_unused_buffer = {
1156 76507c75 Juan Quintela
    .name = "unused_buffer",
1157 76507c75 Juan Quintela
    .get  = get_unused_buffer,
1158 76507c75 Juan Quintela
    .put  = put_unused_buffer,
1159 76507c75 Juan Quintela
};
1160 76507c75 Juan Quintela
1161 7685ee6a Alex Williamson
typedef struct CompatEntry {
1162 7685ee6a Alex Williamson
    char idstr[256];
1163 7685ee6a Alex Williamson
    int instance_id;
1164 7685ee6a Alex Williamson
} CompatEntry;
1165 7685ee6a Alex Williamson
1166 a672b469 aliguori
typedef struct SaveStateEntry {
1167 72cf2d4f Blue Swirl
    QTAILQ_ENTRY(SaveStateEntry) entry;
1168 a672b469 aliguori
    char idstr[256];
1169 a672b469 aliguori
    int instance_id;
1170 4d2ffa08 Jan Kiszka
    int alias_id;
1171 a672b469 aliguori
    int version_id;
1172 a672b469 aliguori
    int section_id;
1173 c163b5ca lirans@il.ibm.com
    SaveSetParamsHandler *set_params;
1174 a672b469 aliguori
    SaveLiveStateHandler *save_live_state;
1175 a672b469 aliguori
    SaveStateHandler *save_state;
1176 a672b469 aliguori
    LoadStateHandler *load_state;
1177 9ed7d6ae Juan Quintela
    const VMStateDescription *vmsd;
1178 a672b469 aliguori
    void *opaque;
1179 7685ee6a Alex Williamson
    CompatEntry *compat;
1180 24312968 Cam Macdonell
    int no_migrate;
1181 a7ae8355 Stefano Stabellini
    int is_ram;
1182 a672b469 aliguori
} SaveStateEntry;
1183 a672b469 aliguori
1184 c163b5ca lirans@il.ibm.com
1185 72cf2d4f Blue Swirl
static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers =
1186 72cf2d4f Blue Swirl
    QTAILQ_HEAD_INITIALIZER(savevm_handlers);
1187 9ed7d6ae Juan Quintela
static int global_section_id;
1188 a672b469 aliguori
1189 8718e999 Juan Quintela
static int calculate_new_instance_id(const char *idstr)
1190 8718e999 Juan Quintela
{
1191 8718e999 Juan Quintela
    SaveStateEntry *se;
1192 8718e999 Juan Quintela
    int instance_id = 0;
1193 8718e999 Juan Quintela
1194 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1195 8718e999 Juan Quintela
        if (strcmp(idstr, se->idstr) == 0
1196 8718e999 Juan Quintela
            && instance_id <= se->instance_id) {
1197 8718e999 Juan Quintela
            instance_id = se->instance_id + 1;
1198 8718e999 Juan Quintela
        }
1199 8718e999 Juan Quintela
    }
1200 8718e999 Juan Quintela
    return instance_id;
1201 8718e999 Juan Quintela
}
1202 8718e999 Juan Quintela
1203 7685ee6a Alex Williamson
static int calculate_compat_instance_id(const char *idstr)
1204 7685ee6a Alex Williamson
{
1205 7685ee6a Alex Williamson
    SaveStateEntry *se;
1206 7685ee6a Alex Williamson
    int instance_id = 0;
1207 7685ee6a Alex Williamson
1208 7685ee6a Alex Williamson
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1209 7685ee6a Alex Williamson
        if (!se->compat)
1210 7685ee6a Alex Williamson
            continue;
1211 7685ee6a Alex Williamson
1212 7685ee6a Alex Williamson
        if (strcmp(idstr, se->compat->idstr) == 0
1213 7685ee6a Alex Williamson
            && instance_id <= se->compat->instance_id) {
1214 7685ee6a Alex Williamson
            instance_id = se->compat->instance_id + 1;
1215 7685ee6a Alex Williamson
        }
1216 7685ee6a Alex Williamson
    }
1217 7685ee6a Alex Williamson
    return instance_id;
1218 7685ee6a Alex Williamson
}
1219 7685ee6a Alex Williamson
1220 a672b469 aliguori
/* TODO: Individual devices generally have very little idea about the rest
1221 a672b469 aliguori
   of the system, so instance_id should be removed/replaced.
1222 a672b469 aliguori
   Meanwhile pass -1 as instance_id if you do not already have a clearly
1223 a672b469 aliguori
   distinguishing id for all instances of your device class. */
1224 0be71e32 Alex Williamson
int register_savevm_live(DeviceState *dev,
1225 0be71e32 Alex Williamson
                         const char *idstr,
1226 a672b469 aliguori
                         int instance_id,
1227 a672b469 aliguori
                         int version_id,
1228 c163b5ca lirans@il.ibm.com
                         SaveSetParamsHandler *set_params,
1229 a672b469 aliguori
                         SaveLiveStateHandler *save_live_state,
1230 a672b469 aliguori
                         SaveStateHandler *save_state,
1231 a672b469 aliguori
                         LoadStateHandler *load_state,
1232 a672b469 aliguori
                         void *opaque)
1233 a672b469 aliguori
{
1234 8718e999 Juan Quintela
    SaveStateEntry *se;
1235 a672b469 aliguori
1236 7267c094 Anthony Liguori
    se = g_malloc0(sizeof(SaveStateEntry));
1237 a672b469 aliguori
    se->version_id = version_id;
1238 a672b469 aliguori
    se->section_id = global_section_id++;
1239 c163b5ca lirans@il.ibm.com
    se->set_params = set_params;
1240 a672b469 aliguori
    se->save_live_state = save_live_state;
1241 a672b469 aliguori
    se->save_state = save_state;
1242 a672b469 aliguori
    se->load_state = load_state;
1243 a672b469 aliguori
    se->opaque = opaque;
1244 9ed7d6ae Juan Quintela
    se->vmsd = NULL;
1245 24312968 Cam Macdonell
    se->no_migrate = 0;
1246 a7ae8355 Stefano Stabellini
    /* if this is a live_savem then set is_ram */
1247 a7ae8355 Stefano Stabellini
    if (save_live_state != NULL) {
1248 a7ae8355 Stefano Stabellini
        se->is_ram = 1;
1249 a7ae8355 Stefano Stabellini
    }
1250 a672b469 aliguori
1251 7685ee6a Alex Williamson
    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
1252 7685ee6a Alex Williamson
        char *id = dev->parent_bus->info->get_dev_path(dev);
1253 7685ee6a Alex Williamson
        if (id) {
1254 7685ee6a Alex Williamson
            pstrcpy(se->idstr, sizeof(se->idstr), id);
1255 7685ee6a Alex Williamson
            pstrcat(se->idstr, sizeof(se->idstr), "/");
1256 7267c094 Anthony Liguori
            g_free(id);
1257 7685ee6a Alex Williamson
1258 7267c094 Anthony Liguori
            se->compat = g_malloc0(sizeof(CompatEntry));
1259 7685ee6a Alex Williamson
            pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), idstr);
1260 7685ee6a Alex Williamson
            se->compat->instance_id = instance_id == -1 ?
1261 7685ee6a Alex Williamson
                         calculate_compat_instance_id(idstr) : instance_id;
1262 7685ee6a Alex Williamson
            instance_id = -1;
1263 7685ee6a Alex Williamson
        }
1264 7685ee6a Alex Williamson
    }
1265 7685ee6a Alex Williamson
    pstrcat(se->idstr, sizeof(se->idstr), idstr);
1266 7685ee6a Alex Williamson
1267 8718e999 Juan Quintela
    if (instance_id == -1) {
1268 7685ee6a Alex Williamson
        se->instance_id = calculate_new_instance_id(se->idstr);
1269 8718e999 Juan Quintela
    } else {
1270 8718e999 Juan Quintela
        se->instance_id = instance_id;
1271 a672b469 aliguori
    }
1272 7685ee6a Alex Williamson
    assert(!se->compat || se->instance_id == 0);
1273 8718e999 Juan Quintela
    /* add at the end of list */
1274 72cf2d4f Blue Swirl
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
1275 a672b469 aliguori
    return 0;
1276 a672b469 aliguori
}
1277 a672b469 aliguori
1278 0be71e32 Alex Williamson
int register_savevm(DeviceState *dev,
1279 0be71e32 Alex Williamson
                    const char *idstr,
1280 a672b469 aliguori
                    int instance_id,
1281 a672b469 aliguori
                    int version_id,
1282 a672b469 aliguori
                    SaveStateHandler *save_state,
1283 a672b469 aliguori
                    LoadStateHandler *load_state,
1284 a672b469 aliguori
                    void *opaque)
1285 a672b469 aliguori
{
1286 0be71e32 Alex Williamson
    return register_savevm_live(dev, idstr, instance_id, version_id,
1287 c163b5ca lirans@il.ibm.com
                                NULL, NULL, save_state, load_state, opaque);
1288 a672b469 aliguori
}
1289 a672b469 aliguori
1290 0be71e32 Alex Williamson
void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque)
1291 41bd13af aliguori
{
1292 8718e999 Juan Quintela
    SaveStateEntry *se, *new_se;
1293 7685ee6a Alex Williamson
    char id[256] = "";
1294 7685ee6a Alex Williamson
1295 7685ee6a Alex Williamson
    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
1296 7685ee6a Alex Williamson
        char *path = dev->parent_bus->info->get_dev_path(dev);
1297 7685ee6a Alex Williamson
        if (path) {
1298 7685ee6a Alex Williamson
            pstrcpy(id, sizeof(id), path);
1299 7685ee6a Alex Williamson
            pstrcat(id, sizeof(id), "/");
1300 7267c094 Anthony Liguori
            g_free(path);
1301 7685ee6a Alex Williamson
        }
1302 7685ee6a Alex Williamson
    }
1303 7685ee6a Alex Williamson
    pstrcat(id, sizeof(id), idstr);
1304 41bd13af aliguori
1305 72cf2d4f Blue Swirl
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
1306 7685ee6a Alex Williamson
        if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {
1307 72cf2d4f Blue Swirl
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
1308 69e58af9 Alex Williamson
            if (se->compat) {
1309 7267c094 Anthony Liguori
                g_free(se->compat);
1310 69e58af9 Alex Williamson
            }
1311 7267c094 Anthony Liguori
            g_free(se);
1312 41bd13af aliguori
        }
1313 41bd13af aliguori
    }
1314 41bd13af aliguori
}
1315 41bd13af aliguori
1316 0be71e32 Alex Williamson
int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
1317 4d2ffa08 Jan Kiszka
                                   const VMStateDescription *vmsd,
1318 4d2ffa08 Jan Kiszka
                                   void *opaque, int alias_id,
1319 4d2ffa08 Jan Kiszka
                                   int required_for_version)
1320 9ed7d6ae Juan Quintela
{
1321 8718e999 Juan Quintela
    SaveStateEntry *se;
1322 9ed7d6ae Juan Quintela
1323 4d2ffa08 Jan Kiszka
    /* If this triggers, alias support can be dropped for the vmsd. */
1324 4d2ffa08 Jan Kiszka
    assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id);
1325 4d2ffa08 Jan Kiszka
1326 7267c094 Anthony Liguori
    se = g_malloc0(sizeof(SaveStateEntry));
1327 9ed7d6ae Juan Quintela
    se->version_id = vmsd->version_id;
1328 9ed7d6ae Juan Quintela
    se->section_id = global_section_id++;
1329 9ed7d6ae Juan Quintela
    se->save_live_state = NULL;
1330 9ed7d6ae Juan Quintela
    se->save_state = NULL;
1331 9ed7d6ae Juan Quintela
    se->load_state = NULL;
1332 9ed7d6ae Juan Quintela
    se->opaque = opaque;
1333 9ed7d6ae Juan Quintela
    se->vmsd = vmsd;
1334 4d2ffa08 Jan Kiszka
    se->alias_id = alias_id;
1335 2837c8ea Gerd Hoffmann
    se->no_migrate = vmsd->unmigratable;
1336 9ed7d6ae Juan Quintela
1337 7685ee6a Alex Williamson
    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
1338 7685ee6a Alex Williamson
        char *id = dev->parent_bus->info->get_dev_path(dev);
1339 7685ee6a Alex Williamson
        if (id) {
1340 7685ee6a Alex Williamson
            pstrcpy(se->idstr, sizeof(se->idstr), id);
1341 7685ee6a Alex Williamson
            pstrcat(se->idstr, sizeof(se->idstr), "/");
1342 7267c094 Anthony Liguori
            g_free(id);
1343 7685ee6a Alex Williamson
1344 7267c094 Anthony Liguori
            se->compat = g_malloc0(sizeof(CompatEntry));
1345 7685ee6a Alex Williamson
            pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name);
1346 7685ee6a Alex Williamson
            se->compat->instance_id = instance_id == -1 ?
1347 7685ee6a Alex Williamson
                         calculate_compat_instance_id(vmsd->name) : instance_id;
1348 7685ee6a Alex Williamson
            instance_id = -1;
1349 7685ee6a Alex Williamson
        }
1350 7685ee6a Alex Williamson
    }
1351 7685ee6a Alex Williamson
    pstrcat(se->idstr, sizeof(se->idstr), vmsd->name);
1352 7685ee6a Alex Williamson
1353 8718e999 Juan Quintela
    if (instance_id == -1) {
1354 7685ee6a Alex Williamson
        se->instance_id = calculate_new_instance_id(se->idstr);
1355 8718e999 Juan Quintela
    } else {
1356 8718e999 Juan Quintela
        se->instance_id = instance_id;
1357 9ed7d6ae Juan Quintela
    }
1358 7685ee6a Alex Williamson
    assert(!se->compat || se->instance_id == 0);
1359 8718e999 Juan Quintela
    /* add at the end of list */
1360 72cf2d4f Blue Swirl
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
1361 9ed7d6ae Juan Quintela
    return 0;
1362 9ed7d6ae Juan Quintela
}
1363 9ed7d6ae Juan Quintela
1364 0be71e32 Alex Williamson
int vmstate_register(DeviceState *dev, int instance_id,
1365 0be71e32 Alex Williamson
                     const VMStateDescription *vmsd, void *opaque)
1366 4d2ffa08 Jan Kiszka
{
1367 0be71e32 Alex Williamson
    return vmstate_register_with_alias_id(dev, instance_id, vmsd,
1368 0be71e32 Alex Williamson
                                          opaque, -1, 0);
1369 4d2ffa08 Jan Kiszka
}
1370 4d2ffa08 Jan Kiszka
1371 0be71e32 Alex Williamson
void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
1372 0be71e32 Alex Williamson
                        void *opaque)
1373 9ed7d6ae Juan Quintela
{
1374 1eb7538b Juan Quintela
    SaveStateEntry *se, *new_se;
1375 1eb7538b Juan Quintela
1376 72cf2d4f Blue Swirl
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
1377 1eb7538b Juan Quintela
        if (se->vmsd == vmsd && se->opaque == opaque) {
1378 72cf2d4f Blue Swirl
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
1379 69e58af9 Alex Williamson
            if (se->compat) {
1380 7267c094 Anthony Liguori
                g_free(se->compat);
1381 69e58af9 Alex Williamson
            }
1382 7267c094 Anthony Liguori
            g_free(se);
1383 1eb7538b Juan Quintela
        }
1384 1eb7538b Juan Quintela
    }
1385 9ed7d6ae Juan Quintela
}
1386 9ed7d6ae Juan Quintela
1387 811814bd Juan Quintela
static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
1388 811814bd Juan Quintela
                                    void *opaque);
1389 811814bd Juan Quintela
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
1390 811814bd Juan Quintela
                                   void *opaque);
1391 811814bd Juan Quintela
1392 9ed7d6ae Juan Quintela
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
1393 9ed7d6ae Juan Quintela
                       void *opaque, int version_id)
1394 9ed7d6ae Juan Quintela
{
1395 9ed7d6ae Juan Quintela
    VMStateField *field = vmsd->fields;
1396 811814bd Juan Quintela
    int ret;
1397 9ed7d6ae Juan Quintela
1398 9ed7d6ae Juan Quintela
    if (version_id > vmsd->version_id) {
1399 9ed7d6ae Juan Quintela
        return -EINVAL;
1400 9ed7d6ae Juan Quintela
    }
1401 9ed7d6ae Juan Quintela
    if (version_id < vmsd->minimum_version_id_old) {
1402 9ed7d6ae Juan Quintela
        return -EINVAL;
1403 9ed7d6ae Juan Quintela
    }
1404 9ed7d6ae Juan Quintela
    if  (version_id < vmsd->minimum_version_id) {
1405 9ed7d6ae Juan Quintela
        return vmsd->load_state_old(f, opaque, version_id);
1406 9ed7d6ae Juan Quintela
    }
1407 fd4d52de Juan Quintela
    if (vmsd->pre_load) {
1408 fd4d52de Juan Quintela
        int ret = vmsd->pre_load(opaque);
1409 fd4d52de Juan Quintela
        if (ret)
1410 fd4d52de Juan Quintela
            return ret;
1411 fd4d52de Juan Quintela
    }
1412 9ed7d6ae Juan Quintela
    while(field->name) {
1413 f11f6a5f Juan Quintela
        if ((field->field_exists &&
1414 f11f6a5f Juan Quintela
             field->field_exists(opaque, version_id)) ||
1415 f11f6a5f Juan Quintela
            (!field->field_exists &&
1416 f11f6a5f Juan Quintela
             field->version_id <= version_id)) {
1417 f752a6aa Juan Quintela
            void *base_addr = opaque + field->offset;
1418 811814bd Juan Quintela
            int i, n_elems = 1;
1419 e61a1e0a Juan Quintela
            int size = field->size;
1420 9ed7d6ae Juan Quintela
1421 e61a1e0a Juan Quintela
            if (field->flags & VMS_VBUFFER) {
1422 e61a1e0a Juan Quintela
                size = *(int32_t *)(opaque+field->size_offset);
1423 33599e2a Juan Quintela
                if (field->flags & VMS_MULTIPLY) {
1424 33599e2a Juan Quintela
                    size *= field->size;
1425 33599e2a Juan Quintela
                }
1426 e61a1e0a Juan Quintela
            }
1427 f752a6aa Juan Quintela
            if (field->flags & VMS_ARRAY) {
1428 f752a6aa Juan Quintela
                n_elems = field->num;
1429 d6698281 Juan Quintela
            } else if (field->flags & VMS_VARRAY_INT32) {
1430 d6698281 Juan Quintela
                n_elems = *(int32_t *)(opaque+field->num_offset);
1431 a624b086 Juan Quintela
            } else if (field->flags & VMS_VARRAY_UINT32) {
1432 a624b086 Juan Quintela
                n_elems = *(uint32_t *)(opaque+field->num_offset);
1433 bdb4941d Juan Quintela
            } else if (field->flags & VMS_VARRAY_UINT16) {
1434 bdb4941d Juan Quintela
                n_elems = *(uint16_t *)(opaque+field->num_offset);
1435 82fa39b7 Juan Quintela
            } else if (field->flags & VMS_VARRAY_UINT8) {
1436 82fa39b7 Juan Quintela
                n_elems = *(uint8_t *)(opaque+field->num_offset);
1437 f752a6aa Juan Quintela
            }
1438 dde0463b Juan Quintela
            if (field->flags & VMS_POINTER) {
1439 e61a1e0a Juan Quintela
                base_addr = *(void **)base_addr + field->start;
1440 dde0463b Juan Quintela
            }
1441 f752a6aa Juan Quintela
            for (i = 0; i < n_elems; i++) {
1442 e61a1e0a Juan Quintela
                void *addr = base_addr + size * i;
1443 ec245e21 Juan Quintela
1444 19df438b Juan Quintela
                if (field->flags & VMS_ARRAY_OF_POINTER) {
1445 19df438b Juan Quintela
                    addr = *(void **)addr;
1446 19df438b Juan Quintela
                }
1447 ec245e21 Juan Quintela
                if (field->flags & VMS_STRUCT) {
1448 fa3aad24 Juan Quintela
                    ret = vmstate_load_state(f, field->vmsd, addr, field->vmsd->version_id);
1449 ec245e21 Juan Quintela
                } else {
1450 e61a1e0a Juan Quintela
                    ret = field->info->get(f, addr, size);
1451 ec245e21 Juan Quintela
1452 ec245e21 Juan Quintela
                }
1453 f752a6aa Juan Quintela
                if (ret < 0) {
1454 f752a6aa Juan Quintela
                    return ret;
1455 f752a6aa Juan Quintela
                }
1456 9ed7d6ae Juan Quintela
            }
1457 9ed7d6ae Juan Quintela
        }
1458 9ed7d6ae Juan Quintela
        field++;
1459 9ed7d6ae Juan Quintela
    }
1460 811814bd Juan Quintela
    ret = vmstate_subsection_load(f, vmsd, opaque);
1461 811814bd Juan Quintela
    if (ret != 0) {
1462 811814bd Juan Quintela
        return ret;
1463 811814bd Juan Quintela
    }
1464 752ff2fa Juan Quintela
    if (vmsd->post_load) {
1465 e59fb374 Juan Quintela
        return vmsd->post_load(opaque, version_id);
1466 752ff2fa Juan Quintela
    }
1467 9ed7d6ae Juan Quintela
    return 0;
1468 9ed7d6ae Juan Quintela
}
1469 9ed7d6ae Juan Quintela
1470 9ed7d6ae Juan Quintela
void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
1471 84e2e3eb Juan Quintela
                        void *opaque)
1472 9ed7d6ae Juan Quintela
{
1473 9ed7d6ae Juan Quintela
    VMStateField *field = vmsd->fields;
1474 9ed7d6ae Juan Quintela
1475 8fb0791d Juan Quintela
    if (vmsd->pre_save) {
1476 8fb0791d Juan Quintela
        vmsd->pre_save(opaque);
1477 8fb0791d Juan Quintela
    }
1478 9ed7d6ae Juan Quintela
    while(field->name) {
1479 f11f6a5f Juan Quintela
        if (!field->field_exists ||
1480 f11f6a5f Juan Quintela
            field->field_exists(opaque, vmsd->version_id)) {
1481 f11f6a5f Juan Quintela
            void *base_addr = opaque + field->offset;
1482 f11f6a5f Juan Quintela
            int i, n_elems = 1;
1483 e61a1e0a Juan Quintela
            int size = field->size;
1484 dde0463b Juan Quintela
1485 e61a1e0a Juan Quintela
            if (field->flags & VMS_VBUFFER) {
1486 e61a1e0a Juan Quintela
                size = *(int32_t *)(opaque+field->size_offset);
1487 33599e2a Juan Quintela
                if (field->flags & VMS_MULTIPLY) {
1488 33599e2a Juan Quintela
                    size *= field->size;
1489 33599e2a Juan Quintela
                }
1490 e61a1e0a Juan Quintela
            }
1491 f11f6a5f Juan Quintela
            if (field->flags & VMS_ARRAY) {
1492 f11f6a5f Juan Quintela
                n_elems = field->num;
1493 d6698281 Juan Quintela
            } else if (field->flags & VMS_VARRAY_INT32) {
1494 d6698281 Juan Quintela
                n_elems = *(int32_t *)(opaque+field->num_offset);
1495 1329d189 Amos Kong
            } else if (field->flags & VMS_VARRAY_UINT32) {
1496 1329d189 Amos Kong
                n_elems = *(uint32_t *)(opaque+field->num_offset);
1497 bdb4941d Juan Quintela
            } else if (field->flags & VMS_VARRAY_UINT16) {
1498 bdb4941d Juan Quintela
                n_elems = *(uint16_t *)(opaque+field->num_offset);
1499 b784421c Juan Quintela
            } else if (field->flags & VMS_VARRAY_UINT8) {
1500 b784421c Juan Quintela
                n_elems = *(uint8_t *)(opaque+field->num_offset);
1501 f11f6a5f Juan Quintela
            }
1502 f11f6a5f Juan Quintela
            if (field->flags & VMS_POINTER) {
1503 e61a1e0a Juan Quintela
                base_addr = *(void **)base_addr + field->start;
1504 f11f6a5f Juan Quintela
            }
1505 f11f6a5f Juan Quintela
            for (i = 0; i < n_elems; i++) {
1506 e61a1e0a Juan Quintela
                void *addr = base_addr + size * i;
1507 ec245e21 Juan Quintela
1508 8595387e Juan Quintela
                if (field->flags & VMS_ARRAY_OF_POINTER) {
1509 8595387e Juan Quintela
                    addr = *(void **)addr;
1510 8595387e Juan Quintela
                }
1511 f11f6a5f Juan Quintela
                if (field->flags & VMS_STRUCT) {
1512 f11f6a5f Juan Quintela
                    vmstate_save_state(f, field->vmsd, addr);
1513 f11f6a5f Juan Quintela
                } else {
1514 e61a1e0a Juan Quintela
                    field->info->put(f, addr, size);
1515 f11f6a5f Juan Quintela
                }
1516 ec245e21 Juan Quintela
            }
1517 dde0463b Juan Quintela
        }
1518 9ed7d6ae Juan Quintela
        field++;
1519 9ed7d6ae Juan Quintela
    }
1520 811814bd Juan Quintela
    vmstate_subsection_save(f, vmsd, opaque);
1521 9ed7d6ae Juan Quintela
}
1522 9ed7d6ae Juan Quintela
1523 4082be4d Juan Quintela
static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
1524 4082be4d Juan Quintela
{
1525 9ed7d6ae Juan Quintela
    if (!se->vmsd) {         /* Old style */
1526 9ed7d6ae Juan Quintela
        return se->load_state(f, se->opaque, version_id);
1527 9ed7d6ae Juan Quintela
    }
1528 9ed7d6ae Juan Quintela
    return vmstate_load_state(f, se->vmsd, se->opaque, version_id);
1529 4082be4d Juan Quintela
}
1530 4082be4d Juan Quintela
1531 dc912121 Alex Williamson
static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
1532 4082be4d Juan Quintela
{
1533 9ed7d6ae Juan Quintela
    if (!se->vmsd) {         /* Old style */
1534 9ed7d6ae Juan Quintela
        se->save_state(f, se->opaque);
1535 dc912121 Alex Williamson
        return;
1536 9ed7d6ae Juan Quintela
    }
1537 9ed7d6ae Juan Quintela
    vmstate_save_state(f,se->vmsd, se->opaque);
1538 4082be4d Juan Quintela
}
1539 4082be4d Juan Quintela
1540 a672b469 aliguori
#define QEMU_VM_FILE_MAGIC           0x5145564d
1541 a672b469 aliguori
#define QEMU_VM_FILE_VERSION_COMPAT  0x00000002
1542 a672b469 aliguori
#define QEMU_VM_FILE_VERSION         0x00000003
1543 a672b469 aliguori
1544 a672b469 aliguori
#define QEMU_VM_EOF                  0x00
1545 a672b469 aliguori
#define QEMU_VM_SECTION_START        0x01
1546 a672b469 aliguori
#define QEMU_VM_SECTION_PART         0x02
1547 a672b469 aliguori
#define QEMU_VM_SECTION_END          0x03
1548 a672b469 aliguori
#define QEMU_VM_SECTION_FULL         0x04
1549 811814bd Juan Quintela
#define QEMU_VM_SUBSECTION           0x05
1550 a672b469 aliguori
1551 e1c37d0e Luiz Capitulino
bool qemu_savevm_state_blocked(Error **errp)
1552 dc912121 Alex Williamson
{
1553 dc912121 Alex Williamson
    SaveStateEntry *se;
1554 dc912121 Alex Williamson
1555 dc912121 Alex Williamson
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1556 dc912121 Alex Williamson
        if (se->no_migrate) {
1557 e1c37d0e Luiz Capitulino
            error_set(errp, QERR_MIGRATION_NOT_SUPPORTED, se->idstr);
1558 dc912121 Alex Williamson
            return true;
1559 dc912121 Alex Williamson
        }
1560 dc912121 Alex Williamson
    }
1561 dc912121 Alex Williamson
    return false;
1562 dc912121 Alex Williamson
}
1563 dc912121 Alex Williamson
1564 539de124 Luiz Capitulino
int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared)
1565 a672b469 aliguori
{
1566 a672b469 aliguori
    SaveStateEntry *se;
1567 39346385 Juan Quintela
    int ret;
1568 a672b469 aliguori
1569 c163b5ca lirans@il.ibm.com
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1570 c163b5ca lirans@il.ibm.com
        if(se->set_params == NULL) {
1571 c163b5ca lirans@il.ibm.com
            continue;
1572 c163b5ca lirans@il.ibm.com
        }
1573 c163b5ca lirans@il.ibm.com
        se->set_params(blk_enable, shared, se->opaque);
1574 c163b5ca lirans@il.ibm.com
    }
1575 c163b5ca lirans@il.ibm.com
    
1576 a672b469 aliguori
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1577 a672b469 aliguori
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1578 a672b469 aliguori
1579 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1580 a672b469 aliguori
        int len;
1581 a672b469 aliguori
1582 a672b469 aliguori
        if (se->save_live_state == NULL)
1583 a672b469 aliguori
            continue;
1584 a672b469 aliguori
1585 a672b469 aliguori
        /* Section type */
1586 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_START);
1587 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1588 a672b469 aliguori
1589 a672b469 aliguori
        /* ID string */
1590 a672b469 aliguori
        len = strlen(se->idstr);
1591 a672b469 aliguori
        qemu_put_byte(f, len);
1592 a672b469 aliguori
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1593 a672b469 aliguori
1594 a672b469 aliguori
        qemu_put_be32(f, se->instance_id);
1595 a672b469 aliguori
        qemu_put_be32(f, se->version_id);
1596 a672b469 aliguori
1597 539de124 Luiz Capitulino
        ret = se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
1598 2975725f Juan Quintela
        if (ret < 0) {
1599 539de124 Luiz Capitulino
            qemu_savevm_state_cancel(f);
1600 2975725f Juan Quintela
            return ret;
1601 2975725f Juan Quintela
        }
1602 a672b469 aliguori
    }
1603 624b9cc2 Juan Quintela
    ret = qemu_file_get_error(f);
1604 39346385 Juan Quintela
    if (ret != 0) {
1605 539de124 Luiz Capitulino
        qemu_savevm_state_cancel(f);
1606 4ec7fcc7 Jan Kiszka
    }
1607 a672b469 aliguori
1608 39346385 Juan Quintela
    return ret;
1609 39346385 Juan Quintela
1610 a672b469 aliguori
}
1611 a672b469 aliguori
1612 39346385 Juan Quintela
/*
1613 07f35073 Dong Xu Wang
 * this function has three return values:
1614 39346385 Juan Quintela
 *   negative: there was one error, and we have -errno.
1615 39346385 Juan Quintela
 *   0 : We haven't finished, caller have to go again
1616 39346385 Juan Quintela
 *   1 : We have finished, we can go to complete phase
1617 39346385 Juan Quintela
 */
1618 539de124 Luiz Capitulino
int qemu_savevm_state_iterate(QEMUFile *f)
1619 a672b469 aliguori
{
1620 a672b469 aliguori
    SaveStateEntry *se;
1621 a672b469 aliguori
    int ret = 1;
1622 a672b469 aliguori
1623 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1624 a672b469 aliguori
        if (se->save_live_state == NULL)
1625 a672b469 aliguori
            continue;
1626 a672b469 aliguori
1627 a672b469 aliguori
        /* Section type */
1628 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_PART);
1629 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1630 a672b469 aliguori
1631 539de124 Luiz Capitulino
        ret = se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque);
1632 2975725f Juan Quintela
        if (ret <= 0) {
1633 90697be8 Jan Kiszka
            /* Do not proceed to the next vmstate before this one reported
1634 90697be8 Jan Kiszka
               completion of the current stage. This serializes the migration
1635 90697be8 Jan Kiszka
               and reduces the probability that a faster changing state is
1636 90697be8 Jan Kiszka
               synchronized over and over again. */
1637 90697be8 Jan Kiszka
            break;
1638 90697be8 Jan Kiszka
        }
1639 a672b469 aliguori
    }
1640 39346385 Juan Quintela
    if (ret != 0) {
1641 39346385 Juan Quintela
        return ret;
1642 39346385 Juan Quintela
    }
1643 624b9cc2 Juan Quintela
    ret = qemu_file_get_error(f);
1644 39346385 Juan Quintela
    if (ret != 0) {
1645 539de124 Luiz Capitulino
        qemu_savevm_state_cancel(f);
1646 4ec7fcc7 Jan Kiszka
    }
1647 39346385 Juan Quintela
    return ret;
1648 a672b469 aliguori
}
1649 a672b469 aliguori
1650 539de124 Luiz Capitulino
int qemu_savevm_state_complete(QEMUFile *f)
1651 a672b469 aliguori
{
1652 a672b469 aliguori
    SaveStateEntry *se;
1653 2975725f Juan Quintela
    int ret;
1654 a672b469 aliguori
1655 ea375f9a Jan Kiszka
    cpu_synchronize_all_states();
1656 ea375f9a Jan Kiszka
1657 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1658 a672b469 aliguori
        if (se->save_live_state == NULL)
1659 a672b469 aliguori
            continue;
1660 a672b469 aliguori
1661 a672b469 aliguori
        /* Section type */
1662 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_END);
1663 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1664 a672b469 aliguori
1665 539de124 Luiz Capitulino
        ret = se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);
1666 2975725f Juan Quintela
        if (ret < 0) {
1667 2975725f Juan Quintela
            return ret;
1668 2975725f Juan Quintela
        }
1669 a672b469 aliguori
    }
1670 a672b469 aliguori
1671 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1672 a672b469 aliguori
        int len;
1673 a672b469 aliguori
1674 9ed7d6ae Juan Quintela
        if (se->save_state == NULL && se->vmsd == NULL)
1675 a672b469 aliguori
            continue;
1676 a672b469 aliguori
1677 a672b469 aliguori
        /* Section type */
1678 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
1679 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1680 a672b469 aliguori
1681 a672b469 aliguori
        /* ID string */
1682 a672b469 aliguori
        len = strlen(se->idstr);
1683 a672b469 aliguori
        qemu_put_byte(f, len);
1684 a672b469 aliguori
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1685 a672b469 aliguori
1686 a672b469 aliguori
        qemu_put_be32(f, se->instance_id);
1687 a672b469 aliguori
        qemu_put_be32(f, se->version_id);
1688 a672b469 aliguori
1689 dc912121 Alex Williamson
        vmstate_save(f, se);
1690 a672b469 aliguori
    }
1691 a672b469 aliguori
1692 a672b469 aliguori
    qemu_put_byte(f, QEMU_VM_EOF);
1693 a672b469 aliguori
1694 624b9cc2 Juan Quintela
    return qemu_file_get_error(f);
1695 a672b469 aliguori
}
1696 a672b469 aliguori
1697 539de124 Luiz Capitulino
void qemu_savevm_state_cancel(QEMUFile *f)
1698 4ec7fcc7 Jan Kiszka
{
1699 4ec7fcc7 Jan Kiszka
    SaveStateEntry *se;
1700 4ec7fcc7 Jan Kiszka
1701 4ec7fcc7 Jan Kiszka
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1702 4ec7fcc7 Jan Kiszka
        if (se->save_live_state) {
1703 539de124 Luiz Capitulino
            se->save_live_state(f, -1, se->opaque);
1704 4ec7fcc7 Jan Kiszka
        }
1705 4ec7fcc7 Jan Kiszka
    }
1706 4ec7fcc7 Jan Kiszka
}
1707 4ec7fcc7 Jan Kiszka
1708 e1c37d0e Luiz Capitulino
static int qemu_savevm_state(QEMUFile *f)
1709 a672b469 aliguori
{
1710 a672b469 aliguori
    int ret;
1711 a672b469 aliguori
1712 e1c37d0e Luiz Capitulino
    if (qemu_savevm_state_blocked(NULL)) {
1713 dc912121 Alex Williamson
        ret = -EINVAL;
1714 dc912121 Alex Williamson
        goto out;
1715 dc912121 Alex Williamson
    }
1716 dc912121 Alex Williamson
1717 539de124 Luiz Capitulino
    ret = qemu_savevm_state_begin(f, 0, 0);
1718 a672b469 aliguori
    if (ret < 0)
1719 a672b469 aliguori
        goto out;
1720 a672b469 aliguori
1721 a672b469 aliguori
    do {
1722 539de124 Luiz Capitulino
        ret = qemu_savevm_state_iterate(f);
1723 a672b469 aliguori
        if (ret < 0)
1724 a672b469 aliguori
            goto out;
1725 a672b469 aliguori
    } while (ret == 0);
1726 a672b469 aliguori
1727 539de124 Luiz Capitulino
    ret = qemu_savevm_state_complete(f);
1728 a672b469 aliguori
1729 a672b469 aliguori
out:
1730 39346385 Juan Quintela
    if (ret == 0) {
1731 624b9cc2 Juan Quintela
        ret = qemu_file_get_error(f);
1732 39346385 Juan Quintela
    }
1733 a672b469 aliguori
1734 a672b469 aliguori
    return ret;
1735 a672b469 aliguori
}
1736 a672b469 aliguori
1737 a7ae8355 Stefano Stabellini
static int qemu_save_device_state(QEMUFile *f)
1738 a7ae8355 Stefano Stabellini
{
1739 a7ae8355 Stefano Stabellini
    SaveStateEntry *se;
1740 a7ae8355 Stefano Stabellini
1741 a7ae8355 Stefano Stabellini
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1742 a7ae8355 Stefano Stabellini
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1743 a7ae8355 Stefano Stabellini
1744 a7ae8355 Stefano Stabellini
    cpu_synchronize_all_states();
1745 a7ae8355 Stefano Stabellini
1746 a7ae8355 Stefano Stabellini
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1747 a7ae8355 Stefano Stabellini
        int len;
1748 a7ae8355 Stefano Stabellini
1749 a7ae8355 Stefano Stabellini
        if (se->is_ram) {
1750 a7ae8355 Stefano Stabellini
            continue;
1751 a7ae8355 Stefano Stabellini
        }
1752 a7ae8355 Stefano Stabellini
        if (se->save_state == NULL && se->vmsd == NULL) {
1753 a7ae8355 Stefano Stabellini
            continue;
1754 a7ae8355 Stefano Stabellini
        }
1755 a7ae8355 Stefano Stabellini
1756 a7ae8355 Stefano Stabellini
        /* Section type */
1757 a7ae8355 Stefano Stabellini
        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
1758 a7ae8355 Stefano Stabellini
        qemu_put_be32(f, se->section_id);
1759 a7ae8355 Stefano Stabellini
1760 a7ae8355 Stefano Stabellini
        /* ID string */
1761 a7ae8355 Stefano Stabellini
        len = strlen(se->idstr);
1762 a7ae8355 Stefano Stabellini
        qemu_put_byte(f, len);
1763 a7ae8355 Stefano Stabellini
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1764 a7ae8355 Stefano Stabellini
1765 a7ae8355 Stefano Stabellini
        qemu_put_be32(f, se->instance_id);
1766 a7ae8355 Stefano Stabellini
        qemu_put_be32(f, se->version_id);
1767 a7ae8355 Stefano Stabellini
1768 a7ae8355 Stefano Stabellini
        vmstate_save(f, se);
1769 a7ae8355 Stefano Stabellini
    }
1770 a7ae8355 Stefano Stabellini
1771 a7ae8355 Stefano Stabellini
    qemu_put_byte(f, QEMU_VM_EOF);
1772 a7ae8355 Stefano Stabellini
1773 a7ae8355 Stefano Stabellini
    return qemu_file_get_error(f);
1774 a7ae8355 Stefano Stabellini
}
1775 a7ae8355 Stefano Stabellini
1776 a672b469 aliguori
static SaveStateEntry *find_se(const char *idstr, int instance_id)
1777 a672b469 aliguori
{
1778 a672b469 aliguori
    SaveStateEntry *se;
1779 a672b469 aliguori
1780 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1781 a672b469 aliguori
        if (!strcmp(se->idstr, idstr) &&
1782 4d2ffa08 Jan Kiszka
            (instance_id == se->instance_id ||
1783 4d2ffa08 Jan Kiszka
             instance_id == se->alias_id))
1784 a672b469 aliguori
            return se;
1785 7685ee6a Alex Williamson
        /* Migrating from an older version? */
1786 7685ee6a Alex Williamson
        if (strstr(se->idstr, idstr) && se->compat) {
1787 7685ee6a Alex Williamson
            if (!strcmp(se->compat->idstr, idstr) &&
1788 7685ee6a Alex Williamson
                (instance_id == se->compat->instance_id ||
1789 7685ee6a Alex Williamson
                 instance_id == se->alias_id))
1790 7685ee6a Alex Williamson
                return se;
1791 7685ee6a Alex Williamson
        }
1792 a672b469 aliguori
    }
1793 a672b469 aliguori
    return NULL;
1794 a672b469 aliguori
}
1795 a672b469 aliguori
1796 811814bd Juan Quintela
static const VMStateDescription *vmstate_get_subsection(const VMStateSubsection *sub, char *idstr)
1797 811814bd Juan Quintela
{
1798 811814bd Juan Quintela
    while(sub && sub->needed) {
1799 811814bd Juan Quintela
        if (strcmp(idstr, sub->vmsd->name) == 0) {
1800 811814bd Juan Quintela
            return sub->vmsd;
1801 811814bd Juan Quintela
        }
1802 811814bd Juan Quintela
        sub++;
1803 811814bd Juan Quintela
    }
1804 811814bd Juan Quintela
    return NULL;
1805 811814bd Juan Quintela
}
1806 811814bd Juan Quintela
1807 811814bd Juan Quintela
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
1808 811814bd Juan Quintela
                                   void *opaque)
1809 811814bd Juan Quintela
{
1810 c6380724 Juan Quintela
    while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) {
1811 811814bd Juan Quintela
        char idstr[256];
1812 811814bd Juan Quintela
        int ret;
1813 c6380724 Juan Quintela
        uint8_t version_id, len, size;
1814 811814bd Juan Quintela
        const VMStateDescription *sub_vmsd;
1815 811814bd Juan Quintela
1816 c6380724 Juan Quintela
        len = qemu_peek_byte(f, 1);
1817 c6380724 Juan Quintela
        if (len < strlen(vmsd->name) + 1) {
1818 c6380724 Juan Quintela
            /* subsection name has be be "section_name/a" */
1819 c6380724 Juan Quintela
            return 0;
1820 c6380724 Juan Quintela
        }
1821 c6380724 Juan Quintela
        size = qemu_peek_buffer(f, (uint8_t *)idstr, len, 2);
1822 c6380724 Juan Quintela
        if (size != len) {
1823 c6380724 Juan Quintela
            return 0;
1824 c6380724 Juan Quintela
        }
1825 c6380724 Juan Quintela
        idstr[size] = 0;
1826 811814bd Juan Quintela
1827 c6380724 Juan Quintela
        if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) {
1828 c6380724 Juan Quintela
            /* it don't have a valid subsection name */
1829 c6380724 Juan Quintela
            return 0;
1830 c6380724 Juan Quintela
        }
1831 3da9eebd Juan Quintela
        sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr);
1832 811814bd Juan Quintela
        if (sub_vmsd == NULL) {
1833 811814bd Juan Quintela
            return -ENOENT;
1834 811814bd Juan Quintela
        }
1835 c6380724 Juan Quintela
        qemu_file_skip(f, 1); /* subsection */
1836 c6380724 Juan Quintela
        qemu_file_skip(f, 1); /* len */
1837 c6380724 Juan Quintela
        qemu_file_skip(f, len); /* idstr */
1838 c6380724 Juan Quintela
        version_id = qemu_get_be32(f);
1839 c6380724 Juan Quintela
1840 811814bd Juan Quintela
        ret = vmstate_load_state(f, sub_vmsd, opaque, version_id);
1841 811814bd Juan Quintela
        if (ret) {
1842 811814bd Juan Quintela
            return ret;
1843 811814bd Juan Quintela
        }
1844 811814bd Juan Quintela
    }
1845 811814bd Juan Quintela
    return 0;
1846 811814bd Juan Quintela
}
1847 811814bd Juan Quintela
1848 811814bd Juan Quintela
static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
1849 811814bd Juan Quintela
                                    void *opaque)
1850 811814bd Juan Quintela
{
1851 811814bd Juan Quintela
    const VMStateSubsection *sub = vmsd->subsections;
1852 811814bd Juan Quintela
1853 811814bd Juan Quintela
    while (sub && sub->needed) {
1854 811814bd Juan Quintela
        if (sub->needed(opaque)) {
1855 811814bd Juan Quintela
            const VMStateDescription *vmsd = sub->vmsd;
1856 811814bd Juan Quintela
            uint8_t len;
1857 811814bd Juan Quintela
1858 811814bd Juan Quintela
            qemu_put_byte(f, QEMU_VM_SUBSECTION);
1859 811814bd Juan Quintela
            len = strlen(vmsd->name);
1860 811814bd Juan Quintela
            qemu_put_byte(f, len);
1861 811814bd Juan Quintela
            qemu_put_buffer(f, (uint8_t *)vmsd->name, len);
1862 811814bd Juan Quintela
            qemu_put_be32(f, vmsd->version_id);
1863 811814bd Juan Quintela
            vmstate_save_state(f, vmsd, opaque);
1864 811814bd Juan Quintela
        }
1865 811814bd Juan Quintela
        sub++;
1866 811814bd Juan Quintela
    }
1867 811814bd Juan Quintela
}
1868 811814bd Juan Quintela
1869 a672b469 aliguori
typedef struct LoadStateEntry {
1870 72cf2d4f Blue Swirl
    QLIST_ENTRY(LoadStateEntry) entry;
1871 a672b469 aliguori
    SaveStateEntry *se;
1872 a672b469 aliguori
    int section_id;
1873 a672b469 aliguori
    int version_id;
1874 a672b469 aliguori
} LoadStateEntry;
1875 a672b469 aliguori
1876 a672b469 aliguori
int qemu_loadvm_state(QEMUFile *f)
1877 a672b469 aliguori
{
1878 72cf2d4f Blue Swirl
    QLIST_HEAD(, LoadStateEntry) loadvm_handlers =
1879 72cf2d4f Blue Swirl
        QLIST_HEAD_INITIALIZER(loadvm_handlers);
1880 f4dbb8dd Juan Quintela
    LoadStateEntry *le, *new_le;
1881 a672b469 aliguori
    uint8_t section_type;
1882 a672b469 aliguori
    unsigned int v;
1883 a672b469 aliguori
    int ret;
1884 a672b469 aliguori
1885 e1c37d0e Luiz Capitulino
    if (qemu_savevm_state_blocked(NULL)) {
1886 dc912121 Alex Williamson
        return -EINVAL;
1887 dc912121 Alex Williamson
    }
1888 dc912121 Alex Williamson
1889 a672b469 aliguori
    v = qemu_get_be32(f);
1890 a672b469 aliguori
    if (v != QEMU_VM_FILE_MAGIC)
1891 a672b469 aliguori
        return -EINVAL;
1892 a672b469 aliguori
1893 a672b469 aliguori
    v = qemu_get_be32(f);
1894 bbfe1408 Juan Quintela
    if (v == QEMU_VM_FILE_VERSION_COMPAT) {
1895 bbfe1408 Juan Quintela
        fprintf(stderr, "SaveVM v2 format is obsolete and don't work anymore\n");
1896 bbfe1408 Juan Quintela
        return -ENOTSUP;
1897 bbfe1408 Juan Quintela
    }
1898 a672b469 aliguori
    if (v != QEMU_VM_FILE_VERSION)
1899 a672b469 aliguori
        return -ENOTSUP;
1900 a672b469 aliguori
1901 a672b469 aliguori
    while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
1902 a672b469 aliguori
        uint32_t instance_id, version_id, section_id;
1903 a672b469 aliguori
        SaveStateEntry *se;
1904 a672b469 aliguori
        char idstr[257];
1905 a672b469 aliguori
        int len;
1906 a672b469 aliguori
1907 a672b469 aliguori
        switch (section_type) {
1908 a672b469 aliguori
        case QEMU_VM_SECTION_START:
1909 a672b469 aliguori
        case QEMU_VM_SECTION_FULL:
1910 a672b469 aliguori
            /* Read section start */
1911 a672b469 aliguori
            section_id = qemu_get_be32(f);
1912 a672b469 aliguori
            len = qemu_get_byte(f);
1913 a672b469 aliguori
            qemu_get_buffer(f, (uint8_t *)idstr, len);
1914 a672b469 aliguori
            idstr[len] = 0;
1915 a672b469 aliguori
            instance_id = qemu_get_be32(f);
1916 a672b469 aliguori
            version_id = qemu_get_be32(f);
1917 a672b469 aliguori
1918 a672b469 aliguori
            /* Find savevm section */
1919 a672b469 aliguori
            se = find_se(idstr, instance_id);
1920 a672b469 aliguori
            if (se == NULL) {
1921 a672b469 aliguori
                fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
1922 a672b469 aliguori
                ret = -EINVAL;
1923 a672b469 aliguori
                goto out;
1924 a672b469 aliguori
            }
1925 a672b469 aliguori
1926 a672b469 aliguori
            /* Validate version */
1927 a672b469 aliguori
            if (version_id > se->version_id) {
1928 a672b469 aliguori
                fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
1929 a672b469 aliguori
                        version_id, idstr, se->version_id);
1930 a672b469 aliguori
                ret = -EINVAL;
1931 a672b469 aliguori
                goto out;
1932 a672b469 aliguori
            }
1933 a672b469 aliguori
1934 a672b469 aliguori
            /* Add entry */
1935 7267c094 Anthony Liguori
            le = g_malloc0(sizeof(*le));
1936 a672b469 aliguori
1937 a672b469 aliguori
            le->se = se;
1938 a672b469 aliguori
            le->section_id = section_id;
1939 a672b469 aliguori
            le->version_id = version_id;
1940 72cf2d4f Blue Swirl
            QLIST_INSERT_HEAD(&loadvm_handlers, le, entry);
1941 a672b469 aliguori
1942 4082be4d Juan Quintela
            ret = vmstate_load(f, le->se, le->version_id);
1943 b5a22e4a Juan Quintela
            if (ret < 0) {
1944 b5a22e4a Juan Quintela
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
1945 b5a22e4a Juan Quintela
                        instance_id, idstr);
1946 b5a22e4a Juan Quintela
                goto out;
1947 b5a22e4a Juan Quintela
            }
1948 a672b469 aliguori
            break;
1949 a672b469 aliguori
        case QEMU_VM_SECTION_PART:
1950 a672b469 aliguori
        case QEMU_VM_SECTION_END:
1951 a672b469 aliguori
            section_id = qemu_get_be32(f);
1952 a672b469 aliguori
1953 72cf2d4f Blue Swirl
            QLIST_FOREACH(le, &loadvm_handlers, entry) {
1954 f4dbb8dd Juan Quintela
                if (le->section_id == section_id) {
1955 f4dbb8dd Juan Quintela
                    break;
1956 f4dbb8dd Juan Quintela
                }
1957 f4dbb8dd Juan Quintela
            }
1958 a672b469 aliguori
            if (le == NULL) {
1959 a672b469 aliguori
                fprintf(stderr, "Unknown savevm section %d\n", section_id);
1960 a672b469 aliguori
                ret = -EINVAL;
1961 a672b469 aliguori
                goto out;
1962 a672b469 aliguori
            }
1963 a672b469 aliguori
1964 4082be4d Juan Quintela
            ret = vmstate_load(f, le->se, le->version_id);
1965 b5a22e4a Juan Quintela
            if (ret < 0) {
1966 b5a22e4a Juan Quintela
                fprintf(stderr, "qemu: warning: error while loading state section id %d\n",
1967 b5a22e4a Juan Quintela
                        section_id);
1968 b5a22e4a Juan Quintela
                goto out;
1969 b5a22e4a Juan Quintela
            }
1970 a672b469 aliguori
            break;
1971 a672b469 aliguori
        default:
1972 a672b469 aliguori
            fprintf(stderr, "Unknown savevm section type %d\n", section_type);
1973 a672b469 aliguori
            ret = -EINVAL;
1974 a672b469 aliguori
            goto out;
1975 a672b469 aliguori
        }
1976 a672b469 aliguori
    }
1977 a672b469 aliguori
1978 ea375f9a Jan Kiszka
    cpu_synchronize_all_post_init();
1979 ea375f9a Jan Kiszka
1980 a672b469 aliguori
    ret = 0;
1981 a672b469 aliguori
1982 a672b469 aliguori
out:
1983 72cf2d4f Blue Swirl
    QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {
1984 72cf2d4f Blue Swirl
        QLIST_REMOVE(le, entry);
1985 7267c094 Anthony Liguori
        g_free(le);
1986 a672b469 aliguori
    }
1987 a672b469 aliguori
1988 42802d47 Juan Quintela
    if (ret == 0) {
1989 42802d47 Juan Quintela
        ret = qemu_file_get_error(f);
1990 624b9cc2 Juan Quintela
    }
1991 a672b469 aliguori
1992 a672b469 aliguori
    return ret;
1993 a672b469 aliguori
}
1994 a672b469 aliguori
1995 a672b469 aliguori
static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
1996 a672b469 aliguori
                              const char *name)
1997 a672b469 aliguori
{
1998 a672b469 aliguori
    QEMUSnapshotInfo *sn_tab, *sn;
1999 a672b469 aliguori
    int nb_sns, i, ret;
2000 a672b469 aliguori
2001 a672b469 aliguori
    ret = -ENOENT;
2002 a672b469 aliguori
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
2003 a672b469 aliguori
    if (nb_sns < 0)
2004 a672b469 aliguori
        return ret;
2005 a672b469 aliguori
    for(i = 0; i < nb_sns; i++) {
2006 a672b469 aliguori
        sn = &sn_tab[i];
2007 a672b469 aliguori
        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
2008 a672b469 aliguori
            *sn_info = *sn;
2009 a672b469 aliguori
            ret = 0;
2010 a672b469 aliguori
            break;
2011 a672b469 aliguori
        }
2012 a672b469 aliguori
    }
2013 7267c094 Anthony Liguori
    g_free(sn_tab);
2014 a672b469 aliguori
    return ret;
2015 a672b469 aliguori
}
2016 a672b469 aliguori
2017 cb499fb2 Kevin Wolf
/*
2018 cb499fb2 Kevin Wolf
 * Deletes snapshots of a given name in all opened images.
2019 cb499fb2 Kevin Wolf
 */
2020 cb499fb2 Kevin Wolf
static int del_existing_snapshots(Monitor *mon, const char *name)
2021 cb499fb2 Kevin Wolf
{
2022 cb499fb2 Kevin Wolf
    BlockDriverState *bs;
2023 cb499fb2 Kevin Wolf
    QEMUSnapshotInfo sn1, *snapshot = &sn1;
2024 cb499fb2 Kevin Wolf
    int ret;
2025 cb499fb2 Kevin Wolf
2026 dbc13590 Markus Armbruster
    bs = NULL;
2027 dbc13590 Markus Armbruster
    while ((bs = bdrv_next(bs))) {
2028 cb499fb2 Kevin Wolf
        if (bdrv_can_snapshot(bs) &&
2029 cb499fb2 Kevin Wolf
            bdrv_snapshot_find(bs, snapshot, name) >= 0)
2030 cb499fb2 Kevin Wolf
        {
2031 cb499fb2 Kevin Wolf
            ret = bdrv_snapshot_delete(bs, name);
2032 cb499fb2 Kevin Wolf
            if (ret < 0) {
2033 cb499fb2 Kevin Wolf
                monitor_printf(mon,
2034 cb499fb2 Kevin Wolf
                               "Error while deleting snapshot on '%s'\n",
2035 cb499fb2 Kevin Wolf
                               bdrv_get_device_name(bs));
2036 cb499fb2 Kevin Wolf
                return -1;
2037 cb499fb2 Kevin Wolf
            }
2038 cb499fb2 Kevin Wolf
        }
2039 cb499fb2 Kevin Wolf
    }
2040 cb499fb2 Kevin Wolf
2041 cb499fb2 Kevin Wolf
    return 0;
2042 cb499fb2 Kevin Wolf
}
2043 cb499fb2 Kevin Wolf
2044 d54908a5 Luiz Capitulino
void do_savevm(Monitor *mon, const QDict *qdict)
2045 a672b469 aliguori
{
2046 a672b469 aliguori
    BlockDriverState *bs, *bs1;
2047 a672b469 aliguori
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
2048 cb499fb2 Kevin Wolf
    int ret;
2049 a672b469 aliguori
    QEMUFile *f;
2050 a672b469 aliguori
    int saved_vm_running;
2051 c2c9a466 Kevin Wolf
    uint64_t vm_state_size;
2052 a672b469 aliguori
#ifdef _WIN32
2053 a672b469 aliguori
    struct _timeb tb;
2054 7d631a11 Miguel Di Ciurcio Filho
    struct tm *ptm;
2055 a672b469 aliguori
#else
2056 a672b469 aliguori
    struct timeval tv;
2057 7d631a11 Miguel Di Ciurcio Filho
    struct tm tm;
2058 a672b469 aliguori
#endif
2059 d54908a5 Luiz Capitulino
    const char *name = qdict_get_try_str(qdict, "name");
2060 a672b469 aliguori
2061 feeee5ac Miguel Di Ciurcio Filho
    /* Verify if there is a device that doesn't support snapshots and is writable */
2062 dbc13590 Markus Armbruster
    bs = NULL;
2063 dbc13590 Markus Armbruster
    while ((bs = bdrv_next(bs))) {
2064 feeee5ac Miguel Di Ciurcio Filho
2065 07b70bfb Markus Armbruster
        if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2066 feeee5ac Miguel Di Ciurcio Filho
            continue;
2067 feeee5ac Miguel Di Ciurcio Filho
        }
2068 feeee5ac Miguel Di Ciurcio Filho
2069 feeee5ac Miguel Di Ciurcio Filho
        if (!bdrv_can_snapshot(bs)) {
2070 feeee5ac Miguel Di Ciurcio Filho
            monitor_printf(mon, "Device '%s' is writable but does not support snapshots.\n",
2071 feeee5ac Miguel Di Ciurcio Filho
                               bdrv_get_device_name(bs));
2072 feeee5ac Miguel Di Ciurcio Filho
            return;
2073 feeee5ac Miguel Di Ciurcio Filho
        }
2074 feeee5ac Miguel Di Ciurcio Filho
    }
2075 feeee5ac Miguel Di Ciurcio Filho
2076 f9092b10 Markus Armbruster
    bs = bdrv_snapshots();
2077 a672b469 aliguori
    if (!bs) {
2078 376253ec aliguori
        monitor_printf(mon, "No block device can accept snapshots\n");
2079 a672b469 aliguori
        return;
2080 a672b469 aliguori
    }
2081 a672b469 aliguori
2082 1354869c Luiz Capitulino
    saved_vm_running = runstate_is_running();
2083 0461d5a6 Luiz Capitulino
    vm_stop(RUN_STATE_SAVE_VM);
2084 a672b469 aliguori
2085 cb499fb2 Kevin Wolf
    memset(sn, 0, sizeof(*sn));
2086 a672b469 aliguori
2087 a672b469 aliguori
    /* fill auxiliary fields */
2088 a672b469 aliguori
#ifdef _WIN32
2089 a672b469 aliguori
    _ftime(&tb);
2090 a672b469 aliguori
    sn->date_sec = tb.time;
2091 a672b469 aliguori
    sn->date_nsec = tb.millitm * 1000000;
2092 a672b469 aliguori
#else
2093 a672b469 aliguori
    gettimeofday(&tv, NULL);
2094 a672b469 aliguori
    sn->date_sec = tv.tv_sec;
2095 a672b469 aliguori
    sn->date_nsec = tv.tv_usec * 1000;
2096 a672b469 aliguori
#endif
2097 74475455 Paolo Bonzini
    sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
2098 a672b469 aliguori
2099 7d631a11 Miguel Di Ciurcio Filho
    if (name) {
2100 7d631a11 Miguel Di Ciurcio Filho
        ret = bdrv_snapshot_find(bs, old_sn, name);
2101 7d631a11 Miguel Di Ciurcio Filho
        if (ret >= 0) {
2102 7d631a11 Miguel Di Ciurcio Filho
            pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
2103 7d631a11 Miguel Di Ciurcio Filho
            pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
2104 7d631a11 Miguel Di Ciurcio Filho
        } else {
2105 7d631a11 Miguel Di Ciurcio Filho
            pstrcpy(sn->name, sizeof(sn->name), name);
2106 7d631a11 Miguel Di Ciurcio Filho
        }
2107 7d631a11 Miguel Di Ciurcio Filho
    } else {
2108 7d631a11 Miguel Di Ciurcio Filho
#ifdef _WIN32
2109 7d631a11 Miguel Di Ciurcio Filho
        ptm = localtime(&tb.time);
2110 7d631a11 Miguel Di Ciurcio Filho
        strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", ptm);
2111 7d631a11 Miguel Di Ciurcio Filho
#else
2112 d7d9b528 Blue Swirl
        /* cast below needed for OpenBSD where tv_sec is still 'long' */
2113 d7d9b528 Blue Swirl
        localtime_r((const time_t *)&tv.tv_sec, &tm);
2114 7d631a11 Miguel Di Ciurcio Filho
        strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", &tm);
2115 7d631a11 Miguel Di Ciurcio Filho
#endif
2116 7d631a11 Miguel Di Ciurcio Filho
    }
2117 7d631a11 Miguel Di Ciurcio Filho
2118 cb499fb2 Kevin Wolf
    /* Delete old snapshots of the same name */
2119 f139a412 Marcelo Tosatti
    if (name && del_existing_snapshots(mon, name) < 0) {
2120 cb499fb2 Kevin Wolf
        goto the_end;
2121 cb499fb2 Kevin Wolf
    }
2122 cb499fb2 Kevin Wolf
2123 a672b469 aliguori
    /* save the VM state */
2124 45566e9c Christoph Hellwig
    f = qemu_fopen_bdrv(bs, 1);
2125 a672b469 aliguori
    if (!f) {
2126 376253ec aliguori
        monitor_printf(mon, "Could not open VM state file\n");
2127 a672b469 aliguori
        goto the_end;
2128 a672b469 aliguori
    }
2129 e1c37d0e Luiz Capitulino
    ret = qemu_savevm_state(f);
2130 2d22b18f aliguori
    vm_state_size = qemu_ftell(f);
2131 a672b469 aliguori
    qemu_fclose(f);
2132 a672b469 aliguori
    if (ret < 0) {
2133 376253ec aliguori
        monitor_printf(mon, "Error %d while writing VM\n", ret);
2134 a672b469 aliguori
        goto the_end;
2135 a672b469 aliguori
    }
2136 a672b469 aliguori
2137 a672b469 aliguori
    /* create the snapshots */
2138 a672b469 aliguori
2139 dbc13590 Markus Armbruster
    bs1 = NULL;
2140 dbc13590 Markus Armbruster
    while ((bs1 = bdrv_next(bs1))) {
2141 feeee5ac Miguel Di Ciurcio Filho
        if (bdrv_can_snapshot(bs1)) {
2142 2d22b18f aliguori
            /* Write VM state size only to the image that contains the state */
2143 2d22b18f aliguori
            sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
2144 a672b469 aliguori
            ret = bdrv_snapshot_create(bs1, sn);
2145 a672b469 aliguori
            if (ret < 0) {
2146 376253ec aliguori
                monitor_printf(mon, "Error while creating snapshot on '%s'\n",
2147 376253ec aliguori
                               bdrv_get_device_name(bs1));
2148 a672b469 aliguori
            }
2149 a672b469 aliguori
        }
2150 a672b469 aliguori
    }
2151 a672b469 aliguori
2152 a672b469 aliguori
 the_end:
2153 a672b469 aliguori
    if (saved_vm_running)
2154 a672b469 aliguori
        vm_start();
2155 a672b469 aliguori
}
2156 a672b469 aliguori
2157 a7ae8355 Stefano Stabellini
void qmp_xen_save_devices_state(const char *filename, Error **errp)
2158 a7ae8355 Stefano Stabellini
{
2159 a7ae8355 Stefano Stabellini
    QEMUFile *f;
2160 a7ae8355 Stefano Stabellini
    int saved_vm_running;
2161 a7ae8355 Stefano Stabellini
    int ret;
2162 a7ae8355 Stefano Stabellini
2163 a7ae8355 Stefano Stabellini
    saved_vm_running = runstate_is_running();
2164 a7ae8355 Stefano Stabellini
    vm_stop(RUN_STATE_SAVE_VM);
2165 a7ae8355 Stefano Stabellini
2166 a7ae8355 Stefano Stabellini
    f = qemu_fopen(filename, "wb");
2167 a7ae8355 Stefano Stabellini
    if (!f) {
2168 a7ae8355 Stefano Stabellini
        error_set(errp, QERR_OPEN_FILE_FAILED, filename);
2169 a7ae8355 Stefano Stabellini
        goto the_end;
2170 a7ae8355 Stefano Stabellini
    }
2171 a7ae8355 Stefano Stabellini
    ret = qemu_save_device_state(f);
2172 a7ae8355 Stefano Stabellini
    qemu_fclose(f);
2173 a7ae8355 Stefano Stabellini
    if (ret < 0) {
2174 a7ae8355 Stefano Stabellini
        error_set(errp, QERR_IO_ERROR);
2175 a7ae8355 Stefano Stabellini
    }
2176 a7ae8355 Stefano Stabellini
2177 a7ae8355 Stefano Stabellini
 the_end:
2178 a7ae8355 Stefano Stabellini
    if (saved_vm_running)
2179 a7ae8355 Stefano Stabellini
        vm_start();
2180 a7ae8355 Stefano Stabellini
    return;
2181 a7ae8355 Stefano Stabellini
}
2182 a7ae8355 Stefano Stabellini
2183 03cd4655 Markus Armbruster
int load_vmstate(const char *name)
2184 a672b469 aliguori
{
2185 f0aa7a8b Miguel Di Ciurcio Filho
    BlockDriverState *bs, *bs_vm_state;
2186 2d22b18f aliguori
    QEMUSnapshotInfo sn;
2187 a672b469 aliguori
    QEMUFile *f;
2188 751c6a17 Gerd Hoffmann
    int ret;
2189 a672b469 aliguori
2190 f0aa7a8b Miguel Di Ciurcio Filho
    bs_vm_state = bdrv_snapshots();
2191 f0aa7a8b Miguel Di Ciurcio Filho
    if (!bs_vm_state) {
2192 f0aa7a8b Miguel Di Ciurcio Filho
        error_report("No block device supports snapshots");
2193 f0aa7a8b Miguel Di Ciurcio Filho
        return -ENOTSUP;
2194 f0aa7a8b Miguel Di Ciurcio Filho
    }
2195 f0aa7a8b Miguel Di Ciurcio Filho
2196 f0aa7a8b Miguel Di Ciurcio Filho
    /* Don't even try to load empty VM states */
2197 f0aa7a8b Miguel Di Ciurcio Filho
    ret = bdrv_snapshot_find(bs_vm_state, &sn, name);
2198 f0aa7a8b Miguel Di Ciurcio Filho
    if (ret < 0) {
2199 f0aa7a8b Miguel Di Ciurcio Filho
        return ret;
2200 f0aa7a8b Miguel Di Ciurcio Filho
    } else if (sn.vm_state_size == 0) {
2201 e11480db Kevin Wolf
        error_report("This is a disk-only snapshot. Revert to it offline "
2202 e11480db Kevin Wolf
            "using qemu-img.");
2203 f0aa7a8b Miguel Di Ciurcio Filho
        return -EINVAL;
2204 f0aa7a8b Miguel Di Ciurcio Filho
    }
2205 f0aa7a8b Miguel Di Ciurcio Filho
2206 f0aa7a8b Miguel Di Ciurcio Filho
    /* Verify if there is any device that doesn't support snapshots and is
2207 f0aa7a8b Miguel Di Ciurcio Filho
    writable and check if the requested snapshot is available too. */
2208 dbc13590 Markus Armbruster
    bs = NULL;
2209 dbc13590 Markus Armbruster
    while ((bs = bdrv_next(bs))) {
2210 feeee5ac Miguel Di Ciurcio Filho
2211 07b70bfb Markus Armbruster
        if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2212 feeee5ac Miguel Di Ciurcio Filho
            continue;
2213 feeee5ac Miguel Di Ciurcio Filho
        }
2214 feeee5ac Miguel Di Ciurcio Filho
2215 feeee5ac Miguel Di Ciurcio Filho
        if (!bdrv_can_snapshot(bs)) {
2216 feeee5ac Miguel Di Ciurcio Filho
            error_report("Device '%s' is writable but does not support snapshots.",
2217 feeee5ac Miguel Di Ciurcio Filho
                               bdrv_get_device_name(bs));
2218 feeee5ac Miguel Di Ciurcio Filho
            return -ENOTSUP;
2219 feeee5ac Miguel Di Ciurcio Filho
        }
2220 feeee5ac Miguel Di Ciurcio Filho
2221 f0aa7a8b Miguel Di Ciurcio Filho
        ret = bdrv_snapshot_find(bs, &sn, name);
2222 f0aa7a8b Miguel Di Ciurcio Filho
        if (ret < 0) {
2223 f0aa7a8b Miguel Di Ciurcio Filho
            error_report("Device '%s' does not have the requested snapshot '%s'",
2224 f0aa7a8b Miguel Di Ciurcio Filho
                           bdrv_get_device_name(bs), name);
2225 f0aa7a8b Miguel Di Ciurcio Filho
            return ret;
2226 f0aa7a8b Miguel Di Ciurcio Filho
        }
2227 a672b469 aliguori
    }
2228 a672b469 aliguori
2229 a672b469 aliguori
    /* Flush all IO requests so they don't interfere with the new state.  */
2230 922453bc Stefan Hajnoczi
    bdrv_drain_all();
2231 a672b469 aliguori
2232 f0aa7a8b Miguel Di Ciurcio Filho
    bs = NULL;
2233 f0aa7a8b Miguel Di Ciurcio Filho
    while ((bs = bdrv_next(bs))) {
2234 f0aa7a8b Miguel Di Ciurcio Filho
        if (bdrv_can_snapshot(bs)) {
2235 f0aa7a8b Miguel Di Ciurcio Filho
            ret = bdrv_snapshot_goto(bs, name);
2236 a672b469 aliguori
            if (ret < 0) {
2237 f0aa7a8b Miguel Di Ciurcio Filho
                error_report("Error %d while activating snapshot '%s' on '%s'",
2238 f0aa7a8b Miguel Di Ciurcio Filho
                             ret, name, bdrv_get_device_name(bs));
2239 f0aa7a8b Miguel Di Ciurcio Filho
                return ret;
2240 a672b469 aliguori
            }
2241 a672b469 aliguori
        }
2242 a672b469 aliguori
    }
2243 a672b469 aliguori
2244 a672b469 aliguori
    /* restore the VM state */
2245 f0aa7a8b Miguel Di Ciurcio Filho
    f = qemu_fopen_bdrv(bs_vm_state, 0);
2246 a672b469 aliguori
    if (!f) {
2247 1ecda02b Markus Armbruster
        error_report("Could not open VM state file");
2248 05f2401e Juan Quintela
        return -EINVAL;
2249 a672b469 aliguori
    }
2250 f0aa7a8b Miguel Di Ciurcio Filho
2251 5a8a49d7 Jan Kiszka
    qemu_system_reset(VMRESET_SILENT);
2252 a672b469 aliguori
    ret = qemu_loadvm_state(f);
2253 f0aa7a8b Miguel Di Ciurcio Filho
2254 a672b469 aliguori
    qemu_fclose(f);
2255 a672b469 aliguori
    if (ret < 0) {
2256 1ecda02b Markus Armbruster
        error_report("Error %d while loading VM state", ret);
2257 05f2401e Juan Quintela
        return ret;
2258 a672b469 aliguori
    }
2259 f0aa7a8b Miguel Di Ciurcio Filho
2260 05f2401e Juan Quintela
    return 0;
2261 7b630349 Juan Quintela
}
2262 7b630349 Juan Quintela
2263 d54908a5 Luiz Capitulino
void do_delvm(Monitor *mon, const QDict *qdict)
2264 a672b469 aliguori
{
2265 a672b469 aliguori
    BlockDriverState *bs, *bs1;
2266 751c6a17 Gerd Hoffmann
    int ret;
2267 d54908a5 Luiz Capitulino
    const char *name = qdict_get_str(qdict, "name");
2268 a672b469 aliguori
2269 f9092b10 Markus Armbruster
    bs = bdrv_snapshots();
2270 a672b469 aliguori
    if (!bs) {
2271 376253ec aliguori
        monitor_printf(mon, "No block device supports snapshots\n");
2272 a672b469 aliguori
        return;
2273 a672b469 aliguori
    }
2274 a672b469 aliguori
2275 dbc13590 Markus Armbruster
    bs1 = NULL;
2276 dbc13590 Markus Armbruster
    while ((bs1 = bdrv_next(bs1))) {
2277 feeee5ac Miguel Di Ciurcio Filho
        if (bdrv_can_snapshot(bs1)) {
2278 a672b469 aliguori
            ret = bdrv_snapshot_delete(bs1, name);
2279 a672b469 aliguori
            if (ret < 0) {
2280 a672b469 aliguori
                if (ret == -ENOTSUP)
2281 376253ec aliguori
                    monitor_printf(mon,
2282 376253ec aliguori
                                   "Snapshots not supported on device '%s'\n",
2283 376253ec aliguori
                                   bdrv_get_device_name(bs1));
2284 a672b469 aliguori
                else
2285 376253ec aliguori
                    monitor_printf(mon, "Error %d while deleting snapshot on "
2286 376253ec aliguori
                                   "'%s'\n", ret, bdrv_get_device_name(bs1));
2287 a672b469 aliguori
            }
2288 a672b469 aliguori
        }
2289 a672b469 aliguori
    }
2290 a672b469 aliguori
}
2291 a672b469 aliguori
2292 376253ec aliguori
void do_info_snapshots(Monitor *mon)
2293 a672b469 aliguori
{
2294 a672b469 aliguori
    BlockDriverState *bs, *bs1;
2295 f9209915 Miguel Di Ciurcio Filho
    QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
2296 f9209915 Miguel Di Ciurcio Filho
    int nb_sns, i, ret, available;
2297 f9209915 Miguel Di Ciurcio Filho
    int total;
2298 f9209915 Miguel Di Ciurcio Filho
    int *available_snapshots;
2299 a672b469 aliguori
    char buf[256];
2300 a672b469 aliguori
2301 f9092b10 Markus Armbruster
    bs = bdrv_snapshots();
2302 a672b469 aliguori
    if (!bs) {
2303 376253ec aliguori
        monitor_printf(mon, "No available block device supports snapshots\n");
2304 a672b469 aliguori
        return;
2305 a672b469 aliguori
    }
2306 a672b469 aliguori
2307 a672b469 aliguori
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
2308 a672b469 aliguori
    if (nb_sns < 0) {
2309 376253ec aliguori
        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
2310 a672b469 aliguori
        return;
2311 a672b469 aliguori
    }
2312 f9209915 Miguel Di Ciurcio Filho
2313 f9209915 Miguel Di Ciurcio Filho
    if (nb_sns == 0) {
2314 f9209915 Miguel Di Ciurcio Filho
        monitor_printf(mon, "There is no snapshot available.\n");
2315 f9209915 Miguel Di Ciurcio Filho
        return;
2316 f9209915 Miguel Di Ciurcio Filho
    }
2317 f9209915 Miguel Di Ciurcio Filho
2318 7267c094 Anthony Liguori
    available_snapshots = g_malloc0(sizeof(int) * nb_sns);
2319 f9209915 Miguel Di Ciurcio Filho
    total = 0;
2320 f9209915 Miguel Di Ciurcio Filho
    for (i = 0; i < nb_sns; i++) {
2321 a672b469 aliguori
        sn = &sn_tab[i];
2322 f9209915 Miguel Di Ciurcio Filho
        available = 1;
2323 f9209915 Miguel Di Ciurcio Filho
        bs1 = NULL;
2324 f9209915 Miguel Di Ciurcio Filho
2325 f9209915 Miguel Di Ciurcio Filho
        while ((bs1 = bdrv_next(bs1))) {
2326 f9209915 Miguel Di Ciurcio Filho
            if (bdrv_can_snapshot(bs1) && bs1 != bs) {
2327 f9209915 Miguel Di Ciurcio Filho
                ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str);
2328 f9209915 Miguel Di Ciurcio Filho
                if (ret < 0) {
2329 f9209915 Miguel Di Ciurcio Filho
                    available = 0;
2330 f9209915 Miguel Di Ciurcio Filho
                    break;
2331 f9209915 Miguel Di Ciurcio Filho
                }
2332 f9209915 Miguel Di Ciurcio Filho
            }
2333 f9209915 Miguel Di Ciurcio Filho
        }
2334 f9209915 Miguel Di Ciurcio Filho
2335 f9209915 Miguel Di Ciurcio Filho
        if (available) {
2336 f9209915 Miguel Di Ciurcio Filho
            available_snapshots[total] = i;
2337 f9209915 Miguel Di Ciurcio Filho
            total++;
2338 f9209915 Miguel Di Ciurcio Filho
        }
2339 a672b469 aliguori
    }
2340 f9209915 Miguel Di Ciurcio Filho
2341 f9209915 Miguel Di Ciurcio Filho
    if (total > 0) {
2342 f9209915 Miguel Di Ciurcio Filho
        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
2343 f9209915 Miguel Di Ciurcio Filho
        for (i = 0; i < total; i++) {
2344 f9209915 Miguel Di Ciurcio Filho
            sn = &sn_tab[available_snapshots[i]];
2345 f9209915 Miguel Di Ciurcio Filho
            monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
2346 f9209915 Miguel Di Ciurcio Filho
        }
2347 f9209915 Miguel Di Ciurcio Filho
    } else {
2348 f9209915 Miguel Di Ciurcio Filho
        monitor_printf(mon, "There is no suitable snapshot available\n");
2349 f9209915 Miguel Di Ciurcio Filho
    }
2350 f9209915 Miguel Di Ciurcio Filho
2351 7267c094 Anthony Liguori
    g_free(sn_tab);
2352 7267c094 Anthony Liguori
    g_free(available_snapshots);
2353 f9209915 Miguel Di Ciurcio Filho
2354 a672b469 aliguori
}
2355 c5705a77 Avi Kivity
2356 c5705a77 Avi Kivity
void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
2357 c5705a77 Avi Kivity
{
2358 1ddde087 Avi Kivity
    qemu_ram_set_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK,
2359 c5705a77 Avi Kivity
                       memory_region_name(mr), dev);
2360 c5705a77 Avi Kivity
}
2361 c5705a77 Avi Kivity
2362 c5705a77 Avi Kivity
void vmstate_unregister_ram(MemoryRegion *mr, DeviceState *dev)
2363 c5705a77 Avi Kivity
{
2364 c5705a77 Avi Kivity
    /* Nothing do to while the implementation is in RAMBlock */
2365 c5705a77 Avi Kivity
}
2366 c5705a77 Avi Kivity
2367 c5705a77 Avi Kivity
void vmstate_register_ram_global(MemoryRegion *mr)
2368 c5705a77 Avi Kivity
{
2369 c5705a77 Avi Kivity
    vmstate_register_ram(mr, NULL);
2370 c5705a77 Avi Kivity
}