Statistics
| Branch: | Revision:

root / savevm.c @ c3d420ea

History | View | Annotate | Download (46.3 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 <signal.h>
27 a672b469 aliguori
#include <time.h>
28 a672b469 aliguori
#include <errno.h>
29 a672b469 aliguori
#include <sys/time.h>
30 a672b469 aliguori
#include <zlib.h>
31 a672b469 aliguori
32 71e72a19 Juan Quintela
/* Needed early for CONFIG_BSD etc. */
33 d40cdb10 blueswir1
#include "config-host.h"
34 d40cdb10 blueswir1
35 a672b469 aliguori
#ifndef _WIN32
36 a672b469 aliguori
#include <sys/times.h>
37 a672b469 aliguori
#include <sys/wait.h>
38 a672b469 aliguori
#include <termios.h>
39 a672b469 aliguori
#include <sys/mman.h>
40 a672b469 aliguori
#include <sys/ioctl.h>
41 a672b469 aliguori
#include <sys/resource.h>
42 a672b469 aliguori
#include <sys/socket.h>
43 a672b469 aliguori
#include <netinet/in.h>
44 a672b469 aliguori
#include <net/if.h>
45 a672b469 aliguori
#include <arpa/inet.h>
46 a672b469 aliguori
#include <dirent.h>
47 a672b469 aliguori
#include <netdb.h>
48 a672b469 aliguori
#include <sys/select.h>
49 71e72a19 Juan Quintela
#ifdef CONFIG_BSD
50 a672b469 aliguori
#include <sys/stat.h>
51 a167ba50 Aurelien Jarno
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
52 a672b469 aliguori
#include <libutil.h>
53 a672b469 aliguori
#else
54 a672b469 aliguori
#include <util.h>
55 a672b469 aliguori
#endif
56 a672b469 aliguori
#ifdef __linux__
57 a672b469 aliguori
#include <pty.h>
58 a672b469 aliguori
#include <malloc.h>
59 a672b469 aliguori
#include <linux/rtc.h>
60 a672b469 aliguori
#endif
61 a672b469 aliguori
#endif
62 a672b469 aliguori
#endif
63 a672b469 aliguori
64 a672b469 aliguori
#ifdef _WIN32
65 49dc768d aliguori
#include <windows.h>
66 a672b469 aliguori
#include <malloc.h>
67 a672b469 aliguori
#include <sys/timeb.h>
68 a672b469 aliguori
#include <mmsystem.h>
69 a672b469 aliguori
#define getopt_long_only getopt_long
70 a672b469 aliguori
#define memalign(align, size) malloc(size)
71 a672b469 aliguori
#endif
72 a672b469 aliguori
73 511d2b14 blueswir1
#include "qemu-common.h"
74 511d2b14 blueswir1
#include "hw/hw.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 "block.h"
81 511d2b14 blueswir1
#include "audio/audio.h"
82 511d2b14 blueswir1
#include "migration.h"
83 511d2b14 blueswir1
#include "qemu_socket.h"
84 72cf2d4f Blue Swirl
#include "qemu-queue.h"
85 511d2b14 blueswir1
86 a672b469 aliguori
/* point to the block driver where the snapshots are managed */
87 a672b469 aliguori
static BlockDriverState *bs_snapshots;
88 a672b469 aliguori
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 18995b98 Nolan
        qemu_mod_timer(timer, qemu_get_clock(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 ed8b330b Gleb Natapov
        timer = qemu_new_timer(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 a672b469 aliguori
    int has_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 c5b76b38 Blue Swirl
        len = recv(s->fd, (void *)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 a672b469 aliguori
    qemu_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 7f79dd28 Paolo Bonzini
    pclose(s->stdio_file);
239 7f79dd28 Paolo Bonzini
    qemu_free(s);
240 7f79dd28 Paolo Bonzini
    return 0;
241 7f79dd28 Paolo Bonzini
}
242 7f79dd28 Paolo Bonzini
243 7f79dd28 Paolo Bonzini
static int stdio_fclose(void *opaque)
244 a672b469 aliguori
{
245 7f79dd28 Paolo Bonzini
    QEMUFileStdio *s = opaque;
246 7f79dd28 Paolo Bonzini
    fclose(s->stdio_file);
247 a672b469 aliguori
    qemu_free(s);
248 a672b469 aliguori
    return 0;
249 a672b469 aliguori
}
250 a672b469 aliguori
251 7f79dd28 Paolo Bonzini
QEMUFile *qemu_popen(FILE *stdio_file, const char *mode)
252 a672b469 aliguori
{
253 7f79dd28 Paolo Bonzini
    QEMUFileStdio *s;
254 a672b469 aliguori
255 7f79dd28 Paolo Bonzini
    if (stdio_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
256 a672b469 aliguori
        fprintf(stderr, "qemu_popen: Argument validity check failed\n");
257 a672b469 aliguori
        return NULL;
258 a672b469 aliguori
    }
259 a672b469 aliguori
260 7f79dd28 Paolo Bonzini
    s = qemu_mallocz(sizeof(QEMUFileStdio));
261 a672b469 aliguori
262 7f79dd28 Paolo Bonzini
    s->stdio_file = stdio_file;
263 a672b469 aliguori
264 a672b469 aliguori
    if(mode[0] == 'r') {
265 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_pclose, 
266 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
267 a672b469 aliguori
    } else {
268 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_pclose, 
269 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
270 a672b469 aliguori
    }
271 a672b469 aliguori
    return s->file;
272 a672b469 aliguori
}
273 a672b469 aliguori
274 a672b469 aliguori
QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
275 a672b469 aliguori
{
276 a672b469 aliguori
    FILE *popen_file;
277 a672b469 aliguori
278 a672b469 aliguori
    popen_file = popen(command, mode);
279 a672b469 aliguori
    if(popen_file == NULL) {
280 a672b469 aliguori
        return NULL;
281 a672b469 aliguori
    }
282 a672b469 aliguori
283 a672b469 aliguori
    return qemu_popen(popen_file, mode);
284 a672b469 aliguori
}
285 a672b469 aliguori
286 7f79dd28 Paolo Bonzini
int qemu_stdio_fd(QEMUFile *f)
287 8a43b1ea Chris Lalancette
{
288 7f79dd28 Paolo Bonzini
    QEMUFileStdio *p;
289 8a43b1ea Chris Lalancette
    int fd;
290 8a43b1ea Chris Lalancette
291 7f79dd28 Paolo Bonzini
    p = (QEMUFileStdio *)f->opaque;
292 7f79dd28 Paolo Bonzini
    fd = fileno(p->stdio_file);
293 8a43b1ea Chris Lalancette
294 8a43b1ea Chris Lalancette
    return fd;
295 8a43b1ea Chris Lalancette
}
296 8a43b1ea Chris Lalancette
297 5ac1fad3 Paolo Bonzini
QEMUFile *qemu_fdopen(int fd, const char *mode)
298 5ac1fad3 Paolo Bonzini
{
299 5ac1fad3 Paolo Bonzini
    QEMUFileStdio *s;
300 5ac1fad3 Paolo Bonzini
301 5ac1fad3 Paolo Bonzini
    if (mode == NULL ||
302 5ac1fad3 Paolo Bonzini
        (mode[0] != 'r' && mode[0] != 'w') ||
303 5ac1fad3 Paolo Bonzini
        mode[1] != 'b' || mode[2] != 0) {
304 5ac1fad3 Paolo Bonzini
        fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
305 5ac1fad3 Paolo Bonzini
        return NULL;
306 5ac1fad3 Paolo Bonzini
    }
307 5ac1fad3 Paolo Bonzini
308 5ac1fad3 Paolo Bonzini
    s = qemu_mallocz(sizeof(QEMUFileStdio));
309 5ac1fad3 Paolo Bonzini
    s->stdio_file = fdopen(fd, mode);
310 5ac1fad3 Paolo Bonzini
    if (!s->stdio_file)
311 5ac1fad3 Paolo Bonzini
        goto fail;
312 5ac1fad3 Paolo Bonzini
313 5ac1fad3 Paolo Bonzini
    if(mode[0] == 'r') {
314 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_fclose, 
315 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
316 5ac1fad3 Paolo Bonzini
    } else {
317 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_fclose, 
318 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
319 5ac1fad3 Paolo Bonzini
    }
320 5ac1fad3 Paolo Bonzini
    return s->file;
321 5ac1fad3 Paolo Bonzini
322 5ac1fad3 Paolo Bonzini
fail:
323 5ac1fad3 Paolo Bonzini
    qemu_free(s);
324 5ac1fad3 Paolo Bonzini
    return NULL;
325 5ac1fad3 Paolo Bonzini
}
326 5ac1fad3 Paolo Bonzini
327 a672b469 aliguori
QEMUFile *qemu_fopen_socket(int fd)
328 a672b469 aliguori
{
329 a672b469 aliguori
    QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket));
330 a672b469 aliguori
331 a672b469 aliguori
    s->fd = fd;
332 c163b5ca lirans@il.ibm.com
    s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, 
333 c163b5ca lirans@il.ibm.com
                             NULL, NULL, NULL);
334 a672b469 aliguori
    return s->file;
335 a672b469 aliguori
}
336 a672b469 aliguori
337 a672b469 aliguori
static int file_put_buffer(void *opaque, const uint8_t *buf,
338 a672b469 aliguori
                            int64_t pos, int size)
339 a672b469 aliguori
{
340 a672b469 aliguori
    QEMUFileStdio *s = opaque;
341 7f79dd28 Paolo Bonzini
    fseek(s->stdio_file, pos, SEEK_SET);
342 5fdb3aa1 Kirill A. Shutemov
    return fwrite(buf, 1, size, s->stdio_file);
343 a672b469 aliguori
}
344 a672b469 aliguori
345 a672b469 aliguori
static int file_get_buffer(void *opaque, uint8_t *buf, 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 7f79dd28 Paolo Bonzini
    return fread(buf, 1, size, s->stdio_file);
350 a672b469 aliguori
}
351 a672b469 aliguori
352 a672b469 aliguori
QEMUFile *qemu_fopen(const char *filename, const char *mode)
353 a672b469 aliguori
{
354 a672b469 aliguori
    QEMUFileStdio *s;
355 a672b469 aliguori
356 7f79dd28 Paolo Bonzini
    if (mode == NULL ||
357 7f79dd28 Paolo Bonzini
        (mode[0] != 'r' && mode[0] != 'w') ||
358 7f79dd28 Paolo Bonzini
        mode[1] != 'b' || mode[2] != 0) {
359 090414a3 Blue Swirl
        fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
360 7f79dd28 Paolo Bonzini
        return NULL;
361 7f79dd28 Paolo Bonzini
    }
362 7f79dd28 Paolo Bonzini
363 a672b469 aliguori
    s = qemu_mallocz(sizeof(QEMUFileStdio));
364 a672b469 aliguori
365 7f79dd28 Paolo Bonzini
    s->stdio_file = fopen(filename, mode);
366 7f79dd28 Paolo Bonzini
    if (!s->stdio_file)
367 a672b469 aliguori
        goto fail;
368 c163b5ca lirans@il.ibm.com
    
369 7f79dd28 Paolo Bonzini
    if(mode[0] == 'w') {
370 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, file_put_buffer, NULL, stdio_fclose, 
371 c163b5ca lirans@il.ibm.com
                                 NULL, NULL, NULL);
372 7f79dd28 Paolo Bonzini
    } else {
373 c163b5ca lirans@il.ibm.com
        s->file = qemu_fopen_ops(s, NULL, file_get_buffer, stdio_fclose, 
374 c163b5ca lirans@il.ibm.com
                               NULL, NULL, NULL);
375 7f79dd28 Paolo Bonzini
    }
376 7f79dd28 Paolo Bonzini
    return s->file;
377 a672b469 aliguori
fail:
378 a672b469 aliguori
    qemu_free(s);
379 a672b469 aliguori
    return NULL;
380 a672b469 aliguori
}
381 a672b469 aliguori
382 178e08a5 aliguori
static int block_put_buffer(void *opaque, const uint8_t *buf,
383 a672b469 aliguori
                           int64_t pos, int size)
384 a672b469 aliguori
{
385 45566e9c Christoph Hellwig
    bdrv_save_vmstate(opaque, buf, pos, size);
386 a672b469 aliguori
    return size;
387 a672b469 aliguori
}
388 a672b469 aliguori
389 178e08a5 aliguori
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
390 a672b469 aliguori
{
391 45566e9c Christoph Hellwig
    return bdrv_load_vmstate(opaque, buf, pos, size);
392 a672b469 aliguori
}
393 a672b469 aliguori
394 a672b469 aliguori
static int bdrv_fclose(void *opaque)
395 a672b469 aliguori
{
396 a672b469 aliguori
    return 0;
397 a672b469 aliguori
}
398 a672b469 aliguori
399 45566e9c Christoph Hellwig
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
400 a672b469 aliguori
{
401 a672b469 aliguori
    if (is_writable)
402 c163b5ca lirans@il.ibm.com
        return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose, 
403 c163b5ca lirans@il.ibm.com
                              NULL, NULL, NULL);
