savevm.c 58.6 KB
Newer Older
A
aliguori 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <sys/time.h>
#include <zlib.h>

J
Juan Quintela 已提交
31
/* Needed early for CONFIG_BSD etc. */
B
blueswir1 已提交
32 33
#include "config-host.h"

A
aliguori 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47
#ifndef _WIN32
#include <sys/times.h>
#include <sys/wait.h>
#include <termios.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <netdb.h>
#include <sys/select.h>
J
Juan Quintela 已提交
48
#ifdef CONFIG_BSD
A
aliguori 已提交
49
#include <sys/stat.h>
A
Aurelien Jarno 已提交
50
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
A
aliguori 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63
#include <libutil.h>
#else
#include <util.h>
#endif
#ifdef __linux__
#include <pty.h>
#include <malloc.h>
#include <linux/rtc.h>
#endif
#endif
#endif

#ifdef _WIN32
64
#include <windows.h>
A
aliguori 已提交
65 66 67 68 69 70 71
#include <malloc.h>
#include <sys/timeb.h>
#include <mmsystem.h>
#define getopt_long_only getopt_long
#define memalign(align, size) malloc(size)
#endif

72 73
#include "qemu-common.h"
#include "hw/hw.h"
74
#include "hw/qdev.h"
75 76 77 78 79 80 81 82
#include "net.h"
#include "monitor.h"
#include "sysemu.h"
#include "qemu-timer.h"
#include "qemu-char.h"
#include "audio/audio.h"
#include "migration.h"
#include "qemu_socket.h"
B
Blue Swirl 已提交
83
#include "qemu-queue.h"
84
#include "qemu-timer.h"
85
#include "cpus.h"
86
#include "memory.h"
87
#include "qmp-commands.h"
88

A
aliguori 已提交
89 90
#define SELF_ANNOUNCE_ROUNDS 5

N
Nolan 已提交
91
#ifndef ETH_P_RARP
S
Stefan Berger 已提交
92
#define ETH_P_RARP 0x8035
N
Nolan 已提交
93 94 95 96 97 98
#endif
#define ARP_HTYPE_ETH 0x0001
#define ARP_PTYPE_IP 0x0800
#define ARP_OP_REQUEST_REV 0x3

static int announce_self_create(uint8_t *buf,
A
aliguori 已提交
99 100
				uint8_t *mac_addr)
{
N
Nolan 已提交
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
    /* Ethernet header. */
    memset(buf, 0xff, 6);         /* destination MAC addr */
    memcpy(buf + 6, mac_addr, 6); /* source MAC addr */
    *(uint16_t *)(buf + 12) = htons(ETH_P_RARP); /* ethertype */

    /* RARP header. */
    *(uint16_t *)(buf + 14) = htons(ARP_HTYPE_ETH); /* hardware addr space */
    *(uint16_t *)(buf + 16) = htons(ARP_PTYPE_IP); /* protocol addr space */
    *(buf + 18) = 6; /* hardware addr length (ethernet) */
    *(buf + 19) = 4; /* protocol addr length (IPv4) */
    *(uint16_t *)(buf + 20) = htons(ARP_OP_REQUEST_REV); /* opcode */
    memcpy(buf + 22, mac_addr, 6); /* source hw addr */
    memset(buf + 28, 0x00, 4);     /* source protocol addr */
    memcpy(buf + 32, mac_addr, 6); /* target hw addr */
    memset(buf + 38, 0x00, 4);     /* target protocol addr */

    /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
    memset(buf + 42, 0x00, 18);

    return 60; /* len (FCS will be added by hardware) */
A
aliguori 已提交
121 122
}

M
Mark McLoughlin 已提交
123
static void qemu_announce_self_iter(NICState *nic, void *opaque)
A
aliguori 已提交
124
{
N
Nolan 已提交
125
    uint8_t buf[60];
M
Mark McLoughlin 已提交
126 127 128 129 130 131 132 133 134 135
    int len;

    len = announce_self_create(buf, nic->conf->macaddr.a);

    qemu_send_packet_raw(&nic->nc, buf, len);
}


static void qemu_announce_self_once(void *opaque)
{
136 137
    static int count = SELF_ANNOUNCE_ROUNDS;
    QEMUTimer *timer = *(QEMUTimer **)opaque;
A
aliguori 已提交
138

M
Mark McLoughlin 已提交
139 140
    qemu_foreach_nic(qemu_announce_self_iter, NULL);

N
Nolan 已提交
141 142
    if (--count) {
        /* delay 50ms, 150ms, 250ms, ... */
143
        qemu_mod_timer(timer, qemu_get_clock_ms(rt_clock) +
N
Nolan 已提交
144
                       50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);
145 146 147 148 149 150 151 152 153
    } else {
	    qemu_del_timer(timer);
	    qemu_free_timer(timer);
    }
}

void qemu_announce_self(void)
{
	static QEMUTimer *timer;
154
	timer = qemu_new_timer_ms(rt_clock, qemu_announce_self_once, &timer);
155
	qemu_announce_self_once(&timer);
A
aliguori 已提交
156 157 158 159 160 161 162 163 164 165 166 167
}

/***********************************************************/
/* savevm/loadvm support */

#define IO_BUF_SIZE 32768

struct QEMUFile {
    QEMUFilePutBufferFunc *put_buffer;
    QEMUFileGetBufferFunc *get_buffer;
    QEMUFileCloseFunc *close;
    QEMUFileRateLimit *rate_limit;
168
    QEMUFileSetRateLimit *set_rate_limit;
L
lirans@il.ibm.com 已提交
169
    QEMUFileGetRateLimit *get_rate_limit;
A
aliguori 已提交
170 171 172 173 174 175 176 177 178
    void *opaque;
    int is_write;

    int64_t buf_offset; /* start of buffer when writing, end of buffer
                           when reading */
    int buf_index;
    int buf_size; /* 0 when writing */
    uint8_t buf[IO_BUF_SIZE];

179
    int last_error;
A
aliguori 已提交
180 181
};

P
Paolo Bonzini 已提交
182
typedef struct QEMUFileStdio
A
aliguori 已提交
183
{
P
Paolo Bonzini 已提交
184
    FILE *stdio_file;
A
aliguori 已提交
185
    QEMUFile *file;
P
Paolo Bonzini 已提交
186
} QEMUFileStdio;
A
aliguori 已提交
187 188 189 190 191 192 193 194 195 196 197 198 199

typedef struct QEMUFileSocket
{
    int fd;
    QEMUFile *file;
} QEMUFileSocket;

static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
{
    QEMUFileSocket *s = opaque;
    ssize_t len;

    do {
B
Blue Swirl 已提交
200
        len = qemu_recv(s->fd, buf, size, 0);
A
aliguori 已提交
201 202 203 204 205 206 207 208 209 210 211
    } while (len == -1 && socket_error() == EINTR);

    if (len == -1)
        len = -socket_error();

    return len;
}

static int socket_close(void *opaque)
{
    QEMUFileSocket *s = opaque;
212
    g_free(s);
A
aliguori 已提交
213 214 215
    return 0;
}

P
Paolo Bonzini 已提交
216
static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
A
aliguori 已提交
217
{
P
Paolo Bonzini 已提交
218 219
    QEMUFileStdio *s = opaque;
    return fwrite(buf, 1, size, s->stdio_file);
A
aliguori 已提交
220 221
}

P
Paolo Bonzini 已提交
222
static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
A
aliguori 已提交
223
{
P
Paolo Bonzini 已提交
224 225
    QEMUFileStdio *s = opaque;
    FILE *fp = s->stdio_file;
226 227 228 229 230 231 232
    int bytes;

    do {
        clearerr(fp);
        bytes = fread(buf, 1, size, fp);
    } while ((bytes == 0) && ferror(fp) && (errno == EINTR));
    return bytes;
A
aliguori 已提交
233 234
}

P
Paolo Bonzini 已提交
235 236 237
static int stdio_pclose(void *opaque)
{
    QEMUFileStdio *s = opaque;
238 239
    int ret;
    ret = pclose(s->stdio_file);
240 241 242
    if (ret == -1) {
        ret = -errno;
    }
243
    g_free(s);
244
    return ret;
P
Paolo Bonzini 已提交
245 246 247
}

static int stdio_fclose(void *opaque)
A
aliguori 已提交
248
{
P
Paolo Bonzini 已提交
249
    QEMUFileStdio *s = opaque;
250 251 252 253
    int ret = 0;
    if (fclose(s->stdio_file) == EOF) {
        ret = -errno;
    }
254
    g_free(s);
255
    return ret;
A
aliguori 已提交
256 257
}

P
Paolo Bonzini 已提交
258
QEMUFile *qemu_popen(FILE *stdio_file, const char *mode)
A
aliguori 已提交
259
{
P
Paolo Bonzini 已提交
260
    QEMUFileStdio *s;
A
aliguori 已提交
261

P
Paolo Bonzini 已提交
262
    if (stdio_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
A
aliguori 已提交
263 264 265 266
        fprintf(stderr, "qemu_popen: Argument validity check failed\n");
        return NULL;
    }

267
    s = g_malloc0(sizeof(QEMUFileStdio));
A
aliguori 已提交
268

P
Paolo Bonzini 已提交
269
    s->stdio_file = stdio_file;
A
aliguori 已提交
270 271

    if(mode[0] == 'r') {
L
lirans@il.ibm.com 已提交
272 273
        s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_pclose, 
				 NULL, NULL, NULL);
A
aliguori 已提交
274
    } else {
L
lirans@il.ibm.com 已提交
275 276
        s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_pclose, 
				 NULL, NULL, NULL);
A
aliguori 已提交
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
    }
    return s->file;
}

QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
{
    FILE *popen_file;

    popen_file = popen(command, mode);
    if(popen_file == NULL) {
        return NULL;
    }

    return qemu_popen(popen_file, mode);
}

P
Paolo Bonzini 已提交
293
int qemu_stdio_fd(QEMUFile *f)
294
{
P
Paolo Bonzini 已提交
295
    QEMUFileStdio *p;
296 297
    int fd;

P
Paolo Bonzini 已提交
298 299
    p = (QEMUFileStdio *)f->opaque;
    fd = fileno(p->stdio_file);
300 301 302 303

    return fd;
}

