Statistics
| Branch: | Revision:

root / savevm.c @ ea375f9a

History | View | Annotate | Download (45.8 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 18995b98 Nolan
#define ETH_P_RARP 0x0835
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 7f79dd28 Paolo Bonzini
        fprintf(stderr, "qemu_fdopen: 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 a672b469 aliguori
    int version_id;
995 a672b469 aliguori
    int section_id;
996 c163b5ca lirans@il.ibm.com
    SaveSetParamsHandler *set_params;
997 a672b469 aliguori
    SaveLiveStateHandler *save_live_state;
998 a672b469 aliguori
    SaveStateHandler *save_state;
999 a672b469 aliguori
    LoadStateHandler *load_state;
1000 9ed7d6ae Juan Quintela
    const VMStateDescription *vmsd;
1001 a672b469 aliguori
    void *opaque;
1002 a672b469 aliguori
} SaveStateEntry;
1003 a672b469 aliguori
1004 c163b5ca lirans@il.ibm.com
1005 72cf2d4f Blue Swirl
static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers =
1006 72cf2d4f Blue Swirl
    QTAILQ_HEAD_INITIALIZER(savevm_handlers);
1007 9ed7d6ae Juan Quintela
static int global_section_id;
1008 a672b469 aliguori
1009 8718e999 Juan Quintela
static int calculate_new_instance_id(const char *idstr)
1010 8718e999 Juan Quintela
{
1011 8718e999 Juan Quintela
    SaveStateEntry *se;
1012 8718e999 Juan Quintela
    int instance_id = 0;
1013 8718e999 Juan Quintela
1014 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1015 8718e999 Juan Quintela
        if (strcmp(idstr, se->idstr) == 0
1016 8718e999 Juan Quintela
            && instance_id <= se->instance_id) {
1017 8718e999 Juan Quintela
            instance_id = se->instance_id + 1;
1018 8718e999 Juan Quintela
        }
1019 8718e999 Juan Quintela
    }
1020 8718e999 Juan Quintela
    return instance_id;
1021 8718e999 Juan Quintela
}
1022 8718e999 Juan Quintela
1023 a672b469 aliguori
/* TODO: Individual devices generally have very little idea about the rest
1024 a672b469 aliguori
   of the system, so instance_id should be removed/replaced.
1025 a672b469 aliguori
   Meanwhile pass -1 as instance_id if you do not already have a clearly
1026 a672b469 aliguori
   distinguishing id for all instances of your device class. */
1027 a672b469 aliguori
int register_savevm_live(const char *idstr,
1028 a672b469 aliguori
                         int instance_id,
1029 a672b469 aliguori
                         int version_id,
1030 c163b5ca lirans@il.ibm.com
                         SaveSetParamsHandler *set_params,
1031 a672b469 aliguori
                         SaveLiveStateHandler *save_live_state,
1032 a672b469 aliguori
                         SaveStateHandler *save_state,
1033 a672b469 aliguori
                         LoadStateHandler *load_state,
1034 a672b469 aliguori
                         void *opaque)
1035 a672b469 aliguori
{
1036 8718e999 Juan Quintela
    SaveStateEntry *se;
1037 a672b469 aliguori
1038 c163b5ca lirans@il.ibm.com
    se = qemu_mallocz(sizeof(SaveStateEntry));
1039 a672b469 aliguori
    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
1040 a672b469 aliguori
    se->version_id = version_id;
1041 a672b469 aliguori
    se->section_id = global_section_id++;
1042 c163b5ca lirans@il.ibm.com
    se->set_params = set_params;
1043 a672b469 aliguori
    se->save_live_state = save_live_state;
1044 a672b469 aliguori
    se->save_state = save_state;
1045 a672b469 aliguori
    se->load_state = load_state;
1046 a672b469 aliguori
    se->opaque = opaque;
1047 9ed7d6ae Juan Quintela
    se->vmsd = NULL;
1048 a672b469 aliguori
1049 8718e999 Juan Quintela
    if (instance_id == -1) {
1050 8718e999 Juan Quintela
        se->instance_id = calculate_new_instance_id(idstr);
1051 8718e999 Juan Quintela
    } else {
1052 8718e999 Juan Quintela
        se->instance_id = instance_id;
1053 a672b469 aliguori
    }
1054 8718e999 Juan Quintela
    /* add at the end of list */
1055 72cf2d4f Blue Swirl
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
1056 a672b469 aliguori
    return 0;
1057 a672b469 aliguori
}
1058 a672b469 aliguori
1059 a672b469 aliguori
int register_savevm(const char *idstr,
1060 a672b469 aliguori
                    int instance_id,
1061 a672b469 aliguori
                    int version_id,
1062 a672b469 aliguori
                    SaveStateHandler *save_state,
1063 a672b469 aliguori
                    LoadStateHandler *load_state,
1064 a672b469 aliguori
                    void *opaque)
1065 a672b469 aliguori
{
1066 a672b469 aliguori
    return register_savevm_live(idstr, instance_id, version_id,
1067 c163b5ca lirans@il.ibm.com
                                NULL, NULL, save_state, load_state, opaque);
1068 a672b469 aliguori
}
1069 a672b469 aliguori
1070 41bd13af aliguori
void unregister_savevm(const char *idstr, void *opaque)
1071 41bd13af aliguori
{
1072 8718e999 Juan Quintela
    SaveStateEntry *se, *new_se;
1073 41bd13af aliguori
1074 72cf2d4f Blue Swirl
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
1075 8718e999 Juan Quintela
        if (strcmp(se->idstr, idstr) == 0 && se->opaque == opaque) {
1076 72cf2d4f Blue Swirl
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
1077 8718e999 Juan Quintela
            qemu_free(se);
1078 41bd13af aliguori
        }
1079 41bd13af aliguori
    }
1080 41bd13af aliguori
}
1081 41bd13af aliguori
1082 9ed7d6ae Juan Quintela
int vmstate_register(int instance_id, const VMStateDescription *vmsd,
1083 9ed7d6ae Juan Quintela
                     void *opaque)
