Statistics
| Branch: | Revision:

root / savevm.c @ 6181ec24

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