404 c163b5ca lirans@il.ibm.com
    return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclose, NULL, NULL, NULL);
405 a672b469 aliguori
}
406 a672b469 aliguori
407 a672b469 aliguori
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
408 a672b469 aliguori
                         QEMUFileGetBufferFunc *get_buffer,
409 a672b469 aliguori
                         QEMUFileCloseFunc *close,
410 19629537 Glauber Costa
                         QEMUFileRateLimit *rate_limit,
411 c163b5ca lirans@il.ibm.com
                         QEMUFileSetRateLimit *set_rate_limit,
412 c163b5ca lirans@il.ibm.com
                         QEMUFileGetRateLimit *get_rate_limit)
413 a672b469 aliguori
{
414 a672b469 aliguori
    QEMUFile *f;
415 a672b469 aliguori
416 a672b469 aliguori
    f = qemu_mallocz(sizeof(QEMUFile));
417 a672b469 aliguori
418 a672b469 aliguori
    f->opaque = opaque;
419 a672b469 aliguori
    f->put_buffer = put_buffer;
420 a672b469 aliguori
    f->get_buffer = get_buffer;
421 a672b469 aliguori
    f->close = close;
422 a672b469 aliguori
    f->rate_limit = rate_limit;
423 19629537 Glauber Costa
    f->set_rate_limit = set_rate_limit;
424 c163b5ca lirans@il.ibm.com
    f->get_rate_limit = get_rate_limit;
425 a672b469 aliguori
    f->is_write = 0;
426 a672b469 aliguori
427 a672b469 aliguori
    return f;
428 a672b469 aliguori
}
429 a672b469 aliguori
430 a672b469 aliguori
int qemu_file_has_error(QEMUFile *f)
431 a672b469 aliguori
{
432 a672b469 aliguori
    return f->has_error;
433 a672b469 aliguori
}
434 a672b469 aliguori
435 4dabe248 aliguori
void qemu_file_set_error(QEMUFile *f)
436 4dabe248 aliguori
{
437 4dabe248 aliguori
    f->has_error = 1;
438 4dabe248 aliguori
}
439 4dabe248 aliguori
440 a672b469 aliguori
void qemu_fflush(QEMUFile *f)
441 a672b469 aliguori
{
442 a672b469 aliguori
    if (!f->put_buffer)
443 a672b469 aliguori
        return;
444 a672b469 aliguori
445 a672b469 aliguori
    if (f->is_write && f->buf_index > 0) {
446 a672b469 aliguori
        int len;
447 a672b469 aliguori
448 a672b469 aliguori
        len = f->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index);
449 a672b469 aliguori
        if (len > 0)
450 a672b469 aliguori
            f->buf_offset += f->buf_index;
451 a672b469 aliguori
        else
452 a672b469 aliguori
            f->has_error = 1;
453 a672b469 aliguori
        f->buf_index = 0;
454 a672b469 aliguori
    }
455 a672b469 aliguori
}
456 a672b469 aliguori
457 a672b469 aliguori
static void qemu_fill_buffer(QEMUFile *f)
458 a672b469 aliguori
{
459 a672b469 aliguori
    int len;
460 a672b469 aliguori
461 a672b469 aliguori
    if (!f->get_buffer)
462 a672b469 aliguori
        return;
463 a672b469 aliguori
464 a672b469 aliguori
    if (f->is_write)
465 a672b469 aliguori
        abort();
466 a672b469 aliguori
467 a672b469 aliguori
    len = f->get_buffer(f->opaque, f->buf, f->buf_offset, IO_BUF_SIZE);
468 a672b469 aliguori
    if (len > 0) {
469 a672b469 aliguori
        f->buf_index = 0;
470 a672b469 aliguori
        f->buf_size = len;
471 a672b469 aliguori
        f->buf_offset += len;
472 a672b469 aliguori
    } else if (len != -EAGAIN)
473 a672b469 aliguori
        f->has_error = 1;
474 a672b469 aliguori
}
475 a672b469 aliguori
476 a672b469 aliguori
int qemu_fclose(QEMUFile *f)
477 a672b469 aliguori
{
478 a672b469 aliguori
    int ret = 0;
479 a672b469 aliguori
    qemu_fflush(f);
480 a672b469 aliguori
    if (f->close)
481 a672b469 aliguori
        ret = f->close(f->opaque);
482 a672b469 aliguori
    qemu_free(f);
483 a672b469 aliguori
    return ret;
484 a672b469 aliguori
}
485 a672b469 aliguori
486 a672b469 aliguori
void qemu_file_put_notify(QEMUFile *f)
487 a672b469 aliguori
{
488 a672b469 aliguori
    f->put_buffer(f->opaque, NULL, 0, 0);
489 a672b469 aliguori
}
490 a672b469 aliguori
491 a672b469 aliguori
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
492 a672b469 aliguori
{
493 a672b469 aliguori
    int l;
494 a672b469 aliguori
495 a672b469 aliguori
    if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
496 a672b469 aliguori
        fprintf(stderr,
497 a672b469 aliguori
                "Attempted to write to buffer while read buffer is not empty\n");
498 a672b469 aliguori
        abort();
499 a672b469 aliguori
    }
500 a672b469 aliguori
501 a672b469 aliguori
    while (!f->has_error && size > 0) {
502 a672b469 aliguori
        l = IO_BUF_SIZE - f->buf_index;
503 a672b469 aliguori
        if (l > size)
504 a672b469 aliguori
            l = size;
505 a672b469 aliguori
        memcpy(f->buf + f->buf_index, buf, l);
506 a672b469 aliguori
        f->is_write = 1;
507 a672b469 aliguori
        f->buf_index += l;
508 a672b469 aliguori
        buf += l;
509 a672b469 aliguori
        size -= l;
510 a672b469 aliguori
        if (f->buf_index >= IO_BUF_SIZE)
511 a672b469 aliguori
            qemu_fflush(f);
512 a672b469 aliguori
    }
513 a672b469 aliguori
}
514 a672b469 aliguori
515 a672b469 aliguori
void qemu_put_byte(QEMUFile *f, int v)
516 a672b469 aliguori
{
517 a672b469 aliguori
    if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
518 a672b469 aliguori
        fprintf(stderr,
519 a672b469 aliguori
                "Attempted to write to buffer while read buffer is not empty\n");
520 a672b469 aliguori
        abort();
521 a672b469 aliguori
    }
522 a672b469 aliguori
523 a672b469 aliguori
    f->buf[f->buf_index++] = v;
524 a672b469 aliguori
    f->is_write = 1;
525 a672b469 aliguori
    if (f->buf_index >= IO_BUF_SIZE)
526 a672b469 aliguori
        qemu_fflush(f);
527 a672b469 aliguori
}
528 a672b469 aliguori
529 a672b469 aliguori
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
530 a672b469 aliguori
{
531 a672b469 aliguori
    int size, l;
532 a672b469 aliguori
533 a672b469 aliguori
    if (f->is_write)
534 a672b469 aliguori
        abort();
535 a672b469 aliguori
536 a672b469 aliguori
    size = size1;
537 a672b469 aliguori
    while (size > 0) {
538 a672b469 aliguori
        l = f->buf_size - f->buf_index;
539 a672b469 aliguori
        if (l == 0) {
540 a672b469 aliguori
            qemu_fill_buffer(f);
541 a672b469 aliguori
            l = f->buf_size - f->buf_index;
542 a672b469 aliguori
            if (l == 0)
543 a672b469 aliguori
                break;
544 a672b469 aliguori
        }
545 a672b469 aliguori
        if (l > size)
546 a672b469 aliguori
            l = size;
547 a672b469 aliguori
        memcpy(buf, f->buf + f->buf_index, l);
548 a672b469 aliguori
        f->buf_index += l;
549 a672b469 aliguori
        buf += l;
550 a672b469 aliguori
        size -= l;
551 a672b469 aliguori
    }
552 a672b469 aliguori
    return size1 - size;
553 a672b469 aliguori
}
554 a672b469 aliguori
555 a672b469 aliguori
int qemu_get_byte(QEMUFile *f)
556 a672b469 aliguori
{
557 a672b469 aliguori
    if (f->is_write)
558 a672b469 aliguori
        abort();
559 a672b469 aliguori
560 a672b469 aliguori
    if (f->buf_index >= f->buf_size) {
561 a672b469 aliguori
        qemu_fill_buffer(f);
562 a672b469 aliguori
        if (f->buf_index >= f->buf_size)
563 a672b469 aliguori
            return 0;
564 a672b469 aliguori
    }
565 a672b469 aliguori
    return f->buf[f->buf_index++];
566 a672b469 aliguori
}
567 a672b469 aliguori
568 a672b469 aliguori
int64_t qemu_ftell(QEMUFile *f)
569 a672b469 aliguori
{
570 a672b469 aliguori
    return f->buf_offset - f->buf_size + f->buf_index;
571 a672b469 aliguori
}
572 a672b469 aliguori
573 a672b469 aliguori
int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
574 a672b469 aliguori
{
575 a672b469 aliguori
    if (whence == SEEK_SET) {
576 a672b469 aliguori
        /* nothing to do */
577 a672b469 aliguori
    } else if (whence == SEEK_CUR) {
578 a672b469 aliguori
        pos += qemu_ftell(f);
579 a672b469 aliguori
    } else {
580 a672b469 aliguori
        /* SEEK_END not supported */
581 a672b469 aliguori
        return -1;
582 a672b469 aliguori
    }
583 a672b469 aliguori
    if (f->put_buffer) {
584 a672b469 aliguori
        qemu_fflush(f);
585 a672b469 aliguori
        f->buf_offset = pos;
586 a672b469 aliguori
    } else {
587 a672b469 aliguori
        f->buf_offset = pos;
588 a672b469 aliguori
        f->buf_index = 0;
589 a672b469 aliguori
        f->buf_size = 0;
590 a672b469 aliguori
    }
591 a672b469 aliguori
    return pos;
592 a672b469 aliguori
}
593 a672b469 aliguori
594 a672b469 aliguori
int qemu_file_rate_limit(QEMUFile *f)
595 a672b469 aliguori
{
596 a672b469 aliguori
    if (f->rate_limit)
597 a672b469 aliguori
        return f->rate_limit(f->opaque);
598 a672b469 aliguori
599 a672b469 aliguori
    return 0;
600 a672b469 aliguori
}
601 a672b469 aliguori
602 c163b5ca lirans@il.ibm.com
size_t qemu_file_get_rate_limit(QEMUFile *f)
603 c163b5ca lirans@il.ibm.com
{
604 c163b5ca lirans@il.ibm.com
    if (f->get_rate_limit)
605 c163b5ca lirans@il.ibm.com
        return f->get_rate_limit(f->opaque);
606 c163b5ca lirans@il.ibm.com
607 c163b5ca lirans@il.ibm.com
    return 0;
608 c163b5ca lirans@il.ibm.com
}
609 c163b5ca lirans@il.ibm.com
610 19629537 Glauber Costa
size_t qemu_file_set_rate_limit(QEMUFile *f, size_t new_rate)
611 19629537 Glauber Costa
{
612 0bb05eaf Glauber Costa
    /* any failed or completed migration keeps its state to allow probing of
613 0bb05eaf Glauber Costa
     * migration data, but has no associated file anymore */
614 0bb05eaf Glauber Costa
    if (f && f->set_rate_limit)
615 19629537 Glauber Costa
        return f->set_rate_limit(f->opaque, new_rate);
616 19629537 Glauber Costa
617 19629537 Glauber Costa
    return 0;
618 19629537 Glauber Costa
}
619 19629537 Glauber Costa
620 a672b469 aliguori
void qemu_put_be16(QEMUFile *f, unsigned int v)
621 a672b469 aliguori
{
622 a672b469 aliguori
    qemu_put_byte(f, v >> 8);
623 a672b469 aliguori
    qemu_put_byte(f, v);
624 a672b469 aliguori
}
625 a672b469 aliguori
626 a672b469 aliguori
void qemu_put_be32(QEMUFile *f, unsigned int v)
627 a672b469 aliguori
{
628 a672b469 aliguori
    qemu_put_byte(f, v >> 24);
629 a672b469 aliguori
    qemu_put_byte(f, v >> 16);
630 a672b469 aliguori
    qemu_put_byte(f, v >> 8);
631 a672b469 aliguori
    qemu_put_byte(f, v);
632 a672b469 aliguori
}
633 a672b469 aliguori
634 a672b469 aliguori
void qemu_put_be64(QEMUFile *f, uint64_t v)
635 a672b469 aliguori
{
636 a672b469 aliguori
    qemu_put_be32(f, v >> 32);
637 a672b469 aliguori
    qemu_put_be32(f, v);
638 a672b469 aliguori
}
639 a672b469 aliguori
640 a672b469 aliguori
unsigned int qemu_get_be16(QEMUFile *f)
641 a672b469 aliguori
{
642 a672b469 aliguori
    unsigned int v;
643 a672b469 aliguori
    v = qemu_get_byte(f) << 8;
644 a672b469 aliguori
    v |= qemu_get_byte(f);
645 a672b469 aliguori
    return v;
646 a672b469 aliguori
}
647 a672b469 aliguori
648 a672b469 aliguori
unsigned int qemu_get_be32(QEMUFile *f)
649 a672b469 aliguori
{
650 a672b469 aliguori
    unsigned int v;
651 a672b469 aliguori
    v = qemu_get_byte(f) << 24;
652 a672b469 aliguori
    v |= qemu_get_byte(f) << 16;
653 a672b469 aliguori
    v |= qemu_get_byte(f) << 8;
654 a672b469 aliguori
    v |= qemu_get_byte(f);
655 a672b469 aliguori
    return v;
656 a672b469 aliguori
}
657 a672b469 aliguori
658 a672b469 aliguori
uint64_t qemu_get_be64(QEMUFile *f)
659 a672b469 aliguori
{
660 a672b469 aliguori
    uint64_t v;
661 a672b469 aliguori
    v = (uint64_t)qemu_get_be32(f) << 32;
662 a672b469 aliguori
    v |= qemu_get_be32(f);
663 a672b469 aliguori
    return v;
664 a672b469 aliguori
}
665 a672b469 aliguori
666 9ed7d6ae Juan Quintela
/* 8 bit int */
667 9ed7d6ae Juan Quintela
668 9ed7d6ae Juan Quintela
static int get_int8(QEMUFile *f, void *pv, size_t size)
669 9ed7d6ae Juan Quintela
{
670 9ed7d6ae Juan Quintela
    int8_t *v = pv;
671 9ed7d6ae Juan Quintela
    qemu_get_s8s(f, v);
672 9ed7d6ae Juan Quintela
    return 0;
673 9ed7d6ae Juan Quintela
}
674 9ed7d6ae Juan Quintela
675 84e2e3eb Juan Quintela
static void put_int8(QEMUFile *f, void *pv, size_t size)
676 9ed7d6ae Juan Quintela
{
677 84e2e3eb Juan Quintela
    int8_t *v = pv;
678 9ed7d6ae Juan Quintela
    qemu_put_s8s(f, v);
679 9ed7d6ae Juan Quintela
}
680 9ed7d6ae Juan Quintela
681 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_int8 = {
682 9ed7d6ae Juan Quintela
    .name = "int8",
683 9ed7d6ae Juan Quintela
    .get  = get_int8,
684 9ed7d6ae Juan Quintela
    .put  = put_int8,
685 9ed7d6ae Juan Quintela
};
686 9ed7d6ae Juan Quintela
687 9ed7d6ae Juan Quintela
/* 16 bit int */
688 9ed7d6ae Juan Quintela
689 9ed7d6ae Juan Quintela
static int get_int16(QEMUFile *f, void *pv, size_t size)
690 9ed7d6ae Juan Quintela
{
691 9ed7d6ae Juan Quintela
    int16_t *v = pv;
692 9ed7d6ae Juan Quintela
    qemu_get_sbe16s(f, v);
693 9ed7d6ae Juan Quintela
    return 0;
694 9ed7d6ae Juan Quintela
}
695 9ed7d6ae Juan Quintela
696 84e2e3eb Juan Quintela
static void put_int16(QEMUFile *f, void *pv, size_t size)
697 9ed7d6ae Juan Quintela
{
698 84e2e3eb Juan Quintela
    int16_t *v = pv;
699 9ed7d6ae Juan Quintela
    qemu_put_sbe16s(f, v);
700 9ed7d6ae Juan Quintela
}
701 9ed7d6ae Juan Quintela
702 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_int16 = {
703 9ed7d6ae Juan Quintela
    .name = "int16",
704 9ed7d6ae Juan Quintela
    .get  = get_int16,
705 9ed7d6ae Juan Quintela
    .put  = put_int16,
706 9ed7d6ae Juan Quintela
};
707 9ed7d6ae Juan Quintela
708 9ed7d6ae Juan Quintela
/* 32 bit int */
709 9ed7d6ae Juan Quintela
710 9ed7d6ae Juan Quintela
static int get_int32(QEMUFile *f, void *pv, size_t size)
711 9ed7d6ae Juan Quintela
{
712 9ed7d6ae Juan Quintela
    int32_t *v = pv;
713 9ed7d6ae Juan Quintela
    qemu_get_sbe32s(f, v);
714 9ed7d6ae Juan Quintela
    return 0;
715 9ed7d6ae Juan Quintela
}
716 9ed7d6ae Juan Quintela
717 84e2e3eb Juan Quintela
static void put_int32(QEMUFile *f, void *pv, size_t size)
718 9ed7d6ae Juan Quintela
{
719 84e2e3eb Juan Quintela
    int32_t *v = pv;
720 9ed7d6ae Juan Quintela
    qemu_put_sbe32s(f, v);
721 9ed7d6ae Juan Quintela
}
722 9ed7d6ae Juan Quintela
723 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_int32 = {
724 9ed7d6ae Juan Quintela
    .name = "int32",
725 9ed7d6ae Juan Quintela
    .get  = get_int32,
726 9ed7d6ae Juan Quintela
    .put  = put_int32,
727 9ed7d6ae Juan Quintela
};
728 9ed7d6ae Juan Quintela
729 82501660 Juan Quintela
/* 32 bit int. See that the received value is the same than the one
730 82501660 Juan Quintela
   in the field */