1084 9ed7d6ae Juan Quintela
{
1085 8718e999 Juan Quintela
    SaveStateEntry *se;
1086 9ed7d6ae Juan Quintela
1087 c163b5ca lirans@il.ibm.com
    se = qemu_mallocz(sizeof(SaveStateEntry));
1088 9ed7d6ae Juan Quintela
    pstrcpy(se->idstr, sizeof(se->idstr), vmsd->name);
1089 9ed7d6ae Juan Quintela
    se->version_id = vmsd->version_id;
1090 9ed7d6ae Juan Quintela
    se->section_id = global_section_id++;
1091 9ed7d6ae Juan Quintela
    se->save_live_state = NULL;
1092 9ed7d6ae Juan Quintela
    se->save_state = NULL;
1093 9ed7d6ae Juan Quintela
    se->load_state = NULL;
1094 9ed7d6ae Juan Quintela
    se->opaque = opaque;
1095 9ed7d6ae Juan Quintela
    se->vmsd = vmsd;
1096 9ed7d6ae Juan Quintela
1097 8718e999 Juan Quintela
    if (instance_id == -1) {
1098 8718e999 Juan Quintela
        se->instance_id = calculate_new_instance_id(vmsd->name);
1099 8718e999 Juan Quintela
    } else {
1100 8718e999 Juan Quintela
        se->instance_id = instance_id;
1101 9ed7d6ae Juan Quintela
    }
1102 8718e999 Juan Quintela
    /* add at the end of list */
1103 72cf2d4f Blue Swirl
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
1104 9ed7d6ae Juan Quintela
    return 0;
1105 9ed7d6ae Juan Quintela
}
1106 9ed7d6ae Juan Quintela
1107 1eb7538b Juan Quintela
void vmstate_unregister(const VMStateDescription *vmsd, void *opaque)
1108 9ed7d6ae Juan Quintela
{
1109 1eb7538b Juan Quintela
    SaveStateEntry *se, *new_se;
1110 1eb7538b Juan Quintela
1111 72cf2d4f Blue Swirl
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
1112 1eb7538b Juan Quintela
        if (se->vmsd == vmsd && se->opaque == opaque) {
1113 72cf2d4f Blue Swirl
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
1114 1eb7538b Juan Quintela
            qemu_free(se);
1115 1eb7538b Juan Quintela
        }
1116 1eb7538b Juan Quintela
    }
1117 9ed7d6ae Juan Quintela
}
1118 9ed7d6ae Juan Quintela
1119 9ed7d6ae Juan Quintela
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
1120 9ed7d6ae Juan Quintela
                       void *opaque, int version_id)
1121 9ed7d6ae Juan Quintela
{
1122 9ed7d6ae Juan Quintela
    VMStateField *field = vmsd->fields;
1123 9ed7d6ae Juan Quintela
1124 9ed7d6ae Juan Quintela
    if (version_id > vmsd->version_id) {
1125 9ed7d6ae Juan Quintela
        return -EINVAL;
1126 9ed7d6ae Juan Quintela
    }
1127 9ed7d6ae Juan Quintela
    if (version_id < vmsd->minimum_version_id_old) {
1128 9ed7d6ae Juan Quintela
        return -EINVAL;
1129 9ed7d6ae Juan Quintela
    }
1130 9ed7d6ae Juan Quintela
    if  (version_id < vmsd->minimum_version_id) {
1131 9ed7d6ae Juan Quintela
        return vmsd->load_state_old(f, opaque, version_id);
1132 9ed7d6ae Juan Quintela
    }
1133 fd4d52de Juan Quintela
    if (vmsd->pre_load) {
1134 fd4d52de Juan Quintela
        int ret = vmsd->pre_load(opaque);
1135 fd4d52de Juan Quintela
        if (ret)
1136 fd4d52de Juan Quintela
            return ret;
1137 fd4d52de Juan Quintela
    }
1138 9ed7d6ae Juan Quintela
    while(field->name) {
1139 f11f6a5f Juan Quintela
        if ((field->field_exists &&
1140 f11f6a5f Juan Quintela
             field->field_exists(opaque, version_id)) ||
1141 f11f6a5f Juan Quintela
            (!field->field_exists &&
1142 f11f6a5f Juan Quintela
             field->version_id <= version_id)) {
1143 f752a6aa Juan Quintela
            void *base_addr = opaque + field->offset;
1144 f752a6aa Juan Quintela
            int ret, i, n_elems = 1;
1145 e61a1e0a Juan Quintela
            int size = field->size;
1146 9ed7d6ae Juan Quintela
1147 e61a1e0a Juan Quintela
            if (field->flags & VMS_VBUFFER) {
1148 e61a1e0a Juan Quintela
                size = *(int32_t *)(opaque+field->size_offset);
1149 33599e2a Juan Quintela
                if (field->flags & VMS_MULTIPLY) {
1150 33599e2a Juan Quintela
                    size *= field->size;
1151 33599e2a Juan Quintela
                }
1152 e61a1e0a Juan Quintela
            }
1153 f752a6aa Juan Quintela
            if (field->flags & VMS_ARRAY) {
1154 f752a6aa Juan Quintela
                n_elems = field->num;
1155 d6698281 Juan Quintela
            } else if (field->flags & VMS_VARRAY_INT32) {
1156 d6698281 Juan Quintela
                n_elems = *(int32_t *)(opaque+field->num_offset);
1157 bdb4941d Juan Quintela
            } else if (field->flags & VMS_VARRAY_UINT16) {
1158 bdb4941d Juan Quintela
                n_elems = *(uint16_t *)(opaque+field->num_offset);
1159 f752a6aa Juan Quintela
            }
1160 dde0463b Juan Quintela
            if (field->flags & VMS_POINTER) {
1161 e61a1e0a Juan Quintela
                base_addr = *(void **)base_addr + field->start;
1162 dde0463b Juan Quintela
            }
1163 f752a6aa Juan Quintela
            for (i = 0; i < n_elems; i++) {
1164 e61a1e0a Juan Quintela
                void *addr = base_addr + size * i;
1165 ec245e21 Juan Quintela
1166 19df438b Juan Quintela
                if (field->flags & VMS_ARRAY_OF_POINTER) {
1167 19df438b Juan Quintela
                    addr = *(void **)addr;
1168 19df438b Juan Quintela
                }
1169 ec245e21 Juan Quintela
                if (field->flags & VMS_STRUCT) {
1170 fa3aad24 Juan Quintela
                    ret = vmstate_load_state(f, field->vmsd, addr, field->vmsd->version_id);
1171 ec245e21 Juan Quintela
                } else {
1172 e61a1e0a Juan Quintela
                    ret = field->info->get(f, addr, size);
1173 ec245e21 Juan Quintela
1174 ec245e21 Juan Quintela
                }
1175 f752a6aa Juan Quintela
                if (ret < 0) {
1176 f752a6aa Juan Quintela
                    return ret;
1177 f752a6aa Juan Quintela
                }
1178 9ed7d6ae Juan Quintela
            }
1179 9ed7d6ae Juan Quintela
        }
1180 9ed7d6ae Juan Quintela
        field++;
1181 9ed7d6ae Juan Quintela
    }
1182 752ff2fa Juan Quintela
    if (vmsd->post_load) {
1183 e59fb374 Juan Quintela
        return vmsd->post_load(opaque, version_id);
1184 752ff2fa Juan Quintela
    }
1185 9ed7d6ae Juan Quintela
    return 0;
1186 9ed7d6ae Juan Quintela
}
1187 9ed7d6ae Juan Quintela
1188 9ed7d6ae Juan Quintela
void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
1189 84e2e3eb Juan Quintela
                        void *opaque)
