Statistics
| Branch: | Revision:

root / savevm.c @ feature-archipelago

History | View | Annotate | Download (32.5 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 28085f7b Orit Wasserman
#include "qemu/iov.h"
42 de08c606 Wenchao Xia
#include "block/snapshot.h"
43 f364ec65 Wenchao Xia
#include "block/qapi.h"
44 511d2b14 blueswir1
45 a672b469 aliguori
#define SELF_ANNOUNCE_ROUNDS 5
46 a672b469 aliguori
47 18995b98 Nolan
#ifndef ETH_P_RARP
48 f8778a77 Stefan Berger
#define ETH_P_RARP 0x8035
49 18995b98 Nolan
#endif
50 18995b98 Nolan
#define ARP_HTYPE_ETH 0x0001
51 18995b98 Nolan
#define ARP_PTYPE_IP 0x0800
52 18995b98 Nolan
#define ARP_OP_REQUEST_REV 0x3
53 18995b98 Nolan
54 18995b98 Nolan
static int announce_self_create(uint8_t *buf,
55 5cecf414 Eduardo Habkost
                                uint8_t *mac_addr)
56 a672b469 aliguori
{
57 18995b98 Nolan
    /* Ethernet header. */
58 18995b98 Nolan
    memset(buf, 0xff, 6);         /* destination MAC addr */
59 18995b98 Nolan
    memcpy(buf + 6, mac_addr, 6); /* source MAC addr */
60 18995b98 Nolan
    *(uint16_t *)(buf + 12) = htons(ETH_P_RARP); /* ethertype */
61 18995b98 Nolan
62 18995b98 Nolan
    /* RARP header. */
63 18995b98 Nolan
    *(uint16_t *)(buf + 14) = htons(ARP_HTYPE_ETH); /* hardware addr space */
64 18995b98 Nolan
    *(uint16_t *)(buf + 16) = htons(ARP_PTYPE_IP); /* protocol addr space */
65 18995b98 Nolan
    *(buf + 18) = 6; /* hardware addr length (ethernet) */
66 18995b98 Nolan
    *(buf + 19) = 4; /* protocol addr length (IPv4) */
67 18995b98 Nolan
    *(uint16_t *)(buf + 20) = htons(ARP_OP_REQUEST_REV); /* opcode */
68 18995b98 Nolan
    memcpy(buf + 22, mac_addr, 6); /* source hw addr */
69 18995b98 Nolan
    memset(buf + 28, 0x00, 4);     /* source protocol addr */
70 18995b98 Nolan
    memcpy(buf + 32, mac_addr, 6); /* target hw addr */
71 18995b98 Nolan
    memset(buf + 38, 0x00, 4);     /* target protocol addr */
72 18995b98 Nolan
73 18995b98 Nolan
    /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
74 18995b98 Nolan
    memset(buf + 42, 0x00, 18);
75 18995b98 Nolan
76 18995b98 Nolan
    return 60; /* len (FCS will be added by hardware) */
77 a672b469 aliguori
}
78 a672b469 aliguori
79 f401ca22 Mark McLoughlin
static void qemu_announce_self_iter(NICState *nic, void *opaque)
80 a672b469 aliguori
{
81 18995b98 Nolan
    uint8_t buf[60];
82 f401ca22 Mark McLoughlin
    int len;
83 f401ca22 Mark McLoughlin
84 f401ca22 Mark McLoughlin
    len = announce_self_create(buf, nic->conf->macaddr.a);
85 f401ca22 Mark McLoughlin
86 b356f76d Jason Wang
    qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
87 f401ca22 Mark McLoughlin
}
88 f401ca22 Mark McLoughlin
89 f401ca22 Mark McLoughlin
90 f401ca22 Mark McLoughlin
static void qemu_announce_self_once(void *opaque)
91 f401ca22 Mark McLoughlin
{
92 ed8b330b Gleb Natapov
    static int count = SELF_ANNOUNCE_ROUNDS;
93 ed8b330b Gleb Natapov
    QEMUTimer *timer = *(QEMUTimer **)opaque;
94 a672b469 aliguori
95 f401ca22 Mark McLoughlin
    qemu_foreach_nic(qemu_announce_self_iter, NULL);
96 f401ca22 Mark McLoughlin
97 18995b98 Nolan
    if (--count) {
98 18995b98 Nolan
        /* delay 50ms, 150ms, 250ms, ... */
99 bc72ad67 Alex Bligh
        timer_mod(timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) +
100 18995b98 Nolan
                       50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);
101 ed8b330b Gleb Natapov
    } else {
102 5cecf414 Eduardo Habkost
            timer_del(timer);
103 5cecf414 Eduardo Habkost
            timer_free(timer);
104 ed8b330b Gleb Natapov
    }
105 ed8b330b Gleb Natapov
}
106 ed8b330b Gleb Natapov
107 ed8b330b Gleb Natapov
void qemu_announce_self(void)
108 ed8b330b Gleb Natapov
{
109 5cecf414 Eduardo Habkost
    static QEMUTimer *timer;
110 5cecf414 Eduardo Habkost
    timer = timer_new_ms(QEMU_CLOCK_REALTIME, qemu_announce_self_once, &timer);
111 5cecf414 Eduardo Habkost
    qemu_announce_self_once(&timer);
112 a672b469 aliguori
}
113 a672b469 aliguori
114 a672b469 aliguori
/***********************************************************/
115 a672b469 aliguori
/* savevm/loadvm support */
116 a672b469 aliguori
117 05fcc848 Kevin Wolf
static ssize_t block_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
118 05fcc848 Kevin Wolf
                                   int64_t pos)
119 05fcc848 Kevin Wolf
{
120 05fcc848 Kevin Wolf
    int ret;
121 05fcc848 Kevin Wolf
    QEMUIOVector qiov;
122 05fcc848 Kevin Wolf
123 05fcc848 Kevin Wolf
    qemu_iovec_init_external(&qiov, iov, iovcnt);
124 05fcc848 Kevin Wolf
    ret = bdrv_writev_vmstate(opaque, &qiov, pos);
125 05fcc848 Kevin Wolf
    if (ret < 0) {
126 05fcc848 Kevin Wolf
        return ret;
127 05fcc848 Kevin Wolf
    }
128 05fcc848 Kevin Wolf
129 05fcc848 Kevin Wolf
    return qiov.size;
130 05fcc848 Kevin Wolf
}
131 05fcc848 Kevin Wolf
132 178e08a5 aliguori
static int block_put_buffer(void *opaque, const uint8_t *buf,
133 a672b469 aliguori
                           int64_t pos, int size)
134 a672b469 aliguori
{
135 45566e9c Christoph Hellwig
    bdrv_save_vmstate(opaque, buf, pos, size);
136 a672b469 aliguori
    return size;
137 a672b469 aliguori
}
138 a672b469 aliguori
139 178e08a5 aliguori
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
140 a672b469 aliguori
{
141 45566e9c Christoph Hellwig
    return bdrv_load_vmstate(opaque, buf, pos, size);
142 a672b469 aliguori
}
143 a672b469 aliguori
144 a672b469 aliguori
static int bdrv_fclose(void *opaque)
145 a672b469 aliguori
{
146 ad492c92 Paolo Bonzini
    return bdrv_flush(opaque);
147 a672b469 aliguori
}
148 a672b469 aliguori
149 9229bf3c Paolo Bonzini
static const QEMUFileOps bdrv_read_ops = {
150 9229bf3c Paolo Bonzini
    .get_buffer = block_get_buffer,
151 9229bf3c Paolo Bonzini
    .close =      bdrv_fclose
152 9229bf3c Paolo Bonzini
};
153 9229bf3c Paolo Bonzini
154 9229bf3c Paolo Bonzini
static const QEMUFileOps bdrv_write_ops = {
155 05fcc848 Kevin Wolf
    .put_buffer     = block_put_buffer,
156 05fcc848 Kevin Wolf
    .writev_buffer  = block_writev_buffer,
157 05fcc848 Kevin Wolf
    .close          = bdrv_fclose
158 9229bf3c Paolo Bonzini
};
159 9229bf3c Paolo Bonzini
160 45566e9c Christoph Hellwig
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
161 a672b469 aliguori
{
162 38ff78d3 Eduardo Habkost
    if (is_writable) {
163 9229bf3c Paolo Bonzini
        return qemu_fopen_ops(bs, &bdrv_write_ops);
164 38ff78d3 Eduardo Habkost
    }
165 9229bf3c Paolo Bonzini
    return qemu_fopen_ops(bs, &bdrv_read_ops);
166 a672b469 aliguori
}
167 a672b469 aliguori
168 2ff68d07 Paolo Bonzini
169 bb1a6d8c Eduardo Habkost
/* QEMUFile timer support.
170 bb1a6d8c Eduardo Habkost
 * Not in qemu-file.c to not add qemu-timer.c as dependency to qemu-file.c
171 bb1a6d8c Eduardo Habkost
 */
