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