1190 9ed7d6ae Juan Quintela
{
1191 9ed7d6ae Juan Quintela
    VMStateField *field = vmsd->fields;
1192 9ed7d6ae Juan Quintela
1193 8fb0791d Juan Quintela
    if (vmsd->pre_save) {
1194 8fb0791d Juan Quintela
        vmsd->pre_save(opaque);
1195 8fb0791d Juan Quintela
    }
1196 9ed7d6ae Juan Quintela
    while(field->name) {
1197 f11f6a5f Juan Quintela
        if (!field->field_exists ||
1198 f11f6a5f Juan Quintela
            field->field_exists(opaque, vmsd->version_id)) {
1199 f11f6a5f Juan Quintela
            void *base_addr = opaque + field->offset;
1200 f11f6a5f Juan Quintela
            int i, n_elems = 1;
1201 e61a1e0a Juan Quintela
            int size = field->size;
1202 dde0463b Juan Quintela
1203 e61a1e0a Juan Quintela
            if (field->flags & VMS_VBUFFER) {
1204 e61a1e0a Juan Quintela
                size = *(int32_t *)(opaque+field->size_offset);
1205 33599e2a Juan Quintela
                if (field->flags & VMS_MULTIPLY) {
1206 33599e2a Juan Quintela
                    size *= field->size;
1207 33599e2a Juan Quintela
                }
1208 e61a1e0a Juan Quintela
            }
1209 f11f6a5f Juan Quintela
            if (field->flags & VMS_ARRAY) {
1210 f11f6a5f Juan Quintela
                n_elems = field->num;
1211 d6698281 Juan Quintela
            } else if (field->flags & VMS_VARRAY_INT32) {
1212 d6698281 Juan Quintela
                n_elems = *(int32_t *)(opaque+field->num_offset);
1213 bdb4941d Juan Quintela
            } else if (field->flags & VMS_VARRAY_UINT16) {
1214 bdb4941d Juan Quintela
                n_elems = *(uint16_t *)(opaque+field->num_offset);
1215 f11f6a5f Juan Quintela
            }
1216 f11f6a5f Juan Quintela
            if (field->flags & VMS_POINTER) {
1217 e61a1e0a Juan Quintela
                base_addr = *(void **)base_addr + field->start;
1218 f11f6a5f Juan Quintela
            }
1219 f11f6a5f Juan Quintela
            for (i = 0; i < n_elems; i++) {
1220 e61a1e0a Juan Quintela
                void *addr = base_addr + size * i;
1221 ec245e21 Juan Quintela
1222 8595387e Juan Quintela
                if (field->flags & VMS_ARRAY_OF_POINTER) {
1223 8595387e Juan Quintela
                    addr = *(void **)addr;
1224 8595387e Juan Quintela
                }
1225 f11f6a5f Juan Quintela
                if (field->flags & VMS_STRUCT) {
1226 f11f6a5f Juan Quintela
                    vmstate_save_state(f, field->vmsd, addr);
1227 f11f6a5f Juan Quintela
                } else {
1228 e61a1e0a Juan Quintela
                    field->info->put(f, addr, size);
1229 f11f6a5f Juan Quintela
                }
1230 ec245e21 Juan Quintela
            }
1231 dde0463b Juan Quintela
        }
1232 9ed7d6ae Juan Quintela
        field++;
1233 9ed7d6ae Juan Quintela
    }
1234 8fb0791d Juan Quintela
    if (vmsd->post_save) {
1235 8fb0791d Juan Quintela
        vmsd->post_save(opaque);
1236 8fb0791d Juan Quintela
    }
1237 9ed7d6ae Juan Quintela
}
1238 9ed7d6ae Juan Quintela
1239 4082be4d Juan Quintela
static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
1240 4082be4d Juan Quintela
{
1241 9ed7d6ae Juan Quintela
    if (!se->vmsd) {         /* Old style */
1242 9ed7d6ae Juan Quintela
        return se->load_state(f, se->opaque, version_id);
1243 9ed7d6ae Juan Quintela
    }
1244 9ed7d6ae Juan Quintela
    return vmstate_load_state(f, se->vmsd, se->opaque, version_id);
1245 4082be4d Juan Quintela
}
1246 4082be4d Juan Quintela
1247 4082be4d Juan Quintela
static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
1248 4082be4d Juan Quintela
{
1249 9ed7d6ae Juan Quintela
    if (!se->vmsd) {         /* Old style */
1250 9ed7d6ae Juan Quintela
        se->save_state(f, se->opaque);
1251 9ed7d6ae Juan Quintela
        return;
1252 9ed7d6ae Juan Quintela
    }
1253 9ed7d6ae Juan Quintela
    vmstate_save_state(f,se->vmsd, se->opaque);
1254 4082be4d Juan Quintela
}
1255 4082be4d Juan Quintela
1256 a672b469 aliguori
#define QEMU_VM_FILE_MAGIC           0x5145564d
1257 a672b469 aliguori
#define QEMU_VM_FILE_VERSION_COMPAT  0x00000002
1258 a672b469 aliguori
#define QEMU_VM_FILE_VERSION         0x00000003
1259 a672b469 aliguori
1260 a672b469 aliguori
#define QEMU_VM_EOF                  0x00
1261 a672b469 aliguori
#define QEMU_VM_SECTION_START        0x01
1262 a672b469 aliguori
#define QEMU_VM_SECTION_PART         0x02
1263 a672b469 aliguori
#define QEMU_VM_SECTION_END          0x03
1264 a672b469 aliguori
#define QEMU_VM_SECTION_FULL         0x04
1265 a672b469 aliguori
1266 f327aa0c Jan Kiszka
int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
1267 f327aa0c Jan Kiszka
                            int shared)
1268 a672b469 aliguori
{
1269 a672b469 aliguori
    SaveStateEntry *se;
1270 a672b469 aliguori
1271 c163b5ca lirans@il.ibm.com
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1272 c163b5ca lirans@il.ibm.com
        if(se->set_params == NULL) {
1273 c163b5ca lirans@il.ibm.com
            continue;
1274 c163b5ca lirans@il.ibm.com
        }
1275 c163b5ca lirans@il.ibm.com
        se->set_params(blk_enable, shared, se->opaque);
1276 c163b5ca lirans@il.ibm.com
    }
1277 c163b5ca lirans@il.ibm.com
    
1278 a672b469 aliguori
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1279 a672b469 aliguori
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1280 a672b469 aliguori
1281 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1282 a672b469 aliguori
        int len;
1283 a672b469 aliguori
1284 a672b469 aliguori
        if (se->save_live_state == NULL)
1285 a672b469 aliguori
            continue;
1286 a672b469 aliguori
1287 a672b469 aliguori
        /* Section type */