172 2ff68d07 Paolo Bonzini
173 40daca54 Alex Bligh
void timer_put(QEMUFile *f, QEMUTimer *ts)
174 2ff68d07 Paolo Bonzini
{
175 2ff68d07 Paolo Bonzini
    uint64_t expire_time;
176 2ff68d07 Paolo Bonzini
177 e93379b0 Alex Bligh
    expire_time = timer_expire_time_ns(ts);
178 2ff68d07 Paolo Bonzini
    qemu_put_be64(f, expire_time);
179 2ff68d07 Paolo Bonzini
}
180 2ff68d07 Paolo Bonzini
181 40daca54 Alex Bligh
void timer_get(QEMUFile *f, QEMUTimer *ts)
182 2ff68d07 Paolo Bonzini
{
183 2ff68d07 Paolo Bonzini
    uint64_t expire_time;
184 2ff68d07 Paolo Bonzini
185 2ff68d07 Paolo Bonzini
    expire_time = qemu_get_be64(f);
186 2ff68d07 Paolo Bonzini
    if (expire_time != -1) {
187 bc72ad67 Alex Bligh
        timer_mod_ns(ts, expire_time);
188 2ff68d07 Paolo Bonzini
    } else {
189 bc72ad67 Alex Bligh
        timer_del(ts);
190 2ff68d07 Paolo Bonzini
    }
191 2ff68d07 Paolo Bonzini
}
192 2ff68d07 Paolo Bonzini
193 2ff68d07 Paolo Bonzini
194 bb1a6d8c Eduardo Habkost
/* VMState timer support.
195 bb1a6d8c Eduardo Habkost
 * Not in vmstate.c to not add qemu-timer.c as dependency to vmstate.c
196 bb1a6d8c Eduardo Habkost
 */
197 dde0463b Juan Quintela
198 dde0463b Juan Quintela
static int get_timer(QEMUFile *f, void *pv, size_t size)
199 dde0463b Juan Quintela
{
200 dde0463b Juan Quintela
    QEMUTimer *v = pv;
201 40daca54 Alex Bligh
    timer_get(f, v);
202 dde0463b Juan Quintela
    return 0;
203 dde0463b Juan Quintela
}
204 dde0463b Juan Quintela
205 84e2e3eb Juan Quintela
static void put_timer(QEMUFile *f, void *pv, size_t size)
206 dde0463b Juan Quintela
{
207 84e2e3eb Juan Quintela
    QEMUTimer *v = pv;
208 40daca54 Alex Bligh
    timer_put(f, v);
209 dde0463b Juan Quintela
}
210 dde0463b Juan Quintela
211 dde0463b Juan Quintela
const VMStateInfo vmstate_info_timer = {
212 dde0463b Juan Quintela
    .name = "timer",
213 dde0463b Juan Quintela
    .get  = get_timer,
214 dde0463b Juan Quintela
    .put  = put_timer,
215 dde0463b Juan Quintela
};
216 dde0463b Juan Quintela
217 08e99e29 Peter Maydell
218 7685ee6a Alex Williamson
typedef struct CompatEntry {
219 7685ee6a Alex Williamson
    char idstr[256];
220 7685ee6a Alex Williamson
    int instance_id;
221 7685ee6a Alex Williamson
} CompatEntry;
222 7685ee6a Alex Williamson
223 a672b469 aliguori
typedef struct SaveStateEntry {
224 72cf2d4f Blue Swirl
    QTAILQ_ENTRY(SaveStateEntry) entry;
225 a672b469 aliguori
    char idstr[256];
226 a672b469 aliguori
    int instance_id;
227 4d2ffa08 Jan Kiszka
    int alias_id;
228 a672b469 aliguori
    int version_id;
229 a672b469 aliguori
    int section_id;
230 22ea40f4 Juan Quintela
    SaveVMHandlers *ops;
231 9ed7d6ae Juan Quintela
    const VMStateDescription *vmsd;
232 a672b469 aliguori
    void *opaque;
233 7685ee6a Alex Williamson
    CompatEntry *compat;
234 24312968 Cam Macdonell
    int no_migrate;
235 a7ae8355 Stefano Stabellini
    int is_ram;
236 a672b469 aliguori
} SaveStateEntry;
237 a672b469 aliguori
238 c163b5ca lirans@il.ibm.com
239 72cf2d4f Blue Swirl
static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers =
240 72cf2d4f Blue Swirl
    QTAILQ_HEAD_INITIALIZER(savevm_handlers);
241 9ed7d6ae Juan Quintela
static int global_section_id;
242 a672b469 aliguori
243 8718e999 Juan Quintela
static int calculate_new_instance_id(const char *idstr)
244 8718e999 Juan Quintela
{
245 8718e999 Juan Quintela
    SaveStateEntry *se;
246 8718e999 Juan Quintela
    int instance_id = 0;
247 8718e999 Juan Quintela
248 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
249 8718e999 Juan Quintela
        if (strcmp(idstr, se->idstr) == 0
250 8718e999 Juan Quintela
            && instance_id <= se->instance_id) {
251 8718e999 Juan Quintela
            instance_id = se->instance_id + 1;
252 8718e999 Juan Quintela
        }
253 8718e999 Juan Quintela
    }
254 8718e999 Juan Quintela
    return instance_id;
255 8718e999 Juan Quintela
}
256 8718e999 Juan Quintela
257 7685ee6a Alex Williamson
static int calculate_compat_instance_id(const char *idstr)
258 7685ee6a Alex Williamson
{
259 7685ee6a Alex Williamson
    SaveStateEntry *se;
260 7685ee6a Alex Williamson
    int instance_id = 0;
261 7685ee6a Alex Williamson
262 7685ee6a Alex Williamson
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
263 38ff78d3 Eduardo Habkost
        if (!se->compat) {
264 7685ee6a Alex Williamson
            continue;
265 38ff78d3 Eduardo Habkost
        }
266 7685ee6a Alex Williamson
267 7685ee6a Alex Williamson
        if (strcmp(idstr, se->compat->idstr) == 0
268 7685ee6a Alex Williamson
            && instance_id <= se->compat->instance_id) {
269 7685ee6a Alex Williamson
            instance_id = se->compat->instance_id + 1;
270 7685ee6a Alex Williamson
        }
271 7685ee6a Alex Williamson
    }
272 7685ee6a Alex Williamson
    return instance_id;
273 7685ee6a Alex Williamson
}
274 7685ee6a Alex Williamson
275 a672b469 aliguori
/* TODO: Individual devices generally have very little idea about the rest
276 a672b469 aliguori
   of the system, so instance_id should be removed/replaced.
277 a672b469 aliguori
   Meanwhile pass -1 as instance_id if you do not already have a clearly
278 a672b469 aliguori
   distinguishing id for all instances of your device class. */
279 0be71e32 Alex Williamson
int register_savevm_live(DeviceState *dev,
280 0be71e32 Alex Williamson
                         const char *idstr,
281 a672b469 aliguori
                         int instance_id,
282 a672b469 aliguori
                         int version_id,
283 7908c78d Juan Quintela
                         SaveVMHandlers *ops,
284 a672b469 aliguori
                         void *opaque)
285 a672b469 aliguori
{
286 8718e999 Juan Quintela
    SaveStateEntry *se;
287 a672b469 aliguori
288 7267c094 Anthony Liguori
    se = g_malloc0(sizeof(SaveStateEntry));
289 a672b469 aliguori
    se->version_id = version_id;
290 a672b469 aliguori
    se->section_id = global_section_id++;
291 7908c78d Juan Quintela
    se->ops = ops;
292 a672b469 aliguori
    se->opaque = opaque;
293 9ed7d6ae Juan Quintela
    se->vmsd = NULL;
294 24312968 Cam Macdonell
    se->no_migrate = 0;
295 a7ae8355 Stefano Stabellini
    /* if this is a live_savem then set is_ram */
296 16310a3c Juan Quintela
    if (ops->save_live_setup != NULL) {
297 a7ae8355 Stefano Stabellini
        se->is_ram = 1;
298 a7ae8355 Stefano Stabellini
    }
299 a672b469 aliguori
300 09e5ab63 Anthony Liguori
    if (dev) {
301 09e5ab63 Anthony Liguori
        char *id = qdev_get_dev_path(dev);
302 7685ee6a Alex Williamson
        if (id) {
303 7685ee6a Alex Williamson
            pstrcpy(se->idstr, sizeof(se->idstr), id);
304 7685ee6a Alex Williamson
            pstrcat(se->idstr, sizeof(se->idstr), "/");
305 7267c094 Anthony Liguori
            g_free(id);
306 7685ee6a Alex Williamson
307 7267c094 Anthony Liguori
            se->compat = g_malloc0(sizeof(CompatEntry));
308 7685ee6a Alex Williamson
            pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), idstr);
309 7685ee6a Alex Williamson
            se->compat->instance_id = instance_id == -1 ?
310 7685ee6a Alex Williamson
                         calculate_compat_instance_id(idstr) : instance_id;
311 7685ee6a Alex Williamson
            instance_id = -1;
312 7685ee6a Alex Williamson
        }
313 7685ee6a Alex Williamson
    }
314 7685ee6a Alex Williamson
    pstrcat(se->idstr, sizeof(se->idstr), idstr);
315 7685ee6a Alex Williamson
316 8718e999 Juan Quintela
    if (instance_id == -1) {
317 7685ee6a Alex Williamson
        se->instance_id = calculate_new_instance_id(se->idstr);
318 8718e999 Juan Quintela
    } else {
319 8718e999 Juan Quintela
        se->instance_id = instance_id;
320 a672b469 aliguori
    }
321 7685ee6a Alex Williamson
    assert(!se->compat || se->instance_id == 0);
322 8718e999 Juan Quintela
    /* add at the end of list */
323 72cf2d4f Blue Swirl
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
324 a672b469 aliguori
    return 0;
325 a672b469 aliguori
}
326 a672b469 aliguori
327 0be71e32 Alex Williamson
int register_savevm(DeviceState *dev,
328 0be71e32 Alex Williamson
                    const char *idstr,
329 a672b469 aliguori
                    int instance_id,
330 a672b469 aliguori
                    int version_id,
331 a672b469 aliguori
                    SaveStateHandler *save_state,
332 a672b469 aliguori
                    LoadStateHandler *load_state,
333 a672b469 aliguori
                    void *opaque)
