Annotation of qemu/savevm.c, revision 1.1.1.6

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

unix.superglobalmegacorp.com