731 82501660 Juan Quintela
732 82501660 Juan Quintela
static int get_int32_equal(QEMUFile *f, void *pv, size_t size)
733 82501660 Juan Quintela
{
734 82501660 Juan Quintela
    int32_t *v = pv;
735 82501660 Juan Quintela
    int32_t v2;
736 82501660 Juan Quintela
    qemu_get_sbe32s(f, &v2);
737 82501660 Juan Quintela
738 82501660 Juan Quintela
    if (*v == v2)
739 82501660 Juan Quintela
        return 0;
740 82501660 Juan Quintela
    return -EINVAL;
741 82501660 Juan Quintela
}
742 82501660 Juan Quintela
743 82501660 Juan Quintela
const VMStateInfo vmstate_info_int32_equal = {
744 82501660 Juan Quintela
    .name = "int32 equal",
745 82501660 Juan Quintela
    .get  = get_int32_equal,
746 82501660 Juan Quintela
    .put  = put_int32,
747 82501660 Juan Quintela
};
748 82501660 Juan Quintela
749 0a031e0a Juan Quintela
/* 32 bit int. See that the received value is the less or the same
750 0a031e0a Juan Quintela
   than the one in the field */
751 0a031e0a Juan Quintela
752 0a031e0a Juan Quintela
static int get_int32_le(QEMUFile *f, void *pv, size_t size)
753 0a031e0a Juan Quintela
{
754 0a031e0a Juan Quintela
    int32_t *old = pv;
755 0a031e0a Juan Quintela
    int32_t new;
756 0a031e0a Juan Quintela
    qemu_get_sbe32s(f, &new);
757 0a031e0a Juan Quintela
758 0a031e0a Juan Quintela
    if (*old <= new)
759 0a031e0a Juan Quintela
        return 0;
760 0a031e0a Juan Quintela
    return -EINVAL;
761 0a031e0a Juan Quintela
}
762 0a031e0a Juan Quintela
763 0a031e0a Juan Quintela
const VMStateInfo vmstate_info_int32_le = {
764 0a031e0a Juan Quintela
    .name = "int32 equal",
765 0a031e0a Juan Quintela
    .get  = get_int32_le,
766 0a031e0a Juan Quintela
    .put  = put_int32,
767 0a031e0a Juan Quintela
};
768 0a031e0a Juan Quintela
769 9ed7d6ae Juan Quintela
/* 64 bit int */
770 9ed7d6ae Juan Quintela
771 9ed7d6ae Juan Quintela
static int get_int64(QEMUFile *f, void *pv, size_t size)
772 9ed7d6ae Juan Quintela
{
773 9ed7d6ae Juan Quintela
    int64_t *v = pv;
774 9ed7d6ae Juan Quintela
    qemu_get_sbe64s(f, v);
775 9ed7d6ae Juan Quintela
    return 0;
776 9ed7d6ae Juan Quintela
}
777 9ed7d6ae Juan Quintela
778 84e2e3eb Juan Quintela
static void put_int64(QEMUFile *f, void *pv, size_t size)
779 9ed7d6ae Juan Quintela
{
780 84e2e3eb Juan Quintela
    int64_t *v = pv;
781 9ed7d6ae Juan Quintela
    qemu_put_sbe64s(f, v);
782 9ed7d6ae Juan Quintela
}
783 9ed7d6ae Juan Quintela
784 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_int64 = {
785 9ed7d6ae Juan Quintela
    .name = "int64",
786 9ed7d6ae Juan Quintela
    .get  = get_int64,
787 9ed7d6ae Juan Quintela
    .put  = put_int64,
788 9ed7d6ae Juan Quintela
};
789 9ed7d6ae Juan Quintela
790 9ed7d6ae Juan Quintela
/* 8 bit unsigned int */
791 9ed7d6ae Juan Quintela
792 9ed7d6ae Juan Quintela
static int get_uint8(QEMUFile *f, void *pv, size_t size)
793 9ed7d6ae Juan Quintela
{
794 9ed7d6ae Juan Quintela
    uint8_t *v = pv;
795 9ed7d6ae Juan Quintela
    qemu_get_8s(f, v);
796 9ed7d6ae Juan Quintela
    return 0;
797 9ed7d6ae Juan Quintela
}
798 9ed7d6ae Juan Quintela
799 84e2e3eb Juan Quintela
static void put_uint8(QEMUFile *f, void *pv, size_t size)
800 9ed7d6ae Juan Quintela
{
801 84e2e3eb Juan Quintela
    uint8_t *v = pv;
802 9ed7d6ae Juan Quintela
    qemu_put_8s(f, v);
803 9ed7d6ae Juan Quintela
}
804 9ed7d6ae Juan Quintela
805 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_uint8 = {
806 9ed7d6ae Juan Quintela
    .name = "uint8",
807 9ed7d6ae Juan Quintela
    .get  = get_uint8,
808 9ed7d6ae Juan Quintela
    .put  = put_uint8,
809 9ed7d6ae Juan Quintela
};
810 9ed7d6ae Juan Quintela
811 9ed7d6ae Juan Quintela
/* 16 bit unsigned int */
812 9ed7d6ae Juan Quintela
813 9ed7d6ae Juan Quintela
static int get_uint16(QEMUFile *f, void *pv, size_t size)
814 9ed7d6ae Juan Quintela
{
815 9ed7d6ae Juan Quintela
    uint16_t *v = pv;
816 9ed7d6ae Juan Quintela
    qemu_get_be16s(f, v);
817 9ed7d6ae Juan Quintela
    return 0;
818 9ed7d6ae Juan Quintela
}
819 9ed7d6ae Juan Quintela
820 84e2e3eb Juan Quintela
static void put_uint16(QEMUFile *f, void *pv, size_t size)
821 9ed7d6ae Juan Quintela
{
822 84e2e3eb Juan Quintela
    uint16_t *v = pv;
823 9ed7d6ae Juan Quintela
    qemu_put_be16s(f, v);
824 9ed7d6ae Juan Quintela
}
825 9ed7d6ae Juan Quintela
826 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_uint16 = {
827 9ed7d6ae Juan Quintela
    .name = "uint16",
828 9ed7d6ae Juan Quintela
    .get  = get_uint16,
829 9ed7d6ae Juan Quintela
    .put  = put_uint16,
830 9ed7d6ae Juan Quintela
};
831 9ed7d6ae Juan Quintela
832 9ed7d6ae Juan Quintela
/* 32 bit unsigned int */
833 9ed7d6ae Juan Quintela
834 9ed7d6ae Juan Quintela
static int get_uint32(QEMUFile *f, void *pv, size_t size)
835 9ed7d6ae Juan Quintela
{
836 9ed7d6ae Juan Quintela
    uint32_t *v = pv;
837 9ed7d6ae Juan Quintela
    qemu_get_be32s(f, v);
838 9ed7d6ae Juan Quintela
    return 0;
839 9ed7d6ae Juan Quintela
}
840 9ed7d6ae Juan Quintela
841 84e2e3eb Juan Quintela
static void put_uint32(QEMUFile *f, void *pv, size_t size)
842 9ed7d6ae Juan Quintela
{
843 84e2e3eb Juan Quintela
    uint32_t *v = pv;
844 9ed7d6ae Juan Quintela
    qemu_put_be32s(f, v);
845 9ed7d6ae Juan Quintela
}
846 9ed7d6ae Juan Quintela
847 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_uint32 = {
848 9ed7d6ae Juan Quintela
    .name = "uint32",
849 9ed7d6ae Juan Quintela
    .get  = get_uint32,
850 9ed7d6ae Juan Quintela
    .put  = put_uint32,
851 9ed7d6ae Juan Quintela
};
852 9ed7d6ae Juan Quintela
853 9ed7d6ae Juan Quintela
/* 64 bit unsigned int */
854 9ed7d6ae Juan Quintela
855 9ed7d6ae Juan Quintela
static int get_uint64(QEMUFile *f, void *pv, size_t size)
856 9ed7d6ae Juan Quintela
{
857 9ed7d6ae Juan Quintela
    uint64_t *v = pv;
858 9ed7d6ae Juan Quintela
    qemu_get_be64s(f, v);
859 9ed7d6ae Juan Quintela
    return 0;
860 9ed7d6ae Juan Quintela
}
861 9ed7d6ae Juan Quintela
862 84e2e3eb Juan Quintela
static void put_uint64(QEMUFile *f, void *pv, size_t size)
863 9ed7d6ae Juan Quintela
{
864 84e2e3eb Juan Quintela
    uint64_t *v = pv;
865 9ed7d6ae Juan Quintela
    qemu_put_be64s(f, v);
866 9ed7d6ae Juan Quintela
}
867 9ed7d6ae Juan Quintela
868 9ed7d6ae Juan Quintela
const VMStateInfo vmstate_info_uint64 = {
869 9ed7d6ae Juan Quintela
    .name = "uint64",
870 9ed7d6ae Juan Quintela
    .get  = get_uint64,
871 9ed7d6ae Juan Quintela
    .put  = put_uint64,
872 9ed7d6ae Juan Quintela
};
873 9ed7d6ae Juan Quintela
874 80cd83e7 Juan Quintela
/* 8 bit int. See that the received value is the same than the one
875 80cd83e7 Juan Quintela
   in the field */