1288 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_START);
1289 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1290 a672b469 aliguori
1291 a672b469 aliguori
        /* ID string */
1292 a672b469 aliguori
        len = strlen(se->idstr);
1293 a672b469 aliguori
        qemu_put_byte(f, len);
1294 a672b469 aliguori
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1295 a672b469 aliguori
1296 a672b469 aliguori
        qemu_put_be32(f, se->instance_id);
1297 a672b469 aliguori
        qemu_put_be32(f, se->version_id);
1298 a672b469 aliguori
1299 f327aa0c Jan Kiszka
        se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque);
1300 a672b469 aliguori
    }
1301 a672b469 aliguori
1302 4ec7fcc7 Jan Kiszka
    if (qemu_file_has_error(f)) {
1303 f327aa0c Jan Kiszka
        qemu_savevm_state_cancel(mon, f);
1304 a672b469 aliguori
        return -EIO;
1305 4ec7fcc7 Jan Kiszka
    }
1306 a672b469 aliguori
1307 a672b469 aliguori
    return 0;
1308 a672b469 aliguori
}
1309 a672b469 aliguori
1310 f327aa0c Jan Kiszka
int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
1311 a672b469 aliguori
{
1312 a672b469 aliguori
    SaveStateEntry *se;
1313 a672b469 aliguori
    int ret = 1;
1314 a672b469 aliguori
1315 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1316 a672b469 aliguori
        if (se->save_live_state == NULL)
1317 a672b469 aliguori
            continue;
1318 a672b469 aliguori
1319 a672b469 aliguori
        /* Section type */
1320 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_PART);
1321 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1322 a672b469 aliguori
1323 90697be8 Jan Kiszka
        ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque);
1324 90697be8 Jan Kiszka
        if (!ret) {
1325 90697be8 Jan Kiszka
            /* Do not proceed to the next vmstate before this one reported
1326 90697be8 Jan Kiszka
               completion of the current stage. This serializes the migration
1327 90697be8 Jan Kiszka
               and reduces the probability that a faster changing state is
1328 90697be8 Jan Kiszka
               synchronized over and over again. */
1329 90697be8 Jan Kiszka
            break;
1330 90697be8 Jan Kiszka
        }
1331 a672b469 aliguori
    }
1332 a672b469 aliguori
1333 a672b469 aliguori
    if (ret)
1334 a672b469 aliguori
        return 1;
1335 a672b469 aliguori
1336 4ec7fcc7 Jan Kiszka
    if (qemu_file_has_error(f)) {
1337 f327aa0c Jan Kiszka
        qemu_savevm_state_cancel(mon, f);
1338 a672b469 aliguori
        return -EIO;
1339 4ec7fcc7 Jan Kiszka
    }
1340 a672b469 aliguori
1341 a672b469 aliguori
    return 0;
1342 a672b469 aliguori
}
1343 a672b469 aliguori
1344 f327aa0c Jan Kiszka
int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
1345 a672b469 aliguori
{
1346 a672b469 aliguori
    SaveStateEntry *se;
1347 a672b469 aliguori
1348 ea375f9a Jan Kiszka
    cpu_synchronize_all_states();
1349 ea375f9a Jan Kiszka
1350 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1351 a672b469 aliguori
        if (se->save_live_state == NULL)
1352 a672b469 aliguori
            continue;
1353 a672b469 aliguori
1354 a672b469 aliguori
        /* Section type */
1355 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_END);
1356 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1357 a672b469 aliguori
1358 f327aa0c Jan Kiszka
        se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);
1359 a672b469 aliguori
    }
1360 a672b469 aliguori
1361 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1362 a672b469 aliguori
        int len;
1363 a672b469 aliguori
1364 9ed7d6ae Juan Quintela
        if (se->save_state == NULL && se->vmsd == NULL)
1365 a672b469 aliguori
            continue;
1366 a672b469 aliguori
1367 a672b469 aliguori
        /* Section type */
1368 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
1369 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
1370 a672b469 aliguori
1371 a672b469 aliguori
        /* ID string */
1372 a672b469 aliguori
        len = strlen(se->idstr);
1373 a672b469 aliguori
        qemu_put_byte(f, len);
1374 a672b469 aliguori
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
1375 a672b469 aliguori
1376 a672b469 aliguori
        qemu_put_be32(f, se->instance_id);
1377 a672b469 aliguori
        qemu_put_be32(f, se->version_id);
1378 a672b469 aliguori
1379 4082be4d Juan Quintela
        vmstate_save(f, se);
1380 a672b469 aliguori
    }
1381 a672b469 aliguori
1382 a672b469 aliguori
    qemu_put_byte(f, QEMU_VM_EOF);
1383 a672b469 aliguori
1384 a672b469 aliguori
    if (qemu_file_has_error(f))
1385 a672b469 aliguori
        return -EIO;
1386 a672b469 aliguori
1387 a672b469 aliguori
    return 0;
1388 a672b469 aliguori
}
1389 a672b469 aliguori
1390 f327aa0c Jan Kiszka
void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f)
1391 4ec7fcc7 Jan Kiszka
{
1392 4ec7fcc7 Jan Kiszka
    SaveStateEntry *se;
1393 4ec7fcc7 Jan Kiszka
1394 4ec7fcc7 Jan Kiszka
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1395 4ec7fcc7 Jan Kiszka
        if (se->save_live_state) {
1396 f327aa0c Jan Kiszka
            se->save_live_state(mon, f, -1, se->opaque);
1397 4ec7fcc7 Jan Kiszka
        }
1398 4ec7fcc7 Jan Kiszka
    }
1399 4ec7fcc7 Jan Kiszka
}
1400 4ec7fcc7 Jan Kiszka
1401 f327aa0c Jan Kiszka
static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
1402 a672b469 aliguori
{
1403 a672b469 aliguori
    int saved_vm_running;
1404 a672b469 aliguori
    int ret;
1405 a672b469 aliguori
1406 a672b469 aliguori
    saved_vm_running = vm_running;
1407 a672b469 aliguori
    vm_stop(0);
1408 a672b469 aliguori
1409 a672b469 aliguori
    bdrv_flush_all();
1410 a672b469 aliguori
1411 f327aa0c Jan Kiszka
    ret = qemu_savevm_state_begin(mon, f, 0, 0);
1412 a672b469 aliguori
    if (ret < 0)
1413 a672b469 aliguori
        goto out;
1414 a672b469 aliguori
1415 a672b469 aliguori
    do {
1416 f327aa0c Jan Kiszka
        ret = qemu_savevm_state_iterate(mon, f);
1417 a672b469 aliguori
        if (ret < 0)
1418 a672b469 aliguori
            goto out;
1419 a672b469 aliguori
    } while (ret == 0);
1420 a672b469 aliguori
1421 f327aa0c Jan Kiszka
    ret = qemu_savevm_state_complete(mon, f);
1422 a672b469 aliguori
1423 a672b469 aliguori
out:
1424 a672b469 aliguori
    if (qemu_file_has_error(f))
1425 a672b469 aliguori
        ret = -EIO;
1426 a672b469 aliguori
1427 a672b469 aliguori
    if (!ret && saved_vm_running)
1428 a672b469 aliguori
        vm_start();
1429 a672b469 aliguori
1430 a672b469 aliguori
    return ret;
1431 a672b469 aliguori
}
1432 a672b469 aliguori
1433 a672b469 aliguori
static SaveStateEntry *find_se(const char *idstr, int instance_id)
1434 a672b469 aliguori
{
1435 a672b469 aliguori
    SaveStateEntry *se;
1436 a672b469 aliguori
1437 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1438 a672b469 aliguori
        if (!strcmp(se->idstr, idstr) &&
1439 a672b469 aliguori
            instance_id == se->instance_id)
1440 a672b469 aliguori
            return se;
1441 a672b469 aliguori
    }