P
Paolo Bonzini 已提交
304 305 306 307 308 309 310 311 312 313 314
QEMUFile *qemu_fdopen(int fd, const char *mode)
{
    QEMUFileStdio *s;

    if (mode == NULL ||
	(mode[0] != 'r' && mode[0] != 'w') ||
	mode[1] != 'b' || mode[2] != 0) {
        fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
        return NULL;
    }

315
    s = g_malloc0(sizeof(QEMUFileStdio));
P
Paolo Bonzini 已提交
316 317 318 319 320
    s->stdio_file = fdopen(fd, mode);
    if (!s->stdio_file)
        goto fail;

    if(mode[0] == 'r') {
L
lirans@il.ibm.com 已提交
321 322
        s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_fclose, 
				 NULL, NULL, NULL);
P
Paolo Bonzini 已提交
323
    } else {
L
lirans@il.ibm.com 已提交
324 325
        s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_fclose, 
				 NULL, NULL, NULL);
P
Paolo Bonzini 已提交
326 327 328 329
    }
    return s->file;

fail:
330
    g_free(s);
P
Paolo Bonzini 已提交
331 332 333
    return NULL;
}

A
aliguori 已提交
334 335
QEMUFile *qemu_fopen_socket(int fd)
{
336
    QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket));
A
aliguori 已提交
337 338

    s->fd = fd;
L
lirans@il.ibm.com 已提交
339 340
    s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, 
			     NULL, NULL, NULL);
A
aliguori 已提交
341 342 343 344 345 346 347
    return s->file;
}

static int file_put_buffer(void *opaque, const uint8_t *buf,
                            int64_t pos, int size)
{
    QEMUFileStdio *s = opaque;
P
Paolo Bonzini 已提交
348
    fseek(s->stdio_file, pos, SEEK_SET);
349
    return fwrite(buf, 1, size, s->stdio_file);
A
aliguori 已提交
350 351 352 353 354
}

static int file_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
{
    QEMUFileStdio *s = opaque;
P
Paolo Bonzini 已提交
355 356
    fseek(s->stdio_file, pos, SEEK_SET);
    return fread(buf, 1, size, s->stdio_file);
A
aliguori 已提交
357 358 359 360 361 362
}

QEMUFile *qemu_fopen(const char *filename, const char *mode)
{
    QEMUFileStdio *s;

P
Paolo Bonzini 已提交
363 364 365
    if (mode == NULL ||
	(mode[0] != 'r' && mode[0] != 'w') ||
	mode[1] != 'b' || mode[2] != 0) {
B
Blue Swirl 已提交
366
        fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
P
Paolo Bonzini 已提交
367 368 369
        return NULL;
    }

370
    s = g_malloc0(sizeof(QEMUFileStdio));
A
aliguori 已提交
371

P
Paolo Bonzini 已提交
372 373
    s->stdio_file = fopen(filename, mode);
    if (!s->stdio_file)
A
aliguori 已提交
374
        goto fail;
L
lirans@il.ibm.com 已提交
375
    
P
Paolo Bonzini 已提交
376
    if(mode[0] == 'w') {
L
lirans@il.ibm.com 已提交
377 378
        s->file = qemu_fopen_ops(s, file_put_buffer, NULL, stdio_fclose, 
				 NULL, NULL, NULL);
P
Paolo Bonzini 已提交
379
    } else {
L
lirans@il.ibm.com 已提交
380 381
        s->file = qemu_fopen_ops(s, NULL, file_get_buffer, stdio_fclose, 
			       NULL, NULL, NULL);
P
Paolo Bonzini 已提交
382 383
    }
    return s->file;
A
aliguori 已提交
384
fail:
385
    g_free(s);
A
aliguori 已提交
386 387 388
    return NULL;
}

389
static int block_put_buffer(void *opaque, const uint8_t *buf,
A
aliguori 已提交
390 391
                           int64_t pos, int size)
{
392
    bdrv_save_vmstate(opaque, buf, pos, size);
A
aliguori 已提交
393 394 395
    return size;
}

396
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
A
aliguori 已提交
397
{
398
    return bdrv_load_vmstate(opaque, buf, pos, size);
A
aliguori 已提交
399 400 401 402 403 404 405
}

static int bdrv_fclose(void *opaque)
{
    return 0;
}

406
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
A
aliguori 已提交
407 408
{
    if (is_writable)
L
lirans@il.ibm.com 已提交
409 410 411
        return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose, 
			      NULL, NULL, NULL);
    return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclose, NULL, NULL, NULL);
A
aliguori 已提交
412 413 414 415 416
}

QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
                         QEMUFileGetBufferFunc *get_buffer,
                         QEMUFileCloseFunc *close,
417
                         QEMUFileRateLimit *rate_limit,
L
lirans@il.ibm.com 已提交
418 419
                         QEMUFileSetRateLimit *set_rate_limit,
                         QEMUFileGetRateLimit *get_rate_limit)
A
aliguori 已提交
420 421 422
{
    QEMUFile *f;

423
    f = g_malloc0(sizeof(QEMUFile));
A
aliguori 已提交
424 425 426 427 428 429

    f->opaque = opaque;
    f->put_buffer = put_buffer;
    f->get_buffer = get_buffer;
    f->close = close;
    f->rate_limit = rate_limit;
430
    f->set_rate_limit = set_rate_limit;
L
lirans@il.ibm.com 已提交
431
    f->get_rate_limit = get_rate_limit;
A
aliguori 已提交
432 433 434 435 436
    f->is_write = 0;

    return f;
}

437
int qemu_file_get_error(QEMUFile *f)
A
aliguori 已提交
438
{
439
    return f->last_error;
A
aliguori 已提交
440 441
}

442
void qemu_file_set_error(QEMUFile *f, int ret)
443
{
444
    f->last_error = ret;
445 446
}

447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
/** Sets last_error conditionally
 *
 * Sets last_error only if ret is negative _and_ no error
 * was set before.
 */
static void qemu_file_set_if_error(QEMUFile *f, int ret)
{
    if (ret < 0 && !f->last_error) {
        qemu_file_set_error(f, ret);
    }
}

/** Flushes QEMUFile buffer
 *
 * In case of error, last_error is set.
 */
A
aliguori 已提交
463 464 465 466 467 468 469 470 471 472 473 474
void qemu_fflush(QEMUFile *f)
{
    if (!f->put_buffer)
        return;

    if (f->is_write && f->buf_index > 0) {
        int len;

        len = f->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index);
        if (len > 0)
            f->buf_offset += f->buf_index;
        else
475
            qemu_file_set_error(f, -EINVAL);
A
aliguori 已提交
476 477 478 479 480 481 482
        f->buf_index = 0;
    }
}

static void qemu_fill_buffer(QEMUFile *f)
{
    int len;
483
    int pending;
A
aliguori 已提交
484 485 486 487 488 489 490

    if (!f->get_buffer)
        return;

    if (f->is_write)
        abort();

491 492 493 494 495 496 497 498 499
    pending = f->buf_size - f->buf_index;
    if (pending > 0) {
        memmove(f->buf, f->buf + f->buf_index, pending);
    }
    f->buf_index = 0;
    f->buf_size = pending;

    len = f->get_buffer(f->opaque, f->buf + pending, f->buf_offset,
                        IO_BUF_SIZE - pending);
A
aliguori 已提交
500
    if (len > 0) {
501
        f->buf_size += len;
A
aliguori 已提交
502
        f->buf_offset += len;
503 504
    } else if (len == 0) {
        f->last_error = -EIO;
A
aliguori 已提交
505
    } else if (len != -EAGAIN)
506
        qemu_file_set_error(f, len);
A
aliguori 已提交
507 508
}

509 510 511 512 513 514 515
/** Calls close function and set last_error if needed
 *
 * Internal function. qemu_fflush() must be called before this.
 *
 * Returns f->close() return value, or 0 if close function is not set.
 */
static int qemu_close(QEMUFile *f)
A
aliguori 已提交
516 517
{
    int ret = 0;
518
    if (f->close) {
A
aliguori 已提交
519
        ret = f->close(f->opaque);
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
        qemu_file_set_if_error(f, ret);
    }
    return ret;
}

/** Closes the file
 *
 * Returns negative error value if any error happened on previous operations or
 * while closing the file. Returns 0 or positive number on success.
 *
 * The meaning of return value on success depends on the specific backend
 * being used.
 */
int qemu_fclose(QEMUFile *f)
{
    int ret;
    qemu_fflush(f);
    ret = qemu_close(f);
    /* If any error was spotted before closing, we should report it
     * instead of the close() return value.
     */
    if (f->last_error) {
        ret = f->last_error;
    }
544
    g_free(f);
A
aliguori 已提交
545 546 547 548 549 550 551 552 553 554 555 556
    return ret;
}

void qemu_file_put_notify(QEMUFile *f)
{
    f->put_buffer(f->opaque, NULL, 0, 0);
}

void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
{
    int l;

557
    if (!f->last_error && f->is_write == 0 && f->buf_index > 0) {
A
aliguori 已提交
558 559 560 561 562
        fprintf(stderr,
                "Attempted to write to buffer while read buffer is not empty\n");
        abort();
    }

563
    while (!f->last_error && size > 0) {
A
aliguori 已提交
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
        l = IO_BUF_SIZE - f->buf_index;
        if (l > size)
            l = size;
        memcpy(f->buf + f->buf_index, buf, l);
        f->is_write = 1;
        f->buf_index += l;
        buf += l;
        size -= l;
        if (f->buf_index >= IO_BUF_SIZE)
            qemu_fflush(f);
    }
}

void qemu_put_byte(QEMUFile *f, int v)
{
579
    if (!f->last_error && f->is_write == 0 && f->buf_index > 0) {
A
aliguori 已提交
580 581 582 583 584 585 586 587 588 589 590
        fprintf(stderr,
                "Attempted to write to buffer while read buffer is not empty\n");
        abort();
    }

    f->buf[f->buf_index++] = v;
    f->is_write = 1;
    if (f->buf_index >= IO_BUF_SIZE)
        qemu_fflush(f);
}