334 a672b469 aliguori
{
335 7908c78d Juan Quintela
    SaveVMHandlers *ops = g_malloc0(sizeof(SaveVMHandlers));
336 7908c78d Juan Quintela
    ops->save_state = save_state;
337 7908c78d Juan Quintela
    ops->load_state = load_state;
338 0be71e32 Alex Williamson
    return register_savevm_live(dev, idstr, instance_id, version_id,
339 7908c78d Juan Quintela
                                ops, opaque);
340 a672b469 aliguori
}
341 a672b469 aliguori
342 0be71e32 Alex Williamson
void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque)
343 41bd13af aliguori
{
344 8718e999 Juan Quintela
    SaveStateEntry *se, *new_se;
345 7685ee6a Alex Williamson
    char id[256] = "";
346 7685ee6a Alex Williamson
347 09e5ab63 Anthony Liguori
    if (dev) {
348 09e5ab63 Anthony Liguori
        char *path = qdev_get_dev_path(dev);
349 7685ee6a Alex Williamson
        if (path) {
350 7685ee6a Alex Williamson
            pstrcpy(id, sizeof(id), path);
351 7685ee6a Alex Williamson
            pstrcat(id, sizeof(id), "/");
352 7267c094 Anthony Liguori
            g_free(path);
353 7685ee6a Alex Williamson
        }
354 7685ee6a Alex Williamson
    }
355 7685ee6a Alex Williamson
    pstrcat(id, sizeof(id), idstr);
356 41bd13af aliguori
357 72cf2d4f Blue Swirl
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
358 7685ee6a Alex Williamson
        if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {
359 72cf2d4f Blue Swirl
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
360 69e58af9 Alex Williamson
            if (se->compat) {
361 7267c094 Anthony Liguori
                g_free(se->compat);
362 69e58af9 Alex Williamson
            }
363 22ea40f4 Juan Quintela
            g_free(se->ops);
364 7267c094 Anthony Liguori
            g_free(se);
365 41bd13af aliguori
        }
366 41bd13af aliguori
    }
367 41bd13af aliguori
}
368 41bd13af aliguori
369 0be71e32 Alex Williamson
int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
370 4d2ffa08 Jan Kiszka
                                   const VMStateDescription *vmsd,
371 4d2ffa08 Jan Kiszka
                                   void *opaque, int alias_id,
372 4d2ffa08 Jan Kiszka
                                   int required_for_version)
373 9ed7d6ae Juan Quintela
{
374 8718e999 Juan Quintela
    SaveStateEntry *se;
375 9ed7d6ae Juan Quintela
376 4d2ffa08 Jan Kiszka
    /* If this triggers, alias support can be dropped for the vmsd. */
377 4d2ffa08 Jan Kiszka
    assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id);
378 4d2ffa08 Jan Kiszka
379 7267c094 Anthony Liguori
    se = g_malloc0(sizeof(SaveStateEntry));
380 9ed7d6ae Juan Quintela
    se->version_id = vmsd->version_id;
381 9ed7d6ae Juan Quintela
    se->section_id = global_section_id++;
382 9ed7d6ae Juan Quintela
    se->opaque = opaque;
383 9ed7d6ae Juan Quintela
    se->vmsd = vmsd;
384 4d2ffa08 Jan Kiszka
    se->alias_id = alias_id;
385 2837c8ea Gerd Hoffmann
    se->no_migrate = vmsd->unmigratable;
386 9ed7d6ae Juan Quintela
387 09e5ab63 Anthony Liguori
    if (dev) {
388 09e5ab63 Anthony Liguori
        char *id = qdev_get_dev_path(dev);
389 7685ee6a Alex Williamson
        if (id) {
390 7685ee6a Alex Williamson
            pstrcpy(se->idstr, sizeof(se->idstr), id);
391 7685ee6a Alex Williamson
            pstrcat(se->idstr, sizeof(se->idstr), "/");
392 7267c094 Anthony Liguori
            g_free(id);
393 7685ee6a Alex Williamson
394 7267c094 Anthony Liguori
            se->compat = g_malloc0(sizeof(CompatEntry));
395 7685ee6a Alex Williamson
            pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name);
396 7685ee6a Alex Williamson
            se->compat->instance_id = instance_id == -1 ?
397 7685ee6a Alex Williamson
                         calculate_compat_instance_id(vmsd->name) : instance_id;
398 7685ee6a Alex Williamson
            instance_id = -1;
399 7685ee6a Alex Williamson
        }
400 7685ee6a Alex Williamson
    }
401 7685ee6a Alex Williamson
    pstrcat(se->idstr, sizeof(se->idstr), vmsd->name);
402 7685ee6a Alex Williamson
403 8718e999 Juan Quintela
    if (instance_id == -1) {
404 7685ee6a Alex Williamson
        se->instance_id = calculate_new_instance_id(se->idstr);
405 8718e999 Juan Quintela
    } else {
406 8718e999 Juan Quintela
        se->instance_id = instance_id;
407 9ed7d6ae Juan Quintela
    }
408 7685ee6a Alex Williamson
    assert(!se->compat || se->instance_id == 0);
409 8718e999 Juan Quintela
    /* add at the end of list */
410 72cf2d4f Blue Swirl
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
411 9ed7d6ae Juan Quintela
    return 0;
412 9ed7d6ae Juan Quintela
}
413 9ed7d6ae Juan Quintela
414 0be71e32 Alex Williamson
void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
415 0be71e32 Alex Williamson
                        void *opaque)
416 9ed7d6ae Juan Quintela
{
417 1eb7538b Juan Quintela
    SaveStateEntry *se, *new_se;
418 1eb7538b Juan Quintela
419 72cf2d4f Blue Swirl
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
420 1eb7538b Juan Quintela
        if (se->vmsd == vmsd && se->opaque == opaque) {
421 72cf2d4f Blue Swirl
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
422 69e58af9 Alex Williamson
            if (se->compat) {
423 7267c094 Anthony Liguori
                g_free(se->compat);
424 69e58af9 Alex Williamson
            }
425 7267c094 Anthony Liguori
            g_free(se);
426 1eb7538b Juan Quintela
        }
427 1eb7538b Juan Quintela
    }
428 9ed7d6ae Juan Quintela
}
429 9ed7d6ae Juan Quintela
430 4082be4d Juan Quintela
static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
431 4082be4d Juan Quintela
{
432 9ed7d6ae Juan Quintela
    if (!se->vmsd) {         /* Old style */
433 22ea40f4 Juan Quintela
        return se->ops->load_state(f, se->opaque, version_id);
434 9ed7d6ae Juan Quintela
    }
435 9ed7d6ae Juan Quintela
    return vmstate_load_state(f, se->vmsd, se->opaque, version_id);
436 4082be4d Juan Quintela
}
437 4082be4d Juan Quintela
438 dc912121 Alex Williamson
static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
439 4082be4d Juan Quintela
{
440 9ed7d6ae Juan Quintela
    if (!se->vmsd) {         /* Old style */
441 22ea40f4 Juan Quintela
        se->ops->save_state(f, se->opaque);
442 dc912121 Alex Williamson
        return;
443 9ed7d6ae Juan Quintela
    }
444 38ff78d3 Eduardo Habkost
    vmstate_save_state(f, se->vmsd, se->opaque);
445 4082be4d Juan Quintela
}
446 4082be4d Juan Quintela
447 e1c37d0e Luiz Capitulino
bool qemu_savevm_state_blocked(Error **errp)
448 dc912121 Alex Williamson
{
449 dc912121 Alex Williamson
    SaveStateEntry *se;
450 dc912121 Alex Williamson
451 dc912121 Alex Williamson
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
452 dc912121 Alex Williamson
        if (se->no_migrate) {
453 e1c37d0e Luiz Capitulino
            error_set(errp, QERR_MIGRATION_NOT_SUPPORTED, se->idstr);
454 dc912121 Alex Williamson
            return true;
455 dc912121 Alex Williamson
        }
456 dc912121 Alex Williamson
    }
457 dc912121 Alex Williamson
    return false;
458 dc912121 Alex Williamson
}
459 dc912121 Alex Williamson
460 47c8c17a Paolo Bonzini
void qemu_savevm_state_begin(QEMUFile *f,
461 47c8c17a Paolo Bonzini
                             const MigrationParams *params)
462 a672b469 aliguori
{
463 a672b469 aliguori
    SaveStateEntry *se;
464 39346385 Juan Quintela
    int ret;
465 a672b469 aliguori
466 c163b5ca lirans@il.ibm.com
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
467 22ea40f4 Juan Quintela
        if (!se->ops || !se->ops->set_params) {
468 c163b5ca lirans@il.ibm.com
            continue;
469 6607ae23 Isaku Yamahata
        }
470 22ea40f4 Juan Quintela
        se->ops->set_params(params, se->opaque);
471 c163b5ca lirans@il.ibm.com
    }
472 38ff78d3 Eduardo Habkost
473 a672b469 aliguori
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
474 a672b469 aliguori
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
475 a672b469 aliguori
476 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
477 a672b469 aliguori
        int len;
478 a672b469 aliguori
479 d1315aac Juan Quintela
        if (!se->ops || !se->ops->save_live_setup) {
480 a672b469 aliguori
            continue;
481 22ea40f4 Juan Quintela
        }