876 80cd83e7 Juan Quintela
877 80cd83e7 Juan Quintela
static int get_uint8_equal(QEMUFile *f, void *pv, size_t size)
878 80cd83e7 Juan Quintela
{
879 80cd83e7 Juan Quintela
    uint8_t *v = pv;
880 80cd83e7 Juan Quintela
    uint8_t v2;
881 80cd83e7 Juan Quintela
    qemu_get_8s(f, &v2);
882 80cd83e7 Juan Quintela
883 80cd83e7 Juan Quintela
    if (*v == v2)
884 80cd83e7 Juan Quintela
        return 0;
885 80cd83e7 Juan Quintela
    return -EINVAL;
886 80cd83e7 Juan Quintela
}
887 80cd83e7 Juan Quintela
888 80cd83e7 Juan Quintela
const VMStateInfo vmstate_info_uint8_equal = {
889 aa1cce69 Juan Quintela
    .name = "uint8 equal",
890 80cd83e7 Juan Quintela
    .get  = get_uint8_equal,
891 80cd83e7 Juan Quintela
    .put  = put_uint8,
892 80cd83e7 Juan Quintela
};
893 80cd83e7 Juan Quintela
894 dc3b83a0 Juan Quintela
/* 16 bit unsigned int int. See that the received value is the same than the one
895 dc3b83a0 Juan Quintela
   in the field */
896 dc3b83a0 Juan Quintela
897 dc3b83a0 Juan Quintela
static int get_uint16_equal(QEMUFile *f, void *pv, size_t size)
898 dc3b83a0 Juan Quintela
{
899 dc3b83a0 Juan Quintela
    uint16_t *v = pv;
900 dc3b83a0 Juan Quintela
    uint16_t v2;
901 dc3b83a0 Juan Quintela
    qemu_get_be16s(f, &v2);
902 dc3b83a0 Juan Quintela
903 dc3b83a0 Juan Quintela
    if (*v == v2)
904 dc3b83a0 Juan Quintela
        return 0;
905 dc3b83a0 Juan Quintela
    return -EINVAL;
906 dc3b83a0 Juan Quintela
}
907 dc3b83a0 Juan Quintela
908 dc3b83a0 Juan Quintela
const VMStateInfo vmstate_info_uint16_equal = {
909 dc3b83a0 Juan Quintela
    .name = "uint16 equal",
910 dc3b83a0 Juan Quintela
    .get  = get_uint16_equal,
911 dc3b83a0 Juan Quintela
    .put  = put_uint16,
912 dc3b83a0 Juan Quintela
};
913 dc3b83a0 Juan Quintela
914 dde0463b Juan Quintela
/* timers  */
915 dde0463b Juan Quintela
916 dde0463b Juan Quintela
static int get_timer(QEMUFile *f, void *pv, size_t size)
917 dde0463b Juan Quintela
{
918 dde0463b Juan Quintela
    QEMUTimer *v = pv;
919 dde0463b Juan Quintela
    qemu_get_timer(f, v);
920 dde0463b Juan Quintela
    return 0;
921 dde0463b Juan Quintela
}
922 dde0463b Juan Quintela
923 84e2e3eb Juan Quintela
static void put_timer(QEMUFile *f, void *pv, size_t size)
924 dde0463b Juan Quintela
{
925 84e2e3eb Juan Quintela
    QEMUTimer *v = pv;
926 dde0463b Juan Quintela
    qemu_put_timer(f, v);
927 dde0463b Juan Quintela
}
928 dde0463b Juan Quintela
929 dde0463b Juan Quintela
const VMStateInfo vmstate_info_timer = {
930 dde0463b Juan Quintela
    .name = "timer",
931 dde0463b Juan Quintela
    .get  = get_timer,
932 dde0463b Juan Quintela
    .put  = put_timer,
933 dde0463b Juan Quintela
};
934 dde0463b Juan Quintela
935 6f67c50f Juan Quintela
/* uint8_t buffers */
936 6f67c50f Juan Quintela
937 6f67c50f Juan Quintela
static int get_buffer(QEMUFile *f, void *pv, size_t size)
938 6f67c50f Juan Quintela
{
939 6f67c50f Juan Quintela
    uint8_t *v = pv;
940 6f67c50f Juan Quintela
    qemu_get_buffer(f, v, size);
941 6f67c50f Juan Quintela
    return 0;
942 6f67c50f Juan Quintela
}
943 6f67c50f Juan Quintela
944 84e2e3eb Juan Quintela
static void put_buffer(QEMUFile *f, void *pv, size_t size)
945 6f67c50f Juan Quintela
{
946 84e2e3eb Juan Quintela
    uint8_t *v = pv;
947 6f67c50f Juan Quintela
    qemu_put_buffer(f, v, size);
948 6f67c50f Juan Quintela
}
949 6f67c50f Juan Quintela
950 6f67c50f Juan Quintela
const VMStateInfo vmstate_info_buffer = {
951 6f67c50f Juan Quintela
    .name = "buffer",
952 6f67c50f Juan Quintela
    .get  = get_buffer,
953 6f67c50f Juan Quintela
    .put  = put_buffer,
954 6f67c50f Juan Quintela
};
955 6f67c50f Juan Quintela
956 76507c75 Juan Quintela
/* unused buffers: space that was used for some fields that are
957 76507c75 Juan Quintela
   not usefull anymore */
958 76507c75 Juan Quintela
959 76507c75 Juan Quintela
static int get_unused_buffer(QEMUFile *f, void *pv, size_t size)
960 76507c75 Juan Quintela
{
961 21174c34 Jan Kiszka
    uint8_t buf[1024];
962 21174c34 Jan Kiszka
    int block_len;
963 21174c34 Jan Kiszka
964 21174c34 Jan Kiszka
    while (size > 0) {
965 21174c34 Jan Kiszka
        block_len = MIN(sizeof(buf), size);
966 21174c34 Jan Kiszka
        size -= block_len;
967 21174c34 Jan Kiszka
        qemu_get_buffer(f, buf, block_len);
968 21174c34 Jan Kiszka
    }
969 21174c34 Jan Kiszka
   return 0;
970 76507c75 Juan Quintela
}
971 76507c75 Juan Quintela
972 76507c75 Juan Quintela
static void put_unused_buffer(QEMUFile *f, void *pv, size_t size)
973 76507c75 Juan Quintela
{
974 21174c34 Jan Kiszka
    static const uint8_t buf[1024];
975 21174c34 Jan Kiszka
    int block_len;
976 21174c34 Jan Kiszka
977 21174c34 Jan Kiszka
    while (size > 0) {
978 21174c34 Jan Kiszka
        block_len = MIN(sizeof(buf), size);
979 21174c34 Jan Kiszka
        size -= block_len;
980 21174c34 Jan Kiszka
        qemu_put_buffer(f, buf, block_len);
981 21174c34 Jan Kiszka
    }
982 76507c75 Juan Quintela
}
983 76507c75 Juan Quintela
984 76507c75 Juan Quintela
const VMStateInfo vmstate_info_unused_buffer = {
985 76507c75 Juan Quintela
    .name = "unused_buffer",
986 76507c75 Juan Quintela
    .get  = get_unused_buffer,
987 76507c75 Juan Quintela
    .put  = put_unused_buffer,
988 76507c75 Juan Quintela
};
989 76507c75 Juan Quintela
990 a672b469 aliguori
typedef struct SaveStateEntry {
991 72cf2d4f Blue Swirl
    QTAILQ_ENTRY(SaveStateEntry) entry;
992 a672b469 aliguori
    char idstr[256];
993 a672b469 aliguori
    int instance_id;
994 4d2ffa08 Jan Kiszka
    int alias_id;
995 a672b469 aliguori
    int version_id;
996 a672b469 aliguori
    int section_id;
997 c163b5ca lirans@il.ibm.com
    SaveSetParamsHandler *set_params;
998 a672b469 aliguori
    SaveLiveStateHandler *save_live_state;
999 a672b469 aliguori
    SaveStateHandler *save_state;
1000 a672b469 aliguori
    LoadStateHandler *load_state;
1001 9ed7d6ae Juan Quintela
    const VMStateDescription *vmsd;
1002 a672b469 aliguori
    void *opaque;
1003 a672b469 aliguori
} SaveStateEntry;
1004 a672b469 aliguori
1005 c163b5ca lirans@il.ibm.com
1006 72cf2d4f Blue Swirl
static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers =
1007 72cf2d4f Blue Swirl
    QTAILQ_HEAD_INITIALIZER(savevm_handlers);
1008 9ed7d6ae Juan Quintela
static int global_section_id;
1009 a672b469 aliguori
1010 8718e999 Juan Quintela
static int calculate_new_instance_id(const char *idstr)
1011 8718e999 Juan Quintela
{
1012 8718e999 Juan Quintela
    SaveStateEntry *se;
1013 8718e999 Juan Quintela
    int instance_id = 0;
1014 8718e999 Juan Quintela
1015 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1016 8718e999 Juan Quintela
        if (strcmp(idstr, se->idstr) == 0
1017 8718e999 Juan Quintela
            && instance_id <= se->instance_id) {
1018 8718e999 Juan Quintela
            instance_id = se->instance_id + 1;
1019 8718e999 Juan Quintela
        }
1020 8718e999 Juan Quintela
    }
1021 8718e999 Juan Quintela
    return instance_id;
1022 8718e999 Juan Quintela
}
1023 8718e999 Juan Quintela
1024 a672b469 aliguori
/* TODO: Individual devices generally have very little idea about the rest
1025 a672b469 aliguori
   of the system, so instance_id should be removed/replaced.
1026 a672b469 aliguori
   Meanwhile pass -1 as instance_id if you do not already have a clearly
1027 a672b469 aliguori
   distinguishing id for all instances of your device class. */
1028 a672b469 aliguori
int register_savevm_live(const char *idstr,
1029 a672b469 aliguori
                         int instance_id,
1030 a672b469 aliguori
                         int version_id,
1031 c163b5ca lirans@il.ibm.com
                         SaveSetParamsHandler *set_params,
1032 a672b469 aliguori
                         SaveLiveStateHandler *save_live_state,
1033 a672b469 aliguori
                         SaveStateHandler *save_state,
1034 a672b469 aliguori
                         LoadStateHandler *load_state,
1035 a672b469 aliguori
                         void *opaque)