591
static void qemu_file_skip(QEMUFile *f, int size)
A
aliguori 已提交
592
{
593 594 595 596 597 598
    if (f->buf_index + size <= f->buf_size) {
        f->buf_index += size;
    }
}

static int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset)
A
aliguori 已提交
599
{
600 601
    int pending;
    int index;
A
aliguori 已提交
602

J
Juan Quintela 已提交
603
    if (f->is_write) {
A
aliguori 已提交
604
        abort();
J
Juan Quintela 已提交
605
    }
A
aliguori 已提交
606

607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
    index = f->buf_index + offset;
    pending = f->buf_size - index;
    if (pending < size) {
        qemu_fill_buffer(f);
        index = f->buf_index + offset;
        pending = f->buf_size - index;
    }

    if (pending <= 0) {
        return 0;
    }
    if (size > pending) {
        size = pending;
    }

    memcpy(buf, f->buf + index, size);
    return size;
}

int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
{
    int pending = size;
    int done = 0;

    while (pending > 0) {
        int res;

        res = qemu_peek_buffer(f, buf, pending, 0);
        if (res == 0) {
            return done;
A
aliguori 已提交
637
        }
638 639 640 641
        qemu_file_skip(f, res);
        buf += res;
        pending -= res;
        done += res;
A
aliguori 已提交
642
    }
643
    return done;
A
aliguori 已提交
644 645
}

646
static int qemu_peek_byte(QEMUFile *f, int offset)
J
Juan Quintela 已提交
647
{
648 649
    int index = f->buf_index + offset;

J
Juan Quintela 已提交
650
    if (f->is_write) {
J
Juan Quintela 已提交
651
        abort();
J
Juan Quintela 已提交
652
    }
J
Juan Quintela 已提交
653

654
    if (index >= f->buf_size) {
J
Juan Quintela 已提交
655
        qemu_fill_buffer(f);
656 657
        index = f->buf_index + offset;
        if (index >= f->buf_size) {
J
Juan Quintela 已提交
658
            return 0;
J
Juan Quintela 已提交
659
        }
J
Juan Quintela 已提交
660
    }
661
    return f->buf[index];
J
Juan Quintela 已提交
662 663
}

A
aliguori 已提交
664 665
int qemu_get_byte(QEMUFile *f)
{
666
    int result;
A
aliguori 已提交
667

668 669
    result = qemu_peek_byte(f, 0);
    qemu_file_skip(f, 1);
670
    return result;
A
aliguori 已提交
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706
}

int64_t qemu_ftell(QEMUFile *f)
{
    return f->buf_offset - f->buf_size + f->buf_index;
}

int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
{
    if (whence == SEEK_SET) {
        /* nothing to do */
    } else if (whence == SEEK_CUR) {
        pos += qemu_ftell(f);
    } else {
        /* SEEK_END not supported */
        return -1;
    }
    if (f->put_buffer) {
        qemu_fflush(f);
        f->buf_offset = pos;
    } else {
        f->buf_offset = pos;
        f->buf_index = 0;
        f->buf_size = 0;
    }
    return pos;
}

int qemu_file_rate_limit(QEMUFile *f)
{
    if (f->rate_limit)
        return f->rate_limit(f->opaque);

    return 0;
}

M
Michael S. Tsirkin 已提交
707
int64_t qemu_file_get_rate_limit(QEMUFile *f)
L
lirans@il.ibm.com 已提交
708 709 710 711 712 713 714
{
    if (f->get_rate_limit)
        return f->get_rate_limit(f->opaque);

    return 0;
}

M
Michael S. Tsirkin 已提交
715
int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate)
716
{
717 718 719
    /* any failed or completed migration keeps its state to allow probing of
     * migration data, but has no associated file anymore */
    if (f && f->set_rate_limit)
720 721 722 723 724
        return f->set_rate_limit(f->opaque, new_rate);

    return 0;
}

A
aliguori 已提交
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
void qemu_put_be16(QEMUFile *f, unsigned int v)
{
    qemu_put_byte(f, v >> 8);
    qemu_put_byte(f, v);
}

void qemu_put_be32(QEMUFile *f, unsigned int v)
{
    qemu_put_byte(f, v >> 24);
    qemu_put_byte(f, v >> 16);
    qemu_put_byte(f, v >> 8);
    qemu_put_byte(f, v);
}

void qemu_put_be64(QEMUFile *f, uint64_t v)
{
    qemu_put_be32(f, v >> 32);
    qemu_put_be32(f, v);
}

unsigned int qemu_get_be16(QEMUFile *f)
{
    unsigned int v;
    v = qemu_get_byte(f) << 8;
    v |= qemu_get_byte(f);
    return v;
}

unsigned int qemu_get_be32(QEMUFile *f)
{
    unsigned int v;
    v = qemu_get_byte(f) << 24;
    v |= qemu_get_byte(f) << 16;
    v |= qemu_get_byte(f) << 8;
    v |= qemu_get_byte(f);
    return v;
}

uint64_t qemu_get_be64(QEMUFile *f)
{
    uint64_t v;
    v = (uint64_t)qemu_get_be32(f) << 32;
    v |= qemu_get_be32(f);
    return v;
}

771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794

/* timer */

void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
{
    uint64_t expire_time;

    expire_time = qemu_timer_expire_time_ns(ts);
    qemu_put_be64(f, expire_time);
}

void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
{
    uint64_t expire_time;

    expire_time = qemu_get_be64(f);
    if (expire_time != -1) {
        qemu_mod_timer_ns(ts, expire_time);
    } else {
        qemu_del_timer(ts);
    }
}


G
Gerd Hoffmann 已提交
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
/* bool */

static int get_bool(QEMUFile *f, void *pv, size_t size)
{
    bool *v = pv;
    *v = qemu_get_byte(f);
    return 0;
}

static void put_bool(QEMUFile *f, void *pv, size_t size)
{
    bool *v = pv;
    qemu_put_byte(f, *v);
}

const VMStateInfo vmstate_info_bool = {
    .name = "bool",
    .get  = get_bool,
    .put  = put_bool,
};

816 817 818 819 820 821 822 823 824
/* 8 bit int */

static int get_int8(QEMUFile *f, void *pv, size_t size)
{
    int8_t *v = pv;
    qemu_get_s8s(f, v);
    return 0;
}

825
static void put_int8(QEMUFile *f, void *pv, size_t size)
826
{
827
    int8_t *v = pv;
828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845
    qemu_put_s8s(f, v);
}

const VMStateInfo vmstate_info_int8 = {
    .name = "int8",
    .get  = get_int8,
    .put  = put_int8,
};

/* 16 bit int */

static int get_int16(QEMUFile *f, void *pv, size_t size)
{
    int16_t *v = pv;
    qemu_get_sbe16s(f, v);
    return 0;
}

846
static void put_int16(QEMUFile *f, void *pv, size_t size)
847
{
848
    int16_t *v = pv;
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
    qemu_put_sbe16s(f, v);
}

const VMStateInfo vmstate_info_int16 = {
    .name = "int16",
    .get  = get_int16,
    .put  = put_int16,
};

/* 32 bit int */

static int get_int32(QEMUFile *f, void *pv, size_t size)
{
    int32_t *v = pv;
    qemu_get_sbe32s(f, v);
    return 0;
}

867
static void put_int32(QEMUFile *f, void *pv, size_t size)
868
{
869
    int32_t *v = pv;
870 871 872 873 874 875 876 877 878
    qemu_put_sbe32s(f, v);
}

const VMStateInfo vmstate_info_int32 = {
    .name = "int32",
    .get  = get_int32,
    .put  = put_int32,
};

879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898
/* 32 bit int. See that the received value is the same than the one
   in the field */

static int get_int32_equal(QEMUFile *f, void *pv, size_t size)
{
    int32_t *v = pv;
    int32_t v2;
    qemu_get_sbe32s(f, &v2);

    if (*v == v2)
        return 0;
    return -EINVAL;
}

const VMStateInfo vmstate_info_int32_equal = {
    .name = "int32 equal",
    .get  = get_int32_equal,
    .put  = put_int32,
};

899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
/* 32 bit int. See that the received value is the less or the same
   than the one in the field */

static int get_int32_le(QEMUFile *f, void *pv, size_t size)
{
    int32_t *old = pv;
    int32_t new;
    qemu_get_sbe32s(f, &new);

    if (*old <= new)
        return 0;
    return -EINVAL;
}

const VMStateInfo vmstate_info_int32_le = {
    .name = "int32 equal",
    .get  = get_int32_le,
    .put  = put_int32,
};

919 920 921 922 923 924 925 926 927
/* 64 bit int */

static int get_int64(QEMUFile *f, void *pv, size_t size)
{
    int64_t *v = pv;
    qemu_get_sbe64s(f, v);
    return 0;
}

928
static void put_int64(QEMUFile *f, void *pv, size_t size)
929
{
930
    int64_t *v = pv;
931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948
    qemu_put_sbe64s(f, v);
}

const VMStateInfo vmstate_info_int64 = {
    .name = "int64",
    .get  = get_int64,
    .put  = put_int64,
};

/* 8 bit unsigned int */

static int get_uint8(QEMUFile *f, void *pv, size_t size)
{
    uint8_t *v = pv;
    qemu_get_8s(f, v);
    return 0;
}

949
static void put_uint8(QEMUFile *f, void *pv, size_t size)
950
{
951
    uint8_t *v = pv;
952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969
    qemu_put_8s(f, v);
}

const VMStateInfo vmstate_info_uint8 = {
    .name = "uint8",
    .get  = get_uint8,
    .put  = put_uint8,
};

/* 16 bit unsigned int */

static int get_uint16(QEMUFile *f, void *pv, size_t size)
{
    uint16_t *v = pv;
    qemu_get_be16s(f, v);
    return 0;
}

970
static void put_uint16(QEMUFile *f, void *pv, size_t size)
971
{
972
    uint16_t *v = pv;
973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
    qemu_put_be16s(f, v);
}

const VMStateInfo vmstate_info_uint16 = {
    .name = "uint16",
    .get  = get_uint16,
    .put  = put_uint16,
};

