Statistics
| Branch: | Revision:

root / savevm.c @ 640e5404

History | View | Annotate | Download (54.6 kB)

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