1036 a672b469 aliguori
{
1037 8718e999 Juan Quintela
    SaveStateEntry *se;
1038 a672b469 aliguori
1039 c163b5ca lirans@il.ibm.com
    se = qemu_mallocz(sizeof(SaveStateEntry));
1040 a672b469 aliguori
    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
1041 a672b469 aliguori
    se->version_id = version_id;
1042 a672b469 aliguori
    se->section_id = global_section_id++;
1043 c163b5ca lirans@il.ibm.com
    se->set_params = set_params;
1044 a672b469 aliguori
    se->save_live_state = save_live_state;
1045 a672b469 aliguori
    se->save_state = save_state;
1046 a672b469 aliguori
    se->load_state = load_state;
1047 a672b469 aliguori
    se->opaque = opaque;
1048 9ed7d6ae Juan Quintela
    se->vmsd = NULL;
1049 a672b469 aliguori
1050 8718e999 Juan Quintela
    if (instance_id == -1) {
1051 8718e999 Juan Quintela
        se->instance_id = calculate_new_instance_id(idstr);
1052 8718e999 Juan Quintela
    } else {
1053 8718e999 Juan Quintela
        se->instance_id = instance_id;
1054 a672b469 aliguori
    }
1055 8718e999 Juan Quintela
    /* add at the end of list */
1056 72cf2d4f Blue Swirl
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
1057 a672b469 aliguori
    return 0;
1058 a672b469 aliguori
}
1059 a672b469 aliguori
1060 a672b469 aliguori
int register_savevm(const char *idstr,
1061 a672b469 aliguori
                    int instance_id,
1062 a672b469 aliguori
                    int version_id,
1063 a672b469 aliguori
                    SaveStateHandler *save_state,
1064 a672b469 aliguori
                    LoadStateHandler *load_state,
1065 a672b469 aliguori
                    void *opaque)
1066 a672b469 aliguori
{
1067 a672b469 aliguori
    return register_savevm_live(idstr, instance_id, version_id,
1068 c163b5ca lirans@il.ibm.com
                                NULL, NULL, save_state, load_state, opaque);
1069 a672b469 aliguori
}
1070 a672b469 aliguori
1071 41bd13af aliguori
void unregister_savevm(const char *idstr, void *opaque)
1072 41bd13af aliguori
{
1073 8718e999 Juan Quintela
    SaveStateEntry *se, *new_se;
1074 41bd13af aliguori
1075 72cf2d4f Blue Swirl
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
1076 8718e999 Juan Quintela
        if (strcmp(se->idstr, idstr) == 0 && se->opaque == opaque) {
1077 72cf2d4f Blue Swirl
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
1078 8718e999 Juan Quintela
            qemu_free(se);
1079 41bd13af aliguori
        }
1080 41bd13af aliguori
    }
1081 41bd13af aliguori
}
1082 41bd13af aliguori
1083 4d2ffa08 Jan Kiszka
int vmstate_register_with_alias_id(int instance_id,
1084 4d2ffa08 Jan Kiszka
                                   const VMStateDescription *vmsd,
1085 4d2ffa08 Jan Kiszka
                                   void *opaque, int alias_id,
1086 4d2ffa08 Jan Kiszka
                                   int required_for_version)
1087 9ed7d6ae Juan Quintela
{
1088 8718e999 Juan Quintela
    SaveStateEntry *se;
1089 9ed7d6ae Juan Quintela
1090 4d2ffa08 Jan Kiszka
    /* If this triggers, alias support can be dropped for the vmsd. */
1091 4d2ffa08 Jan Kiszka
    assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id);
1092 4d2ffa08 Jan Kiszka
1093 c163b5ca lirans@il.ibm.com
    se = qemu_mallocz(sizeof(SaveStateEntry));
1094 9ed7d6ae Juan Quintela
    pstrcpy(se->idstr, sizeof(se->idstr), vmsd->name);
1095 9ed7d6ae Juan Quintela
    se->version_id = vmsd->version_id;
1096 9ed7d6ae Juan Quintela
    se->section_id = global_section_id++;
1097 9ed7d6ae Juan Quintela
    se->save_live_state = NULL;
1098 9ed7d6ae Juan Quintela
    se->save_state = NULL;
1099 9ed7d6ae Juan Quintela
    se->load_state = NULL;
1100 9ed7d6ae Juan Quintela
    se->opaque = opaque;
1101 9ed7d6ae Juan Quintela
    se->vmsd = vmsd;
1102 4d2ffa08 Jan Kiszka
    se->alias_id = alias_id;
1103 9ed7d6ae Juan Quintela
1104 8718e999 Juan Quintela
    if (instance_id == -1) {
1105 8718e999 Juan Quintela
        se->instance_id = calculate_new_instance_id(vmsd->name);
1106 8718e999 Juan Quintela
    } else {
1107 8718e999 Juan Quintela
        se->instance_id = instance_id;
1108 9ed7d6ae Juan Quintela
    }
1109 8718e999 Juan Quintela
    /* add at the end of list */
1110 72cf2d4f Blue Swirl
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
1111 9ed7d6ae Juan Quintela
    return 0;
1112 9ed7d6ae Juan Quintela
}
1113 9ed7d6ae Juan Quintela
1114 4d2ffa08 Jan Kiszka
int vmstate_register(int instance_id, const VMStateDescription *vmsd,
1115 4d2ffa08 Jan Kiszka
                     void *opaque)
1116 4d2ffa08 Jan Kiszka
{
1117 4d2ffa08 Jan Kiszka
    return vmstate_register_with_alias_id(instance_id, vmsd, opaque, -1, 0);
1118 4d2ffa08 Jan Kiszka
}
1119 4d2ffa08 Jan Kiszka
1120 1eb7538b Juan Quintela
void vmstate_unregister(const VMStateDescription *vmsd, void *opaque)
1121 9ed7d6ae Juan Quintela
{
1122 1eb7538b Juan Quintela
    SaveStateEntry *se, *new_se;
1123 1eb7538b Juan Quintela
1124 72cf2d4f Blue Swirl
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
1125 1eb7538b Juan Quintela
        if (se->vmsd == vmsd && se->opaque == opaque) {
1126 72cf2d4f Blue Swirl
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
1127 1eb7538b Juan Quintela
            qemu_free(se);
1128 1eb7538b Juan Quintela
        }
1129 1eb7538b Juan Quintela
    }
1130 9ed7d6ae Juan Quintela
}
1131 9ed7d6ae Juan Quintela
1132 9ed7d6ae Juan Quintela
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
1133 9ed7d6ae Juan Quintela
                       void *opaque, int version_id)
1134 9ed7d6ae Juan Quintela
{
1135 9ed7d6ae Juan Quintela
    VMStateField *field = vmsd->fields;
1136 9ed7d6ae Juan Quintela
1137 9ed7d6ae Juan Quintela
    if (version_id > vmsd->version_id) {
1138 9ed7d6ae Juan Quintela
        return -EINVAL;
1139 9ed7d6ae Juan Quintela
    }
1140 9ed7d6ae Juan Quintela
    if (version_id < vmsd->minimum_version_id_old) {
1141 9ed7d6ae Juan Quintela
        return -EINVAL;
1142 9ed7d6ae Juan Quintela
    }
1143 9ed7d6ae Juan Quintela
    if  (version_id < vmsd->minimum_version_id) {
1144 9ed7d6ae Juan Quintela
        return vmsd->load_state_old(f, opaque, version_id);
1145 9ed7d6ae Juan Quintela
    }
1146 fd4d52de Juan Quintela
    if (vmsd->pre_load) {
1147 fd4d52de Juan Quintela
        int ret = vmsd->pre_load(opaque);
1148 fd4d52de Juan Quintela
        if (ret)
1149 fd4d52de Juan Quintela
            return ret;
1150 fd4d52de Juan Quintela
    }
1151 9ed7d6ae Juan Quintela
    while(field->name) {
1152 f11f6a5f Juan Quintela
        if ((field->field_exists &&
1153 f11f6a5f Juan Quintela
             field->field_exists(opaque, version_id)) ||
1154 f11f6a5f Juan Quintela
            (!field->field_exists &&
1155 f11f6a5f Juan Quintela
             field->version_id <= version_id)) {
1156 f752a6aa Juan Quintela
            void *base_addr = opaque + field->offset;
1157 f752a6aa Juan Quintela
            int ret, i, n_elems = 1;
1158 e61a1e0a Juan Quintela
            int size = field->size;
1159 9ed7d6ae Juan Quintela
1160 e61a1e0a Juan Quintela
            if (field->flags & VMS_VBUFFER) {
1161 e61a1e0a Juan Quintela
                size = *(int32_t *)(opaque+field->size_offset);
1162 33599e2a Juan Quintela
                if (field->flags & VMS_MULTIPLY) {
1163 33599e2a Juan Quintela
                    size *= field->size;
1164 33599e2a Juan Quintela
                }
1165 e61a1e0a Juan Quintela
            }
1166 f752a6aa Juan Quintela
            if (field->flags & VMS_ARRAY) {
1167 f752a6aa Juan Quintela
                n_elems = field->num;
1168 d6698281 Juan Quintela
            } else if (field->flags & VMS_VARRAY_INT32) {
1169 d6698281 Juan Quintela
                n_elems = *(int32_t *)(opaque+field->num_offset);
1170 bdb4941d Juan Quintela
            } else if (field->flags & VMS_VARRAY_UINT16) {
1171 bdb4941d Juan Quintela
                n_elems = *(uint16_t *)(opaque+field->num_offset);
1172 f752a6aa Juan Quintela
            }
1173 dde0463b Juan Quintela
            if (field->flags & VMS_POINTER) {
1174 e61a1e0a Juan Quintela
                base_addr = *(void **)base_addr + field->start;
1175 dde0463b Juan Quintela
            }
1176 f752a6aa Juan Quintela
            for (i = 0; i < n_elems; i++) {
1177 e61a1e0a Juan Quintela
                void *addr = base_addr + size * i;
1178 ec245e21 Juan Quintela
1179 19df438b Juan Quintela
                if (field->flags & VMS_ARRAY_OF_POINTER) {
1180 19df438b Juan Quintela
                    addr = *(void **)addr;
1181 19df438b Juan Quintela
                }
1182 ec245e21 Juan Quintela
                if (field->flags & VMS_STRUCT) {
1183 fa3aad24 Juan Quintela
                    ret = vmstate_load_state(f, field->vmsd, addr, field->vmsd->version_id);
1184 ec245e21 Juan Quintela
                } else {
1185 e61a1e0a Juan Quintela
                    ret = field->info->get(f, addr, size);
1186 ec245e21 Juan Quintela
1187 ec245e21 Juan Quintela
                }
1188 f752a6aa Juan Quintela
                if (ret < 0) {
1189 f752a6aa Juan Quintela
                    return ret;
1190 f752a6aa Juan Quintela
                }
1191 9ed7d6ae Juan Quintela
            }
1192 9ed7d6ae Juan Quintela
        }
1193 9ed7d6ae Juan Quintela
        field++;
1194 9ed7d6ae Juan Quintela
    }
1195 752ff2fa Juan Quintela
    if (vmsd->post_load) {
1196 e59fb374 Juan Quintela
        return vmsd->post_load(opaque, version_id);
1197 752ff2fa Juan Quintela
    }
1198 9ed7d6ae Juan Quintela
    return 0;
1199 9ed7d6ae Juan Quintela
}
1200 9ed7d6ae Juan Quintela
1201 9ed7d6ae Juan Quintela
void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
1202 84e2e3eb Juan Quintela
                        void *opaque)