/* 32 bit unsigned int */

static int get_uint32(QEMUFile *f, void *pv, size_t size)
{
    uint32_t *v = pv;
    qemu_get_be32s(f, v);
    return 0;
}

991
static void put_uint32(QEMUFile *f, void *pv, size_t size)
992
{
993
    uint32_t *v = pv;
994 995 996 997 998 999 1000 1001 1002
    qemu_put_be32s(f, v);
}

const VMStateInfo vmstate_info_uint32 = {
    .name = "uint32",
    .get  = get_uint32,
    .put  = put_uint32,
};

1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
/* 32 bit uint. See that the received value is the same than the one
   in the field */

static int get_uint32_equal(QEMUFile *f, void *pv, size_t size)
{
    uint32_t *v = pv;
    uint32_t v2;
    qemu_get_be32s(f, &v2);

    if (*v == v2) {
        return 0;
    }
    return -EINVAL;
}

const VMStateInfo vmstate_info_uint32_equal = {
    .name = "uint32 equal",
    .get  = get_uint32_equal,
    .put  = put_uint32,
};

1024 1025 1026 1027 1028 1029 1030 1031 1032
/* 64 bit unsigned int */

static int get_uint64(QEMUFile *f, void *pv, size_t size)
{
    uint64_t *v = pv;
    qemu_get_be64s(f, v);
    return 0;
}

1033
static void put_uint64(QEMUFile *f, void *pv, size_t size)
1034
{
1035
    uint64_t *v = pv;
1036 1037 1038 1039 1040 1041 1042 1043 1044
    qemu_put_be64s(f, v);
}

const VMStateInfo vmstate_info_uint64 = {
    .name = "uint64",
    .get  = get_uint64,
    .put  = put_uint64,
};

1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
/* 8 bit int. See that the received value is the same than the one
   in the field */

static int get_uint8_equal(QEMUFile *f, void *pv, size_t size)
{
    uint8_t *v = pv;
    uint8_t v2;
    qemu_get_8s(f, &v2);

    if (*v == v2)
        return 0;
    return -EINVAL;
}

const VMStateInfo vmstate_info_uint8_equal = {
J
Juan Quintela 已提交
1060
    .name = "uint8 equal",
1061 1062 1063 1064
    .get  = get_uint8_equal,
    .put  = put_uint8,
};

1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084
/* 16 bit unsigned int int. See that the received value is the same than the one
   in the field */

static int get_uint16_equal(QEMUFile *f, void *pv, size_t size)
{
    uint16_t *v = pv;
    uint16_t v2;
    qemu_get_be16s(f, &v2);

    if (*v == v2)
        return 0;
    return -EINVAL;
}

const VMStateInfo vmstate_info_uint16_equal = {
    .name = "uint16 equal",
    .get  = get_uint16_equal,
    .put  = put_uint16,
};

J
Juan Quintela 已提交
1085 1086 1087 1088 1089 1090 1091 1092 1093
/* timers  */

static int get_timer(QEMUFile *f, void *pv, size_t size)
{
    QEMUTimer *v = pv;
    qemu_get_timer(f, v);
    return 0;
}

1094
static void put_timer(QEMUFile *f, void *pv, size_t size)
J
Juan Quintela 已提交
1095
{
1096
    QEMUTimer *v = pv;
J
Juan Quintela 已提交
1097 1098 1099 1100 1101 1102 1103 1104 1105
    qemu_put_timer(f, v);
}

const VMStateInfo vmstate_info_timer = {
    .name = "timer",
    .get  = get_timer,
    .put  = put_timer,
};

1106 1107 1108 1109 1110 1111 1112 1113 1114
/* uint8_t buffers */

static int get_buffer(QEMUFile *f, void *pv, size_t size)
{
    uint8_t *v = pv;
    qemu_get_buffer(f, v, size);
    return 0;
}

1115
static void put_buffer(QEMUFile *f, void *pv, size_t size)
1116
{
1117
    uint8_t *v = pv;
1118 1119 1120 1121 1122 1123 1124 1125 1126
    qemu_put_buffer(f, v, size);
}

const VMStateInfo vmstate_info_buffer = {
    .name = "buffer",
    .get  = get_buffer,
    .put  = put_buffer,
};

J
Juan Quintela 已提交
1127
/* unused buffers: space that was used for some fields that are
1128
   not useful anymore */
J
Juan Quintela 已提交
1129 1130 1131

static int get_unused_buffer(QEMUFile *f, void *pv, size_t size)
{
J
Jan Kiszka 已提交
1132 1133 1134 1135 1136 1137 1138 1139 1140
    uint8_t buf[1024];
    int block_len;

    while (size > 0) {
        block_len = MIN(sizeof(buf), size);
        size -= block_len;
        qemu_get_buffer(f, buf, block_len);
    }
   return 0;
J
Juan Quintela 已提交
1141 1142 1143 1144
}

static void put_unused_buffer(QEMUFile *f, void *pv, size_t size)
{
J
Jan Kiszka 已提交
1145 1146 1147 1148 1149 1150 1151 1152
    static const uint8_t buf[1024];
    int block_len;

    while (size > 0) {
        block_len = MIN(sizeof(buf), size);
        size -= block_len;
        qemu_put_buffer(f, buf, block_len);
    }
J
Juan Quintela 已提交
1153 1154 1155 1156 1157 1158 1159 1160
}

const VMStateInfo vmstate_info_unused_buffer = {
    .name = "unused_buffer",
    .get  = get_unused_buffer,
    .put  = put_unused_buffer,
};

1161 1162 1163 1164 1165
typedef struct CompatEntry {
    char idstr[256];
    int instance_id;
} CompatEntry;

A
aliguori 已提交
1166
typedef struct SaveStateEntry {
B
Blue Swirl 已提交
1167
    QTAILQ_ENTRY(SaveStateEntry) entry;
A
aliguori 已提交
1168 1169
    char idstr[256];
    int instance_id;
J
Jan Kiszka 已提交
1170
    int alias_id;
A
aliguori 已提交
1171 1172
    int version_id;
    int section_id;
L
lirans@il.ibm.com 已提交
1173
    SaveSetParamsHandler *set_params;
A
aliguori 已提交
1174 1175 1176
    SaveLiveStateHandler *save_live_state;
    SaveStateHandler *save_state;
    LoadStateHandler *load_state;
1177
    const VMStateDescription *vmsd;
A
aliguori 已提交
1178
    void *opaque;
1179
    CompatEntry *compat;
1180
    int no_migrate;
1181
    int is_ram;
A
aliguori 已提交
1182 1183
} SaveStateEntry;

L
lirans@il.ibm.com 已提交
1184

B
Blue Swirl 已提交
1185 1186
static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers =
    QTAILQ_HEAD_INITIALIZER(savevm_handlers);
1187
static int global_section_id;
A
aliguori 已提交
1188

1189 1190 1191 1192 1193
static int calculate_new_instance_id(const char *idstr)
{
    SaveStateEntry *se;
    int instance_id = 0;

B
Blue Swirl 已提交
1194
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
1195 1196 1197 1198 1199 1200 1201 1202
        if (strcmp(idstr, se->idstr) == 0
            && instance_id <= se->instance_id) {
            instance_id = se->instance_id + 1;
        }
    }
    return instance_id;
}

1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
static int calculate_compat_instance_id(const char *idstr)
{
    SaveStateEntry *se;
    int instance_id = 0;

    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
        if (!se->compat)
            continue;

        if (strcmp(idstr, se->compat->idstr) == 0
            && instance_id <= se->compat->instance_id) {
            instance_id = se->compat->instance_id + 1;
        }
    }
    return instance_id;
}

A
aliguori 已提交
1220 1221 1222 1223
/* TODO: Individual devices generally have very little idea about the rest
   of the system, so instance_id should be removed/replaced.
   Meanwhile pass -1 as instance_id if you do not already have a clearly
   distinguishing id for all instances of your device class. */
A
Alex Williamson 已提交
1224 1225
int register_savevm_live(DeviceState *dev,
                         const char *idstr,
A
aliguori 已提交
1226 1227
                         int instance_id,
                         int version_id,
L
lirans@il.ibm.com 已提交
1228
                         SaveSetParamsHandler *set_params,
A
aliguori 已提交
1229 1230 1231 1232 1233
                         SaveLiveStateHandler *save_live_state,
                         SaveStateHandler *save_state,
                         LoadStateHandler *load_state,
                         void *opaque)
{
1234
    SaveStateEntry *se;
A
aliguori 已提交
1235

1236
    se = g_malloc0(sizeof(SaveStateEntry));
A
aliguori 已提交
1237 1238
    se->version_id = version_id;
    se->section_id = global_section_id++;
L
lirans@il.ibm.com 已提交
1239
    se->set_params = set_params;
A
aliguori 已提交
1240 1241 1242 1243
    se->save_live_state = save_live_state;
    se->save_state = save_state;
    se->load_state = load_state;
    se->opaque = opaque;
1244
    se->vmsd = NULL;
1245
    se->no_migrate = 0;
1246 1247 1248 1249
    /* if this is a live_savem then set is_ram */
    if (save_live_state != NULL) {
        se->is_ram = 1;
    }
A
aliguori 已提交
1250

1251 1252 1253 1254 1255
    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
        char *id = dev->parent_bus->info->get_dev_path(dev);
        if (id) {
            pstrcpy(se->idstr, sizeof(se->idstr), id);
            pstrcat(se->idstr, sizeof(se->idstr), "/");
1256
            g_free(id);
1257

1258
            se->compat = g_malloc0(sizeof(CompatEntry));
1259 1260 1261 1262 1263 1264 1265 1266
            pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), idstr);
            se->compat->instance_id = instance_id == -1 ?
                         calculate_compat_instance_id(idstr) : instance_id;
            instance_id = -1;
        }
    }
    pstrcat(se->idstr, sizeof(se->idstr), idstr);

1267
    if (instance_id == -1) {
1268
        se->instance_id = calculate_new_instance_id(se->idstr);
1269 1270
    } else {
        se->instance_id = instance_id;
A
aliguori 已提交
1271
    }
