Include assert.h from qemu-common.h
[qemu] / qemu-img.c
1 /*
2  * QEMU disk image utility
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 "osdep.h"
26 #include "block_int.h"
27 #include <stdio.h>
28
29 #ifdef _WIN32
30 #include <windows.h>
31 #endif
32
33 /* Default to cache=writeback as data integrity is not important for qemu-tcg. */
34 #define BRDV_O_FLAGS BDRV_O_CACHE_WB
35
36 static void QEMU_NORETURN error(const char *fmt, ...)
37 {
38     va_list ap;
39     va_start(ap, fmt);
40     fprintf(stderr, "qemu-img: ");
41     vfprintf(stderr, fmt, ap);
42     fprintf(stderr, "\n");
43     exit(1);
44     va_end(ap);
45 }
46
47 static void format_print(void *opaque, const char *name)
48 {
49     printf(" %s", name);
50 }
51
52 /* Please keep in synch with qemu-img.texi */
53 static void help(void)
54 {
55     printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
56            "usage: qemu-img command [command options]\n"
57            "QEMU disk image utility\n"
58            "\n"
59            "Command syntax:\n"
60            "  check [-f fmt] filename\n"
61            "  create [-e] [-6] [-F fmt] [-b base_image] [-f fmt] filename [size]\n"
62            "  commit [-f fmt] filename\n"
63            "  convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
64            "  info [-f fmt] filename\n"
65            "  snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename\n"
66            "\n"
67            "Command parameters:\n"
68            "  'filename' is a disk image filename\n"
69            "  'base_image' is the read-only disk image which is used as base for a copy on\n"
70            "    write image; the copy on write image only stores the modified data\n"
71            "  'output_base_image' forces the output image to be created as a copy on write\n"
72            "    image of the specified base image; 'output_base_image' should have the same\n"
73            "    content as the input's base image, however the path, image format, etc may\n"
74            "    differ\n"
75            "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
76            "  'size' is the disk image size in kilobytes. Optional suffixes\n"
77            "    'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are\n"
78            "    supported any 'k' or 'K' is ignored\n"
79            "  'output_filename' is the destination disk image filename\n"
80            "  'output_fmt' is the destination format\n"
81            "  '-c' indicates that target image must be compressed (qcow format only)\n"
82            "  '-e' indicates that the target image must be encrypted (qcow format only)\n"
83            "  '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
84            "  '-h' with or without a command shows this help and lists the supported formats\n"
85            "\n"
86            "Parameters to snapshot subcommand:\n"
87            "  'snapshot' is the name of the snapshot to create, apply or delete\n"
88            "  '-a' applies a snapshot (revert disk to saved state)\n"
89            "  '-c' creates a snapshot\n"
90            "  '-d' deletes a snapshot\n"
91            "  '-l' lists all snapshots in the given image\n"
92            );
93     printf("\nSupported formats:");
94     bdrv_iterate_format(format_print, NULL);
95     printf("\n");
96     exit(1);
97 }
98
99 #if defined(WIN32)
100 /* XXX: put correct support for win32 */
101 static int read_password(char *buf, int buf_size)
102 {
103     int c, i;
104     printf("Password: ");
105     fflush(stdout);
106     i = 0;
107     for(;;) {
108         c = getchar();
109         if (c == '\n')
110             break;
111         if (i < (buf_size - 1))
112             buf[i++] = c;
113     }
114     buf[i] = '\0';
115     return 0;
116 }
117
118 #else
119
120 #include <termios.h>
121
122 static struct termios oldtty;
123
124 static void term_exit(void)
125 {
126     tcsetattr (0, TCSANOW, &oldtty);
127 }
128
129 static void term_init(void)
130 {
131     struct termios tty;
132
133     tcgetattr (0, &tty);
134     oldtty = tty;
135
136     tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
137                           |INLCR|IGNCR|ICRNL|IXON);
138     tty.c_oflag |= OPOST;
139     tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
140     tty.c_cflag &= ~(CSIZE|PARENB);
141     tty.c_cflag |= CS8;
142     tty.c_cc[VMIN] = 1;
143     tty.c_cc[VTIME] = 0;
144
145     tcsetattr (0, TCSANOW, &tty);
146
147     atexit(term_exit);
148 }
149
150 static int read_password(char *buf, int buf_size)
151 {
152     uint8_t ch;
153     int i, ret;
154
155     printf("password: ");
156     fflush(stdout);
157     term_init();
158     i = 0;
159     for(;;) {
160         ret = read(0, &ch, 1);
161         if (ret == -1) {
162             if (errno == EAGAIN || errno == EINTR) {
163                 continue;
164             } else {
165                 ret = -1;
166                 break;
167             }
168         } else if (ret == 0) {
169             ret = -1;
170             break;
171         } else {
172             if (ch == '\r') {
173                 ret = 0;
174                 break;
175             }
176             if (i < (buf_size - 1))
177                 buf[i++] = ch;
178         }
179     }
180     term_exit();
181     buf[i] = '\0';
182     printf("\n");
183     return ret;
184 }
185 #endif
186
187 static BlockDriverState *bdrv_new_open(const char *filename,
188                                        const char *fmt)
189 {
190     BlockDriverState *bs;
191     BlockDriver *drv;
192     char password[256];
193
194     bs = bdrv_new("");
195     if (!bs)
196         error("Not enough memory");
197     if (fmt) {
198         drv = bdrv_find_format(fmt);
199         if (!drv)
200             error("Unknown file format '%s'", fmt);
201     } else {
202         drv = NULL;
203     }
204     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
205         error("Could not open '%s'", filename);
206     }
207     if (bdrv_is_encrypted(bs)) {
208         printf("Disk image '%s' is encrypted.\n", filename);
209         if (read_password(password, sizeof(password)) < 0)
210             error("No password given");
211         if (bdrv_set_key(bs, password) < 0)
212             error("invalid password");
213     }
214     return bs;
215 }
216
217 static int img_create(int argc, char **argv)
218 {
219     int c, ret, flags;
220     const char *fmt = "raw";
221     const char *base_fmt = NULL;
222     const char *filename;
223     const char *base_filename = NULL;
224     uint64_t size;
225     double sizef;
226     const char *p;
227     BlockDriver *drv;
228
229     flags = 0;
230     for(;;) {
231         c = getopt(argc, argv, "F:b:f:he6");
232         if (c == -1)
233             break;
234         switch(c) {
235         case 'h':
236             help();
237             break;
238         case 'F':
239             base_fmt = optarg;
240             break;
241         case 'b':
242             base_filename = optarg;
243             break;
244         case 'f':
245             fmt = optarg;
246             break;
247         case 'e':
248             flags |= BLOCK_FLAG_ENCRYPT;
249             break;
250         case '6':
251             flags |= BLOCK_FLAG_COMPAT6;
252             break;
253         }
254     }
255     if (optind >= argc)
256         help();
257     filename = argv[optind++];
258     size = 0;
259     if (base_filename) {
260         BlockDriverState *bs;
261         BlockDriver *base_drv = NULL;
262
263         if (base_fmt) {
264             base_drv = bdrv_find_format(base_fmt);
265             if (base_drv == NULL)
266                 error("Unknown basefile format '%s'", base_fmt);
267         }
268
269         bs = bdrv_new_open(base_filename, base_fmt);
270         bdrv_get_geometry(bs, &size);
271         size *= 512;
272         bdrv_delete(bs);
273     } else {
274         if (optind >= argc)
275             help();
276         p = argv[optind];
277         sizef = strtod(p, (char **)&p);
278         if (*p == 'M') {
279             size = (uint64_t)(sizef * 1024 * 1024);
280         } else if (*p == 'G') {
281             size = (uint64_t)(sizef * 1024 * 1024 * 1024);
282         } else if (*p == 'k' || *p == 'K' || *p == '\0') {
283             size = (uint64_t)(sizef * 1024);
284         } else {
285             help();
286         }
287     }
288     drv = bdrv_find_format(fmt);
289     if (!drv)
290         error("Unknown file format '%s'", fmt);
291     printf("Formatting '%s', fmt=%s",
292            filename, fmt);
293     if (flags & BLOCK_FLAG_ENCRYPT)
294         printf(", encrypted");
295     if (flags & BLOCK_FLAG_COMPAT6)
296         printf(", compatibility level=6");
297     if (base_filename) {
298         printf(", backing_file=%s",
299                base_filename);
300          if (base_fmt)
301              printf(", backing_fmt=%s",
302                     base_fmt);
303     }
304     printf(", size=%" PRIu64 " kB\n", size / 1024);
305     ret = bdrv_create2(drv, filename, size / 512, base_filename, base_fmt, flags);
306     if (ret < 0) {
307         if (ret == -ENOTSUP) {
308             error("Formatting or formatting option not supported for file format '%s'", fmt);
309         } else if (ret == -EFBIG) {
310             error("The image size is too large for file format '%s'", fmt);
311         } else {
312             error("Error while formatting");
313         }
314     }
315     return 0;
316 }
317
318 static int img_check(int argc, char **argv)
319 {
320     int c, ret;
321     const char *filename, *fmt;
322     BlockDriver *drv;
323     BlockDriverState *bs;
324
325     fmt = NULL;
326     for(;;) {
327         c = getopt(argc, argv, "f:h");
328         if (c == -1)
329             break;
330         switch(c) {
331         case 'h':
332             help();
333             break;
334         case 'f':
335             fmt = optarg;
336             break;
337         }
338     }
339     if (optind >= argc)
340         help();
341     filename = argv[optind++];
342
343     bs = bdrv_new("");
344     if (!bs)
345         error("Not enough memory");
346     if (fmt) {
347         drv = bdrv_find_format(fmt);
348         if (!drv)
349             error("Unknown file format '%s'", fmt);
350     } else {
351         drv = NULL;
352     }
353     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
354         error("Could not open '%s'", filename);
355     }
356     ret = bdrv_check(bs);
357     switch(ret) {
358     case 0:
359         printf("No errors were found on the image.\n");
360         break;
361     case -ENOTSUP:
362         error("This image format does not support checks");
363         break;
364     default:
365         if (ret < 0) {
366             error("An error occurred during the check");
367         } else {
368             printf("%d errors were found on the image.\n", ret);
369         }
370         break;
371     }
372
373     bdrv_delete(bs);
374     return 0;
375 }
376
377 static int img_commit(int argc, char **argv)
378 {
379     int c, ret;
380     const char *filename, *fmt;
381     BlockDriver *drv;
382     BlockDriverState *bs;
383
384     fmt = NULL;
385     for(;;) {
386         c = getopt(argc, argv, "f:h");
387         if (c == -1)
388             break;
389         switch(c) {
390         case 'h':
391             help();
392             break;
393         case 'f':
394             fmt = optarg;
395             break;
396         }
397     }
398     if (optind >= argc)
399         help();
400     filename = argv[optind++];
401
402     bs = bdrv_new("");
403     if (!bs)
404         error("Not enough memory");
405     if (fmt) {
406         drv = bdrv_find_format(fmt);
407         if (!drv)
408             error("Unknown file format '%s'", fmt);
409     } else {
410         drv = NULL;
411     }
412     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
413         error("Could not open '%s'", filename);
414     }
415     ret = bdrv_commit(bs);
416     switch(ret) {
417     case 0:
418         printf("Image committed.\n");
419         break;
420     case -ENOENT:
421         error("No disk inserted");
422         break;
423     case -EACCES:
424         error("Image is read-only");
425         break;
426     case -ENOTSUP:
427         error("Image is already committed");
428         break;
429     default:
430         error("Error while committing image");
431         break;
432     }
433
434     bdrv_delete(bs);
435     return 0;
436 }
437
438 static int is_not_zero(const uint8_t *sector, int len)
439 {
440     int i;
441     len >>= 2;
442     for(i = 0;i < len; i++) {
443         if (((uint32_t *)sector)[i] != 0)
444             return 1;
445     }
446     return 0;
447 }
448
449 /*
450  * Returns true iff the first sector pointed to by 'buf' contains at least
451  * a non-NUL byte.
452  *
453  * 'pnum' is set to the number of sectors (including and immediately following
454  * the first one) that are known to be in the same allocated/unallocated state.
455  */
456 static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
457 {
458     int v, i;
459
460     if (n <= 0) {
461         *pnum = 0;
462         return 0;
463     }
464     v = is_not_zero(buf, 512);
465     for(i = 1; i < n; i++) {
466         buf += 512;
467         if (v != is_not_zero(buf, 512))
468             break;
469     }
470     *pnum = i;
471     return v;
472 }
473
474 #define IO_BUF_SIZE 65536
475
476 static int img_convert(int argc, char **argv)
477 {
478     int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
479     const char *fmt, *out_fmt, *out_baseimg, *out_filename;
480     BlockDriver *drv;
481     BlockDriverState **bs, *out_bs;
482     int64_t total_sectors, nb_sectors, sector_num, bs_offset;
483     uint64_t bs_sectors;
484     uint8_t buf[IO_BUF_SIZE];
485     const uint8_t *buf1;
486     BlockDriverInfo bdi;
487
488     fmt = NULL;
489     out_fmt = "raw";
490     out_baseimg = NULL;
491     flags = 0;
492     for(;;) {
493         c = getopt(argc, argv, "f:O:B:hce6");
494         if (c == -1)
495             break;
496         switch(c) {
497         case 'h':
498             help();
499             break;
500         case 'f':
501             fmt = optarg;
502             break;
503         case 'O':
504             out_fmt = optarg;
505             break;
506         case 'B':
507             out_baseimg = optarg;
508             break;
509         case 'c':
510             flags |= BLOCK_FLAG_COMPRESS;
511             break;
512         case 'e':
513             flags |= BLOCK_FLAG_ENCRYPT;
514             break;
515         case '6':
516             flags |= BLOCK_FLAG_COMPAT6;
517             break;
518         }
519     }
520
521     bs_n = argc - optind - 1;
522     if (bs_n < 1) help();
523
524     out_filename = argv[argc - 1];
525
526     if (bs_n > 1 && out_baseimg)
527         error("-B makes no sense when concatenating multiple input images");
528         
529     bs = calloc(bs_n, sizeof(BlockDriverState *));
530     if (!bs)
531         error("Out of memory");
532
533     total_sectors = 0;
534     for (bs_i = 0; bs_i < bs_n; bs_i++) {
535         bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
536         if (!bs[bs_i])
537             error("Could not open '%s'", argv[optind + bs_i]);
538         bdrv_get_geometry(bs[bs_i], &bs_sectors);
539         total_sectors += bs_sectors;
540     }
541
542     drv = bdrv_find_format(out_fmt);
543     if (!drv)
544         error("Unknown file format '%s'", out_fmt);
545     if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
546         error("Compression not supported for this file format");
547     if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
548         error("Encryption not supported for this file format");
549     if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
550         error("Alternative compatibility level not supported for this file format");
551     if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
552         error("Compression and encryption not supported at the same time");
553
554     ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
555     if (ret < 0) {
556         if (ret == -ENOTSUP) {
557             error("Formatting not supported for file format '%s'", out_fmt);
558         } else if (ret == -EFBIG) {
559             error("The image size is too large for file format '%s'", out_fmt);
560         } else {
561             error("Error while formatting '%s'", out_filename);
562         }
563     }
564
565     out_bs = bdrv_new_open(out_filename, out_fmt);
566
567     bs_i = 0;
568     bs_offset = 0;
569     bdrv_get_geometry(bs[0], &bs_sectors);
570
571     if (flags & BLOCK_FLAG_COMPRESS) {
572         if (bdrv_get_info(out_bs, &bdi) < 0)
573             error("could not get block driver info");
574         cluster_size = bdi.cluster_size;
575         if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
576             error("invalid cluster size");
577         cluster_sectors = cluster_size >> 9;
578         sector_num = 0;
579         for(;;) {
580             int64_t bs_num;
581             int remainder;
582             uint8_t *buf2;
583
584             nb_sectors = total_sectors - sector_num;
585             if (nb_sectors <= 0)
586                 break;
587             if (nb_sectors >= cluster_sectors)
588                 n = cluster_sectors;
589             else
590                 n = nb_sectors;
591
592             bs_num = sector_num - bs_offset;
593             assert (bs_num >= 0);
594             remainder = n;
595             buf2 = buf;
596             while (remainder > 0) {
597                 int nlow;
598                 while (bs_num == bs_sectors) {
599                     bs_i++;
600                     assert (bs_i < bs_n);
601                     bs_offset += bs_sectors;
602                     bdrv_get_geometry(bs[bs_i], &bs_sectors);
603                     bs_num = 0;
604                     /* printf("changing part: sector_num=%lld, "
605                        "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
606                        sector_num, bs_i, bs_offset, bs_sectors); */
607                 }
608                 assert (bs_num < bs_sectors);
609
610                 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
611
612                 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0) 
613                     error("error while reading");
614
615                 buf2 += nlow * 512;
616                 bs_num += nlow;
617
618                 remainder -= nlow;
619             }
620             assert (remainder == 0);
621
622             if (n < cluster_sectors)
623                 memset(buf + n * 512, 0, cluster_size - n * 512);
624             if (is_not_zero(buf, cluster_size)) {
625                 if (bdrv_write_compressed(out_bs, sector_num, buf,
626                                           cluster_sectors) != 0)
627                     error("error while compressing sector %" PRId64,
628                           sector_num);
629             }
630             sector_num += n;
631         }
632         /* signal EOF to align */
633         bdrv_write_compressed(out_bs, 0, NULL, 0);
634     } else {
635         sector_num = 0; // total number of sectors converted so far
636         for(;;) {
637             nb_sectors = total_sectors - sector_num;
638             if (nb_sectors <= 0)
639                 break;
640             if (nb_sectors >= (IO_BUF_SIZE / 512))
641                 n = (IO_BUF_SIZE / 512);
642             else
643                 n = nb_sectors;
644
645             while (sector_num - bs_offset >= bs_sectors) {
646                 bs_i ++;
647                 assert (bs_i < bs_n);
648                 bs_offset += bs_sectors;
649                 bdrv_get_geometry(bs[bs_i], &bs_sectors);
650                 /* printf("changing part: sector_num=%lld, bs_i=%d, "
651                   "bs_offset=%lld, bs_sectors=%lld\n",
652                    sector_num, bs_i, bs_offset, bs_sectors); */
653             }
654
655             if (n > bs_offset + bs_sectors - sector_num)
656                 n = bs_offset + bs_sectors - sector_num;
657
658             if (drv != &bdrv_host_device) {
659                 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
660                                        n, &n1)) {
661                     sector_num += n1;
662                     continue;
663                 }
664                 /* The next 'n1' sectors are allocated in the input image. Copy
665                    only those as they may be followed by unallocated sectors. */
666                 n = n1;
667             } else {
668                 n1 = n;
669             }
670
671             if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) 
672                 error("error while reading");
673             /* NOTE: at the same time we convert, we do not write zero
674                sectors to have a chance to compress the image. Ideally, we
675                should add a specific call to have the info to go faster */
676             buf1 = buf;
677             while (n > 0) {
678                 /* If the output image is being created as a copy on write image,
679                    copy all sectors even the ones containing only NUL bytes,
680                    because they may differ from the sectors in the base image.
681
682                    If the output is to a host device, we also write out
683                    sectors that are entirely 0, since whatever data was
684                    already there is garbage, not 0s. */
685                 if (drv == &bdrv_host_device || out_baseimg ||
686                     is_allocated_sectors(buf1, n, &n1)) {
687                     if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
688                         error("error while writing");
689                 }
690                 sector_num += n1;
691                 n -= n1;
692                 buf1 += n1 * 512;
693             }
694         }
695     }
696     bdrv_delete(out_bs);
697     for (bs_i = 0; bs_i < bs_n; bs_i++)
698         bdrv_delete(bs[bs_i]);
699     free(bs);
700     return 0;
701 }
702
703 #ifdef _WIN32
704 static int64_t get_allocated_file_size(const char *filename)
705 {
706     typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
707     get_compressed_t get_compressed;
708     struct _stati64 st;
709
710     /* WinNT support GetCompressedFileSize to determine allocate size */
711     get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
712     if (get_compressed) {
713         DWORD high, low;
714         low = get_compressed(filename, &high);
715         if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
716             return (((int64_t) high) << 32) + low;
717     }
718
719     if (_stati64(filename, &st) < 0)
720         return -1;
721     return st.st_size;
722 }
723 #else
724 static int64_t get_allocated_file_size(const char *filename)
725 {
726     struct stat st;
727     if (stat(filename, &st) < 0)
728         return -1;
729     return (int64_t)st.st_blocks * 512;
730 }
731 #endif
732
733 static void dump_snapshots(BlockDriverState *bs)
734 {
735     QEMUSnapshotInfo *sn_tab, *sn;
736     int nb_sns, i;
737     char buf[256];
738
739     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
740     if (nb_sns <= 0)
741         return;
742     printf("Snapshot list:\n");
743     printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
744     for(i = 0; i < nb_sns; i++) {
745         sn = &sn_tab[i];
746         printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
747     }
748     qemu_free(sn_tab);
749 }
750
751 static int img_info(int argc, char **argv)
752 {
753     int c;
754     const char *filename, *fmt;
755     BlockDriver *drv;
756     BlockDriverState *bs;
757     char fmt_name[128], size_buf[128], dsize_buf[128];
758     uint64_t total_sectors;
759     int64_t allocated_size;
760     char backing_filename[1024];
761     char backing_filename2[1024];
762     BlockDriverInfo bdi;
763
764     fmt = NULL;
765     for(;;) {
766         c = getopt(argc, argv, "f:h");
767         if (c == -1)
768             break;
769         switch(c) {
770         case 'h':
771             help();
772             break;
773         case 'f':
774             fmt = optarg;
775             break;
776         }
777     }
778     if (optind >= argc)
779         help();
780     filename = argv[optind++];
781
782     bs = bdrv_new("");
783     if (!bs)
784         error("Not enough memory");
785     if (fmt) {
786         drv = bdrv_find_format(fmt);
787         if (!drv)
788             error("Unknown file format '%s'", fmt);
789     } else {
790         drv = NULL;
791     }
792     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
793         error("Could not open '%s'", filename);
794     }
795     bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
796     bdrv_get_geometry(bs, &total_sectors);
797     get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
798     allocated_size = get_allocated_file_size(filename);
799     if (allocated_size < 0)
800         snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
801     else
802         get_human_readable_size(dsize_buf, sizeof(dsize_buf),
803                                 allocated_size);
804     printf("image: %s\n"
805            "file format: %s\n"
806            "virtual size: %s (%" PRId64 " bytes)\n"
807            "disk size: %s\n",
808            filename, fmt_name, size_buf,
809            (total_sectors * 512),
810            dsize_buf);
811     if (bdrv_is_encrypted(bs))
812         printf("encrypted: yes\n");
813     if (bdrv_get_info(bs, &bdi) >= 0) {
814         if (bdi.cluster_size != 0)
815             printf("cluster_size: %d\n", bdi.cluster_size);
816     }
817     bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
818     if (backing_filename[0] != '\0') {
819         path_combine(backing_filename2, sizeof(backing_filename2),
820                      filename, backing_filename);
821         printf("backing file: %s (actual path: %s)\n",
822                backing_filename,
823                backing_filename2);
824     }
825     dump_snapshots(bs);
826     bdrv_delete(bs);
827     return 0;
828 }
829
830 #define SNAPSHOT_LIST   1
831 #define SNAPSHOT_CREATE 2
832 #define SNAPSHOT_APPLY  3
833 #define SNAPSHOT_DELETE 4
834
835 static void img_snapshot(int argc, char **argv)
836 {
837     BlockDriverState *bs;
838     QEMUSnapshotInfo sn;
839     char *filename, *snapshot_name = NULL;
840     int c, ret;
841     int action = 0;
842     qemu_timeval tv;
843
844     /* Parse commandline parameters */
845     for(;;) {
846         c = getopt(argc, argv, "la:c:d:h");
847         if (c == -1)
848             break;
849         switch(c) {
850         case 'h':
851             help();
852             return;
853         case 'l':
854             if (action) {
855                 help();
856                 return;
857             }
858             action = SNAPSHOT_LIST;
859             break;
860         case 'a':
861             if (action) {
862                 help();
863                 return;
864             }
865             action = SNAPSHOT_APPLY;
866             snapshot_name = optarg;
867             break;
868         case 'c':
869             if (action) {
870                 help();
871                 return;
872             }
873             action = SNAPSHOT_CREATE;
874             snapshot_name = optarg;
875             break;
876         case 'd':
877             if (action) {
878                 help();
879                 return;
880             }
881             action = SNAPSHOT_DELETE;
882             snapshot_name = optarg;
883             break;
884         }
885     }
886
887     if (optind >= argc)
888         help();
889     filename = argv[optind++];
890
891     /* Open the image */
892     bs = bdrv_new("");
893     if (!bs)
894         error("Not enough memory");
895
896     if (bdrv_open2(bs, filename, 0, NULL) < 0) {
897         error("Could not open '%s'", filename);
898     }
899
900     /* Perform the requested action */
901     switch(action) {
902     case SNAPSHOT_LIST:
903         dump_snapshots(bs);
904         break;
905
906     case SNAPSHOT_CREATE:
907         memset(&sn, 0, sizeof(sn));
908         pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
909
910         qemu_gettimeofday(&tv);
911         sn.date_sec = tv.tv_sec;
912         sn.date_nsec = tv.tv_usec * 1000;
913
914         ret = bdrv_snapshot_create(bs, &sn);
915         if (ret)
916             error("Could not create snapshot '%s': %d (%s)",
917                 snapshot_name, ret, strerror(-ret));
918         break;
919
920     case SNAPSHOT_APPLY:
921         ret = bdrv_snapshot_goto(bs, snapshot_name);
922         if (ret)
923             error("Could not apply snapshot '%s': %d (%s)",
924                 snapshot_name, ret, strerror(-ret));
925         break;
926
927     case SNAPSHOT_DELETE:
928         ret = bdrv_snapshot_delete(bs, snapshot_name);
929         if (ret)
930             error("Could not delete snapshot '%s': %d (%s)",
931                 snapshot_name, ret, strerror(-ret));
932         break;
933     }
934
935     /* Cleanup */
936     bdrv_delete(bs);
937 }
938
939 int main(int argc, char **argv)
940 {
941     const char *cmd;
942
943     bdrv_init();
944     if (argc < 2)
945         help();
946     cmd = argv[1];
947     argc--; argv++;
948     if (!strcmp(cmd, "create")) {
949         img_create(argc, argv);
950     } else if (!strcmp(cmd, "check")) {
951         img_check(argc, argv);
952     } else if (!strcmp(cmd, "commit")) {
953         img_commit(argc, argv);
954     } else if (!strcmp(cmd, "convert")) {
955         img_convert(argc, argv);
956     } else if (!strcmp(cmd, "info")) {
957         img_info(argc, argv);
958     } else if (!strcmp(cmd, "snapshot")) {
959         img_snapshot(argc, argv);
960     } else {
961         help();
962     }
963     return 0;
964 }