482 6bd68781 Juan Quintela
        if (se->ops && se->ops->is_active) {
483 6bd68781 Juan Quintela
            if (!se->ops->is_active(se->opaque)) {
484 6bd68781 Juan Quintela
                continue;
485 6bd68781 Juan Quintela
            }
486 6bd68781 Juan Quintela
        }
487 a672b469 aliguori
        /* Section type */
488 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_START);
489 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
490 a672b469 aliguori
491 a672b469 aliguori
        /* ID string */
492 a672b469 aliguori
        len = strlen(se->idstr);
493 a672b469 aliguori
        qemu_put_byte(f, len);
494 a672b469 aliguori
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
495 a672b469 aliguori
496 a672b469 aliguori
        qemu_put_be32(f, se->instance_id);
497 a672b469 aliguori
        qemu_put_be32(f, se->version_id);
498 a672b469 aliguori
499 d1315aac Juan Quintela
        ret = se->ops->save_live_setup(f, se->opaque);
500 2975725f Juan Quintela
        if (ret < 0) {
501 47c8c17a Paolo Bonzini
            qemu_file_set_error(f, ret);
502 47c8c17a Paolo Bonzini
            break;
503 2975725f Juan Quintela
        }
504 a672b469 aliguori
    }
505 a672b469 aliguori
}
506 a672b469 aliguori
507 39346385 Juan Quintela
/*
508 07f35073 Dong Xu Wang
 * this function has three return values:
509 39346385 Juan Quintela
 *   negative: there was one error, and we have -errno.
510 39346385 Juan Quintela
 *   0 : We haven't finished, caller have to go again
511 39346385 Juan Quintela
 *   1 : We have finished, we can go to complete phase
512 39346385 Juan Quintela
 */
513 539de124 Luiz Capitulino
int qemu_savevm_state_iterate(QEMUFile *f)
514 a672b469 aliguori
{
515 a672b469 aliguori
    SaveStateEntry *se;
516 a672b469 aliguori
    int ret = 1;
517 a672b469 aliguori
518 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
519 16310a3c Juan Quintela
        if (!se->ops || !se->ops->save_live_iterate) {
520 a672b469 aliguori
            continue;
521 22ea40f4 Juan Quintela
        }
522 6bd68781 Juan Quintela
        if (se->ops && se->ops->is_active) {
523 6bd68781 Juan Quintela
            if (!se->ops->is_active(se->opaque)) {
524 6bd68781 Juan Quintela
                continue;
525 6bd68781 Juan Quintela
            }
526 6bd68781 Juan Quintela
        }
527 aac844ed Juan Quintela
        if (qemu_file_rate_limit(f)) {
528 aac844ed Juan Quintela
            return 0;
529 aac844ed Juan Quintela
        }
530 517a13c9 Juan Quintela
        trace_savevm_section_start();
531 a672b469 aliguori
        /* Section type */
532 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_PART);
533 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
534 a672b469 aliguori
535 16310a3c Juan Quintela
        ret = se->ops->save_live_iterate(f, se->opaque);
536 517a13c9 Juan Quintela
        trace_savevm_section_end(se->section_id);
537 517a13c9 Juan Quintela
538 47c8c17a Paolo Bonzini
        if (ret < 0) {
539 47c8c17a Paolo Bonzini
            qemu_file_set_error(f, ret);
540 47c8c17a Paolo Bonzini
        }
541 2975725f Juan Quintela
        if (ret <= 0) {
542 90697be8 Jan Kiszka
            /* Do not proceed to the next vmstate before this one reported
543 90697be8 Jan Kiszka
               completion of the current stage. This serializes the migration
544 90697be8 Jan Kiszka
               and reduces the probability that a faster changing state is
545 90697be8 Jan Kiszka
               synchronized over and over again. */
546 90697be8 Jan Kiszka
            break;
547 90697be8 Jan Kiszka
        }
548 a672b469 aliguori
    }
549 39346385 Juan Quintela
    return ret;
550 a672b469 aliguori
}
551 a672b469 aliguori
552 47c8c17a Paolo Bonzini
void qemu_savevm_state_complete(QEMUFile *f)
553 a672b469 aliguori
{
554 a672b469 aliguori
    SaveStateEntry *se;
555 2975725f Juan Quintela
    int ret;
556 a672b469 aliguori
557 ea375f9a Jan Kiszka
    cpu_synchronize_all_states();
558 ea375f9a Jan Kiszka
559 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
560 16310a3c Juan Quintela
        if (!se->ops || !se->ops->save_live_complete) {
561 a672b469 aliguori
            continue;
562 22ea40f4 Juan Quintela
        }
563 6bd68781 Juan Quintela
        if (se->ops && se->ops->is_active) {
564 6bd68781 Juan Quintela
            if (!se->ops->is_active(se->opaque)) {
565 6bd68781 Juan Quintela
                continue;
566 6bd68781 Juan Quintela
            }
567 6bd68781 Juan Quintela
        }
568 517a13c9 Juan Quintela
        trace_savevm_section_start();
569 a672b469 aliguori
        /* Section type */
570 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_END);
571 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
572 a672b469 aliguori
573 16310a3c Juan Quintela
        ret = se->ops->save_live_complete(f, se->opaque);
574 517a13c9 Juan Quintela
        trace_savevm_section_end(se->section_id);
575 2975725f Juan Quintela
        if (ret < 0) {
576 47c8c17a Paolo Bonzini
            qemu_file_set_error(f, ret);
577 47c8c17a Paolo Bonzini
            return;
578 2975725f Juan Quintela
        }
579 a672b469 aliguori
    }
580 a672b469 aliguori
581 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
582 a672b469 aliguori
        int len;
583 a672b469 aliguori
584 22ea40f4 Juan Quintela
        if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
585 5cecf414 Eduardo Habkost
            continue;
586 22ea40f4 Juan Quintela
        }
587 517a13c9 Juan Quintela
        trace_savevm_section_start();
588 a672b469 aliguori
        /* Section type */
589 a672b469 aliguori
        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
590 a672b469 aliguori
        qemu_put_be32(f, se->section_id);
591 a672b469 aliguori
592 a672b469 aliguori
        /* ID string */
593 a672b469 aliguori
        len = strlen(se->idstr);
594 a672b469 aliguori
        qemu_put_byte(f, len);
595 a672b469 aliguori
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
596 a672b469 aliguori
597 a672b469 aliguori
        qemu_put_be32(f, se->instance_id);
598 a672b469 aliguori
        qemu_put_be32(f, se->version_id);
599 a672b469 aliguori
600 dc912121 Alex Williamson
        vmstate_save(f, se);
601 517a13c9 Juan Quintela
        trace_savevm_section_end(se->section_id);
602 a672b469 aliguori
    }
603 a672b469 aliguori
604 a672b469 aliguori
    qemu_put_byte(f, QEMU_VM_EOF);
605 edaae611 Paolo Bonzini
    qemu_fflush(f);
606 a672b469 aliguori
}
607 a672b469 aliguori
608 e4ed1541 Juan Quintela
uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size)
609 e4ed1541 Juan Quintela
{
610 e4ed1541 Juan Quintela
    SaveStateEntry *se;
611 e4ed1541 Juan Quintela
    uint64_t ret = 0;
612 e4ed1541 Juan Quintela
613 e4ed1541 Juan Quintela
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
614 e4ed1541 Juan Quintela
        if (!se->ops || !se->ops->save_live_pending) {
615 e4ed1541 Juan Quintela
            continue;
616 e4ed1541 Juan Quintela
        }
617 e4ed1541 Juan Quintela
        if (se->ops && se->ops->is_active) {
618 e4ed1541 Juan Quintela
            if (!se->ops->is_active(se->opaque)) {
619 e4ed1541 Juan Quintela
                continue;
620 e4ed1541 Juan Quintela
            }
621 e4ed1541 Juan Quintela
        }
622 e4ed1541 Juan Quintela
        ret += se->ops->save_live_pending(f, se->opaque, max_size);
623 e4ed1541 Juan Quintela
    }
624 e4ed1541 Juan Quintela
    return ret;
625 e4ed1541 Juan Quintela
}
626 e4ed1541 Juan Quintela
627 6522773f Juan Quintela
void qemu_savevm_state_cancel(void)
628 4ec7fcc7 Jan Kiszka
{
629 4ec7fcc7 Jan Kiszka
    SaveStateEntry *se;
630 4ec7fcc7 Jan Kiszka
631 4ec7fcc7 Jan Kiszka
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
632 9b5bfab0 Juan Quintela
        if (se->ops && se->ops->cancel) {
633 9b5bfab0 Juan Quintela
            se->ops->cancel(se->opaque);
634 4ec7fcc7 Jan Kiszka
        }
635 4ec7fcc7 Jan Kiszka
    }