1272
    assert(!se->compat || se->instance_id == 0);
1273
    /* add at the end of list */
B
Blue Swirl 已提交
1274
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
A
aliguori 已提交
1275 1276 1277
    return 0;
}

A
Alex Williamson 已提交
1278 1279
int register_savevm(DeviceState *dev,
                    const char *idstr,
A
aliguori 已提交
1280 1281 1282 1283 1284 1285
                    int instance_id,
                    int version_id,
                    SaveStateHandler *save_state,
                    LoadStateHandler *load_state,
                    void *opaque)
{
A
Alex Williamson 已提交
1286
    return register_savevm_live(dev, idstr, instance_id, version_id,
L
lirans@il.ibm.com 已提交
1287
                                NULL, NULL, save_state, load_state, opaque);
A
aliguori 已提交
1288 1289
}

A
Alex Williamson 已提交
1290
void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque)
1291
{
1292
    SaveStateEntry *se, *new_se;
1293 1294 1295 1296 1297 1298 1299
    char id[256] = "";

    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
        char *path = dev->parent_bus->info->get_dev_path(dev);
        if (path) {
            pstrcpy(id, sizeof(id), path);
            pstrcat(id, sizeof(id), "/");
1300
            g_free(path);
1301 1302 1303
        }
    }
    pstrcat(id, sizeof(id), idstr);
1304

B
Blue Swirl 已提交
1305
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
1306
        if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {
B
Blue Swirl 已提交
1307
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
1308
            if (se->compat) {
1309
                g_free(se->compat);
1310
            }
1311
            g_free(se);
1312 1313 1314 1315
        }
    }
}

A
Alex Williamson 已提交
1316
int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
J
Jan Kiszka 已提交
1317 1318 1319
                                   const VMStateDescription *vmsd,
                                   void *opaque, int alias_id,
                                   int required_for_version)
1320
{
1321
    SaveStateEntry *se;
1322

J
Jan Kiszka 已提交
1323 1324 1325
    /* If this triggers, alias support can be dropped for the vmsd. */
    assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id);

1326
    se = g_malloc0(sizeof(SaveStateEntry));
1327 1328 1329 1330 1331 1332 1333
    se->version_id = vmsd->version_id;
    se->section_id = global_section_id++;
    se->save_live_state = NULL;
    se->save_state = NULL;
    se->load_state = NULL;
    se->opaque = opaque;
    se->vmsd = vmsd;
J
Jan Kiszka 已提交
1334
    se->alias_id = alias_id;
1335
    se->no_migrate = vmsd->unmigratable;
1336

1337 1338 1339 1340 1341
    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
        char *id = dev->parent_bus->info->get_dev_path(dev);
        if (id) {
            pstrcpy(se->idstr, sizeof(se->idstr), id);
            pstrcat(se->idstr, sizeof(se->idstr), "/");
1342
            g_free(id);
1343

1344
            se->compat = g_malloc0(sizeof(CompatEntry));
1345 1346 1347 1348 1349 1350 1351 1352
            pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name);
            se->compat->instance_id = instance_id == -1 ?
                         calculate_compat_instance_id(vmsd->name) : instance_id;
            instance_id = -1;
        }
    }
    pstrcat(se->idstr, sizeof(se->idstr), vmsd->name);

1353
    if (instance_id == -1) {
1354
        se->instance_id = calculate_new_instance_id(se->idstr);
1355 1356
    } else {
        se->instance_id = instance_id;
1357
    }
1358
    assert(!se->compat || se->instance_id == 0);
1359
    /* add at the end of list */
B
Blue Swirl 已提交
1360
    QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);
1361 1362 1363
    return 0;
}

A
Alex Williamson 已提交
1364 1365
int vmstate_register(DeviceState *dev, int instance_id,
                     const VMStateDescription *vmsd, void *opaque)
J
Jan Kiszka 已提交
1366
{
A
Alex Williamson 已提交
1367 1368
    return vmstate_register_with_alias_id(dev, instance_id, vmsd,
                                          opaque, -1, 0);
J
Jan Kiszka 已提交
1369 1370
}

A
Alex Williamson 已提交
1371 1372
void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
                        void *opaque)
1373
{
1374 1375
    SaveStateEntry *se, *new_se;

B
Blue Swirl 已提交
1376
    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {
1377
        if (se->vmsd == vmsd && se->opaque == opaque) {
B
Blue Swirl 已提交
1378
            QTAILQ_REMOVE(&savevm_handlers, se, entry);
1379
            if (se->compat) {
1380
                g_free(se->compat);
1381
            }
1382
            g_free(se);
1383 1384
        }
    }
1385 1386
}

J
Juan Quintela 已提交
1387 1388 1389 1390 1391
static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
                                    void *opaque);
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
                                   void *opaque);

1392 1393 1394 1395
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
                       void *opaque, int version_id)
{
    VMStateField *field = vmsd->fields;
J
Juan Quintela 已提交
1396
    int ret;
1397 1398 1399 1400 1401 1402 1403 1404 1405 1406

    if (version_id > vmsd->version_id) {
        return -EINVAL;
    }
    if (version_id < vmsd->minimum_version_id_old) {
        return -EINVAL;
    }
    if  (version_id < vmsd->minimum_version_id) {
        return vmsd->load_state_old(f, opaque, version_id);
    }
J
Juan Quintela 已提交
1407 1408 1409 1410 1411
    if (vmsd->pre_load) {
        int ret = vmsd->pre_load(opaque);
        if (ret)
            return ret;
    }
1412
    while(field->name) {
1413 1414 1415 1416
        if ((field->field_exists &&
             field->field_exists(opaque, version_id)) ||
            (!field->field_exists &&
             field->version_id <= version_id)) {
J
Juan Quintela 已提交
1417
            void *base_addr = opaque + field->offset;
J
Juan Quintela 已提交
1418
            int i, n_elems = 1;
J
Juan Quintela 已提交
1419
            int size = field->size;
1420

J
Juan Quintela 已提交
1421 1422
            if (field->flags & VMS_VBUFFER) {
                size = *(int32_t *)(opaque+field->size_offset);
1423 1424 1425
                if (field->flags & VMS_MULTIPLY) {
                    size *= field->size;
                }
J
Juan Quintela 已提交
1426
            }
J
Juan Quintela 已提交
1427 1428
            if (field->flags & VMS_ARRAY) {
                n_elems = field->num;
1429 1430
            } else if (field->flags & VMS_VARRAY_INT32) {
                n_elems = *(int32_t *)(opaque+field->num_offset);
J
Juan Quintela 已提交
1431 1432
            } else if (field->flags & VMS_VARRAY_UINT32) {
                n_elems = *(uint32_t *)(opaque+field->num_offset);
1433 1434
            } else if (field->flags & VMS_VARRAY_UINT16) {
                n_elems = *(uint16_t *)(opaque+field->num_offset);
1435 1436
            } else if (field->flags & VMS_VARRAY_UINT8) {
                n_elems = *(uint8_t *)(opaque+field->num_offset);
J
Juan Quintela 已提交
1437
            }
J
Juan Quintela 已提交
1438
            if (field->flags & VMS_POINTER) {
J
Juan Quintela 已提交
1439
                base_addr = *(void **)base_addr + field->start;
J
Juan Quintela 已提交
1440
            }
J
Juan Quintela 已提交
1441
            for (i = 0; i < n_elems; i++) {
J
Juan Quintela 已提交
1442
                void *addr = base_addr + size * i;
J
Juan Quintela 已提交
1443

1444 1445 1446
                if (field->flags & VMS_ARRAY_OF_POINTER) {
                    addr = *(void **)addr;
                }
J
Juan Quintela 已提交
1447
                if (field->flags & VMS_STRUCT) {
1448
                    ret = vmstate_load_state(f, field->vmsd, addr, field->vmsd->version_id);
J
Juan Quintela 已提交
1449
                } else {
J
Juan Quintela 已提交
1450
                    ret = field->info->get(f, addr, size);
J
Juan Quintela 已提交
1451 1452

                }
J
Juan Quintela 已提交
1453 1454 1455
                if (ret < 0) {
                    return ret;
                }
1456 1457 1458 1459
            }
        }
        field++;
    }
J
Juan Quintela 已提交
1460 1461 1462 1463
    ret = vmstate_subsection_load(f, vmsd, opaque);
    if (ret != 0) {
        return ret;
    }
1464
    if (vmsd->post_load) {
1465
        return vmsd->post_load(opaque, version_id);
1466
    }
1467 1468 1469 1470
    return 0;
}

void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
1471
                        void *opaque)
1472 1473 1474
{
    VMStateField *field = vmsd->fields;

1475 1476 1477
    if (vmsd->pre_save) {
        vmsd->pre_save(opaque);
    }
1478
    while(field->name) {
1479 1480 1481 1482
        if (!field->field_exists ||
            field->field_exists(opaque, vmsd->version_id)) {
            void *base_addr = opaque + field->offset;
            int i, n_elems = 1;
J
Juan Quintela 已提交
1483
            int size = field->size;
J
Juan Quintela 已提交
1484

J
Juan Quintela 已提交
1485 1486
            if (field->flags & VMS_VBUFFER) {
                size = *(int32_t *)(opaque+field->size_offset);
1487 1488 1489
                if (field->flags & VMS_MULTIPLY) {
                    size *= field->size;
                }
J
Juan Quintela 已提交
1490
            }
1491 1492
            if (field->flags & VMS_ARRAY) {
                n_elems = field->num;
1493 1494
            } else if (field->flags & VMS_VARRAY_INT32) {
                n_elems = *(int32_t *)(opaque+field->num_offset);
1495 1496
            } else if (field->flags & VMS_VARRAY_UINT32) {
                n_elems = *(uint32_t *)(opaque+field->num_offset);
1497 1498
            } else if (field->flags & VMS_VARRAY_UINT16) {
                n_elems = *(uint16_t *)(opaque+field->num_offset);
1499 1500
            } else if (field->flags & VMS_VARRAY_UINT8) {
                n_elems = *(uint8_t *)(opaque+field->num_offset);
1501 1502
            }
            if (field->flags & VMS_POINTER) {
J
Juan Quintela 已提交
1503
                base_addr = *(void **)base_addr + field->start;
1504 1505
            }
            for (i = 0; i < n_elems; i++) {
J
Juan Quintela 已提交
1506
                void *addr = base_addr + size * i;
J
Juan Quintela 已提交
1507

1508 1509 1510
                if (field->flags & VMS_ARRAY_OF_POINTER) {
                    addr = *(void **)addr;
                }
1511 1512 1513
                if (field->flags & VMS_STRUCT) {
                    vmstate_save_state(f, field->vmsd, addr);
                } else {
J
Juan Quintela 已提交
1514
                    field->info->put(f, addr, size);
1515
                }
J
Juan Quintela 已提交
1516
            }
J
Juan Quintela 已提交
1517
        }
1518 1519
        field++;
    }
J
Juan Quintela 已提交
1520
    vmstate_subsection_save(f, vmsd, opaque);
1521 1522
}