1442 a672b469 aliguori
    return NULL;
1443 a672b469 aliguori
}
1444 a672b469 aliguori
1445 a672b469 aliguori
typedef struct LoadStateEntry {
1446 72cf2d4f Blue Swirl
    QLIST_ENTRY(LoadStateEntry) entry;
1447 a672b469 aliguori
    SaveStateEntry *se;
1448 a672b469 aliguori
    int section_id;
1449 a672b469 aliguori
    int version_id;
1450 a672b469 aliguori
} LoadStateEntry;
1451 a672b469 aliguori
1452 a672b469 aliguori
int qemu_loadvm_state(QEMUFile *f)
1453 a672b469 aliguori
{
1454 72cf2d4f Blue Swirl
    QLIST_HEAD(, LoadStateEntry) loadvm_handlers =
1455 72cf2d4f Blue Swirl
        QLIST_HEAD_INITIALIZER(loadvm_handlers);
1456 f4dbb8dd Juan Quintela
    LoadStateEntry *le, *new_le;
1457 a672b469 aliguori
    uint8_t section_type;
1458 a672b469 aliguori
    unsigned int v;
1459 a672b469 aliguori
    int ret;
1460 a672b469 aliguori
1461 a672b469 aliguori
    v = qemu_get_be32(f);
1462 a672b469 aliguori
    if (v != QEMU_VM_FILE_MAGIC)
1463 a672b469 aliguori
        return -EINVAL;
1464 a672b469 aliguori
1465 a672b469 aliguori
    v = qemu_get_be32(f);
1466 bbfe1408 Juan Quintela
    if (v == QEMU_VM_FILE_VERSION_COMPAT) {
1467 bbfe1408 Juan Quintela
        fprintf(stderr, "SaveVM v2 format is obsolete and don't work anymore\n");
1468 bbfe1408 Juan Quintela
        return -ENOTSUP;
1469 bbfe1408 Juan Quintela
    }
1470 a672b469 aliguori
    if (v != QEMU_VM_FILE_VERSION)
1471 a672b469 aliguori
        return -ENOTSUP;
1472 a672b469 aliguori
1473 a672b469 aliguori
    while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
1474 a672b469 aliguori
        uint32_t instance_id, version_id, section_id;
1475 a672b469 aliguori
        SaveStateEntry *se;
1476 a672b469 aliguori
        char idstr[257];
1477 a672b469 aliguori
        int len;
1478 a672b469 aliguori
1479 a672b469 aliguori
        switch (section_type) {
1480 a672b469 aliguori
        case QEMU_VM_SECTION_START:
1481 a672b469 aliguori
        case QEMU_VM_SECTION_FULL:
1482 a672b469 aliguori
            /* Read section start */
1483 a672b469 aliguori
            section_id = qemu_get_be32(f);
1484 a672b469 aliguori
            len = qemu_get_byte(f);
1485 a672b469 aliguori
            qemu_get_buffer(f, (uint8_t *)idstr, len);
1486 a672b469 aliguori
            idstr[len] = 0;
1487 a672b469 aliguori
            instance_id = qemu_get_be32(f);
1488 a672b469 aliguori
            version_id = qemu_get_be32(f);
1489 a672b469 aliguori
1490 a672b469 aliguori
            /* Find savevm section */
1491 a672b469 aliguori
            se = find_se(idstr, instance_id);
1492 a672b469 aliguori
            if (se == NULL) {
1493 a672b469 aliguori
                fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
1494 a672b469 aliguori
                ret = -EINVAL;
1495 a672b469 aliguori
                goto out;
1496 a672b469 aliguori
            }
1497 a672b469 aliguori
1498 a672b469 aliguori
            /* Validate version */
1499 a672b469 aliguori
            if (version_id > se->version_id) {
1500 a672b469 aliguori
                fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
1501 a672b469 aliguori
                        version_id, idstr, se->version_id);
1502 a672b469 aliguori
                ret = -EINVAL;
1503 a672b469 aliguori
                goto out;
1504 a672b469 aliguori
            }
1505 a672b469 aliguori
1506 a672b469 aliguori
            /* Add entry */
1507 a672b469 aliguori
            le = qemu_mallocz(sizeof(*le));
1508 a672b469 aliguori
1509 a672b469 aliguori
            le->se = se;
1510 a672b469 aliguori
            le->section_id = section_id;
1511 a672b469 aliguori
            le->version_id = version_id;
1512 72cf2d4f Blue Swirl
            QLIST_INSERT_HEAD(&loadvm_handlers, le, entry);
1513 a672b469 aliguori
1514 4082be4d Juan Quintela
            ret = vmstate_load(f, le->se, le->version_id);
1515 b5a22e4a Juan Quintela
            if (ret < 0) {
1516 b5a22e4a Juan Quintela
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
1517 b5a22e4a Juan Quintela
                        instance_id, idstr);
1518 b5a22e4a Juan Quintela
                goto out;
1519 b5a22e4a Juan Quintela
            }
1520 a672b469 aliguori
            break;
1521 a672b469 aliguori
        case QEMU_VM_SECTION_PART:
1522 a672b469 aliguori
        case QEMU_VM_SECTION_END:
1523 a672b469 aliguori
            section_id = qemu_get_be32(f);
1524 a672b469 aliguori
1525 72cf2d4f Blue Swirl
            QLIST_FOREACH(le, &loadvm_handlers, entry) {
1526 f4dbb8dd Juan Quintela
                if (le->section_id == section_id) {
1527 f4dbb8dd Juan Quintela
                    break;
1528 f4dbb8dd Juan Quintela
                }
1529 f4dbb8dd Juan Quintela
            }
1530 a672b469 aliguori
            if (le == NULL) {
1531 a672b469 aliguori
                fprintf(stderr, "Unknown savevm section %d\n", section_id);
1532 a672b469 aliguori
                ret = -EINVAL;
1533 a672b469 aliguori
                goto out;
1534 a672b469 aliguori
            }