636 4ec7fcc7 Jan Kiszka
}
637 4ec7fcc7 Jan Kiszka
638 e1c37d0e Luiz Capitulino
static int qemu_savevm_state(QEMUFile *f)
639 a672b469 aliguori
{
640 a672b469 aliguori
    int ret;
641 6607ae23 Isaku Yamahata
    MigrationParams params = {
642 6607ae23 Isaku Yamahata
        .blk = 0,
643 6607ae23 Isaku Yamahata
        .shared = 0
644 6607ae23 Isaku Yamahata
    };
645 a672b469 aliguori
646 e1c37d0e Luiz Capitulino
    if (qemu_savevm_state_blocked(NULL)) {
647 04943eba Paolo Bonzini
        return -EINVAL;
648 dc912121 Alex Williamson
    }
649 dc912121 Alex Williamson
650 9b095037 Paolo Bonzini
    qemu_mutex_unlock_iothread();
651 47c8c17a Paolo Bonzini
    qemu_savevm_state_begin(f, &params);
652 9b095037 Paolo Bonzini
    qemu_mutex_lock_iothread();
653 9b095037 Paolo Bonzini
654 47c8c17a Paolo Bonzini
    while (qemu_file_get_error(f) == 0) {
655 47c8c17a Paolo Bonzini
        if (qemu_savevm_state_iterate(f) > 0) {
656 47c8c17a Paolo Bonzini
            break;
657 47c8c17a Paolo Bonzini
        }
658 47c8c17a Paolo Bonzini
    }
659 a672b469 aliguori
660 47c8c17a Paolo Bonzini
    ret = qemu_file_get_error(f);
661 39346385 Juan Quintela
    if (ret == 0) {
662 47c8c17a Paolo Bonzini
        qemu_savevm_state_complete(f);
663 624b9cc2 Juan Quintela
        ret = qemu_file_get_error(f);
664 39346385 Juan Quintela
    }
665 04943eba Paolo Bonzini
    if (ret != 0) {
666 04943eba Paolo Bonzini
        qemu_savevm_state_cancel();
667 04943eba Paolo Bonzini
    }
668 a672b469 aliguori
    return ret;
669 a672b469 aliguori
}
670 a672b469 aliguori
671 a7ae8355 Stefano Stabellini
static int qemu_save_device_state(QEMUFile *f)
672 a7ae8355 Stefano Stabellini
{
673 a7ae8355 Stefano Stabellini
    SaveStateEntry *se;
674 a7ae8355 Stefano Stabellini
675 a7ae8355 Stefano Stabellini
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
676 a7ae8355 Stefano Stabellini
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
677 a7ae8355 Stefano Stabellini
678 a7ae8355 Stefano Stabellini
    cpu_synchronize_all_states();
679 a7ae8355 Stefano Stabellini
680 a7ae8355 Stefano Stabellini
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
681 a7ae8355 Stefano Stabellini
        int len;
682 a7ae8355 Stefano Stabellini
683 a7ae8355 Stefano Stabellini
        if (se->is_ram) {
684 a7ae8355 Stefano Stabellini
            continue;
685 a7ae8355 Stefano Stabellini
        }
686 22ea40f4 Juan Quintela
        if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
687 a7ae8355 Stefano Stabellini
            continue;
688 a7ae8355 Stefano Stabellini
        }
689 a7ae8355 Stefano Stabellini
690 a7ae8355 Stefano Stabellini
        /* Section type */
691 a7ae8355 Stefano Stabellini
        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
692 a7ae8355 Stefano Stabellini
        qemu_put_be32(f, se->section_id);
693 a7ae8355 Stefano Stabellini
694 a7ae8355 Stefano Stabellini
        /* ID string */
695 a7ae8355 Stefano Stabellini
        len = strlen(se->idstr);
696 a7ae8355 Stefano Stabellini
        qemu_put_byte(f, len);
697 a7ae8355 Stefano Stabellini
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
698 a7ae8355 Stefano Stabellini
699 a7ae8355 Stefano Stabellini
        qemu_put_be32(f, se->instance_id);
700 a7ae8355 Stefano Stabellini
        qemu_put_be32(f, se->version_id);
701 a7ae8355 Stefano Stabellini
702 a7ae8355 Stefano Stabellini
        vmstate_save(f, se);
703 a7ae8355 Stefano Stabellini
    }
704 a7ae8355 Stefano Stabellini
705 a7ae8355 Stefano Stabellini
    qemu_put_byte(f, QEMU_VM_EOF);
706 a7ae8355 Stefano Stabellini
707 a7ae8355 Stefano Stabellini
    return qemu_file_get_error(f);
708 a7ae8355 Stefano Stabellini
}
709 a7ae8355 Stefano Stabellini
710 a672b469 aliguori
static SaveStateEntry *find_se(const char *idstr, int instance_id)
711 a672b469 aliguori
{
712 a672b469 aliguori
    SaveStateEntry *se;
713 a672b469 aliguori
714 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
715 a672b469 aliguori
        if (!strcmp(se->idstr, idstr) &&
716 4d2ffa08 Jan Kiszka
            (instance_id == se->instance_id ||
717 4d2ffa08 Jan Kiszka
             instance_id == se->alias_id))
718 a672b469 aliguori
            return se;
719 7685ee6a Alex Williamson
        /* Migrating from an older version? */
720 7685ee6a Alex Williamson
        if (strstr(se->idstr, idstr) && se->compat) {
721 7685ee6a Alex Williamson
            if (!strcmp(se->compat->idstr, idstr) &&
722 7685ee6a Alex Williamson
                (instance_id == se->compat->instance_id ||
723 7685ee6a Alex Williamson
                 instance_id == se->alias_id))
724 7685ee6a Alex Williamson
                return se;
725 7685ee6a Alex Williamson
        }
726 a672b469 aliguori
    }
727 a672b469 aliguori
    return NULL;
728 a672b469 aliguori
}
729 a672b469 aliguori
730 a672b469 aliguori
typedef struct LoadStateEntry {
731 72cf2d4f Blue Swirl
    QLIST_ENTRY(LoadStateEntry) entry;
732 a672b469 aliguori
    SaveStateEntry *se;
733 a672b469 aliguori
    int section_id;
734 a672b469 aliguori
    int version_id;
735 a672b469 aliguori
} LoadStateEntry;
736 a672b469 aliguori
737 a672b469 aliguori
int qemu_loadvm_state(QEMUFile *f)
738 a672b469 aliguori
{
739 72cf2d4f Blue Swirl
    QLIST_HEAD(, LoadStateEntry) loadvm_handlers =
740 72cf2d4f Blue Swirl
        QLIST_HEAD_INITIALIZER(loadvm_handlers);
741 f4dbb8dd Juan Quintela
    LoadStateEntry *le, *new_le;
742 a672b469 aliguori
    uint8_t section_type;
743 a672b469 aliguori
    unsigned int v;
744 a672b469 aliguori
    int ret;
745 a672b469 aliguori
746 e1c37d0e Luiz Capitulino
    if (qemu_savevm_state_blocked(NULL)) {
747 dc912121 Alex Williamson
        return -EINVAL;
748 dc912121 Alex Williamson
    }
749 dc912121 Alex Williamson
750 a672b469 aliguori
    v = qemu_get_be32(f);
751 38ff78d3 Eduardo Habkost
    if (v != QEMU_VM_FILE_MAGIC) {
752 a672b469 aliguori
        return -EINVAL;
753 38ff78d3 Eduardo Habkost
    }
754 a672b469 aliguori
755 a672b469 aliguori
    v = qemu_get_be32(f);
756 bbfe1408 Juan Quintela
    if (v == QEMU_VM_FILE_VERSION_COMPAT) {
757 bbfe1408 Juan Quintela
        fprintf(stderr, "SaveVM v2 format is obsolete and don't work anymore\n");
758 bbfe1408 Juan Quintela
        return -ENOTSUP;
759 bbfe1408 Juan Quintela
    }
760 38ff78d3 Eduardo Habkost
    if (v != QEMU_VM_FILE_VERSION) {
761 a672b469 aliguori
        return -ENOTSUP;
762 38ff78d3 Eduardo Habkost
    }
763 a672b469 aliguori
764 a672b469 aliguori
    while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
765 a672b469 aliguori
        uint32_t instance_id, version_id, section_id;
766 a672b469 aliguori
        SaveStateEntry *se;
767 a672b469 aliguori
        char idstr[257];
768 a672b469 aliguori
        int len;
769 a672b469 aliguori
770 a672b469 aliguori
        switch (section_type) {
771 a672b469 aliguori
        case QEMU_VM_SECTION_START:
772 a672b469 aliguori
        case QEMU_VM_SECTION_FULL:
773 a672b469 aliguori
            /* Read section start */
774 a672b469 aliguori
            section_id = qemu_get_be32(f);
775 a672b469 aliguori
            len = qemu_get_byte(f);
776 a672b469 aliguori
            qemu_get_buffer(f, (uint8_t *)idstr, len);
777 a672b469 aliguori
            idstr[len] = 0;
778 a672b469 aliguori
            instance_id = qemu_get_be32(f);
779 a672b469 aliguori
            version_id = qemu_get_be32(f);
780 a672b469 aliguori
781 a672b469 aliguori
            /* Find savevm section */
782 a672b469 aliguori
            se = find_se(idstr, instance_id);
783 a672b469 aliguori
            if (se == NULL) {
784 a672b469 aliguori
                fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
785 a672b469 aliguori
                ret = -EINVAL;
786 a672b469 aliguori
                goto out;
787 a672b469 aliguori
            }
788 a672b469 aliguori
789 a672b469 aliguori
            /* Validate version */
790 a672b469 aliguori
            if (version_id > se->version_id) {
791 a672b469 aliguori
                fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
792 a672b469 aliguori
                        version_id, idstr, se->version_id);
793 a672b469 aliguori
                ret = -EINVAL;
794 a672b469 aliguori
                goto out;
795 a672b469 aliguori
            }
796 a672b469 aliguori
797 a672b469 aliguori
            /* Add entry */
798 7267c094 Anthony Liguori
            le = g_malloc0(sizeof(*le));
799 a672b469 aliguori
800 a672b469 aliguori
            le->se = se;
801 a672b469 aliguori
            le->section_id = section_id;
802 a672b469 aliguori
            le->version_id = version_id;
803 72cf2d4f Blue Swirl
            QLIST_INSERT_HEAD(&loadvm_handlers, le, entry);
804 a672b469 aliguori
805 4082be4d Juan Quintela
            ret = vmstate_load(f, le->se, le->version_id);
806 b5a22e4a Juan Quintela
            if (ret < 0) {
807 b5a22e4a Juan Quintela
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
808 b5a22e4a Juan Quintela
                        instance_id, idstr);
809 b5a22e4a Juan Quintela
                goto out;
810 b5a22e4a Juan Quintela
            }