1523 1524
static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
{
1525 1526 1527 1528
    if (!se->vmsd) {         /* Old style */
        return se->load_state(f, se->opaque, version_id);
    }
    return vmstate_load_state(f, se->vmsd, se->opaque, version_id);
1529 1530
}

A
Alex Williamson 已提交
1531
static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
1532
{
1533 1534
    if (!se->vmsd) {         /* Old style */
        se->save_state(f, se->opaque);
A
Alex Williamson 已提交
1535
        return;
1536 1537
    }
    vmstate_save_state(f,se->vmsd, se->opaque);
1538 1539
}

A
aliguori 已提交
1540 1541 1542 1543 1544 1545 1546 1547 1548
#define QEMU_VM_FILE_MAGIC           0x5145564d
#define QEMU_VM_FILE_VERSION_COMPAT  0x00000002
#define QEMU_VM_FILE_VERSION         0x00000003

#define QEMU_VM_EOF                  0x00
#define QEMU_VM_SECTION_START        0x01
#define QEMU_VM_SECTION_PART         0x02
#define QEMU_VM_SECTION_END          0x03
#define QEMU_VM_SECTION_FULL         0x04
J
Juan Quintela 已提交
1549
#define QEMU_VM_SUBSECTION           0x05
A
aliguori 已提交
1550

L
Luiz Capitulino 已提交
1551
bool qemu_savevm_state_blocked(Error **errp)
A
Alex Williamson 已提交
1552 1553 1554 1555 1556
{
    SaveStateEntry *se;

    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
        if (se->no_migrate) {
L
Luiz Capitulino 已提交
1557
            error_set(errp, QERR_MIGRATION_NOT_SUPPORTED, se->idstr);
A
Alex Williamson 已提交
1558 1559 1560 1561 1562 1563
            return true;
        }
    }
    return false;
}

1564
int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared)
A
aliguori 已提交
1565 1566
{
    SaveStateEntry *se;
J
Juan Quintela 已提交
1567
    int ret;
A
aliguori 已提交
1568

L
lirans@il.ibm.com 已提交
1569 1570 1571 1572 1573 1574 1575
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
        if(se->set_params == NULL) {
            continue;
	}
	se->set_params(blk_enable, shared, se->opaque);
    }
    
A
aliguori 已提交
1576 1577 1578
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);

B
Blue Swirl 已提交
1579
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
A
aliguori 已提交
1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596
        int len;

        if (se->save_live_state == NULL)
            continue;

        /* Section type */
        qemu_put_byte(f, QEMU_VM_SECTION_START);
        qemu_put_be32(f, se->section_id);

        /* ID string */
        len = strlen(se->idstr);
        qemu_put_byte(f, len);
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);

        qemu_put_be32(f, se->instance_id);
        qemu_put_be32(f, se->version_id);

1597
        ret = se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
1598
        if (ret < 0) {
1599
            qemu_savevm_state_cancel(f);
1600 1601
            return ret;
        }
A
aliguori 已提交
1602
    }
1603
    ret = qemu_file_get_error(f);
J
Juan Quintela 已提交
1604
    if (ret != 0) {
1605
        qemu_savevm_state_cancel(f);
1606
    }
A
aliguori 已提交
1607

J
Juan Quintela 已提交
1608 1609
    return ret;

A
aliguori 已提交
1610 1611
}

J
Juan Quintela 已提交
1612
/*
D
Dong Xu Wang 已提交
1613
 * this function has three return values:
J
Juan Quintela 已提交
1614 1615 1616 1617
 *   negative: there was one error, and we have -errno.
 *   0 : We haven't finished, caller have to go again
 *   1 : We have finished, we can go to complete phase
 */
1618
int qemu_savevm_state_iterate(QEMUFile *f)
A
aliguori 已提交
1619 1620 1621 1622
{
    SaveStateEntry *se;
    int ret = 1;

B
Blue Swirl 已提交
1623
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
A
aliguori 已提交
1624 1625 1626 1627 1628 1629 1630
        if (se->save_live_state == NULL)
            continue;

        /* Section type */
        qemu_put_byte(f, QEMU_VM_SECTION_PART);
        qemu_put_be32(f, se->section_id);

1631
        ret = se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque);
1632
        if (ret <= 0) {
1633 1634 1635 1636 1637 1638
            /* Do not proceed to the next vmstate before this one reported
               completion of the current stage. This serializes the migration
               and reduces the probability that a faster changing state is
               synchronized over and over again. */
            break;
        }
A
aliguori 已提交
1639
    }
J
Juan Quintela 已提交
1640 1641 1642
    if (ret != 0) {
        return ret;
    }
1643
    ret = qemu_file_get_error(f);
J
Juan Quintela 已提交
1644
    if (ret != 0) {
1645
        qemu_savevm_state_cancel(f);
1646
    }
J
Juan Quintela 已提交
1647
    return ret;
A
aliguori 已提交
1648 1649
}

1650
int qemu_savevm_state_complete(QEMUFile *f)
A
aliguori 已提交
1651 1652
{
    SaveStateEntry *se;
1653
    int ret;
A
aliguori 已提交
1654

1655 1656
    cpu_synchronize_all_states();

B
Blue Swirl 已提交
1657
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
A
aliguori 已提交
1658 1659 1660 1661 1662 1663 1664
        if (se->save_live_state == NULL)
            continue;

        /* Section type */
        qemu_put_byte(f, QEMU_VM_SECTION_END);
        qemu_put_be32(f, se->section_id);

1665
        ret = se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);
1666 1667 1668
        if (ret < 0) {
            return ret;
        }
A
aliguori 已提交
1669 1670
    }

B
Blue Swirl 已提交
1671
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
A
aliguori 已提交
1672 1673
        int len;

1674
	if (se->save_state == NULL && se->vmsd == NULL)
A
aliguori 已提交
1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688
	    continue;

        /* Section type */
        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
        qemu_put_be32(f, se->section_id);

        /* ID string */
        len = strlen(se->idstr);
        qemu_put_byte(f, len);
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);

        qemu_put_be32(f, se->instance_id);
        qemu_put_be32(f, se->version_id);

A
Alex Williamson 已提交
1689
        vmstate_save(f, se);
A
aliguori 已提交
1690 1691 1692 1693
    }

    qemu_put_byte(f, QEMU_VM_EOF);

1694
    return qemu_file_get_error(f);
A
aliguori 已提交
1695 1696
}

1697
void qemu_savevm_state_cancel(QEMUFile *f)
1698 1699 1700 1701 1702
{
    SaveStateEntry *se;

    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
        if (se->save_live_state) {
1703
            se->save_live_state(f, -1, se->opaque);
1704 1705 1706 1707
        }
    }
}

L
Luiz Capitulino 已提交
1708
static int qemu_savevm_state(QEMUFile *f)
A
aliguori 已提交
1709 1710 1711
{
    int ret;

L
Luiz Capitulino 已提交
1712
    if (qemu_savevm_state_blocked(NULL)) {
A
Alex Williamson 已提交
1713 1714 1715 1716
        ret = -EINVAL;
        goto out;
    }

1717
    ret = qemu_savevm_state_begin(f, 0, 0);
A
aliguori 已提交
1718 1719 1720 1721
    if (ret < 0)
        goto out;

    do {
1722
        ret = qemu_savevm_state_iterate(f);
A
aliguori 已提交
1723 1724 1725 1726
        if (ret < 0)
            goto out;
    } while (ret == 0);

1727
    ret = qemu_savevm_state_complete(f);
A
aliguori 已提交
1728 1729

out:
J
Juan Quintela 已提交
1730
    if (ret == 0) {
1731
        ret = qemu_file_get_error(f);
J
Juan Quintela 已提交
1732
    }
A
aliguori 已提交
1733 1734 1735 1736

    return ret;
}

1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
static int qemu_save_device_state(QEMUFile *f)
{
    SaveStateEntry *se;

    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);

    cpu_synchronize_all_states();

    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
        int len;

        if (se->is_ram) {
            continue;
        }
        if (se->save_state == NULL && se->vmsd == NULL) {
            continue;
        }

        /* Section type */
        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
        qemu_put_be32(f, se->section_id);

        /* ID string */
        len = strlen(se->idstr);
        qemu_put_byte(f, len);
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);

        qemu_put_be32(f, se->instance_id);
        qemu_put_be32(f, se->version_id);

        vmstate_save(f, se);
    }

    qemu_put_byte(f, QEMU_VM_EOF);

    return qemu_file_get_error(f);
}

A
aliguori 已提交
1776 1777 1778 1779
static SaveStateEntry *find_se(const char *idstr, int instance_id)
{
    SaveStateEntry *se;

B
Blue Swirl 已提交
1780
    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
A
aliguori 已提交
1781
        if (!strcmp(se->idstr, idstr) &&
J
Jan Kiszka 已提交
1782 1783
            (instance_id == se->instance_id ||
             instance_id == se->alias_id))
A
aliguori 已提交
1784
            return se;
1785 1786 1787 1788 1789 1790 1791
        /* Migrating from an older version? */
        if (strstr(se->idstr, idstr) && se->compat) {
            if (!strcmp(se->compat->idstr, idstr) &&
                (instance_id == se->compat->instance_id ||
                 instance_id == se->alias_id))
                return se;
        }
A
aliguori 已提交
1792 1793 1794 1795
    }
    return NULL;
}