1535 a672b469 aliguori
1536 4082be4d Juan Quintela
            ret = vmstate_load(f, le->se, le->version_id);
1537 b5a22e4a Juan Quintela
            if (ret < 0) {
1538 b5a22e4a Juan Quintela
                fprintf(stderr, "qemu: warning: error while loading state section id %d\n",
1539 b5a22e4a Juan Quintela
                        section_id);
1540 b5a22e4a Juan Quintela
                goto out;
1541 b5a22e4a Juan Quintela
            }
1542 a672b469 aliguori
            break;
1543 a672b469 aliguori
        default:
1544 a672b469 aliguori
            fprintf(stderr, "Unknown savevm section type %d\n", section_type);
1545 a672b469 aliguori
            ret = -EINVAL;
1546 a672b469 aliguori
            goto out;
1547 a672b469 aliguori
        }
1548 a672b469 aliguori
    }
1549 a672b469 aliguori
1550 ea375f9a Jan Kiszka
    cpu_synchronize_all_post_init();
1551 ea375f9a Jan Kiszka
1552 a672b469 aliguori
    ret = 0;
1553 a672b469 aliguori
1554 a672b469 aliguori
out:
1555 72cf2d4f Blue Swirl
    QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {
1556 72cf2d4f Blue Swirl
        QLIST_REMOVE(le, entry);
1557 a672b469 aliguori
        qemu_free(le);
1558 a672b469 aliguori
    }
1559 a672b469 aliguori
1560 a672b469 aliguori
    if (qemu_file_has_error(f))
1561 a672b469 aliguori
        ret = -EIO;
1562 a672b469 aliguori
1563 a672b469 aliguori
    return ret;
1564 a672b469 aliguori
}
1565 a672b469 aliguori
1566 a672b469 aliguori
/* device can contain snapshots */
1567 a672b469 aliguori
static int bdrv_can_snapshot(BlockDriverState *bs)
1568 a672b469 aliguori
{
1569 a672b469 aliguori
    return (bs &&
1570 a672b469 aliguori
            !bdrv_is_removable(bs) &&
1571 a672b469 aliguori
            !bdrv_is_read_only(bs));
1572 a672b469 aliguori
}
1573 a672b469 aliguori
1574 a672b469 aliguori
/* device must be snapshots in order to have a reliable snapshot */
1575 a672b469 aliguori
static int bdrv_has_snapshot(BlockDriverState *bs)
1576 a672b469 aliguori
{
1577 a672b469 aliguori
    return (bs &&
1578 a672b469 aliguori
            !bdrv_is_removable(bs) &&
1579 a672b469 aliguori
            !bdrv_is_read_only(bs));
1580 a672b469 aliguori
}
1581 a672b469 aliguori
1582 a672b469 aliguori
static BlockDriverState *get_bs_snapshots(void)
1583 a672b469 aliguori
{
1584 a672b469 aliguori
    BlockDriverState *bs;
1585 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1586 a672b469 aliguori
1587 a672b469 aliguori
    if (bs_snapshots)
1588 a672b469 aliguori
        return bs_snapshots;
1589 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1590 751c6a17 Gerd Hoffmann
        bs = dinfo->bdrv;
1591 a672b469 aliguori
        if (bdrv_can_snapshot(bs))
1592 a672b469 aliguori
            goto ok;
1593 a672b469 aliguori
    }
1594 a672b469 aliguori
    return NULL;
1595 a672b469 aliguori
 ok:
1596 a672b469 aliguori
    bs_snapshots = bs;
1597 a672b469 aliguori
    return bs;
1598 a672b469 aliguori
}
1599 a672b469 aliguori
1600 a672b469 aliguori
static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
1601 a672b469 aliguori
                              const char *name)
1602 a672b469 aliguori
{
1603 a672b469 aliguori
    QEMUSnapshotInfo *sn_tab, *sn;
1604 a672b469 aliguori
    int nb_sns, i, ret;
1605 a672b469 aliguori
1606 a672b469 aliguori
    ret = -ENOENT;
1607 a672b469 aliguori
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1608 a672b469 aliguori
    if (nb_sns < 0)
1609 a672b469 aliguori
        return ret;
1610 a672b469 aliguori
    for(i = 0; i < nb_sns; i++) {
1611 a672b469 aliguori
        sn = &sn_tab[i];
1612 a672b469 aliguori
        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
1613 a672b469 aliguori
            *sn_info = *sn;
1614 a672b469 aliguori
            ret = 0;
1615 a672b469 aliguori
            break;
1616 a672b469 aliguori
        }
1617 a672b469 aliguori
    }
1618 a672b469 aliguori
    qemu_free(sn_tab);
1619 a672b469 aliguori
    return ret;
1620 a672b469 aliguori
}
1621 a672b469 aliguori
1622 cb499fb2 Kevin Wolf
/*
1623 cb499fb2 Kevin Wolf
 * Deletes snapshots of a given name in all opened images.
1624 cb499fb2 Kevin Wolf
 */