811 a672b469 aliguori
            break;
812 a672b469 aliguori
        case QEMU_VM_SECTION_PART:
813 a672b469 aliguori
        case QEMU_VM_SECTION_END:
814 a672b469 aliguori
            section_id = qemu_get_be32(f);
815 a672b469 aliguori
816 72cf2d4f Blue Swirl
            QLIST_FOREACH(le, &loadvm_handlers, entry) {
817 f4dbb8dd Juan Quintela
                if (le->section_id == section_id) {
818 f4dbb8dd Juan Quintela
                    break;
819 f4dbb8dd Juan Quintela
                }
820 f4dbb8dd Juan Quintela
            }
821 a672b469 aliguori
            if (le == NULL) {
822 a672b469 aliguori
                fprintf(stderr, "Unknown savevm section %d\n", section_id);
823 a672b469 aliguori
                ret = -EINVAL;
824 a672b469 aliguori
                goto out;
825 a672b469 aliguori
            }
826 a672b469 aliguori
827 4082be4d Juan Quintela
            ret = vmstate_load(f, le->se, le->version_id);
828 b5a22e4a Juan Quintela
            if (ret < 0) {
829 b5a22e4a Juan Quintela
                fprintf(stderr, "qemu: warning: error while loading state section id %d\n",
830 b5a22e4a Juan Quintela
                        section_id);
831 b5a22e4a Juan Quintela
                goto out;
832 b5a22e4a Juan Quintela
            }
833 a672b469 aliguori
            break;
834 a672b469 aliguori
        default:
835 a672b469 aliguori
            fprintf(stderr, "Unknown savevm section type %d\n", section_type);
836 a672b469 aliguori
            ret = -EINVAL;
837 a672b469 aliguori
            goto out;
838 a672b469 aliguori
        }
839 a672b469 aliguori
    }
840 a672b469 aliguori
841 ea375f9a Jan Kiszka
    cpu_synchronize_all_post_init();
842 ea375f9a Jan Kiszka
843 a672b469 aliguori
    ret = 0;
844 a672b469 aliguori
845 a672b469 aliguori
out:
846 72cf2d4f Blue Swirl
    QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {
847 72cf2d4f Blue Swirl
        QLIST_REMOVE(le, entry);
848 7267c094 Anthony Liguori
        g_free(le);
849 a672b469 aliguori
    }
850 a672b469 aliguori
851 42802d47 Juan Quintela
    if (ret == 0) {
852 42802d47 Juan Quintela
        ret = qemu_file_get_error(f);
853 624b9cc2 Juan Quintela
    }
854 a672b469 aliguori
855 a672b469 aliguori
    return ret;
856 a672b469 aliguori
}
857 a672b469 aliguori
858 29d78271 Stefan Hajnoczi
static BlockDriverState *find_vmstate_bs(void)
859 29d78271 Stefan Hajnoczi
{
860 29d78271 Stefan Hajnoczi
    BlockDriverState *bs = NULL;
861 29d78271 Stefan Hajnoczi
    while ((bs = bdrv_next(bs))) {
862 29d78271 Stefan Hajnoczi
        if (bdrv_can_snapshot(bs)) {
863 29d78271 Stefan Hajnoczi
            return bs;
864 29d78271 Stefan Hajnoczi
        }
865 29d78271 Stefan Hajnoczi
    }
866 29d78271 Stefan Hajnoczi
    return NULL;
867 29d78271 Stefan Hajnoczi
}
868 29d78271 Stefan Hajnoczi
869 cb499fb2 Kevin Wolf
/*
870 cb499fb2 Kevin Wolf
 * Deletes snapshots of a given name in all opened images.
871 cb499fb2 Kevin Wolf
 */
872 cb499fb2 Kevin Wolf
static int del_existing_snapshots(Monitor *mon, const char *name)
873 cb499fb2 Kevin Wolf
{
874 cb499fb2 Kevin Wolf
    BlockDriverState *bs;
875 cb499fb2 Kevin Wolf
    QEMUSnapshotInfo sn1, *snapshot = &sn1;
876 a89d89d3 Wenchao Xia
    Error *err = NULL;
877 cb499fb2 Kevin Wolf
878 dbc13590 Markus Armbruster
    bs = NULL;
879 dbc13590 Markus Armbruster
    while ((bs = bdrv_next(bs))) {
880 cb499fb2 Kevin Wolf
        if (bdrv_can_snapshot(bs) &&
881 38ff78d3 Eduardo Habkost
            bdrv_snapshot_find(bs, snapshot, name) >= 0) {
882 a89d89d3 Wenchao Xia
            bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
883 84d18f06 Markus Armbruster
            if (err) {
884 cb499fb2 Kevin Wolf
                monitor_printf(mon,
885 a89d89d3 Wenchao Xia
                               "Error while deleting snapshot on device '%s':"
886 a89d89d3 Wenchao Xia
                               " %s\n",
887 a89d89d3 Wenchao Xia
                               bdrv_get_device_name(bs),
888 a89d89d3 Wenchao Xia
                               error_get_pretty(err));
889 a89d89d3 Wenchao Xia
                error_free(err);
890 cb499fb2 Kevin Wolf
                return -1;
891 cb499fb2 Kevin Wolf
            }
892 cb499fb2 Kevin Wolf
        }
893 cb499fb2 Kevin Wolf
    }
894 cb499fb2 Kevin Wolf
895 cb499fb2 Kevin Wolf
    return 0;
896 cb499fb2 Kevin Wolf
}
897 cb499fb2 Kevin Wolf
898 d54908a5 Luiz Capitulino
void do_savevm(Monitor *mon, const QDict *qdict)
899 a672b469 aliguori
{
900 a672b469 aliguori
    BlockDriverState *bs, *bs1;
901 a672b469 aliguori
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
902 cb499fb2 Kevin Wolf
    int ret;
903 a672b469 aliguori
    QEMUFile *f;
904 a672b469 aliguori
    int saved_vm_running;
905 c2c9a466 Kevin Wolf
    uint64_t vm_state_size;
906 68b891ec Stefan Weil
    qemu_timeval tv;
907 7d631a11 Miguel Di Ciurcio Filho
    struct tm tm;
908 d54908a5 Luiz Capitulino
    const char *name = qdict_get_try_str(qdict, "name");
909 a672b469 aliguori
910 feeee5ac Miguel Di Ciurcio Filho
    /* Verify if there is a device that doesn't support snapshots and is writable */
911 dbc13590 Markus Armbruster
    bs = NULL;
912 dbc13590 Markus Armbruster
    while ((bs = bdrv_next(bs))) {
913 feeee5ac Miguel Di Ciurcio Filho
914 07b70bfb Markus Armbruster
        if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
915 feeee5ac Miguel Di Ciurcio Filho
            continue;
916 feeee5ac Miguel Di Ciurcio Filho
        }
917 feeee5ac Miguel Di Ciurcio Filho
918 feeee5ac Miguel Di Ciurcio Filho
        if (!bdrv_can_snapshot(bs)) {
919 feeee5ac Miguel Di Ciurcio Filho
            monitor_printf(mon, "Device '%s' is writable but does not support snapshots.\n",
920 feeee5ac Miguel Di Ciurcio Filho
                               bdrv_get_device_name(bs));
921 feeee5ac Miguel Di Ciurcio Filho
            return;
922 feeee5ac Miguel Di Ciurcio Filho
        }
923 feeee5ac Miguel Di Ciurcio Filho
    }
924 feeee5ac Miguel Di Ciurcio Filho
925 29d78271 Stefan Hajnoczi
    bs = find_vmstate_bs();
926 a672b469 aliguori
    if (!bs) {
927 376253ec aliguori
        monitor_printf(mon, "No block device can accept snapshots\n");
928 a672b469 aliguori
        return;
929 a672b469 aliguori
    }
930 a672b469 aliguori
931 1354869c Luiz Capitulino
    saved_vm_running = runstate_is_running();
932 0461d5a6 Luiz Capitulino
    vm_stop(RUN_STATE_SAVE_VM);
933 a672b469 aliguori
934 cb499fb2 Kevin Wolf
    memset(sn, 0, sizeof(*sn));
935 a672b469 aliguori
936 a672b469 aliguori
    /* fill auxiliary fields */
937 68b891ec Stefan Weil
    qemu_gettimeofday(&tv);
938 a672b469 aliguori
    sn->date_sec = tv.tv_sec;
939 a672b469 aliguori
    sn->date_nsec = tv.tv_usec * 1000;
940 bc72ad67 Alex Bligh
    sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