J
Juan Quintela 已提交
1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809
static const VMStateDescription *vmstate_get_subsection(const VMStateSubsection *sub, char *idstr)
{
    while(sub && sub->needed) {
        if (strcmp(idstr, sub->vmsd->name) == 0) {
            return sub->vmsd;
        }
        sub++;
    }
    return NULL;
}

static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
                                   void *opaque)
{
1810
    while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) {
J
Juan Quintela 已提交
1811 1812
        char idstr[256];
        int ret;
1813
        uint8_t version_id, len, size;
J
Juan Quintela 已提交
1814 1815
        const VMStateDescription *sub_vmsd;

1816 1817 1818 1819 1820 1821 1822 1823 1824 1825
        len = qemu_peek_byte(f, 1);
        if (len < strlen(vmsd->name) + 1) {
            /* subsection name has be be "section_name/a" */
            return 0;
        }
        size = qemu_peek_buffer(f, (uint8_t *)idstr, len, 2);
        if (size != len) {
            return 0;
        }
        idstr[size] = 0;
J
Juan Quintela 已提交
1826

1827 1828 1829 1830
        if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) {
            /* it don't have a valid subsection name */
            return 0;
        }
1831
        sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr);
J
Juan Quintela 已提交
1832 1833 1834
        if (sub_vmsd == NULL) {
            return -ENOENT;
        }
1835 1836 1837 1838 1839
        qemu_file_skip(f, 1); /* subsection */
        qemu_file_skip(f, 1); /* len */
        qemu_file_skip(f, len); /* idstr */
        version_id = qemu_get_be32(f);

J
Juan Quintela 已提交
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868
        ret = vmstate_load_state(f, sub_vmsd, opaque, version_id);
        if (ret) {
            return ret;
        }
    }
    return 0;
}

static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
                                    void *opaque)
{
    const VMStateSubsection *sub = vmsd->subsections;

    while (sub && sub->needed) {
        if (sub->needed(opaque)) {
            const VMStateDescription *vmsd = sub->vmsd;
            uint8_t len;

            qemu_put_byte(f, QEMU_VM_SUBSECTION);
            len = strlen(vmsd->name);
            qemu_put_byte(f, len);
            qemu_put_buffer(f, (uint8_t *)vmsd->name, len);
            qemu_put_be32(f, vmsd->version_id);
            vmstate_save_state(f, vmsd, opaque);
        }
        sub++;
    }
}

A
aliguori 已提交
1869
typedef struct LoadStateEntry {
B
Blue Swirl 已提交
1870
    QLIST_ENTRY(LoadStateEntry) entry;
A
aliguori 已提交
1871 1872 1873 1874 1875 1876 1877
    SaveStateEntry *se;
    int section_id;
    int version_id;
} LoadStateEntry;

int qemu_loadvm_state(QEMUFile *f)
{
B
Blue Swirl 已提交
1878 1879
    QLIST_HEAD(, LoadStateEntry) loadvm_handlers =
        QLIST_HEAD_INITIALIZER(loadvm_handlers);
1880
    LoadStateEntry *le, *new_le;
A
aliguori 已提交
1881 1882 1883 1884
    uint8_t section_type;
    unsigned int v;
    int ret;

L
Luiz Capitulino 已提交
1885
    if (qemu_savevm_state_blocked(NULL)) {
A
Alex Williamson 已提交
1886 1887 1888
        return -EINVAL;
    }

A
aliguori 已提交
1889 1890 1891 1892 1893
    v = qemu_get_be32(f);
    if (v != QEMU_VM_FILE_MAGIC)
        return -EINVAL;

    v = qemu_get_be32(f);
J
Juan Quintela 已提交
1894 1895 1896 1897
    if (v == QEMU_VM_FILE_VERSION_COMPAT) {
        fprintf(stderr, "SaveVM v2 format is obsolete and don't work anymore\n");
        return -ENOTSUP;
    }
A
aliguori 已提交
1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934
    if (v != QEMU_VM_FILE_VERSION)
        return -ENOTSUP;

    while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
        uint32_t instance_id, version_id, section_id;
        SaveStateEntry *se;
        char idstr[257];
        int len;

        switch (section_type) {
        case QEMU_VM_SECTION_START:
        case QEMU_VM_SECTION_FULL:
            /* Read section start */
            section_id = qemu_get_be32(f);
            len = qemu_get_byte(f);
            qemu_get_buffer(f, (uint8_t *)idstr, len);
            idstr[len] = 0;
            instance_id = qemu_get_be32(f);
            version_id = qemu_get_be32(f);

            /* Find savevm section */
            se = find_se(idstr, instance_id);
            if (se == NULL) {
                fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
                ret = -EINVAL;
                goto out;
            }

            /* Validate version */
            if (version_id > se->version_id) {
                fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
                        version_id, idstr, se->version_id);
                ret = -EINVAL;
                goto out;
            }

            /* Add entry */
1935
            le = g_malloc0(sizeof(*le));
A
aliguori 已提交
1936 1937 1938 1939

            le->se = se;
            le->section_id = section_id;
            le->version_id = version_id;
B
Blue Swirl 已提交
1940
            QLIST_INSERT_HEAD(&loadvm_handlers, le, entry);
A
aliguori 已提交
1941

1942
            ret = vmstate_load(f, le->se, le->version_id);
1943 1944 1945 1946 1947
            if (ret < 0) {
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
                        instance_id, idstr);
                goto out;
            }
A
aliguori 已提交
1948 1949 1950 1951 1952
            break;
        case QEMU_VM_SECTION_PART:
        case QEMU_VM_SECTION_END:
            section_id = qemu_get_be32(f);

B
Blue Swirl 已提交
1953
            QLIST_FOREACH(le, &loadvm_handlers, entry) {
1954 1955 1956 1957
                if (le->section_id == section_id) {
                    break;
                }
            }
A
aliguori 已提交
1958 1959 1960 1961 1962 1963
            if (le == NULL) {
                fprintf(stderr, "Unknown savevm section %d\n", section_id);
                ret = -EINVAL;
                goto out;
            }

1964
            ret = vmstate_load(f, le->se, le->version_id);
1965 1966 1967 1968 1969
            if (ret < 0) {
                fprintf(stderr, "qemu: warning: error while loading state section id %d\n",
                        section_id);
                goto out;
            }
A
aliguori 已提交
1970 1971 1972 1973 1974 1975 1976 1977
            break;
        default:
            fprintf(stderr, "Unknown savevm section type %d\n", section_type);
            ret = -EINVAL;
            goto out;
        }
    }

1978 1979
    cpu_synchronize_all_post_init();

A
aliguori 已提交
1980 1981 1982
    ret = 0;

out:
B
Blue Swirl 已提交
1983 1984
    QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {
        QLIST_REMOVE(le, entry);
1985
        g_free(le);
A
aliguori 已提交
1986 1987
    }

1988 1989
    if (ret == 0) {
        ret = qemu_file_get_error(f);
1990
    }
A
aliguori 已提交
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012

    return ret;
}

static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
                              const char *name)
{
    QEMUSnapshotInfo *sn_tab, *sn;
    int nb_sns, i, ret;

    ret = -ENOENT;
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
    if (nb_sns < 0)
        return ret;
    for(i = 0; i < nb_sns; i++) {
        sn = &sn_tab[i];
        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
            *sn_info = *sn;
            ret = 0;
            break;
        }
    }
2013
    g_free(sn_tab);
A
aliguori 已提交
2014 2015 2016
    return ret;
}

2017 2018 2019 2020 2021 2022 2023 2024 2025
/*
 * Deletes snapshots of a given name in all opened images.
 */
static int del_existing_snapshots(Monitor *mon, const char *name)
{
    BlockDriverState *bs;
    QEMUSnapshotInfo sn1, *snapshot = &sn1;
    int ret;

2026 2027
    bs = NULL;
    while ((bs = bdrv_next(bs))) {
2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043
        if (bdrv_can_snapshot(bs) &&
            bdrv_snapshot_find(bs, snapshot, name) >= 0)
        {
            ret = bdrv_snapshot_delete(bs, name);
            if (ret < 0) {
                monitor_printf(mon,
                               "Error while deleting snapshot on '%s'\n",
                               bdrv_get_device_name(bs));
                return -1;
            }
        }
    }

    return 0;
}

2044
void do_savevm(Monitor *mon, const QDict *qdict)
A
aliguori 已提交
2045 2046 2047
{
    BlockDriverState *bs, *bs1;
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
2048
    int ret;
A
aliguori 已提交
2049 2050
    QEMUFile *f;
    int saved_vm_running;
K
Kevin Wolf 已提交
2051
    uint64_t vm_state_size;
A
aliguori 已提交
2052 2053
#ifdef _WIN32
    struct _timeb tb;
2054
    struct tm *ptm;
A
aliguori 已提交
2055 2056
#else
    struct timeval tv;
2057
    struct tm tm;
A
aliguori 已提交
2058
#endif
2059
    const char *name = qdict_get_try_str(qdict, "name");
A
aliguori 已提交
2060

2061
    /* Verify if there is a device that doesn't support snapshots and is writable */
2062 2063
    bs = NULL;
    while ((bs = bdrv_next(bs))) {
2064

2065
        if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
            continue;
        }

        if (!bdrv_can_snapshot(bs)) {
            monitor_printf(mon, "Device '%s' is writable but does not support snapshots.\n",
                               bdrv_get_device_name(bs));
            return;
        }
    }

2076
    bs = bdrv_snapshots();
A
aliguori 已提交
2077
    if (!bs) {
A
aliguori 已提交
2078
        monitor_printf(mon, "No block device can accept snapshots\n");
A
aliguori 已提交
2079 2080 2081
        return;
    }

2082
    saved_vm_running = runstate_is_running();
2083
    vm_stop(RUN_STATE_SAVE_VM);
A
aliguori 已提交
2084

2085
    memset(sn, 0, sizeof(*sn));
A
aliguori 已提交
2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096

    /* fill auxiliary fields */