1203 9ed7d6ae Juan Quintela
{
1204 9ed7d6ae Juan Quintela
    VMStateField *field = vmsd->fields;
1205 9ed7d6ae Juan Quintela
1206 8fb0791d Juan Quintela
    if (vmsd->pre_save) {
1207 8fb0791d Juan Quintela
        vmsd->pre_save(opaque);
1208 8fb0791d Juan Quintela
    }
1209 9ed7d6ae Juan Quintela
    while(field->name) {
1210 f11f6a5f Juan Quintela
        if (!field->field_exists ||
1211 f11f6a5f Juan Quintela
            field->field_exists(opaque, vmsd->version_id)) {
1212 f11f6a5f Juan Quintela
            void *base_addr = opaque + field->offset;
1213 f11f6a5f Juan Quintela
            int i, n_elems = 1;
1214 e61a1e0a Juan Quintela
            int size = field->size;
1215 dde0463b Juan Quintela
1216 e61a1e0a Juan Quintela
            if (field->flags & VMS_VBUFFER) {
1217 e61a1e0a Juan Quintela
                size = *(int32_t *)(opaque+field->size_offset);
1218 33599e2a Juan Quintela
                if (field->flags & VMS_MULTIPLY) {
1219 33599e2a Juan Quintela
                    size *= field->size;
1220 33599e2a Juan Quintela
                }
1221 e61a1e0a Juan Quintela
            }
1222 f11f6a5f Juan Quintela
            if (field->flags & VMS_ARRAY) {
1223 f11f6a5f Juan Quintela
                n_elems = field->num;
1224 d6698281 Juan Quintela
            } else if (field->flags & VMS_VARRAY_INT32) {
1225 d6698281 Juan Quintela
                n_elems = *(int32_t *)(opaque+field->num_offset);
1226 bdb4941d Juan Quintela
            } else if (field->flags & VMS_VARRAY_UINT16) {
1227 bdb4941d Juan Quintela
                n_elems = *(uint16_t *)(opaque+field->num_offset);
1228 f11f6a5f Juan Quintela
            }
1229 f11f6a5f Juan Quintela
            if (field->flags & VMS_POINTER) {
1230 e61a1e0a Juan Quintela
                base_addr = *(void **)base_addr + field->start;
1231 f11f6a5f Juan Quintela
            }
1232 f11f6a5f Juan Quintela
            for (i = 0; i < n_elems; i++) {
1233 e61a1e0a Juan Quintela
                void *addr = base_addr + size * i;
1234 ec245e21 Juan Quintela
1235 8595387e Juan Quintela
                if (field->flags & VMS_ARRAY_OF_POINTER) {
1236 8595387e Juan Quintela
                    addr = *(void **)addr;
1237 8595387e Juan Quintela
                }
1238 f11f6a5f Juan Quintela
                if (field->flags & VMS_STRUCT) {
1239 f11f6a5f Juan Quintela
                    vmstate_save_state(f, field->vmsd, addr);
1240 f11f6a5f Juan Quintela
                } else {
1241 e61a1e0a Juan Quintela
                    field->info->put(f, addr, size);
1242 f11f6a5f Juan Quintela
                }
1243 ec245e21 Juan Quintela
            }
1244 dde0463b Juan Quintela
        }
1245 9ed7d6ae Juan Quintela
        field++;
1246 9ed7d6ae Juan Quintela
    }
1247 9ed7d6ae Juan Quintela
}
1248 9ed7d6ae Juan Quintela
1249 4082be4d Juan Quintela
static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
1250 4082be4d Juan Quintela
{
1251 9ed7d6ae Juan Quintela
    if (!se->vmsd) {         /* Old style */
1252 9ed7d6ae Juan Quintela
        return se->load_state(f, se->opaque, version_id);
1253 9ed7d6ae Juan Quintela
    }
1254 9ed7d6ae Juan Quintela
    return vmstate_load_state(f, se->vmsd, se->opaque, version_id);
1255 4082be4d Juan Quintela
}
1256 4082be4d Juan Quintela
1257 4082be4d Juan Quintela
static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
1258 4082be4d Juan Quintela
{
1259 9ed7d6ae Juan Quintela
    if (!se->vmsd) {         /* Old style */
1260 9ed7d6ae Juan Quintela
        se->save_state(f, se->opaque);
1261 9ed7d6ae Juan Quintela
        return;
1262 9ed7d6ae Juan Quintela
    }
1263 9ed7d6ae Juan Quintela
    vmstate_save_state(f,se->vmsd, se->opaque);
1264 4082be4d Juan Quintela
}
1265 4082be4d Juan Quintela
1266 a672b469 aliguori
#define QEMU_VM_FILE_MAGIC           0x5145564d
1267 a672b469 aliguori
#define QEMU_VM_FILE_VERSION_COMPAT  0x00000002
1268 a672b469 aliguori
#define QEMU_VM_FILE_VERSION         0x00000003
1269 a672b469 aliguori
1270 a672b469 aliguori
#define QEMU_VM_EOF                  0x00
1271 a672b469 aliguori
#define QEMU_VM_SECTION_START        0x01
1272 a672b469 aliguori
#define QEMU_VM_SECTION_PART         0x02
1273 a672b469 aliguori
#define QEMU_VM_SECTION_END          0x03
1274 a672b469 aliguori
#define QEMU_VM_SECTION_FULL         0x04
1275 a672b469 aliguori
1276 f327aa0c Jan Kiszka
int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
1277 f327aa0c Jan Kiszka
                            int shared)
1278 a672b469 aliguori
{
1279 a672b469 aliguori
    SaveStateEntry *se;
1280 a672b469 aliguori
1281 c163b5ca lirans@il.ibm.com
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1282 c163b5ca lirans@il.ibm.com
        if(se->set_params == NULL) {
1283 c163b5ca lirans@il.ibm.com
            continue;
1284 c163b5ca lirans@il.ibm.com
        }
1285 c163b5ca lirans@il.ibm.com
        se->set_params(blk_enable, shared, se->opaque);
1286 c163b5ca lirans@il.ibm.com
    }
1287 c163b5ca lirans@il.ibm.com
    
1288 a672b469 aliguori
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1289 a672b469 aliguori
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1290 a672b469 aliguori
1291 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1292 a672b469 aliguori
        int len;
1293 a672b469 aliguori
1294 a672b469 aliguori
        if (se->save_live_state == NULL)
1295 a672b469 aliguori
            continue;
1296 a672b469 aliguori
1297 a672b469 aliguori
        /* Section type */
1298 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_START);
1299 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1300 a672b469 aliguori
1301 a672b469 aliguori
        /* ID string */
1302 a672b469 aliguori
        len = strlen(se->idstr);
1303 a672b469 aliguori
        qemu_put_byte(f, len);
1304 a672b469 aliguori
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1305 a672b469 aliguori
1306 a672b469 aliguori
        qemu_put_be32(f, se->instance_id);
1307 a672b469 aliguori
        qemu_put_be32(f, se->version_id);
1308 a672b469 aliguori
1309 f327aa0c Jan Kiszka
        se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque);
1310 a672b469 aliguori
    }
1311 a672b469 aliguori
1312 4ec7fcc7 Jan Kiszka
    if (qemu_file_has_error(f)) {
1313 f327aa0c Jan Kiszka
        qemu_savevm_state_cancel(mon, f);
1314 a672b469 aliguori
        return -EIO;
1315 4ec7fcc7 Jan Kiszka
    }
1316 a672b469 aliguori
1317 a672b469 aliguori
    return 0;
1318 a672b469 aliguori
}
1319 a672b469 aliguori
1320 f327aa0c Jan Kiszka
int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
1321 a672b469 aliguori
{
1322 a672b469 aliguori
    SaveStateEntry *se;
1323 a672b469 aliguori
    int ret = 1;
1324 a672b469 aliguori
1325 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1326 a672b469 aliguori
        if (se->save_live_state == NULL)
1327 a672b469 aliguori
            continue;
1328 a672b469 aliguori
1329 a672b469 aliguori
        /* Section type */
1330 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_PART);
1331 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1332 a672b469 aliguori
1333 90697be8 Jan Kiszka
        ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque);
1334 90697be8 Jan Kiszka
        if (!ret) {
1335 90697be8 Jan Kiszka
            /* Do not proceed to the next vmstate before this one reported
1336 90697be8 Jan Kiszka
               completion of the current stage. This serializes the migration
1337 90697be8 Jan Kiszka
               and reduces the probability that a faster changing state is
1338 90697be8 Jan Kiszka
               synchronized over and over again. */
1339 90697be8 Jan Kiszka
            break;
1340 90697be8 Jan Kiszka
        }
1341 a672b469 aliguori
    }
1342 a672b469 aliguori
1343 a672b469 aliguori
    if (ret)
1344 a672b469 aliguori
        return 1;
1345 a672b469 aliguori
1346 4ec7fcc7 Jan Kiszka
    if (qemu_file_has_error(f)) {
1347 f327aa0c Jan Kiszka
        qemu_savevm_state_cancel(mon, f);
1348 a672b469 aliguori
        return -EIO;
1349 4ec7fcc7 Jan Kiszka
    }
1350 a672b469 aliguori
1351 a672b469 aliguori
    return 0;
1352 a672b469 aliguori
}
1353 a672b469 aliguori
1354 f327aa0c Jan Kiszka
int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
1355 a672b469 aliguori
{
1356 a672b469 aliguori
    SaveStateEntry *se;
1357 a672b469 aliguori
1358 ea375f9a Jan Kiszka
    cpu_synchronize_all_states();
1359 ea375f9a Jan Kiszka
1360 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1361 a672b469 aliguori
        if (se->save_live_state == NULL)
1362 a672b469 aliguori
            continue;
1363 a672b469 aliguori
1364 a672b469 aliguori
        /* Section type */
1365 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_END);
1366 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1367 a672b469 aliguori
1368 f327aa0c Jan Kiszka
        se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);
1369 a672b469 aliguori
    }
1370 a672b469 aliguori
1371 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1372 a672b469 aliguori
        int len;
1373 a672b469 aliguori
1374 9ed7d6ae Juan Quintela
        if (se->save_state == NULL && se->vmsd == NULL)
1375 a672b469 aliguori
            continue;
1376 a672b469 aliguori
1377 a672b469 aliguori
        /* Section type */
1378 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
1379 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1380 a672b469 aliguori
1381 a672b469 aliguori
        /* ID string */
1382 a672b469 aliguori
        len = strlen(se->idstr);
1383 a672b469 aliguori
        qemu_put_byte(f, len);
1384 a672b469 aliguori
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1385 a672b469 aliguori
1386 a672b469 aliguori
        qemu_put_be32(f, se->instance_id);
1387 a672b469 aliguori
        qemu_put_be32(f, se->version_id);
1388 a672b469 aliguori
1389 4082be4d Juan Quintela
        vmstate_save(f, se);
1390 a672b469 aliguori
    }
1391 a672b469 aliguori
1392 a672b469 aliguori
    qemu_put_byte(f, QEMU_VM_EOF);
1393 a672b469 aliguori
1394 a672b469 aliguori
    if (qemu_file_has_error(f))
1395 a672b469 aliguori
        return -EIO;
1396 a672b469 aliguori
1397 a672b469 aliguori
    return 0;
1398 a672b469 aliguori
}
1399 a672b469 aliguori
1400 f327aa0c Jan Kiszka
void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f)
1401 4ec7fcc7 Jan Kiszka
{
1402 4ec7fcc7 Jan Kiszka
    SaveStateEntry *se;
1403 4ec7fcc7 Jan Kiszka
1404 4ec7fcc7 Jan Kiszka
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1405 4ec7fcc7 Jan Kiszka
        if (se->save_live_state) {
1406 f327aa0c Jan Kiszka
            se->save_live_state(mon, f, -1, se->opaque);
1407 4ec7fcc7 Jan Kiszka
        }
1408 4ec7fcc7 Jan Kiszka
    }
1409 4ec7fcc7 Jan Kiszka
}
1410 4ec7fcc7 Jan Kiszka
1411 f327aa0c Jan Kiszka
static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
1412 a672b469 aliguori
{
1413 a672b469 aliguori
    int saved_vm_running;
1414 a672b469 aliguori
    int ret;
1415 a672b469 aliguori
1416 a672b469 aliguori
    saved_vm_running = vm_running;
1417 a672b469 aliguori
    vm_stop(0);
1418 a672b469 aliguori
1419 a672b469 aliguori
    bdrv_flush_all();
1420 a672b469 aliguori
1421 f327aa0c Jan Kiszka
    ret = qemu_savevm_state_begin(mon, f, 0, 0);
1422 a672b469 aliguori
    if (ret < 0)
1423 a672b469 aliguori
        goto out;
1424 a672b469 aliguori
1425 a672b469 aliguori
    do {
1426 f327aa0c Jan Kiszka
        ret = qemu_savevm_state_iterate(mon, f);
1427 a672b469 aliguori
        if (ret < 0)
1428 a672b469 aliguori
            goto out;
1429 a672b469 aliguori
    } while (ret == 0);
1430 a672b469 aliguori
1431 f327aa0c Jan Kiszka
    ret = qemu_savevm_state_complete(mon, f);
1432 a672b469 aliguori
1433 a672b469 aliguori
out:
1434 a672b469 aliguori
    if (qemu_file_has_error(f))
1435 a672b469 aliguori
        ret = -EIO;
1436 a672b469 aliguori
1437 a672b469 aliguori
    if (!ret && saved_vm_running)
1438 a672b469 aliguori
        vm_start();
1439 a672b469 aliguori
1440 a672b469 aliguori
    return ret;
1441 a672b469 aliguori
}
1442 a672b469 aliguori
1443 a672b469 aliguori
static SaveStateEntry *find_se(const char *idstr, int instance_id)
1444 a672b469 aliguori
{
1445 a672b469 aliguori
    SaveStateEntry *se;
1446 a672b469 aliguori
1447 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1448 a672b469 aliguori
        if (!strcmp(se->idstr, idstr) &&
1449 4d2ffa08 Jan Kiszka
            (instance_id == se->instance_id ||
1450 4d2ffa08 Jan Kiszka
             instance_id == se->alias_id))
1451 a672b469 aliguori
            return se;
1452 a672b469 aliguori
    }
1453 a672b469 aliguori
    return NULL;