941 a672b469 aliguori
942 7d631a11 Miguel Di Ciurcio Filho
    if (name) {
943 7d631a11 Miguel Di Ciurcio Filho
        ret = bdrv_snapshot_find(bs, old_sn, name);
944 7d631a11 Miguel Di Ciurcio Filho
        if (ret >= 0) {
945 7d631a11 Miguel Di Ciurcio Filho
            pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
946 7d631a11 Miguel Di Ciurcio Filho
            pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
947 7d631a11 Miguel Di Ciurcio Filho
        } else {
948 7d631a11 Miguel Di Ciurcio Filho
            pstrcpy(sn->name, sizeof(sn->name), name);
949 7d631a11 Miguel Di Ciurcio Filho
        }
950 7d631a11 Miguel Di Ciurcio Filho
    } else {
951 d7d9b528 Blue Swirl
        /* cast below needed for OpenBSD where tv_sec is still 'long' */
952 d7d9b528 Blue Swirl
        localtime_r((const time_t *)&tv.tv_sec, &tm);
953 7d631a11 Miguel Di Ciurcio Filho
        strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", &tm);
954 7d631a11 Miguel Di Ciurcio Filho
    }
955 7d631a11 Miguel Di Ciurcio Filho
956 cb499fb2 Kevin Wolf
    /* Delete old snapshots of the same name */
957 f139a412 Marcelo Tosatti
    if (name && del_existing_snapshots(mon, name) < 0) {
958 cb499fb2 Kevin Wolf
        goto the_end;
959 cb499fb2 Kevin Wolf
    }
960 cb499fb2 Kevin Wolf
961 a672b469 aliguori
    /* save the VM state */
962 45566e9c Christoph Hellwig
    f = qemu_fopen_bdrv(bs, 1);
963 a672b469 aliguori
    if (!f) {
964 376253ec aliguori
        monitor_printf(mon, "Could not open VM state file\n");
965 a672b469 aliguori
        goto the_end;
966 a672b469 aliguori
    }
967 e1c37d0e Luiz Capitulino
    ret = qemu_savevm_state(f);
968 2d22b18f aliguori
    vm_state_size = qemu_ftell(f);
969 a672b469 aliguori
    qemu_fclose(f);
970 a672b469 aliguori
    if (ret < 0) {
971 376253ec aliguori
        monitor_printf(mon, "Error %d while writing VM\n", ret);
972 a672b469 aliguori
        goto the_end;
973 a672b469 aliguori
    }
974 a672b469 aliguori
975 a672b469 aliguori
    /* create the snapshots */
976 a672b469 aliguori
977 dbc13590 Markus Armbruster
    bs1 = NULL;
978 dbc13590 Markus Armbruster
    while ((bs1 = bdrv_next(bs1))) {
979 feeee5ac Miguel Di Ciurcio Filho
        if (bdrv_can_snapshot(bs1)) {
980 2d22b18f aliguori
            /* Write VM state size only to the image that contains the state */
981 2d22b18f aliguori
            sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
982 a672b469 aliguori
            ret = bdrv_snapshot_create(bs1, sn);
983 a672b469 aliguori
            if (ret < 0) {
984 376253ec aliguori
                monitor_printf(mon, "Error while creating snapshot on '%s'\n",
985 376253ec aliguori
                               bdrv_get_device_name(bs1));
986 a672b469 aliguori
            }
987 a672b469 aliguori
        }
988 a672b469 aliguori
    }
989 a672b469 aliguori
990 a672b469 aliguori
 the_end:
991 38ff78d3 Eduardo Habkost
    if (saved_vm_running) {
992 a672b469 aliguori
        vm_start();
993 38ff78d3 Eduardo Habkost
    }
994 a672b469 aliguori
}
995 a672b469 aliguori
996 a7ae8355 Stefano Stabellini
void qmp_xen_save_devices_state(const char *filename, Error **errp)
997 a7ae8355 Stefano Stabellini
{
998 a7ae8355 Stefano Stabellini
    QEMUFile *f;
999 a7ae8355 Stefano Stabellini
    int saved_vm_running;
1000 a7ae8355 Stefano Stabellini
    int ret;
1001 a7ae8355 Stefano Stabellini
1002 a7ae8355 Stefano Stabellini
    saved_vm_running = runstate_is_running();
1003 a7ae8355 Stefano Stabellini
    vm_stop(RUN_STATE_SAVE_VM);
1004 a7ae8355 Stefano Stabellini
1005 a7ae8355 Stefano Stabellini
    f = qemu_fopen(filename, "wb");
1006 a7ae8355 Stefano Stabellini
    if (!f) {
1007 1befce96 Luiz Capitulino
        error_setg_file_open(errp, errno, filename);
1008 a7ae8355 Stefano Stabellini
        goto the_end;
1009 a7ae8355 Stefano Stabellini
    }
1010 a7ae8355 Stefano Stabellini
    ret = qemu_save_device_state(f);
1011 a7ae8355 Stefano Stabellini
    qemu_fclose(f);
1012 a7ae8355 Stefano Stabellini
    if (ret < 0) {
1013 a7ae8355 Stefano Stabellini
        error_set(errp, QERR_IO_ERROR);
1014 a7ae8355 Stefano Stabellini
    }
1015 a7ae8355 Stefano Stabellini
1016 a7ae8355 Stefano Stabellini
 the_end:
1017 38ff78d3 Eduardo Habkost
    if (saved_vm_running) {
1018 a7ae8355 Stefano Stabellini
        vm_start();
1019 38ff78d3 Eduardo Habkost
    }
1020 a7ae8355 Stefano Stabellini
}
1021 a7ae8355 Stefano Stabellini
1022 03cd4655 Markus Armbruster
int load_vmstate(const char *name)
1023 a672b469 aliguori
{
1024 f0aa7a8b Miguel Di Ciurcio Filho
    BlockDriverState *bs, *bs_vm_state;
1025 2d22b18f aliguori
    QEMUSnapshotInfo sn;
1026 a672b469 aliguori
    QEMUFile *f;
1027 751c6a17 Gerd Hoffmann
    int ret;
1028 a672b469 aliguori
1029 29d78271 Stefan Hajnoczi
    bs_vm_state = find_vmstate_bs();
1030 f0aa7a8b Miguel Di Ciurcio Filho
    if (!bs_vm_state) {
1031 f0aa7a8b Miguel Di Ciurcio Filho
        error_report("No block device supports snapshots");
1032 f0aa7a8b Miguel Di Ciurcio Filho
        return -ENOTSUP;
1033 f0aa7a8b Miguel Di Ciurcio Filho
    }
1034 f0aa7a8b Miguel Di Ciurcio Filho
1035 f0aa7a8b Miguel Di Ciurcio Filho
    /* Don't even try to load empty VM states */
1036 f0aa7a8b Miguel Di Ciurcio Filho
    ret = bdrv_snapshot_find(bs_vm_state, &sn, name);
1037 f0aa7a8b Miguel Di Ciurcio Filho
    if (ret < 0) {
1038 f0aa7a8b Miguel Di Ciurcio Filho
        return ret;
1039 f0aa7a8b Miguel Di Ciurcio Filho
    } else if (sn.vm_state_size == 0) {
1040 e11480db Kevin Wolf
        error_report("This is a disk-only snapshot. Revert to it offline "
1041 e11480db Kevin Wolf
            "using qemu-img.");
1042 f0aa7a8b Miguel Di Ciurcio Filho
        return -EINVAL;
1043 f0aa7a8b Miguel Di Ciurcio Filho
    }
1044 f0aa7a8b Miguel Di Ciurcio Filho
1045 f0aa7a8b Miguel Di Ciurcio Filho
    /* Verify if there is any device that doesn't support snapshots and is
1046 f0aa7a8b Miguel Di Ciurcio Filho
    writable and check if the requested snapshot is available too. */
1047 dbc13590 Markus Armbruster
    bs = NULL;
1048 dbc13590 Markus Armbruster
    while ((bs = bdrv_next(bs))) {
1049 feeee5ac Miguel Di Ciurcio Filho
1050 07b70bfb Markus Armbruster
        if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
1051 feeee5ac Miguel Di Ciurcio Filho
            continue;
1052 feeee5ac Miguel Di Ciurcio Filho
        }
1053 feeee5ac Miguel Di Ciurcio Filho
1054 feeee5ac Miguel Di Ciurcio Filho
        if (!bdrv_can_snapshot(bs)) {
1055 feeee5ac Miguel Di Ciurcio Filho
            error_report("Device '%s' is writable but does not support snapshots.",
1056 feeee5ac Miguel Di Ciurcio Filho
                               bdrv_get_device_name(bs));
1057 feeee5ac Miguel Di Ciurcio Filho
            return -ENOTSUP;
1058 feeee5ac Miguel Di Ciurcio Filho
        }
1059 feeee5ac Miguel Di Ciurcio Filho
1060 f0aa7a8b Miguel Di Ciurcio Filho
        ret = bdrv_snapshot_find(bs, &sn, name);
1061 f0aa7a8b Miguel Di Ciurcio Filho
        if (ret < 0) {
1062 f0aa7a8b Miguel Di Ciurcio Filho
            error_report("Device '%s' does not have the requested snapshot '%s'",
1063 f0aa7a8b Miguel Di Ciurcio Filho
                           bdrv_get_device_name(bs), name);
1064 f0aa7a8b Miguel Di Ciurcio Filho
            return ret;
1065 f0aa7a8b Miguel Di Ciurcio Filho
        }
1066 a672b469 aliguori
    }
1067 a672b469 aliguori
1068 a672b469 aliguori
    /* Flush all IO requests so they don't interfere with the new state.  */
1069 922453bc Stefan Hajnoczi
    bdrv_drain_all();
1070 a672b469 aliguori
1071 f0aa7a8b Miguel Di Ciurcio Filho
    bs = NULL;
