symbian-qemu-0.9.1-12/qemu-symbian-svp/savevm.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 "qemu-common.h"
       
    25 #include "hw/hw.h"
       
    26 #include "net.h"
       
    27 #include "console.h"
       
    28 #include "sysemu.h"
       
    29 #include "qemu-timer.h"
       
    30 #include "qemu-char.h"
       
    31 #include "block.h"
       
    32 #include "audio/audio.h"
       
    33 #include "migration.h"
       
    34 #include "qemu_socket.h"
       
    35 
       
    36 #include <unistd.h>
       
    37 #include <fcntl.h>
       
    38 #include <signal.h>
       
    39 #include <time.h>
       
    40 #include <errno.h>
       
    41 #include <sys/time.h>
       
    42 #include <zlib.h>
       
    43 
       
    44 #ifndef _WIN32
       
    45 #include <sys/times.h>
       
    46 #include <sys/wait.h>
       
    47 #include <termios.h>
       
    48 #include <sys/mman.h>
       
    49 #include <sys/ioctl.h>
       
    50 #include <sys/resource.h>
       
    51 #include <sys/socket.h>
       
    52 #include <netinet/in.h>
       
    53 #include <net/if.h>
       
    54 #if defined(__NetBSD__)
       
    55 #include <net/if_tap.h>
       
    56 #endif
       
    57 #ifdef __linux__
       
    58 #include <linux/if_tun.h>
       
    59 #endif
       
    60 #include <arpa/inet.h>
       
    61 #include <dirent.h>
       
    62 #include <netdb.h>
       
    63 #include <sys/select.h>
       
    64 #ifdef _BSD
       
    65 #include <sys/stat.h>
       
    66 #ifdef __FreeBSD__
       
    67 #include <libutil.h>
       
    68 #else
       
    69 #include <util.h>
       
    70 #endif
       
    71 #elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
       
    72 #include <freebsd/stdlib.h>
       
    73 #else
       
    74 #ifdef __linux__
       
    75 #include <pty.h>
       
    76 #include <malloc.h>
       
    77 #include <linux/rtc.h>
       
    78 #endif
       
    79 #endif
       
    80 #endif
       
    81 
       
    82 #ifdef _WIN32
       
    83 #include <malloc.h>
       
    84 #include <sys/timeb.h>
       
    85 #include <mmsystem.h>
       
    86 #define getopt_long_only getopt_long
       
    87 #define memalign(align, size) malloc(size)
       
    88 #endif
       
    89 
       
    90 /* point to the block driver where the snapshots are managed */
       
    91 static BlockDriverState *bs_snapshots;
       
    92 
       
    93 #define SELF_ANNOUNCE_ROUNDS 5
       
    94 #define ETH_P_EXPERIMENTAL 0x01F1 /* just a number */
       
    95 //#define ETH_P_EXPERIMENTAL 0x0012 /* make it the size of the packet */
       
    96 #define EXPERIMENTAL_MAGIC 0xf1f23f4f
       
    97 
       
    98 static int announce_self_create(uint8_t *buf, 
       
    99 				uint8_t *mac_addr)
       
   100 {
       
   101     uint32_t magic = EXPERIMENTAL_MAGIC;
       
   102     uint16_t proto = htons(ETH_P_EXPERIMENTAL);
       
   103 
       
   104     /* FIXME: should we send a different packet (arp/rarp/ping)? */
       
   105 
       
   106     memset(buf, 0xff, 6);         /* h_dst */
       
   107     memcpy(buf + 6, mac_addr, 6); /* h_src */
       
   108     memcpy(buf + 12, &proto, 2);  /* h_proto */
       
   109     memcpy(buf + 14, &magic, 4);  /* magic */
       
   110 
       
   111     return 18; /* len */
       
   112 }
       
   113 
       
   114 void qemu_announce_self(void)
       
   115 {
       
   116     int i, j, len;
       
   117     VLANState *vlan;
       
   118     VLANClientState *vc;
       
   119     uint8_t buf[256];
       
   120 
       
   121     for (i = 0; i < nb_nics; i++) {
       
   122         len = announce_self_create(buf, nd_table[i].macaddr);
       
   123         vlan = nd_table[i].vlan;
       
   124         for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
       
   125             for (j=0; j < SELF_ANNOUNCE_ROUNDS; j++)
       
   126                 vc->fd_read(vc->opaque, buf, len);
       
   127         }
       
   128     }
       
   129 }
       
   130 
       
   131 /***********************************************************/
       
   132 /* savevm/loadvm support */
       
   133 
       
   134 #define IO_BUF_SIZE 32768
       
   135 
       
   136 struct QEMUFile {
       
   137     QEMUFilePutBufferFunc *put_buffer;
       
   138     QEMUFileGetBufferFunc *get_buffer;
       
   139     QEMUFileCloseFunc *close;
       
   140     QEMUFileRateLimit *rate_limit;
       
   141     void *opaque;
       
   142     int is_write;
       
   143 
       
   144     int64_t buf_offset; /* start of buffer when writing, end of buffer
       
   145                            when reading */
       
   146     int buf_index;
       
   147     int buf_size; /* 0 when writing */
       
   148     uint8_t buf[IO_BUF_SIZE];
       
   149 
       
   150     int has_error;
       
   151 };
       
   152 
       
   153 typedef struct QEMUFilePopen
       
   154 {
       
   155     FILE *popen_file;
       
   156     QEMUFile *file;
       
   157 } QEMUFilePopen;
       
   158 
       
   159 typedef struct QEMUFileSocket
       
   160 {
       
   161     int fd;
       
   162     QEMUFile *file;
       
   163 } QEMUFileSocket;
       
   164 
       
   165 static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
       
   166 {
       
   167     QEMUFileSocket *s = opaque;
       
   168     ssize_t len;
       
   169 
       
   170     do {
       
   171         len = recv(s->fd, buf, size, 0);
       
   172     } while (len == -1 && socket_error() == EINTR);
       
   173 
       
   174     if (len == -1)
       
   175         len = -socket_error();
       
   176 
       
   177     return len;
       
   178 }
       
   179 
       
   180 static int socket_close(void *opaque)
       
   181 {
       
   182     QEMUFileSocket *s = opaque;
       
   183     qemu_free(s);
       
   184     return 0;
       
   185 }
       
   186 
       
   187 static int popen_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
       
   188 {
       
   189     QEMUFilePopen *s = opaque;
       
   190     return fwrite(buf, 1, size, s->popen_file);
       
   191 }
       
   192 
       
   193 static int popen_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
       
   194 {
       
   195     QEMUFilePopen *s = opaque;
       
   196     return fread(buf, 1, size, s->popen_file);
       
   197 }
       
   198 
       
   199 static int popen_close(void *opaque)
       
   200 {
       
   201     QEMUFilePopen *s = opaque;
       
   202     pclose(s->popen_file);
       
   203     qemu_free(s);
       
   204     return 0;
       
   205 }
       
   206 
       
   207 QEMUFile *qemu_popen(FILE *popen_file, const char *mode)
       
   208 {
       
   209     QEMUFilePopen *s;
       
   210 
       
   211     if (popen_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
       
   212         fprintf(stderr, "qemu_popen: Argument validity check failed\n");
       
   213         return NULL;
       
   214     }
       
   215 
       
   216     s = qemu_mallocz(sizeof(QEMUFilePopen));
       
   217     if (!s) {
       
   218         fprintf(stderr, "qemu_popen: malloc failed\n");
       
   219         return NULL;
       
   220     }
       
   221 
       
   222     s->popen_file = popen_file;
       
   223 
       
   224     if(mode[0] == 'r') {
       
   225         s->file = qemu_fopen_ops(s, NULL, popen_get_buffer, popen_close, NULL);
       
   226     } else {
       
   227         s->file = qemu_fopen_ops(s, popen_put_buffer, NULL, popen_close, NULL);
       
   228     }
       
   229     fprintf(stderr, "qemu_popen: returning result of qemu_fopen_ops\n");
       
   230     return s->file;
       
   231 }
       
   232 
       
   233 QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
       
   234 {
       
   235     FILE *popen_file;
       
   236 
       
   237     popen_file = popen(command, mode);
       
   238     if(popen_file == NULL) {
       
   239         return NULL;
       
   240     }
       
   241 
       
   242     return qemu_popen(popen_file, mode);
       
   243 }
       
   244 
       
   245 QEMUFile *qemu_fopen_socket(int fd)
       
   246 {
       
   247     QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket));
       
   248 
       
   249     if (s == NULL)
       
   250         return NULL;
       
   251 
       
   252     s->fd = fd;
       
   253     s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, NULL);
       
   254     return s->file;
       
   255 }
       
   256 
       
   257 typedef struct QEMUFileStdio
       
   258 {
       
   259     FILE *outfile;
       
   260 } QEMUFileStdio;
       
   261 
       
   262 static int file_put_buffer(void *opaque, const uint8_t *buf,
       
   263                             int64_t pos, int size)
       
   264 {
       
   265     QEMUFileStdio *s = opaque;
       
   266     fseek(s->outfile, pos, SEEK_SET);
       
   267     fwrite(buf, 1, size, s->outfile);
       
   268     return size;
       
   269 }
       
   270 
       
   271 static int file_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
       
   272 {
       
   273     QEMUFileStdio *s = opaque;
       
   274     fseek(s->outfile, pos, SEEK_SET);
       
   275     return fread(buf, 1, size, s->outfile);
       
   276 }
       
   277 
       
   278 static int file_close(void *opaque)
       
   279 {
       
   280     QEMUFileStdio *s = opaque;
       
   281     fclose(s->outfile);
       
   282     qemu_free(s);
       
   283     return 0;
       
   284 }
       
   285 
       
   286 QEMUFile *qemu_fopen(const char *filename, const char *mode)
       
   287 {
       
   288     QEMUFileStdio *s;
       
   289 
       
   290     s = qemu_mallocz(sizeof(QEMUFileStdio));
       
   291     if (!s)
       
   292         return NULL;
       
   293 
       
   294     s->outfile = fopen(filename, mode);
       
   295     if (!s->outfile)
       
   296         goto fail;
       
   297 
       
   298     if (!strcmp(mode, "wb"))
       
   299         return qemu_fopen_ops(s, file_put_buffer, NULL, file_close, NULL);
       
   300     else if (!strcmp(mode, "rb"))
       
   301         return qemu_fopen_ops(s, NULL, file_get_buffer, file_close, NULL);
       
   302 
       
   303 fail:
       
   304     if (s->outfile)
       
   305         fclose(s->outfile);
       
   306     qemu_free(s);
       
   307     return NULL;
       
   308 }
       
   309 
       
   310 typedef struct QEMUFileBdrv
       
   311 {
       
   312     BlockDriverState *bs;
       
   313     int64_t base_offset;
       
   314 } QEMUFileBdrv;
       
   315 
       
   316 static int bdrv_put_buffer(void *opaque, const uint8_t *buf,
       
   317                            int64_t pos, int size)
       
   318 {
       
   319     QEMUFileBdrv *s = opaque;
       
   320     bdrv_pwrite(s->bs, s->base_offset + pos, buf, size);
       
   321     return size;
       
   322 }
       
   323 
       
   324 static int bdrv_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
       
   325 {
       
   326     QEMUFileBdrv *s = opaque;
       
   327     return bdrv_pread(s->bs, s->base_offset + pos, buf, size);
       
   328 }
       
   329 
       
   330 static int bdrv_fclose(void *opaque)
       
   331 {
       
   332     QEMUFileBdrv *s = opaque;
       
   333     qemu_free(s);
       
   334     return 0;
       
   335 }
       
   336 
       
   337 static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
       
   338 {
       
   339     QEMUFileBdrv *s;
       
   340 
       
   341     s = qemu_mallocz(sizeof(QEMUFileBdrv));
       
   342     if (!s)
       
   343         return NULL;
       
   344 
       
   345     s->bs = bs;
       
   346     s->base_offset = offset;
       
   347 
       
   348     if (is_writable)
       
   349         return qemu_fopen_ops(s, bdrv_put_buffer, NULL, bdrv_fclose, NULL);
       
   350 
       
   351     return qemu_fopen_ops(s, NULL, bdrv_get_buffer, bdrv_fclose, NULL);
       
   352 }
       
   353 
       
   354 QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
       
   355                          QEMUFileGetBufferFunc *get_buffer,
       
   356                          QEMUFileCloseFunc *close,
       
   357                          QEMUFileRateLimit *rate_limit)
       
   358 {
       
   359     QEMUFile *f;
       
   360 
       
   361     f = qemu_mallocz(sizeof(QEMUFile));
       
   362     if (!f)
       
   363         return NULL;
       
   364 
       
   365     f->opaque = opaque;
       
   366     f->put_buffer = put_buffer;
       
   367     f->get_buffer = get_buffer;
       
   368     f->close = close;
       
   369     f->rate_limit = rate_limit;
       
   370     f->is_write = 0;
       
   371 
       
   372     return f;
       
   373 }
       
   374 
       
   375 int qemu_file_has_error(QEMUFile *f)
       
   376 {
       
   377     return f->has_error;
       
   378 }
       
   379 
       
   380 void qemu_fflush(QEMUFile *f)
       
   381 {
       
   382     if (!f->put_buffer)
       
   383         return;
       
   384 
       
   385     if (f->is_write && f->buf_index > 0) {
       
   386         int len;
       
   387 
       
   388         len = f->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index);
       
   389         if (len > 0)
       
   390             f->buf_offset += f->buf_index;
       
   391         else
       
   392             f->has_error = 1;
       
   393         f->buf_index = 0;
       
   394     }
       
   395 }
       
   396 
       
   397 static void qemu_fill_buffer(QEMUFile *f)
       
   398 {
       
   399     int len;
       
   400 
       
   401     if (!f->get_buffer)
       
   402         return;
       
   403 
       
   404     if (f->is_write)
       
   405         abort();
       
   406 
       
   407     len = f->get_buffer(f->opaque, f->buf, f->buf_offset, IO_BUF_SIZE);
       
   408     if (len > 0) {
       
   409         f->buf_index = 0;
       
   410         f->buf_size = len;
       
   411         f->buf_offset += len;
       
   412     } else if (len != -EAGAIN)
       
   413         f->has_error = 1;
       
   414 }
       
   415 
       
   416 int qemu_fclose(QEMUFile *f)
       
   417 {
       
   418     int ret = 0;
       
   419     qemu_fflush(f);
       
   420     if (f->close)
       
   421         ret = f->close(f->opaque);
       
   422     qemu_free(f);
       
   423     return ret;
       
   424 }
       
   425 
       
   426 void qemu_file_put_notify(QEMUFile *f)
       
   427 {
       
   428     f->put_buffer(f->opaque, NULL, 0, 0);
       
   429 }
       
   430 
       
   431 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
       
   432 {
       
   433     int l;
       
   434 
       
   435     if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
       
   436         fprintf(stderr,
       
   437                 "Attempted to write to buffer while read buffer is not empty\n");
       
   438         abort();
       
   439     }
       
   440 
       
   441     while (!f->has_error && size > 0) {
       
   442         l = IO_BUF_SIZE - f->buf_index;
       
   443         if (l > size)
       
   444             l = size;
       
   445         memcpy(f->buf + f->buf_index, buf, l);
       
   446         f->is_write = 1;
       
   447         f->buf_index += l;
       
   448         buf += l;
       
   449         size -= l;
       
   450         if (f->buf_index >= IO_BUF_SIZE)
       
   451             qemu_fflush(f);
       
   452     }
       
   453 }
       
   454 
       
   455 void qemu_put_byte(QEMUFile *f, int v)
       
   456 {
       
   457     if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
       
   458         fprintf(stderr,
       
   459                 "Attempted to write to buffer while read buffer is not empty\n");
       
   460         abort();
       
   461     }
       
   462 
       
   463     f->buf[f->buf_index++] = v;
       
   464     f->is_write = 1;
       
   465     if (f->buf_index >= IO_BUF_SIZE)
       
   466         qemu_fflush(f);
       
   467 }
       
   468 
       
   469 int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
       
   470 {
       
   471     int size, l;
       
   472 
       
   473     if (f->is_write)
       
   474         abort();
       
   475 
       
   476     size = size1;
       
   477     while (size > 0) {
       
   478         l = f->buf_size - f->buf_index;
       
   479         if (l == 0) {
       
   480             qemu_fill_buffer(f);
       
   481             l = f->buf_size - f->buf_index;
       
   482             if (l == 0)
       
   483                 break;
       
   484         }
       
   485         if (l > size)
       
   486             l = size;
       
   487         memcpy(buf, f->buf + f->buf_index, l);
       
   488         f->buf_index += l;
       
   489         buf += l;
       
   490         size -= l;
       
   491     }
       
   492     return size1 - size;
       
   493 }
       
   494 
       
   495 int qemu_get_byte(QEMUFile *f)
       
   496 {
       
   497     if (f->is_write)
       
   498         abort();
       
   499 
       
   500     if (f->buf_index >= f->buf_size) {
       
   501         qemu_fill_buffer(f);
       
   502         if (f->buf_index >= f->buf_size)
       
   503             return 0;
       
   504     }
       
   505     return f->buf[f->buf_index++];
       
   506 }
       
   507 
       
   508 int64_t qemu_ftell(QEMUFile *f)
       
   509 {
       
   510     return f->buf_offset - f->buf_size + f->buf_index;
       
   511 }
       
   512 
       
   513 int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
       
   514 {
       
   515     if (whence == SEEK_SET) {
       
   516         /* nothing to do */
       
   517     } else if (whence == SEEK_CUR) {
       
   518         pos += qemu_ftell(f);
       
   519     } else {
       
   520         /* SEEK_END not supported */
       
   521         return -1;
       
   522     }
       
   523     if (f->put_buffer) {
       
   524         qemu_fflush(f);
       
   525         f->buf_offset = pos;
       
   526     } else {
       
   527         f->buf_offset = pos;
       
   528         f->buf_index = 0;
       
   529         f->buf_size = 0;
       
   530     }
       
   531     return pos;
       
   532 }
       
   533 
       
   534 int qemu_file_rate_limit(QEMUFile *f)
       
   535 {
       
   536     if (f->rate_limit)
       
   537         return f->rate_limit(f->opaque);
       
   538 
       
   539     return 0;
       
   540 }
       
   541 
       
   542 void qemu_put_be16(QEMUFile *f, unsigned int v)
       
   543 {
       
   544     qemu_put_byte(f, v >> 8);
       
   545     qemu_put_byte(f, v);
       
   546 }
       
   547 
       
   548 void qemu_put_be32(QEMUFile *f, unsigned int v)
       
   549 {
       
   550     qemu_put_byte(f, v >> 24);
       
   551     qemu_put_byte(f, v >> 16);
       
   552     qemu_put_byte(f, v >> 8);
       
   553     qemu_put_byte(f, v);
       
   554 }
       
   555 
       
   556 void qemu_put_be64(QEMUFile *f, uint64_t v)
       
   557 {
       
   558     qemu_put_be32(f, v >> 32);
       
   559     qemu_put_be32(f, v);
       
   560 }
       
   561 
       
   562 unsigned int qemu_get_be16(QEMUFile *f)
       
   563 {
       
   564     unsigned int v;
       
   565     v = qemu_get_byte(f) << 8;
       
   566     v |= qemu_get_byte(f);
       
   567     return v;
       
   568 }
       
   569 
       
   570 unsigned int qemu_get_be32(QEMUFile *f)
       
   571 {
       
   572     unsigned int v;
       
   573     v = qemu_get_byte(f) << 24;
       
   574     v |= qemu_get_byte(f) << 16;
       
   575     v |= qemu_get_byte(f) << 8;
       
   576     v |= qemu_get_byte(f);
       
   577     return v;
       
   578 }
       
   579 
       
   580 uint64_t qemu_get_be64(QEMUFile *f)
       
   581 {
       
   582     uint64_t v;
       
   583     v = (uint64_t)qemu_get_be32(f) << 32;
       
   584     v |= qemu_get_be32(f);
       
   585     return v;
       
   586 }
       
   587 
       
   588 typedef struct SaveStateEntry {
       
   589     char idstr[256];
       
   590     int instance_id;
       
   591     int version_id;
       
   592     int section_id;
       
   593     SaveLiveStateHandler *save_live_state;
       
   594     SaveStateHandler *save_state;
       
   595     LoadStateHandler *load_state;
       
   596     void *opaque;
       
   597     struct SaveStateEntry *next;
       
   598 } SaveStateEntry;
       
   599 
       
   600 static SaveStateEntry *first_se;
       
   601 
       
   602 /* TODO: Individual devices generally have very little idea about the rest
       
   603    of the system, so instance_id should be removed/replaced.
       
   604    Meanwhile pass -1 as instance_id if you do not already have a clearly
       
   605    distinguishing id for all instances of your device class. */
       
   606 int register_savevm_live(const char *idstr,
       
   607                          int instance_id,
       
   608                          int version_id,
       
   609                          SaveLiveStateHandler *save_live_state,
       
   610                          SaveStateHandler *save_state,
       
   611                          LoadStateHandler *load_state,
       
   612                          void *opaque)
       
   613 {
       
   614     SaveStateEntry *se, **pse;
       
   615     static int global_section_id;
       
   616 
       
   617     se = qemu_malloc(sizeof(SaveStateEntry));
       
   618     if (!se)
       
   619         return -1;
       
   620     pstrcpy(se->idstr, sizeof(se->idstr), idstr);
       
   621     se->instance_id = (instance_id == -1) ? 0 : instance_id;
       
   622     se->version_id = version_id;
       
   623     se->section_id = global_section_id++;
       
   624     se->save_live_state = save_live_state;
       
   625     se->save_state = save_state;
       
   626     se->load_state = load_state;
       
   627     se->opaque = opaque;
       
   628     se->next = NULL;
       
   629 
       
   630     /* add at the end of list */
       
   631     pse = &first_se;
       
   632     while (*pse != NULL) {
       
   633         if (instance_id == -1
       
   634                 && strcmp(se->idstr, (*pse)->idstr) == 0
       
   635                 && se->instance_id <= (*pse)->instance_id)
       
   636             se->instance_id = (*pse)->instance_id + 1;
       
   637         pse = &(*pse)->next;
       
   638     }
       
   639     *pse = se;
       
   640     return 0;
       
   641 }
       
   642 
       
   643 int register_savevm(const char *idstr,
       
   644                     int instance_id,
       
   645                     int version_id,
       
   646                     SaveStateHandler *save_state,
       
   647                     LoadStateHandler *load_state,
       
   648                     void *opaque)
       
   649 {
       
   650     return register_savevm_live(idstr, instance_id, version_id,
       
   651                                 NULL, save_state, load_state, opaque);
       
   652 }
       
   653 
       
   654 #define QEMU_VM_FILE_MAGIC           0x5145564d
       
   655 #define QEMU_VM_FILE_VERSION_COMPAT  0x00000002
       
   656 #define QEMU_VM_FILE_VERSION         0x00000003
       
   657 
       
   658 #define QEMU_VM_EOF                  0x00
       
   659 #define QEMU_VM_SECTION_START        0x01
       
   660 #define QEMU_VM_SECTION_PART         0x02
       
   661 #define QEMU_VM_SECTION_END          0x03
       
   662 #define QEMU_VM_SECTION_FULL         0x04
       
   663 
       
   664 int qemu_savevm_state_begin(QEMUFile *f)
       
   665 {
       
   666     SaveStateEntry *se;
       
   667 
       
   668     qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
       
   669     qemu_put_be32(f, QEMU_VM_FILE_VERSION);
       
   670 
       
   671     for (se = first_se; se != NULL; se = se->next) {
       
   672         int len;
       
   673 
       
   674         if (se->save_live_state == NULL)
       
   675             continue;
       
   676 
       
   677         /* Section type */
       
   678         qemu_put_byte(f, QEMU_VM_SECTION_START);
       
   679         qemu_put_be32(f, se->section_id);
       
   680 
       
   681         /* ID string */
       
   682         len = strlen(se->idstr);
       
   683         qemu_put_byte(f, len);
       
   684         qemu_put_buffer(f, (uint8_t *)se->idstr, len);
       
   685 
       
   686         qemu_put_be32(f, se->instance_id);
       
   687         qemu_put_be32(f, se->version_id);
       
   688 
       
   689         se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
       
   690     }
       
   691 
       
   692     if (qemu_file_has_error(f))
       
   693         return -EIO;
       
   694 
       
   695     return 0;
       
   696 }
       
   697 
       
   698 int qemu_savevm_state_iterate(QEMUFile *f)
       
   699 {
       
   700     SaveStateEntry *se;
       
   701     int ret = 1;
       
   702 
       
   703     for (se = first_se; se != NULL; se = se->next) {
       
   704         if (se->save_live_state == NULL)
       
   705             continue;
       
   706 
       
   707         /* Section type */
       
   708         qemu_put_byte(f, QEMU_VM_SECTION_PART);
       
   709         qemu_put_be32(f, se->section_id);
       
   710 
       
   711         ret &= !!se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque);
       
   712     }
       
   713 
       
   714     if (ret)
       
   715         return 1;
       
   716 
       
   717     if (qemu_file_has_error(f))
       
   718         return -EIO;
       
   719 
       
   720     return 0;
       
   721 }
       
   722 
       
   723 int qemu_savevm_state_complete(QEMUFile *f)
       
   724 {
       
   725     SaveStateEntry *se;
       
   726 
       
   727     for (se = first_se; se != NULL; se = se->next) {
       
   728         if (se->save_live_state == NULL)
       
   729             continue;
       
   730 
       
   731         /* Section type */
       
   732         qemu_put_byte(f, QEMU_VM_SECTION_END);
       
   733         qemu_put_be32(f, se->section_id);
       
   734 
       
   735         se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);
       
   736     }
       
   737 
       
   738     for(se = first_se; se != NULL; se = se->next) {
       
   739         int len;
       
   740 
       
   741 	if (se->save_state == NULL)
       
   742 	    continue;
       
   743 
       
   744         /* Section type */
       
   745         qemu_put_byte(f, QEMU_VM_SECTION_FULL);
       
   746         qemu_put_be32(f, se->section_id);
       
   747 
       
   748         /* ID string */
       
   749         len = strlen(se->idstr);
       
   750         qemu_put_byte(f, len);
       
   751         qemu_put_buffer(f, (uint8_t *)se->idstr, len);
       
   752 
       
   753         qemu_put_be32(f, se->instance_id);
       
   754         qemu_put_be32(f, se->version_id);
       
   755 
       
   756         se->save_state(f, se->opaque);
       
   757     }
       
   758 
       
   759     qemu_put_byte(f, QEMU_VM_EOF);
       
   760 
       
   761     if (qemu_file_has_error(f))
       
   762         return -EIO;
       
   763 
       
   764     return 0;
       
   765 }
       
   766 
       
   767 int qemu_savevm_state(QEMUFile *f)
       
   768 {
       
   769     int saved_vm_running;
       
   770     int ret;
       
   771 
       
   772     saved_vm_running = vm_running;
       
   773     vm_stop(0);
       
   774 
       
   775     bdrv_flush_all();
       
   776 
       
   777     ret = qemu_savevm_state_begin(f);
       
   778     if (ret < 0)
       
   779         goto out;
       
   780 
       
   781     do {
       
   782         ret = qemu_savevm_state_iterate(f);
       
   783         if (ret < 0)
       
   784             goto out;
       
   785     } while (ret == 0);
       
   786 
       
   787     ret = qemu_savevm_state_complete(f);
       
   788 
       
   789 out:
       
   790     if (qemu_file_has_error(f))
       
   791         ret = -EIO;
       
   792 
       
   793     if (!ret && saved_vm_running)
       
   794         vm_start();
       
   795 
       
   796     return ret;
       
   797 }
       
   798 
       
   799 static SaveStateEntry *find_se(const char *idstr, int instance_id)
       
   800 {
       
   801     SaveStateEntry *se;
       
   802 
       
   803     for(se = first_se; se != NULL; se = se->next) {
       
   804         if (!strcmp(se->idstr, idstr) &&
       
   805             instance_id == se->instance_id)
       
   806             return se;
       
   807     }
       
   808     return NULL;
       
   809 }
       
   810 
       
   811 typedef struct LoadStateEntry {
       
   812     SaveStateEntry *se;
       
   813     int section_id;
       
   814     int version_id;
       
   815     struct LoadStateEntry *next;
       
   816 } LoadStateEntry;
       
   817 
       
   818 static int qemu_loadvm_state_v2(QEMUFile *f)
       
   819 {
       
   820     SaveStateEntry *se;
       
   821     int len, ret, instance_id, record_len, version_id;
       
   822     int64_t total_len, end_pos, cur_pos;
       
   823     char idstr[256];
       
   824 
       
   825     total_len = qemu_get_be64(f);
       
   826     end_pos = total_len + qemu_ftell(f);
       
   827     for(;;) {
       
   828         if (qemu_ftell(f) >= end_pos)
       
   829             break;
       
   830         len = qemu_get_byte(f);
       
   831         qemu_get_buffer(f, (uint8_t *)idstr, len);
       
   832         idstr[len] = '\0';
       
   833         instance_id = qemu_get_be32(f);
       
   834         version_id = qemu_get_be32(f);
       
   835         record_len = qemu_get_be32(f);
       
   836         cur_pos = qemu_ftell(f);
       
   837         se = find_se(idstr, instance_id);
       
   838         if (!se) {
       
   839             fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
       
   840                     instance_id, idstr);
       
   841         } else {
       
   842             ret = se->load_state(f, se->opaque, version_id);
       
   843             if (ret < 0) {
       
   844                 fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
       
   845                         instance_id, idstr);
       
   846             }
       
   847         }
       
   848         /* always seek to exact end of record */
       
   849         qemu_fseek(f, cur_pos + record_len, SEEK_SET);
       
   850     }
       
   851 
       
   852     if (qemu_file_has_error(f))
       
   853         return -EIO;
       
   854 
       
   855     return 0;
       
   856 }
       
   857 
       
   858 int qemu_loadvm_state(QEMUFile *f)
       
   859 {
       
   860     LoadStateEntry *first_le = NULL;
       
   861     uint8_t section_type;
       
   862     unsigned int v;
       
   863     int ret;
       
   864 
       
   865     v = qemu_get_be32(f);
       
   866     if (v != QEMU_VM_FILE_MAGIC)
       
   867         return -EINVAL;
       
   868 
       
   869     v = qemu_get_be32(f);
       
   870     if (v == QEMU_VM_FILE_VERSION_COMPAT)
       
   871         return qemu_loadvm_state_v2(f);
       
   872     if (v != QEMU_VM_FILE_VERSION)
       
   873         return -ENOTSUP;
       
   874 
       
   875     while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
       
   876         uint32_t instance_id, version_id, section_id;
       
   877         LoadStateEntry *le;
       
   878         SaveStateEntry *se;
       
   879         char idstr[257];
       
   880         int len;
       
   881 
       
   882         switch (section_type) {
       
   883         case QEMU_VM_SECTION_START:
       
   884         case QEMU_VM_SECTION_FULL:
       
   885             /* Read section start */
       
   886             section_id = qemu_get_be32(f);
       
   887             len = qemu_get_byte(f);
       
   888             qemu_get_buffer(f, (uint8_t *)idstr, len);
       
   889             idstr[len] = 0;
       
   890             instance_id = qemu_get_be32(f);
       
   891             version_id = qemu_get_be32(f);
       
   892 
       
   893             /* Find savevm section */
       
   894             se = find_se(idstr, instance_id);
       
   895             if (se == NULL) {
       
   896                 fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
       
   897                 ret = -EINVAL;
       
   898                 goto out;
       
   899             }
       
   900 
       
   901             /* Validate version */
       
   902             if (version_id > se->version_id) {
       
   903                 fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
       
   904                         version_id, idstr, se->version_id);
       
   905                 ret = -EINVAL;
       
   906                 goto out;
       
   907             }
       
   908 
       
   909             /* Add entry */
       
   910             le = qemu_mallocz(sizeof(*le));
       
   911             if (le == NULL) {
       
   912                 ret = -ENOMEM;
       
   913                 goto out;
       
   914             }
       
   915 
       
   916             le->se = se;
       
   917             le->section_id = section_id;
       
   918             le->version_id = version_id;
       
   919             le->next = first_le;
       
   920             first_le = le;
       
   921 
       
   922             le->se->load_state(f, le->se->opaque, le->version_id);
       
   923             break;
       
   924         case QEMU_VM_SECTION_PART:
       
   925         case QEMU_VM_SECTION_END:
       
   926             section_id = qemu_get_be32(f);
       
   927 
       
   928             for (le = first_le; le && le->section_id != section_id; le = le->next);
       
   929             if (le == NULL) {
       
   930                 fprintf(stderr, "Unknown savevm section %d\n", section_id);
       
   931                 ret = -EINVAL;
       
   932                 goto out;
       
   933             }
       
   934 
       
   935             le->se->load_state(f, le->se->opaque, le->version_id);
       
   936             break;
       
   937         default:
       
   938             fprintf(stderr, "Unknown savevm section type %d\n", section_type);
       
   939             ret = -EINVAL;
       
   940             goto out;
       
   941         }
       
   942     }
       
   943 
       
   944     ret = 0;
       
   945 
       
   946 out:
       
   947     while (first_le) {
       
   948         LoadStateEntry *le = first_le;
       
   949         first_le = first_le->next;
       
   950         qemu_free(le);
       
   951     }
       
   952 
       
   953     if (qemu_file_has_error(f))
       
   954         ret = -EIO;
       
   955 
       
   956     return ret;
       
   957 }
       
   958 
       
   959 /* device can contain snapshots */
       
   960 static int bdrv_can_snapshot(BlockDriverState *bs)
       
   961 {
       
   962     return (bs &&
       
   963             !bdrv_is_removable(bs) &&
       
   964             !bdrv_is_read_only(bs));
       
   965 }
       
   966 
       
   967 /* device must be snapshots in order to have a reliable snapshot */
       
   968 static int bdrv_has_snapshot(BlockDriverState *bs)
       
   969 {
       
   970     return (bs &&
       
   971             !bdrv_is_removable(bs) &&
       
   972             !bdrv_is_read_only(bs));
       
   973 }
       
   974 
       
   975 static BlockDriverState *get_bs_snapshots(void)
       
   976 {
       
   977     BlockDriverState *bs;
       
   978     int i;
       
   979 
       
   980     if (bs_snapshots)
       
   981         return bs_snapshots;
       
   982     for(i = 0; i <= nb_drives; i++) {
       
   983         bs = drives_table[i].bdrv;
       
   984         if (bdrv_can_snapshot(bs))
       
   985             goto ok;
       
   986     }
       
   987     return NULL;
       
   988  ok:
       
   989     bs_snapshots = bs;
       
   990     return bs;
       
   991 }
       
   992 
       
   993 static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
       
   994                               const char *name)
       
   995 {
       
   996     QEMUSnapshotInfo *sn_tab, *sn;
       
   997     int nb_sns, i, ret;
       
   998 
       
   999     ret = -ENOENT;
       
  1000     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
       
  1001     if (nb_sns < 0)
       
  1002         return ret;
       
  1003     for(i = 0; i < nb_sns; i++) {
       
  1004         sn = &sn_tab[i];
       
  1005         if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
       
  1006             *sn_info = *sn;
       
  1007             ret = 0;
       
  1008             break;
       
  1009         }
       
  1010     }
       
  1011     qemu_free(sn_tab);
       
  1012     return ret;
       
  1013 }
       
  1014 
       
  1015 static void do_savevm_file(const char *name)
       
  1016 {
       
  1017     QEMUFile *f;
       
  1018     int saved_vm_running;
       
  1019 
       
  1020     qemu_aio_flush();
       
  1021     saved_vm_running = vm_running;
       
  1022     vm_stop(0);
       
  1023 
       
  1024     f = qemu_fopen(name, "wb");
       
  1025     if (!f) {
       
  1026         term_printf("Unable to create snapshot\n");
       
  1027         return;
       
  1028     }
       
  1029 
       
  1030     qemu_savevm_state(f);
       
  1031     qemu_fclose(f);
       
  1032 
       
  1033     if (saved_vm_running)
       
  1034         vm_start();
       
  1035 }
       
  1036 
       
  1037 void do_savevm(const char *name)
       
  1038 {
       
  1039     BlockDriverState *bs, *bs1;
       
  1040     QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
       
  1041     int must_delete, ret, i;
       
  1042     BlockDriverInfo bdi1, *bdi = &bdi1;
       
  1043     QEMUFile *f;
       
  1044     int saved_vm_running;
       
  1045     uint32_t vm_state_size;
       
  1046 #ifdef _WIN32
       
  1047     struct _timeb tb;
       
  1048 #else
       
  1049     struct timeval tv;
       
  1050 #endif
       
  1051 
       
  1052     if (strncmp(name, "file:", 5) == 0) {
       
  1053         do_savevm_file(name + 5);
       
  1054         return;
       
  1055     }
       
  1056 
       
  1057     bs = get_bs_snapshots();
       
  1058     if (!bs) {
       
  1059         term_printf("No block device can accept snapshots\n");
       
  1060         return;
       
  1061     }
       
  1062 
       
  1063     /* ??? Should this occur after vm_stop?  */
       
  1064     qemu_aio_flush();
       
  1065 
       
  1066     saved_vm_running = vm_running;
       
  1067     vm_stop(0);
       
  1068 
       
  1069     must_delete = 0;
       
  1070     if (name) {
       
  1071         ret = bdrv_snapshot_find(bs, old_sn, name);
       
  1072         if (ret >= 0) {
       
  1073             must_delete = 1;
       
  1074         }
       
  1075     }
       
  1076     memset(sn, 0, sizeof(*sn));
       
  1077     if (must_delete) {
       
  1078         pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
       
  1079         pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
       
  1080     } else {
       
  1081         if (name)
       
  1082             pstrcpy(sn->name, sizeof(sn->name), name);
       
  1083     }
       
  1084 
       
  1085     /* fill auxiliary fields */
       
  1086 #ifdef _WIN32
       
  1087     _ftime(&tb);
       
  1088     sn->date_sec = tb.time;
       
  1089     sn->date_nsec = tb.millitm * 1000000;
       
  1090 #else
       
  1091     gettimeofday(&tv, NULL);
       
  1092     sn->date_sec = tv.tv_sec;
       
  1093     sn->date_nsec = tv.tv_usec * 1000;
       
  1094 #endif
       
  1095     sn->vm_clock_nsec = qemu_get_clock(vm_clock);
       
  1096 
       
  1097     if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
       
  1098         term_printf("Device %s does not support VM state snapshots\n",
       
  1099                     bdrv_get_device_name(bs));
       
  1100         goto the_end;
       
  1101     }
       
  1102 
       
  1103     /* save the VM state */
       
  1104     f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
       
  1105     if (!f) {
       
  1106         term_printf("Could not open VM state file\n");
       
  1107         goto the_end;
       
  1108     }
       
  1109     ret = qemu_savevm_state(f);
       
  1110     vm_state_size = qemu_ftell(f);
       
  1111     qemu_fclose(f);
       
  1112     if (ret < 0) {
       
  1113         term_printf("Error %d while writing VM\n", ret);
       
  1114         goto the_end;
       
  1115     }
       
  1116 
       
  1117     /* create the snapshots */
       
  1118 
       
  1119     for(i = 0; i < nb_drives; i++) {
       
  1120         bs1 = drives_table[i].bdrv;
       
  1121         if (bdrv_has_snapshot(bs1)) {
       
  1122             if (must_delete) {
       
  1123                 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
       
  1124                 if (ret < 0) {
       
  1125                     term_printf("Error while deleting snapshot on '%s'\n",
       
  1126                                 bdrv_get_device_name(bs1));
       
  1127                 }
       
  1128             }
       
  1129             /* Write VM state size only to the image that contains the state */
       
  1130             sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
       
  1131             ret = bdrv_snapshot_create(bs1, sn);
       
  1132             if (ret < 0) {
       
  1133                 term_printf("Error while creating snapshot on '%s'\n",
       
  1134                             bdrv_get_device_name(bs1));
       
  1135             }
       
  1136         }
       
  1137     }
       
  1138 
       
  1139  the_end:
       
  1140     if (saved_vm_running)
       
  1141         vm_start();
       
  1142 }
       
  1143 
       
  1144 static void do_loadvm_file(const char *name)
       
  1145 {
       
  1146     QEMUFile *f;
       
  1147     int saved_vm_running;
       
  1148     int ret;
       
  1149 
       
  1150     qemu_aio_flush();
       
  1151 
       
  1152     saved_vm_running = vm_running;
       
  1153     vm_stop(0);
       
  1154 
       
  1155     f = qemu_fopen(name, "rb");
       
  1156     if (!f) {
       
  1157         term_printf("Unable to open snapshot\n");
       
  1158         return;
       
  1159     }
       
  1160 
       
  1161     ret = qemu_loadvm_state(f);
       
  1162     qemu_fclose(f);
       
  1163     if (ret < 0) {
       
  1164         term_printf("Error %d while loading VM state\n", ret);
       
  1165     }
       
  1166 
       
  1167     if (saved_vm_running)
       
  1168         vm_start();
       
  1169 }
       
  1170 
       
  1171 void do_loadvm(const char *name)
       
  1172 {
       
  1173     BlockDriverState *bs, *bs1;
       
  1174     BlockDriverInfo bdi1, *bdi = &bdi1;
       
  1175     QEMUSnapshotInfo sn;
       
  1176     QEMUFile *f;
       
  1177     int i, ret;
       
  1178     int saved_vm_running;
       
  1179 
       
  1180     if (strncmp(name, "file:", 5) == 0) {
       
  1181         do_loadvm_file(name + 5);
       
  1182         return;
       
  1183     }
       
  1184     bs = get_bs_snapshots();
       
  1185     if (!bs) {
       
  1186         term_printf("No block device supports snapshots\n");
       
  1187         return;
       
  1188     }
       
  1189 
       
  1190     /* Flush all IO requests so they don't interfere with the new state.  */
       
  1191     qemu_aio_flush();
       
  1192 
       
  1193     saved_vm_running = vm_running;
       
  1194     vm_stop(0);
       
  1195 
       
  1196     for(i = 0; i <= nb_drives; i++) {
       
  1197         bs1 = drives_table[i].bdrv;
       
  1198         if (bdrv_has_snapshot(bs1)) {
       
  1199             ret = bdrv_snapshot_goto(bs1, name);
       
  1200             if (ret < 0) {
       
  1201                 if (bs != bs1)
       
  1202                     term_printf("Warning: ");
       
  1203                 switch(ret) {
       
  1204                 case -ENOTSUP:
       
  1205                     term_printf("Snapshots not supported on device '%s'\n",
       
  1206                                 bdrv_get_device_name(bs1));
       
  1207                     break;
       
  1208                 case -ENOENT:
       
  1209                     term_printf("Could not find snapshot '%s' on device '%s'\n",
       
  1210                                 name, bdrv_get_device_name(bs1));
       
  1211                     break;
       
  1212                 default:
       
  1213                     term_printf("Error %d while activating snapshot on '%s'\n",
       
  1214                                 ret, bdrv_get_device_name(bs1));
       
  1215                     break;
       
  1216                 }
       
  1217                 /* fatal on snapshot block device */
       
  1218                 if (bs == bs1)
       
  1219                     goto the_end;
       
  1220             }
       
  1221         }
       
  1222     }
       
  1223 
       
  1224     if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
       
  1225         term_printf("Device %s does not support VM state snapshots\n",
       
  1226                     bdrv_get_device_name(bs));
       
  1227         return;
       
  1228     }
       
  1229 
       
  1230     /* Don't even try to load empty VM states */
       
  1231     ret = bdrv_snapshot_find(bs, &sn, name);
       
  1232     if ((ret >= 0) && (sn.vm_state_size == 0))
       
  1233         goto the_end;
       
  1234 
       
  1235     /* restore the VM state */
       
  1236     f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
       
  1237     if (!f) {
       
  1238         term_printf("Could not open VM state file\n");
       
  1239         goto the_end;
       
  1240     }
       
  1241     ret = qemu_loadvm_state(f);
       
  1242     qemu_fclose(f);
       
  1243     if (ret < 0) {
       
  1244         term_printf("Error %d while loading VM state\n", ret);
       
  1245     }
       
  1246  the_end:
       
  1247     if (saved_vm_running)
       
  1248         vm_start();
       
  1249 }
       
  1250 
       
  1251 void do_delvm(const char *name)
       
  1252 {
       
  1253     BlockDriverState *bs, *bs1;
       
  1254     int i, ret;
       
  1255 
       
  1256     bs = get_bs_snapshots();
       
  1257     if (!bs) {
       
  1258         term_printf("No block device supports snapshots\n");
       
  1259         return;
       
  1260     }
       
  1261 
       
  1262     for(i = 0; i <= nb_drives; i++) {
       
  1263         bs1 = drives_table[i].bdrv;
       
  1264         if (bdrv_has_snapshot(bs1)) {
       
  1265             ret = bdrv_snapshot_delete(bs1, name);
       
  1266             if (ret < 0) {
       
  1267                 if (ret == -ENOTSUP)
       
  1268                     term_printf("Snapshots not supported on device '%s'\n",
       
  1269                                 bdrv_get_device_name(bs1));
       
  1270                 else
       
  1271                     term_printf("Error %d while deleting snapshot on '%s'\n",
       
  1272                                 ret, bdrv_get_device_name(bs1));
       
  1273             }
       
  1274         }
       
  1275     }
       
  1276 }
       
  1277 
       
  1278 void do_info_snapshots(void)
       
  1279 {
       
  1280     BlockDriverState *bs, *bs1;
       
  1281     QEMUSnapshotInfo *sn_tab, *sn;
       
  1282     int nb_sns, i;
       
  1283     char buf[256];
       
  1284 
       
  1285     bs = get_bs_snapshots();
       
  1286     if (!bs) {
       
  1287         term_printf("No available block device supports snapshots\n");
       
  1288         return;
       
  1289     }
       
  1290     term_printf("Snapshot devices:");
       
  1291     for(i = 0; i <= nb_drives; i++) {
       
  1292         bs1 = drives_table[i].bdrv;
       
  1293         if (bdrv_has_snapshot(bs1)) {
       
  1294             if (bs == bs1)
       
  1295                 term_printf(" %s", bdrv_get_device_name(bs1));
       
  1296         }
       
  1297     }
       
  1298     term_printf("\n");
       
  1299 
       
  1300     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
       
  1301     if (nb_sns < 0) {
       
  1302         term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
       
  1303         return;
       
  1304     }
       
  1305     term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
       
  1306     term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
       
  1307     for(i = 0; i < nb_sns; i++) {
       
  1308         sn = &sn_tab[i];
       
  1309         term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
       
  1310     }
       
  1311     qemu_free(sn_tab);
       
  1312 }