1625 cb499fb2 Kevin Wolf
static int del_existing_snapshots(Monitor *mon, const char *name)
1626 cb499fb2 Kevin Wolf
{
1627 cb499fb2 Kevin Wolf
    BlockDriverState *bs;
1628 cb499fb2 Kevin Wolf
    DriveInfo *dinfo;
1629 cb499fb2 Kevin Wolf
    QEMUSnapshotInfo sn1, *snapshot = &sn1;
1630 cb499fb2 Kevin Wolf
    int ret;
1631 cb499fb2 Kevin Wolf
1632 cb499fb2 Kevin Wolf
    QTAILQ_FOREACH(dinfo, &drives, next) {
1633 cb499fb2 Kevin Wolf
        bs = dinfo->bdrv;
1634 cb499fb2 Kevin Wolf
        if (bdrv_can_snapshot(bs) &&
1635 cb499fb2 Kevin Wolf
            bdrv_snapshot_find(bs, snapshot, name) >= 0)
1636 cb499fb2 Kevin Wolf
        {
1637 cb499fb2 Kevin Wolf
            ret = bdrv_snapshot_delete(bs, name);
1638 cb499fb2 Kevin Wolf
            if (ret < 0) {
1639 cb499fb2 Kevin Wolf
                monitor_printf(mon,
1640 cb499fb2 Kevin Wolf
                               "Error while deleting snapshot on '%s'\n",
1641 cb499fb2 Kevin Wolf
                               bdrv_get_device_name(bs));
1642 cb499fb2 Kevin Wolf
                return -1;
1643 cb499fb2 Kevin Wolf
            }
1644 cb499fb2 Kevin Wolf
        }
1645 cb499fb2 Kevin Wolf
    }
1646 cb499fb2 Kevin Wolf
1647 cb499fb2 Kevin Wolf
    return 0;
1648 cb499fb2 Kevin Wolf
}
1649 cb499fb2 Kevin Wolf
1650 d54908a5 Luiz Capitulino
void do_savevm(Monitor *mon, const QDict *qdict)
1651 a672b469 aliguori
{
1652 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1653 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1654 a672b469 aliguori
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
1655 cb499fb2 Kevin Wolf
    int ret;
1656 a672b469 aliguori
    QEMUFile *f;
1657 a672b469 aliguori
    int saved_vm_running;
1658 2d22b18f aliguori
    uint32_t vm_state_size;
1659 a672b469 aliguori
#ifdef _WIN32
1660 a672b469 aliguori
    struct _timeb tb;
1661 a672b469 aliguori
#else
1662 a672b469 aliguori
    struct timeval tv;
1663 a672b469 aliguori
#endif
1664 d54908a5 Luiz Capitulino
    const char *name = qdict_get_try_str(qdict, "name");
1665 a672b469 aliguori
1666 a672b469 aliguori
    bs = get_bs_snapshots();
1667 a672b469 aliguori
    if (!bs) {
1668 376253ec aliguori
        monitor_printf(mon, "No block device can accept snapshots\n");
1669 a672b469 aliguori
        return;
1670 a672b469 aliguori
    }
1671 a672b469 aliguori
1672 a672b469 aliguori
    /* ??? Should this occur after vm_stop?  */
1673 a672b469 aliguori
    qemu_aio_flush();
1674 a672b469 aliguori
1675 a672b469 aliguori
    saved_vm_running = vm_running;
1676 a672b469 aliguori
    vm_stop(0);
1677 a672b469 aliguori
1678 cb499fb2 Kevin Wolf
    memset(sn, 0, sizeof(*sn));
1679 a672b469 aliguori
    if (name) {
1680 a672b469 aliguori
        ret = bdrv_snapshot_find(bs, old_sn, name);
1681 a672b469 aliguori
        if (ret >= 0) {
1682 cb499fb2 Kevin Wolf
            pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
1683 cb499fb2 Kevin Wolf
            pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
1684 cb499fb2 Kevin Wolf
        } else {
1685 a672b469 aliguori
            pstrcpy(sn->name, sizeof(sn->name), name);
1686 cb499fb2 Kevin Wolf
        }
1687 a672b469 aliguori
    }
1688 a672b469 aliguori
1689 a672b469 aliguori
    /* fill auxiliary fields */
1690 a672b469 aliguori
#ifdef _WIN32
1691 a672b469 aliguori
    _ftime(&tb);
1692 a672b469 aliguori
    sn->date_sec = tb.time;
1693 a672b469 aliguori
    sn->date_nsec = tb.millitm * 1000000;
1694 a672b469 aliguori
#else
1695 a672b469 aliguori
    gettimeofday(&tv, NULL);
1696 a672b469 aliguori
    sn->date_sec = tv.tv_sec;
1697 a672b469 aliguori
    sn->date_nsec = tv.tv_usec * 1000;
1698 a672b469 aliguori
#endif
1699 a672b469 aliguori
    sn->vm_clock_nsec = qemu_get_clock(vm_clock);
1700 a672b469 aliguori
1701 cb499fb2 Kevin Wolf
    /* Delete old snapshots of the same name */
1702 f139a412 Marcelo Tosatti
    if (name && del_existing_snapshots(mon, name) < 0) {
1703 cb499fb2 Kevin Wolf
        goto the_end;
1704 cb499fb2 Kevin Wolf
    }
1705 cb499fb2 Kevin Wolf
1706 a672b469 aliguori
    /* save the VM state */
1707 45566e9c Christoph Hellwig
    f = qemu_fopen_bdrv(bs, 1);
1708 a672b469 aliguori
    if (!f) {
1709 376253ec aliguori
        monitor_printf(mon, "Could not open VM state file\n");
1710 a672b469 aliguori
        goto the_end;
1711 a672b469 aliguori
    }
1712 f327aa0c Jan Kiszka
    ret = qemu_savevm_state(mon, f);
1713 2d22b18f aliguori
    vm_state_size = qemu_ftell(f);
1714 a672b469 aliguori
    qemu_fclose(f);
1715 a672b469 aliguori
    if (ret < 0) {
1716 376253ec aliguori
        monitor_printf(mon, "Error %d while writing VM\n", ret);
1717 a672b469 aliguori
        goto the_end;
1718 a672b469 aliguori
    }
1719 a672b469 aliguori
1720 a672b469 aliguori
    /* create the snapshots */
1721 a672b469 aliguori
1722 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1723 751c6a17 Gerd Hoffmann
        bs1 = dinfo->bdrv;
1724 a672b469 aliguori
        if (bdrv_has_snapshot(bs1)) {
1725 2d22b18f aliguori
            /* Write VM state size only to the image that contains the state */
1726 2d22b18f aliguori
            sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
1727 a672b469 aliguori
            ret = bdrv_snapshot_create(bs1, sn);
1728 a672b469 aliguori
            if (ret < 0) {
1729 376253ec aliguori
                monitor_printf(mon, "Error while creating snapshot on '%s'\n",
1730 376253ec aliguori
                               bdrv_get_device_name(bs1));
1731 a672b469 aliguori
            }
1732 a672b469 aliguori
        }
1733 a672b469 aliguori
    }
1734 a672b469 aliguori
1735 a672b469 aliguori
 the_end:
1736 a672b469 aliguori
    if (saved_vm_running)
1737 a672b469 aliguori
        vm_start();