#ifdef _WIN32
    _ftime(&tb);
    sn->date_sec = tb.time;
    sn->date_nsec = tb.millitm * 1000000;
#else
    gettimeofday(&tv, NULL);
    sn->date_sec = tv.tv_sec;
    sn->date_nsec = tv.tv_usec * 1000;
#endif
2097
    sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
A
aliguori 已提交
2098

2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111
    if (name) {
        ret = bdrv_snapshot_find(bs, old_sn, name);
        if (ret >= 0) {
            pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
            pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
        } else {
            pstrcpy(sn->name, sizeof(sn->name), name);
        }
    } else {
#ifdef _WIN32
        ptm = localtime(&tb.time);
        strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", ptm);
#else
B
Blue Swirl 已提交
2112 2113
        /* cast below needed for OpenBSD where tv_sec is still 'long' */
        localtime_r((const time_t *)&tv.tv_sec, &tm);
2114 2115 2116 2117
        strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", &tm);
#endif
    }

2118
    /* Delete old snapshots of the same name */
2119
    if (name && del_existing_snapshots(mon, name) < 0) {
2120 2121 2122
        goto the_end;
    }

A
aliguori 已提交
2123
    /* save the VM state */
2124
    f = qemu_fopen_bdrv(bs, 1);
A
aliguori 已提交
2125
    if (!f) {
A
aliguori 已提交
2126
        monitor_printf(mon, "Could not open VM state file\n");
A
aliguori 已提交
2127 2128
        goto the_end;
    }
L
Luiz Capitulino 已提交
2129
    ret = qemu_savevm_state(f);
2130
    vm_state_size = qemu_ftell(f);
A
aliguori 已提交
2131 2132
    qemu_fclose(f);
    if (ret < 0) {
A
aliguori 已提交
2133
        monitor_printf(mon, "Error %d while writing VM\n", ret);
A
aliguori 已提交
2134 2135 2136 2137 2138
        goto the_end;
    }

    /* create the snapshots */

2139 2140
    bs1 = NULL;
    while ((bs1 = bdrv_next(bs1))) {
2141
        if (bdrv_can_snapshot(bs1)) {
2142 2143
            /* Write VM state size only to the image that contains the state */
            sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
A
aliguori 已提交
2144 2145
            ret = bdrv_snapshot_create(bs1, sn);
            if (ret < 0) {
A
aliguori 已提交
2146 2147
                monitor_printf(mon, "Error while creating snapshot on '%s'\n",
                               bdrv_get_device_name(bs1));
A
aliguori 已提交
2148 2149 2150 2151 2152 2153 2154 2155 2156
            }
        }
    }

 the_end:
    if (saved_vm_running)
        vm_start();
}

2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182
void qmp_xen_save_devices_state(const char *filename, Error **errp)
{
    QEMUFile *f;
    int saved_vm_running;
    int ret;

    saved_vm_running = runstate_is_running();
    vm_stop(RUN_STATE_SAVE_VM);

    f = qemu_fopen(filename, "wb");
    if (!f) {
        error_set(errp, QERR_OPEN_FILE_FAILED, filename);
        goto the_end;
    }
    ret = qemu_save_device_state(f);
    qemu_fclose(f);
    if (ret < 0) {
        error_set(errp, QERR_IO_ERROR);
    }

 the_end:
    if (saved_vm_running)
        vm_start();
    return;
}

2183
int load_vmstate(const char *name)
A
aliguori 已提交
2184
{
2185
    BlockDriverState *bs, *bs_vm_state;
2186
    QEMUSnapshotInfo sn;
A
aliguori 已提交
2187
    QEMUFile *f;
G
Gerd Hoffmann 已提交
2188
    int ret;
A
aliguori 已提交
2189

2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200
    bs_vm_state = bdrv_snapshots();
    if (!bs_vm_state) {
        error_report("No block device supports snapshots");
        return -ENOTSUP;
    }

    /* Don't even try to load empty VM states */
    ret = bdrv_snapshot_find(bs_vm_state, &sn, name);
    if (ret < 0) {
        return ret;
    } else if (sn.vm_state_size == 0) {
2201 2202
        error_report("This is a disk-only snapshot. Revert to it offline "
            "using qemu-img.");
2203 2204 2205 2206 2207
        return -EINVAL;
    }

    /* Verify if there is any device that doesn't support snapshots and is
    writable and check if the requested snapshot is available too. */
2208 2209
    bs = NULL;
    while ((bs = bdrv_next(bs))) {
2210

2211
        if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2212 2213 2214 2215 2216 2217 2218 2219 2220
            continue;
        }

        if (!bdrv_can_snapshot(bs)) {
            error_report("Device '%s' is writable but does not support snapshots.",
                               bdrv_get_device_name(bs));
            return -ENOTSUP;
        }

2221 2222 2223 2224 2225 2226
        ret = bdrv_snapshot_find(bs, &sn, name);
        if (ret < 0) {
            error_report("Device '%s' does not have the requested snapshot '%s'",
                           bdrv_get_device_name(bs), name);
            return ret;
        }
A
aliguori 已提交
2227 2228 2229
    }

    /* Flush all IO requests so they don't interfere with the new state.  */
2230
    bdrv_drain_all();
A
aliguori 已提交
2231

2232 2233 2234 2235
    bs = NULL;
    while ((bs = bdrv_next(bs))) {
        if (bdrv_can_snapshot(bs)) {
            ret = bdrv_snapshot_goto(bs, name);
A
aliguori 已提交
2236
            if (ret < 0) {
2237 2238 2239
                error_report("Error %d while activating snapshot '%s' on '%s'",
                             ret, name, bdrv_get_device_name(bs));
                return ret;
A
aliguori 已提交
2240 2241 2242 2243 2244
            }
        }
    }

    /* restore the VM state */
2245
    f = qemu_fopen_bdrv(bs_vm_state, 0);
A
aliguori 已提交
2246
    if (!f) {
2247
        error_report("Could not open VM state file");
2248
        return -EINVAL;
A
aliguori 已提交
2249
    }
2250

J
Jan Kiszka 已提交
2251
    qemu_system_reset(VMRESET_SILENT);
A
aliguori 已提交
2252
    ret = qemu_loadvm_state(f);
2253

A
aliguori 已提交
2254 2255
    qemu_fclose(f);
    if (ret < 0) {
2256
        error_report("Error %d while loading VM state", ret);
2257
        return ret;
A
aliguori 已提交
2258
    }
2259

2260
    return 0;
2261 2262
}

2263
void do_delvm(Monitor *mon, const QDict *qdict)
A
aliguori 已提交
2264 2265
{
    BlockDriverState *bs, *bs1;
G
Gerd Hoffmann 已提交
2266
    int ret;
2267
    const char *name = qdict_get_str(qdict, "name");
A
aliguori 已提交
2268

2269
    bs = bdrv_snapshots();
A
aliguori 已提交
2270
    if (!bs) {
A
aliguori 已提交
2271
        monitor_printf(mon, "No block device supports snapshots\n");
A
aliguori 已提交
2272 2273 2274
        return;
    }

2275 2276
    bs1 = NULL;
    while ((bs1 = bdrv_next(bs1))) {
2277
        if (bdrv_can_snapshot(bs1)) {
A
aliguori 已提交
2278 2279 2280
            ret = bdrv_snapshot_delete(bs1, name);
            if (ret < 0) {
                if (ret == -ENOTSUP)
A
aliguori 已提交
2281 2282 2283
                    monitor_printf(mon,
                                   "Snapshots not supported on device '%s'\n",
                                   bdrv_get_device_name(bs1));
A
aliguori 已提交
2284
                else
A
aliguori 已提交
2285 2286
                    monitor_printf(mon, "Error %d while deleting snapshot on "
                                   "'%s'\n", ret, bdrv_get_device_name(bs1));
A
aliguori 已提交
2287 2288 2289 2290 2291
            }
        }
    }
}

A
aliguori 已提交
2292
void do_info_snapshots(Monitor *mon)
A
aliguori 已提交
2293 2294
{
    BlockDriverState *bs, *bs1;
2295 2296 2297 2298
    QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
    int nb_sns, i, ret, available;
    int total;
    int *available_snapshots;
A
aliguori 已提交
2299 2300
    char buf[256];

2301
    bs = bdrv_snapshots();
A
aliguori 已提交
2302
    if (!bs) {
A
aliguori 已提交
2303
        monitor_printf(mon, "No available block device supports snapshots\n");
A
aliguori 已提交
2304 2305 2306 2307 2308
        return;
    }

    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
    if (nb_sns < 0) {
A
aliguori 已提交
2309
        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
A
aliguori 已提交
2310 2311
        return;
    }
2312 2313 2314 2315 2316 2317

    if (nb_sns == 0) {
        monitor_printf(mon, "There is no snapshot available.\n");
        return;
    }

2318
    available_snapshots = g_malloc0(sizeof(int) * nb_sns);
2319 2320
    total = 0;
    for (i = 0; i < nb_sns; i++) {
A
aliguori 已提交
2321
        sn = &sn_tab[i];
2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338
        available = 1;
        bs1 = NULL;

        while ((bs1 = bdrv_next(bs1))) {
            if (bdrv_can_snapshot(bs1) && bs1 != bs) {
                ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str);
                if (ret < 0) {
                    available = 0;
                    break;
                }
            }
        }

        if (available) {
            available_snapshots[total] = i;
            total++;
        }
A
aliguori 已提交
2339
    }
2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350

    if (total > 0) {
        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
        for (i = 0; i < total; i++) {
            sn = &sn_tab[available_snapshots[i]];
            monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
        }
    } else {
        monitor_printf(mon, "There is no suitable snapshot available\n");
    }

2351 2352
    g_free(sn_tab);
    g_free(available_snapshots);
2353

A
aliguori 已提交
2354
}
2355 2356 2357

void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
{
2358
    qemu_ram_set_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK,
2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370
                       memory_region_name(mr), dev);
}

void vmstate_unregister_ram(MemoryRegion *mr, DeviceState *dev)
{
    /* Nothing do to while the implementation is in RAMBlock */
}

void vmstate_register_ram_global(MemoryRegion *mr)
{
    vmstate_register_ram(mr, NULL);
}