Statistics
| Branch: | Revision:

root / savevm.c @ 8cfd0495

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