1738 a672b469 aliguori
}
1739 a672b469 aliguori
1740 05f2401e Juan Quintela
int load_vmstate(Monitor *mon, const char *name)
1741 a672b469 aliguori
{
1742 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1743 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1744 2d22b18f aliguori
    QEMUSnapshotInfo sn;
1745 a672b469 aliguori
    QEMUFile *f;
1746 751c6a17 Gerd Hoffmann
    int ret;
1747 a672b469 aliguori
1748 a672b469 aliguori
    bs = get_bs_snapshots();
1749 a672b469 aliguori
    if (!bs) {
1750 376253ec aliguori
        monitor_printf(mon, "No block device supports snapshots\n");
1751 05f2401e Juan Quintela
        return -EINVAL;
1752 a672b469 aliguori
    }
1753 a672b469 aliguori
1754 a672b469 aliguori
    /* Flush all IO requests so they don't interfere with the new state.  */
1755 a672b469 aliguori
    qemu_aio_flush();
1756 a672b469 aliguori
1757 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1758 751c6a17 Gerd Hoffmann
        bs1 = dinfo->bdrv;
1759 a672b469 aliguori
        if (bdrv_has_snapshot(bs1)) {
1760 a672b469 aliguori
            ret = bdrv_snapshot_goto(bs1, name);
1761 a672b469 aliguori
            if (ret < 0) {
1762 a672b469 aliguori
                if (bs != bs1)
1763 376253ec aliguori
                    monitor_printf(mon, "Warning: ");
1764 a672b469 aliguori
                switch(ret) {
1765 a672b469 aliguori
                case -ENOTSUP:
1766 376253ec aliguori
                    monitor_printf(mon,
1767 376253ec aliguori
                                   "Snapshots not supported on device '%s'\n",
1768 376253ec aliguori
                                   bdrv_get_device_name(bs1));
1769 a672b469 aliguori
                    break;
1770 a672b469 aliguori
                case -ENOENT:
1771 376253ec aliguori
                    monitor_printf(mon, "Could not find snapshot '%s' on "
1772 376253ec aliguori
                                   "device '%s'\n",
1773 376253ec aliguori
                                   name, bdrv_get_device_name(bs1));
1774 a672b469 aliguori
                    break;
1775 a672b469 aliguori
                default:
1776 376253ec aliguori
                    monitor_printf(mon, "Error %d while activating snapshot on"
1777 376253ec aliguori
                                   " '%s'\n", ret, bdrv_get_device_name(bs1));
1778 a672b469 aliguori
                    break;
1779 a672b469 aliguori
                }
1780 a672b469 aliguori
                /* fatal on snapshot block device */
1781 a672b469 aliguori
                if (bs == bs1)
1782 05f2401e Juan Quintela
                    return 0;
1783 a672b469 aliguori
            }
1784 a672b469 aliguori
        }
1785 a672b469 aliguori
    }
1786 a672b469 aliguori
1787 2d22b18f aliguori
    /* Don't even try to load empty VM states */
1788 2d22b18f aliguori
    ret = bdrv_snapshot_find(bs, &sn, name);
1789 2d22b18f aliguori
    if ((ret >= 0) && (sn.vm_state_size == 0))
1790 05f2401e Juan Quintela
        return -EINVAL;
1791 2d22b18f aliguori
1792 a672b469 aliguori
    /* restore the VM state */
1793 45566e9c Christoph Hellwig
    f = qemu_fopen_bdrv(bs, 0);
1794 a672b469 aliguori
    if (!f) {
1795 376253ec aliguori
        monitor_printf(mon, "Could not open VM state file\n");
1796 05f2401e Juan Quintela
        return -EINVAL;
1797 a672b469 aliguori
    }
1798 a672b469 aliguori
    ret = qemu_loadvm_state(f);
1799 a672b469 aliguori
    qemu_fclose(f);
1800 a672b469 aliguori
    if (ret < 0) {
1801 376253ec aliguori
        monitor_printf(mon, "Error %d while loading VM state\n", ret);
1802 05f2401e Juan Quintela
        return ret;
1803 a672b469 aliguori
    }
1804 05f2401e Juan Quintela
    return 0;
1805 7b630349 Juan Quintela
}
1806 7b630349 Juan Quintela
1807 d54908a5 Luiz Capitulino
void do_delvm(Monitor *mon, const QDict *qdict)
1808 a672b469 aliguori
{
1809 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1810 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1811 751c6a17 Gerd Hoffmann
    int ret;
1812 d54908a5 Luiz Capitulino
    const char *name = qdict_get_str(qdict, "name");
1813 a672b469 aliguori
1814 a672b469 aliguori
    bs = get_bs_snapshots();
1815 a672b469 aliguori
    if (!bs) {
1816 376253ec aliguori
        monitor_printf(mon, "No block device supports snapshots\n");
1817 a672b469 aliguori
        return;
1818 a672b469 aliguori
    }
1819 a672b469 aliguori
1820 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1821 751c6a17 Gerd Hoffmann
        bs1 = dinfo->bdrv;
1822 a672b469 aliguori
        if (bdrv_has_snapshot(bs1)) {
1823 a672b469 aliguori
            ret = bdrv_snapshot_delete(bs1, name);
1824 a672b469 aliguori
            if (ret < 0) {
1825 a672b469 aliguori
                if (ret == -ENOTSUP)
1826 376253ec aliguori
                    monitor_printf(mon,
1827 376253ec aliguori
                                   "Snapshots not supported on device '%s'\n",
1828 376253ec aliguori
                                   bdrv_get_device_name(bs1));
1829 a672b469 aliguori
                else
1830 376253ec aliguori
                    monitor_printf(mon, "Error %d while deleting snapshot on "
1831 376253ec aliguori
                                   "'%s'\n", ret, bdrv_get_device_name(bs1));
1832 a672b469 aliguori
            }
1833 a672b469 aliguori
        }
1834 a672b469 aliguori
    }
1835 a672b469 aliguori
}
1836 a672b469 aliguori
1837 376253ec aliguori
void do_info_snapshots(Monitor *mon)
1838 a672b469 aliguori
{
1839 751c6a17 Gerd Hoffmann
    DriveInfo *dinfo;
1840 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1841 a672b469 aliguori
    QEMUSnapshotInfo *sn_tab, *sn;
1842 a672b469 aliguori
    int nb_sns, i;
1843 a672b469 aliguori
    char buf[256];
1844 a672b469 aliguori
1845 a672b469 aliguori
    bs = get_bs_snapshots();
1846 a672b469 aliguori
    if (!bs) {
1847 376253ec aliguori
        monitor_printf(mon, "No available block device supports snapshots\n");
1848 a672b469 aliguori
        return;
1849 a672b469 aliguori
    }
1850 376253ec aliguori
    monitor_printf(mon, "Snapshot devices:");
1851 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(dinfo, &drives, next) {
1852 751c6a17 Gerd Hoffmann
        bs1 = dinfo->bdrv;
1853 a672b469 aliguori
        if (bdrv_has_snapshot(bs1)) {
1854 a672b469 aliguori
            if (bs == bs1)
1855 376253ec aliguori
                monitor_printf(mon, " %s", bdrv_get_device_name(bs1));
1856 a672b469 aliguori
        }
1857 a672b469 aliguori
    }
1858 376253ec aliguori
    monitor_printf(mon, "\n");
1859 a672b469 aliguori
1860 a672b469 aliguori
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1861 a672b469 aliguori
    if (nb_sns < 0) {
1862 376253ec aliguori
        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
1863 a672b469 aliguori
        return;
1864 a672b469 aliguori
    }
1865 376253ec aliguori
    monitor_printf(mon, "Snapshot list (from %s):\n",
1866 376253ec aliguori
                   bdrv_get_device_name(bs));
1867 376253ec aliguori
    monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1868 a672b469 aliguori
    for(i = 0; i < nb_sns; i++) {
1869 a672b469 aliguori
        sn = &sn_tab[i];
1870 376253ec aliguori
        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1871 a672b469 aliguori
    }
1872 a672b469 aliguori
    qemu_free(sn_tab);
1873 a672b469 aliguori
}