1454 a672b469 aliguori
}
1455 a672b469 aliguori
1456 a672b469 aliguori
typedef struct LoadStateEntry {
1457 72cf2d4f Blue Swirl
    QLIST_ENTRY(LoadStateEntry) entry;
1458 a672b469 aliguori
    SaveStateEntry *se;
1459 a672b469 aliguori
    int section_id;
1460 a672b469 aliguori
    int version_id;
1461 a672b469 aliguori
} LoadStateEntry;
1462 a672b469 aliguori
1463 a672b469 aliguori
int qemu_loadvm_state(QEMUFile *f)
1464 a672b469 aliguori
{
1465 72cf2d4f Blue Swirl
    QLIST_HEAD(, LoadStateEntry) loadvm_handlers =
1466 72cf2d4f Blue Swirl
        QLIST_HEAD_INITIALIZER(loadvm_handlers);
1467 f4dbb8dd Juan Quintela
    LoadStateEntry *le, *new_le;
1468 a672b469 aliguori
    uint8_t section_type;
1469 a672b469 aliguori
    unsigned int v;
1470 a672b469 aliguori
    int ret;
1471 a672b469 aliguori
1472 a672b469 aliguori
    v = qemu_get_be32(f);
1473 a672b469 aliguori
    if (v != QEMU_VM_FILE_MAGIC)
1474 a672b469 aliguori
        return -EINVAL;
1475 a672b469 aliguori
1476 a672b469 aliguori
    v = qemu_get_be32(f);
1477 bbfe1408 Juan Quintela
    if (v == QEMU_VM_FILE_VERSION_COMPAT) {
1478 bbfe1408 Juan Quintela
        fprintf(stderr, "SaveVM v2 format is obsolete and don't work anymore\n");
1479 bbfe1408 Juan Quintela
        return -ENOTSUP;
1480 bbfe1408 Juan Quintela
    }
1481 a672b469 aliguori
    if (v != QEMU_VM_FILE_VERSION)
1482 a672b469 aliguori
        return -ENOTSUP;
1483 a672b469 aliguori
1484 a672b469 aliguori
    while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
1485 a672b469 aliguori
        uint32_t instance_id, version_id, section_id;
1486 a672b469 aliguori
        SaveStateEntry *se;
1487 a672b469 aliguori
        char idstr[257];
1488 a672b469 aliguori
        int len;
1489 a672b469 aliguori
1490 a672b469 aliguori
        switch (section_type) {
1491 a672b469 aliguori
        case QEMU_VM_SECTION_START:
1492 a672b469 aliguori
        case QEMU_VM_SECTION_FULL:
1493 a672b469 aliguori
            /* Read section start */
1494 a672b469 aliguori
            section_id = qemu_get_be32(f);
1495 a672b469 aliguori
            len = qemu_get_byte(f);
1496 a672b469 aliguori
            qemu_get_buffer(f, (uint8_t *)idstr, len);
1497 a672b469 aliguori
            idstr[len] = 0;
1498 a672b469 aliguori
            instance_id = qemu_get_be32(f);
1499 a672b469 aliguori
            version_id = qemu_get_be32(f);
1500 a672b469 aliguori
1501 a672b469 aliguori
            /* Find savevm section */
1502 a672b469 aliguori
            se = find_se(idstr, instance_id);
1503 a672b469 aliguori
            if (se == NULL) {
1504 a672b469 aliguori
                fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
1505 a672b469 aliguori
                ret = -EINVAL;
1506 a672b469 aliguori
                goto out;
1507 a672b469 aliguori
            }
1508 a672b469 aliguori
1509 a672b469 aliguori
            /* Validate version */
1510 a672b469 aliguori
            if (version_id > se->version_id) {
1511 a672b469 aliguori
                fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
1512 a672b469 aliguori
                        version_id, idstr, se->version_id);
1513 a672b469 aliguori
                ret = -EINVAL;
1514 a672b469 aliguori
                goto out;
1515 a672b469 aliguori
            }
1516 a672b469 aliguori
1517 a672b469 aliguori
            /* Add entry */
1518 a672b469 aliguori
            le = qemu_mallocz(sizeof(*le));
1519 a672b469 aliguori
1520 a672b469 aliguori
            le->se = se;
1521 a672b469 aliguori
            le->section_id = section_id;
1522 a672b469 aliguori
            le->version_id = version_id;
1523 72cf2d4f Blue Swirl
            QLIST_INSERT_HEAD(&loadvm_handlers, le, entry);
1524 a672b469 aliguori
1525 4082be4d Juan Quintela
            ret = vmstate_load(f, le->se, le->version_id);
1526 b5a22e4a Juan Quintela
            if (ret < 0) {
1527 b5a22e4a Juan Quintela
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
1528 b5a22e4a Juan Quintela
                        instance_id, idstr);
1529 b5a22e4a Juan Quintela
                goto out;
1530 b5a22e4a Juan Quintela
            }
1531 a672b469 aliguori
            break;
1532 a672b469 aliguori
        case QEMU_VM_SECTION_PART:
1533 a672b469 aliguori
        case QEMU_VM_SECTION_END:
1534 a672b469 aliguori
            section_id = qemu_get_be32(f);
1535 a672b469 aliguori
1536 72cf2d4f Blue Swirl
            QLIST_FOREACH(le, &loadvm_handlers, entry) {
1537 f4dbb8dd Juan Quintela
                if (le->section_id == section_id) {
1538 f4dbb8dd Juan Quintela
                    break;
1539 f4dbb8dd Juan Quintela
                }
1540 f4dbb8dd Juan Quintela
            }
1541 a672b469 aliguori
            if (le == NULL) {
1542 a672b469 aliguori
                fprintf(stderr, "Unknown savevm section %d\n", section_id);
1543 a672b469 aliguori
                ret = -EINVAL;
1544 a672b469 aliguori
                goto out;
1545 a672b469 aliguori
            }
1546 a672b469 aliguori
1547 4082be4d Juan Quintela
            ret = vmstate_load(f, le->se, le->version_id);
1548 b5a22e4a Juan Quintela
            if (ret < 0) {
1549 b5a22e4a Juan Quintela
                fprintf(stderr, "qemu: warning: error while loading state section id %d\n",
1550 b5a22e4a Juan Quintela
                        section_id);
1551 b5a22e4a Juan Quintela
                goto out;
1552 b5a22e4a Juan Quintela
            }
1553 a672b469 aliguori
            break;
1554 a672b469 aliguori
        default:
1555 a672b469 aliguori
            fprintf(stderr, "Unknown savevm section type %d\n", section_type);
1556 a672b469 aliguori
            ret = -EINVAL;
1557 a672b469 aliguori
            goto out;
1558 a672b469 aliguori
        }
1559 a672b469 aliguori
    }
1560 a672b469 aliguori
1561 ea375f9a Jan Kiszka
    cpu_synchronize_all_post_init();
1562 ea375f9a Jan Kiszka
1563 a672b469 aliguori
    ret = 0;
1564 a672b469 aliguori
1565 a672b469 aliguori
out:
1566 72cf2d4f Blue Swirl
    QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {
1567 72cf2d4f Blue Swirl
        QLIST_REMOVE(le, entry);
1568 a672b469 aliguori
        qemu_free(le);
1569 a672b469 aliguori
    }
1570 a672b469 aliguori
1571 a672b469 aliguori
    if (qemu_file_has_error(f))
1572 a672b469 aliguori
        ret = -EIO;
1573 a672b469 aliguori
1574 a672b469 aliguori
    return ret;
1575 a672b469 aliguori
}
1576 a672b469 aliguori
1577 a672b469 aliguori
/* device can contain snapshots */
1578 a672b469 aliguori
static int bdrv_can_snapshot(BlockDriverState *bs)
1579 a672b469 aliguori
{
1580 a672b469 aliguori
    return (bs &&
1581 a672b469 aliguori
            !bdrv_is_removable(bs) &&
1582 a672b469 aliguori
            !bdrv_is_read_only(bs));
1583 a672b469 aliguori
}
1584 a672b469 aliguori
1585 a672b469 aliguori
/* device must be snapshots in order to have a reliable snapshot */
1586 a672b469 aliguori
static int bdrv_has_snapshot(BlockDriverState *bs)
1587 a672b469 aliguori
{
1588 a672b469 aliguori
    return (bs &&
1589 a672b469 aliguori
            !bdrv_is_removable(bs) &&
1590 a672b469 aliguori
            !bdrv_is_read_only(bs));
1591 a672b469 aliguori
}
1592 a672b469 aliguori
1593 a672b469 aliguori
static BlockDriverState *get_bs_snapshots(void)
1594 a672b469 aliguori
{
1595 a672b469 aliguori
    BlockDriverState *bs;
1596 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1597 a672b469 aliguori
1598 a672b469 aliguori
    if (bs_snapshots)
1599 a672b469 aliguori
        return bs_snapshots;
1600 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1601 751c6a17 Gerd Hoffmann
        bs = dinfo->bdrv;
1602 a672b469 aliguori
        if (bdrv_can_snapshot(bs))
1603 a672b469 aliguori
            goto ok;
1604 a672b469 aliguori
    }
1605 a672b469 aliguori
    return NULL;
1606 a672b469 aliguori
 ok:
1607 a672b469 aliguori
    bs_snapshots = bs;
1608 a672b469 aliguori
    return bs;
1609 a672b469 aliguori
}
1610 a672b469 aliguori
1611 a672b469 aliguori
static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
1612 a672b469 aliguori
                              const char *name)
1613 a672b469 aliguori
{
1614 a672b469 aliguori
    QEMUSnapshotInfo *sn_tab, *sn;
1615 a672b469 aliguori
    int nb_sns, i, ret;
1616 a672b469 aliguori
1617 a672b469 aliguori
    ret = -ENOENT;
1618 a672b469 aliguori
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1619 a672b469 aliguori
    if (nb_sns < 0)
1620 a672b469 aliguori
        return ret;
1621 a672b469 aliguori
    for(i = 0; i < nb_sns; i++) {
1622 a672b469 aliguori
        sn = &sn_tab[i];
1623 a672b469 aliguori
        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
1624 a672b469 aliguori
            *sn_info = *sn;
1625 a672b469 aliguori
            ret = 0;
1626 a672b469 aliguori
            break;
1627 a672b469 aliguori
        }
1628 a672b469 aliguori
    }
1629 a672b469 aliguori
    qemu_free(sn_tab);
1630 a672b469 aliguori
    return ret;
1631 a672b469 aliguori
}
1632 a672b469 aliguori
1633 cb499fb2 Kevin Wolf
/*
1634 cb499fb2 Kevin Wolf
 * Deletes snapshots of a given name in all opened images.
1635 cb499fb2 Kevin Wolf
 */
