Statistics
| Branch: | Revision:

root / savevm.c @ 0389ced4

History | View | Annotate | Download (53.3 kB)

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