1072 f0aa7a8b Miguel Di Ciurcio Filho
    while ((bs = bdrv_next(bs))) {
1073 f0aa7a8b Miguel Di Ciurcio Filho
        if (bdrv_can_snapshot(bs)) {
1074 f0aa7a8b Miguel Di Ciurcio Filho
            ret = bdrv_snapshot_goto(bs, name);
1075 a672b469 aliguori
            if (ret < 0) {
1076 f0aa7a8b Miguel Di Ciurcio Filho
                error_report("Error %d while activating snapshot '%s' on '%s'",
1077 f0aa7a8b Miguel Di Ciurcio Filho
                             ret, name, bdrv_get_device_name(bs));
1078 f0aa7a8b Miguel Di Ciurcio Filho
                return ret;
1079 a672b469 aliguori
            }
1080 a672b469 aliguori
        }
1081 a672b469 aliguori
    }
1082 a672b469 aliguori
1083 a672b469 aliguori
    /* restore the VM state */
1084 f0aa7a8b Miguel Di Ciurcio Filho
    f = qemu_fopen_bdrv(bs_vm_state, 0);
1085 a672b469 aliguori
    if (!f) {
1086 1ecda02b Markus Armbruster
        error_report("Could not open VM state file");
1087 05f2401e Juan Quintela
        return -EINVAL;
1088 a672b469 aliguori
    }
1089 f0aa7a8b Miguel Di Ciurcio Filho
1090 5a8a49d7 Jan Kiszka
    qemu_system_reset(VMRESET_SILENT);
1091 a672b469 aliguori
    ret = qemu_loadvm_state(f);
1092 f0aa7a8b Miguel Di Ciurcio Filho
1093 a672b469 aliguori
    qemu_fclose(f);
1094 a672b469 aliguori
    if (ret < 0) {
1095 1ecda02b Markus Armbruster
        error_report("Error %d while loading VM state", ret);
1096 05f2401e Juan Quintela
        return ret;
1097 a672b469 aliguori
    }
1098 f0aa7a8b Miguel Di Ciurcio Filho
1099 05f2401e Juan Quintela
    return 0;
1100 7b630349 Juan Quintela
}
1101 7b630349 Juan Quintela
1102 d54908a5 Luiz Capitulino
void do_delvm(Monitor *mon, const QDict *qdict)
1103 a672b469 aliguori
{
1104 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1105 a89d89d3 Wenchao Xia
    Error *err = NULL;
1106 d54908a5 Luiz Capitulino
    const char *name = qdict_get_str(qdict, "name");
1107 a672b469 aliguori
1108 29d78271 Stefan Hajnoczi
    bs = find_vmstate_bs();
1109 a672b469 aliguori
    if (!bs) {
1110 376253ec aliguori
        monitor_printf(mon, "No block device supports snapshots\n");
1111 a672b469 aliguori
        return;
1112 a672b469 aliguori
    }
1113 a672b469 aliguori
1114 dbc13590 Markus Armbruster
    bs1 = NULL;
1115 dbc13590 Markus Armbruster
    while ((bs1 = bdrv_next(bs1))) {
1116 feeee5ac Miguel Di Ciurcio Filho
        if (bdrv_can_snapshot(bs1)) {
1117 a89d89d3 Wenchao Xia
            bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
1118 84d18f06 Markus Armbruster
            if (err) {
1119 a89d89d3 Wenchao Xia
                monitor_printf(mon,
1120 a89d89d3 Wenchao Xia
                               "Error while deleting snapshot on device '%s':"
1121 a89d89d3 Wenchao Xia
                               " %s\n",
1122 a89d89d3 Wenchao Xia
                               bdrv_get_device_name(bs),
1123 a89d89d3 Wenchao Xia
                               error_get_pretty(err));
1124 a89d89d3 Wenchao Xia
                error_free(err);
1125 a672b469 aliguori
            }
1126 a672b469 aliguori
        }
1127 a672b469 aliguori
    }
1128 a672b469 aliguori
}
1129 a672b469 aliguori
1130 84f2d0ea Wenchao Xia
void do_info_snapshots(Monitor *mon, const QDict *qdict)
1131 a672b469 aliguori
{
1132 a672b469 aliguori
    BlockDriverState *bs, *bs1;
1133 f9209915 Miguel Di Ciurcio Filho
    QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
1134 f9209915 Miguel Di Ciurcio Filho
    int nb_sns, i, ret, available;
1135 f9209915 Miguel Di Ciurcio Filho
    int total;
1136 f9209915 Miguel Di Ciurcio Filho
    int *available_snapshots;
1137 a672b469 aliguori
1138 29d78271 Stefan Hajnoczi
    bs = find_vmstate_bs();
1139 a672b469 aliguori
    if (!bs) {
1140 376253ec aliguori
        monitor_printf(mon, "No available block device supports snapshots\n");
1141 a672b469 aliguori
        return;
1142 a672b469 aliguori
    }
1143 a672b469 aliguori
1144 a672b469 aliguori
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1145 a672b469 aliguori
    if (nb_sns < 0) {
1146 376253ec aliguori
        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
1147 a672b469 aliguori
        return;
1148 a672b469 aliguori
    }
1149 f9209915 Miguel Di Ciurcio Filho
1150 f9209915 Miguel Di Ciurcio Filho
    if (nb_sns == 0) {
1151 f9209915 Miguel Di Ciurcio Filho
        monitor_printf(mon, "There is no snapshot available.\n");
1152 f9209915 Miguel Di Ciurcio Filho
        return;
1153 f9209915 Miguel Di Ciurcio Filho
    }
1154 f9209915 Miguel Di Ciurcio Filho
1155 7267c094 Anthony Liguori
    available_snapshots = g_malloc0(sizeof(int) * nb_sns);
1156 f9209915 Miguel Di Ciurcio Filho
    total = 0;
1157 f9209915 Miguel Di Ciurcio Filho
    for (i = 0; i < nb_sns; i++) {
1158 a672b469 aliguori
        sn = &sn_tab[i];
1159 f9209915 Miguel Di Ciurcio Filho
        available = 1;
1160 f9209915 Miguel Di Ciurcio Filho
        bs1 = NULL;
1161 f9209915 Miguel Di Ciurcio Filho
1162 f9209915 Miguel Di Ciurcio Filho
        while ((bs1 = bdrv_next(bs1))) {
1163 f9209915 Miguel Di Ciurcio Filho
            if (bdrv_can_snapshot(bs1) && bs1 != bs) {
1164 f9209915 Miguel Di Ciurcio Filho
                ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str);
1165 f9209915 Miguel Di Ciurcio Filho
                if (ret < 0) {
1166 f9209915 Miguel Di Ciurcio Filho
                    available = 0;
1167 f9209915 Miguel Di Ciurcio Filho
                    break;
1168 f9209915 Miguel Di Ciurcio Filho
                }
1169 f9209915 Miguel Di Ciurcio Filho
            }
1170 f9209915 Miguel Di Ciurcio Filho
        }
1171 f9209915 Miguel Di Ciurcio Filho
1172 f9209915 Miguel Di Ciurcio Filho
        if (available) {
1173 f9209915 Miguel Di Ciurcio Filho
            available_snapshots[total] = i;
1174 f9209915 Miguel Di Ciurcio Filho
            total++;
1175 f9209915 Miguel Di Ciurcio Filho
        }
1176 a672b469 aliguori
    }
1177 f9209915 Miguel Di Ciurcio Filho
1178 f9209915 Miguel Di Ciurcio Filho
    if (total > 0) {
1179 5b917044 Wenchao Xia
        bdrv_snapshot_dump((fprintf_function)monitor_printf, mon, NULL);
1180 5b917044 Wenchao Xia
        monitor_printf(mon, "\n");
1181 f9209915 Miguel Di Ciurcio Filho
        for (i = 0; i < total; i++) {
1182 f9209915 Miguel Di Ciurcio Filho
            sn = &sn_tab[available_snapshots[i]];
1183 5b917044 Wenchao Xia
            bdrv_snapshot_dump((fprintf_function)monitor_printf, mon, sn);
1184 5b917044 Wenchao Xia
            monitor_printf(mon, "\n");
1185 f9209915 Miguel Di Ciurcio Filho
        }
1186 f9209915 Miguel Di Ciurcio Filho
    } else {
1187 f9209915 Miguel Di Ciurcio Filho
        monitor_printf(mon, "There is no suitable snapshot available\n");
1188 f9209915 Miguel Di Ciurcio Filho
    }
1189 f9209915 Miguel Di Ciurcio Filho
1190 7267c094 Anthony Liguori
    g_free(sn_tab);
1191 7267c094 Anthony Liguori
    g_free(available_snapshots);
1192 f9209915 Miguel Di Ciurcio Filho
1193 a672b469 aliguori
}
1194 c5705a77 Avi Kivity
1195 c5705a77 Avi Kivity
void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
1196 c5705a77 Avi Kivity
{
1197 1ddde087 Avi Kivity
    qemu_ram_set_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK,
1198 c5705a77 Avi Kivity
                       memory_region_name(mr), dev);
1199 c5705a77 Avi Kivity
}
1200 c5705a77 Avi Kivity
1201 c5705a77 Avi Kivity
void vmstate_unregister_ram(MemoryRegion *mr, DeviceState *dev)
1202 c5705a77 Avi Kivity
{
1203 c5705a77 Avi Kivity
    /* Nothing do to while the implementation is in RAMBlock */
1204 c5705a77 Avi Kivity
}
1205 c5705a77 Avi Kivity
1206 c5705a77 Avi Kivity
void vmstate_register_ram_global(MemoryRegion *mr)
1207 c5705a77 Avi Kivity
{
1208 c5705a77 Avi Kivity
    vmstate_register_ram(mr, NULL);
1209 c5705a77 Avi Kivity
}