1636 cb499fb2 Kevin Wolf
static int del_existing_snapshots(Monitor *mon, const char *name)
1637 cb499fb2 Kevin Wolf
{
1638 cb499fb2 Kevin Wolf
    BlockDriverState *bs;
1639 cb499fb2 Kevin Wolf
    DriveInfo *dinfo;
1640 cb499fb2 Kevin Wolf
    QEMUSnapshotInfo sn1, *snapshot = &sn1;
1641 cb499fb2 Kevin Wolf
    int ret;
1642 cb499fb2 Kevin Wolf
1643 cb499fb2 Kevin Wolf
    QTAILQ_FOREACH(dinfo, &drives, next) {
1644 cb499fb2 Kevin Wolf
        bs = dinfo->bdrv;
1645 cb499fb2 Kevin Wolf
        if (bdrv_can_snapshot(bs) &&
1646 cb499fb2 Kevin Wolf
            bdrv_snapshot_find(bs, snapshot, name) >= 0)
1647 cb499fb2 Kevin Wolf
        {
1648 cb499fb2 Kevin Wolf
            ret = bdrv_snapshot_delete(bs, name);
1649 cb499fb2 Kevin Wolf
            if (ret < 0) {
1650 cb499fb2 Kevin Wolf
                monitor_printf(mon,
1651 cb499fb2 Kevin Wolf
                               "Error while deleting snapshot on '%s'\n",
1652 cb499fb2 Kevin Wolf
                               bdrv_get_device_name(bs));
1653 cb499fb2 Kevin Wolf
                return -1;
1654 cb499fb2 Kevin Wolf
            }
1655 cb499fb2 Kevin Wolf
        }
1656 cb499fb2 Kevin Wolf
    }
1657 cb499fb2 Kevin Wolf
1658 cb499fb2 Kevin Wolf
    return 0;
1659 cb499fb2 Kevin Wolf
}
1660 cb499fb2 Kevin Wolf
1661 d54908a5 Luiz Capitulino
void do_savevm(Monitor *mon, const QDict *qdict)
1662 a672b469 aliguori
{
1663 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1664 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1665 a672b469 aliguori
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
1666 cb499fb2 Kevin Wolf
    int ret;
1667 a672b469 aliguori
    QEMUFile *f;
1668 a672b469 aliguori
    int saved_vm_running;
1669 2d22b18f aliguori
    uint32_t vm_state_size;
1670 a672b469 aliguori
#ifdef _WIN32
1671 a672b469 aliguori
    struct _timeb tb;
1672 a672b469 aliguori
#else
1673 a672b469 aliguori
    struct timeval tv;
1674 a672b469 aliguori
#endif
1675 d54908a5 Luiz Capitulino
    const char *name = qdict_get_try_str(qdict, "name");
1676 a672b469 aliguori
1677 a672b469 aliguori
    bs = get_bs_snapshots();
1678 a672b469 aliguori
    if (!bs) {
1679 376253ec aliguori
        monitor_printf(mon, "No block device can accept snapshots\n");
1680 a672b469 aliguori
        return;
1681 a672b469 aliguori
    }
1682 a672b469 aliguori
1683 a672b469 aliguori
    /* ??? Should this occur after vm_stop?  */
1684 a672b469 aliguori
    qemu_aio_flush();
1685 a672b469 aliguori
1686 a672b469 aliguori
    saved_vm_running = vm_running;
1687 a672b469 aliguori
    vm_stop(0);
1688 a672b469 aliguori
1689 cb499fb2 Kevin Wolf
    memset(sn, 0, sizeof(*sn));
1690 a672b469 aliguori
    if (name) {
1691 a672b469 aliguori
        ret = bdrv_snapshot_find(bs, old_sn, name);
1692 a672b469 aliguori
        if (ret >= 0) {
1693 cb499fb2 Kevin Wolf
            pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
1694 cb499fb2 Kevin Wolf
            pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
1695 cb499fb2 Kevin Wolf
        } else {
1696 a672b469 aliguori
            pstrcpy(sn->name, sizeof(sn->name), name);
1697 cb499fb2 Kevin Wolf
        }
1698 a672b469 aliguori
    }
1699 a672b469 aliguori
1700 a672b469 aliguori
    /* fill auxiliary fields */
1701 a672b469 aliguori
#ifdef _WIN32
1702 a672b469 aliguori
    _ftime(&tb);
1703 a672b469 aliguori
    sn->date_sec = tb.time;
1704 a672b469 aliguori
    sn->date_nsec = tb.millitm * 1000000;
1705 a672b469 aliguori
#else
1706 a672b469 aliguori
    gettimeofday(&tv, NULL);
1707 a672b469 aliguori
    sn->date_sec = tv.tv_sec;
1708 a672b469 aliguori
    sn->date_nsec = tv.tv_usec * 1000;
1709 a672b469 aliguori
#endif
1710 a672b469 aliguori
    sn->vm_clock_nsec = qemu_get_clock(vm_clock);
1711 a672b469 aliguori
1712 cb499fb2 Kevin Wolf
    /* Delete old snapshots of the same name */
1713 f139a412 Marcelo Tosatti
    if (name && del_existing_snapshots(mon, name) < 0) {
1714 cb499fb2 Kevin Wolf
        goto the_end;
1715 cb499fb2 Kevin Wolf
    }
1716 cb499fb2 Kevin Wolf
1717 a672b469 aliguori
    /* save the VM state */
1718 45566e9c Christoph Hellwig
    f = qemu_fopen_bdrv(bs, 1);
1719 a672b469 aliguori
    if (!f) {
1720 376253ec aliguori
        monitor_printf(mon, "Could not open VM state file\n");
1721 a672b469 aliguori
        goto the_end;
1722 a672b469 aliguori
    }
1723 f327aa0c Jan Kiszka
    ret = qemu_savevm_state(mon, f);
1724 2d22b18f aliguori
    vm_state_size = qemu_ftell(f);
1725 a672b469 aliguori
    qemu_fclose(f);
1726 a672b469 aliguori
    if (ret < 0) {
1727 376253ec aliguori
        monitor_printf(mon, "Error %d while writing VM\n", ret);
1728 a672b469 aliguori
        goto the_end;
1729 a672b469 aliguori
    }
1730 a672b469 aliguori
1731 a672b469 aliguori
    /* create the snapshots */
1732 a672b469 aliguori
1733 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1734 751c6a17 Gerd Hoffmann
        bs1 = dinfo->bdrv;
1735 a672b469 aliguori
        if (bdrv_has_snapshot(bs1)) {
1736 2d22b18f aliguori
            /* Write VM state size only to the image that contains the state */
1737 2d22b18f aliguori
            sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
1738 a672b469 aliguori
            ret = bdrv_snapshot_create(bs1, sn);
1739 a672b469 aliguori
            if (ret < 0) {
1740 376253ec aliguori
                monitor_printf(mon, "Error while creating snapshot on '%s'\n",
1741 376253ec aliguori
                               bdrv_get_device_name(bs1));
1742 a672b469 aliguori
            }
1743 a672b469 aliguori
        }
1744 a672b469 aliguori
    }
1745 a672b469 aliguori
1746 a672b469 aliguori
 the_end:
1747 a672b469 aliguori
    if (saved_vm_running)
1748 a672b469 aliguori
        vm_start();
1749 a672b469 aliguori
}
1750 a672b469 aliguori
1751 03cd4655 Markus Armbruster
int load_vmstate(const char *name)
1752 a672b469 aliguori
{
1753 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1754 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1755 2d22b18f aliguori
    QEMUSnapshotInfo sn;
1756 a672b469 aliguori
    QEMUFile *f;
1757 751c6a17 Gerd Hoffmann
    int ret;
1758 a672b469 aliguori
1759 a672b469 aliguori
    bs = get_bs_snapshots();
1760 a672b469 aliguori
    if (!bs) {
1761 1ecda02b Markus Armbruster
        error_report("No block device supports snapshots");
1762 05f2401e Juan Quintela
        return -EINVAL;
1763 a672b469 aliguori
    }
1764 a672b469 aliguori
1765 a672b469 aliguori
    /* Flush all IO requests so they don't interfere with the new state.  */
1766 a672b469 aliguori
    qemu_aio_flush();
1767 a672b469 aliguori
1768 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1769 751c6a17 Gerd Hoffmann
        bs1 = dinfo->bdrv;
1770 a672b469 aliguori
        if (bdrv_has_snapshot(bs1)) {
1771 a672b469 aliguori
            ret = bdrv_snapshot_goto(bs1, name);
1772 a672b469 aliguori
            if (ret < 0) {
1773 a672b469 aliguori
                switch(ret) {
1774 a672b469 aliguori
                case -ENOTSUP:
1775 1ecda02b Markus Armbruster
                    error_report("%sSnapshots not supported on device '%s'",
1776 1ecda02b Markus Armbruster
                                 bs != bs1 ? "Warning: " : "",
1777 1ecda02b Markus Armbruster
                                 bdrv_get_device_name(bs1));
1778 a672b469 aliguori
                    break;
1779 a672b469 aliguori
                case -ENOENT:
1780 1ecda02b Markus Armbruster
                    error_report("%sCould not find snapshot '%s' on device '%s'",
1781 1ecda02b Markus Armbruster
                                 bs != bs1 ? "Warning: " : "",
1782 1ecda02b Markus Armbruster
                                 name, bdrv_get_device_name(bs1));
1783 a672b469 aliguori
                    break;
1784 a672b469 aliguori
                default:
1785 1ecda02b Markus Armbruster
                    error_report("%sError %d while activating snapshot on '%s'",
1786 1ecda02b Markus Armbruster
                                 bs != bs1 ? "Warning: " : "",
1787 1ecda02b Markus Armbruster
                                 ret, bdrv_get_device_name(bs1));
1788 a672b469 aliguori
                    break;
1789 a672b469 aliguori
                }
1790 a672b469 aliguori
                /* fatal on snapshot block device */
1791 a672b469 aliguori
                if (bs == bs1)
1792 05f2401e Juan Quintela
                    return 0;
1793 a672b469 aliguori
            }
1794 a672b469 aliguori
        }
1795 a672b469 aliguori
    }
1796 a672b469 aliguori
1797 2d22b18f aliguori
    /* Don't even try to load empty VM states */
1798 2d22b18f aliguori
    ret = bdrv_snapshot_find(bs, &sn, name);
1799 2d22b18f aliguori
    if ((ret >= 0) && (sn.vm_state_size == 0))
1800 05f2401e Juan Quintela
        return -EINVAL;
1801 2d22b18f aliguori
1802 a672b469 aliguori
    /* restore the VM state */
1803 45566e9c Christoph Hellwig
    f = qemu_fopen_bdrv(bs, 0);
1804 a672b469 aliguori
    if (!f) {
1805 1ecda02b Markus Armbruster
        error_report("Could not open VM state file");
1806 05f2401e Juan Quintela
        return -EINVAL;
1807 a672b469 aliguori
    }
1808 a672b469 aliguori
    ret = qemu_loadvm_state(f);
1809 a672b469 aliguori
    qemu_fclose(f);
1810 a672b469 aliguori
    if (ret < 0) {
1811 1ecda02b Markus Armbruster
        error_report("Error %d while loading VM state", ret);
1812 05f2401e Juan Quintela
        return ret;
1813 a672b469 aliguori
    }
1814 05f2401e Juan Quintela
    return 0;
1815 7b630349 Juan Quintela
}
1816 7b630349 Juan Quintela
1817 d54908a5 Luiz Capitulino
void do_delvm(Monitor *mon, const QDict *qdict)
1818 a672b469 aliguori
{
1819 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1820 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1821 751c6a17 Gerd Hoffmann
    int ret;
1822 d54908a5 Luiz Capitulino
    const char *name = qdict_get_str(qdict, "name");
1823 a672b469 aliguori
1824 a672b469 aliguori
    bs = get_bs_snapshots();
1825 a672b469 aliguori
    if (!bs) {
1826 376253ec aliguori
        monitor_printf(mon, "No block device supports snapshots\n");
1827 a672b469 aliguori
        return;
1828 a672b469 aliguori
    }
1829 a672b469 aliguori
1830 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1831 751c6a17 Gerd Hoffmann
        bs1 = dinfo->bdrv;
1832 a672b469 aliguori
        if (bdrv_has_snapshot(bs1)) {
1833 a672b469 aliguori
            ret = bdrv_snapshot_delete(bs1, name);
1834 a672b469 aliguori
            if (ret < 0) {
1835 a672b469 aliguori
                if (ret == -ENOTSUP)
1836 376253ec aliguori
                    monitor_printf(mon,
1837 376253ec aliguori
                                   "Snapshots not supported on device '%s'\n",
1838 376253ec aliguori
                                   bdrv_get_device_name(bs1));
1839 a672b469 aliguori
                else
1840 376253ec aliguori
                    monitor_printf(mon, "Error %d while deleting snapshot on "
1841 376253ec aliguori
                                   "'%s'\n", ret, bdrv_get_device_name(bs1));
1842 a672b469 aliguori
            }
1843 a672b469 aliguori
        }
1844 a672b469 aliguori
    }
1845 a672b469 aliguori
}
1846 a672b469 aliguori
1847 376253ec aliguori
void do_info_snapshots(Monitor *mon)
1848 a672b469 aliguori
{
1849 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1850 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1851 a672b469 aliguori
    QEMUSnapshotInfo *sn_tab, *sn;
1852 a672b469 aliguori
    int nb_sns, i;
1853 a672b469 aliguori
    char buf[256];
1854 a672b469 aliguori
1855 a672b469 aliguori
    bs = get_bs_snapshots();
1856 a672b469 aliguori
    if (!bs) {
1857 376253ec aliguori
        monitor_printf(mon, "No available block device supports snapshots\n");
1858 a672b469 aliguori
        return;
1859 a672b469 aliguori
    }
1860 376253ec aliguori
    monitor_printf(mon, "Snapshot devices:");
1861 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1862 751c6a17 Gerd Hoffmann
        bs1 = dinfo->bdrv;
1863 a672b469 aliguori
        if (bdrv_has_snapshot(bs1)) {
1864 a672b469 aliguori
            if (bs == bs1)
1865 376253ec aliguori
                monitor_printf(mon, " %s", bdrv_get_device_name(bs1));
1866 a672b469 aliguori
        }
1867 a672b469 aliguori
    }
1868 376253ec aliguori
    monitor_printf(mon, "\n");
1869 a672b469 aliguori
1870 a672b469 aliguori
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1871 a672b469 aliguori
    if (nb_sns < 0) {
1872 376253ec aliguori
        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
1873 a672b469 aliguori
        return;
1874 a672b469 aliguori
    }
1875 376253ec aliguori
    monitor_printf(mon, "Snapshot list (from %s):\n",
1876 376253ec aliguori
                   bdrv_get_device_name(bs));
1877 376253ec aliguori
    monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1878 a672b469 aliguori
    for(i = 0; i < nb_sns; i++) {
1879 a672b469 aliguori
        sn = &sn_tab[i];
1880 376253ec aliguori
        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1881 a672b469 aliguori
    }
1882 a672b469 aliguori
    qemu_free(sn_tab);
1883 a672b469 aliguori
}