00329790b6af8f8911c2ae5002922933fdc51659
[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 "qemu-option.h"
26 #include "osdep.h"
27 #include "block_int.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     BlockDriver *drv;
226     QEMUOptionParameter *param = NULL;
227     char *options = NULL;
228
229     flags = 0;
230     for(;;) {
231         c = getopt(argc, argv, "F:b:f:he6o:");
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         case 'o':
254             options = optarg;
255             break;
256         }
257     }
258     if (optind >= argc)
259         help();
260     filename = argv[optind++];
261
262     /* Find driver and parse its options */
263     drv = bdrv_find_format(fmt);
264     if (!drv)
265         error("Unknown file format '%s'", fmt);
266
267     if (options) {
268         param = parse_option_parameters(options, drv->create_options, param);
269         if (param == NULL) {
270             error("Invalid options for file format '%s'.", fmt);
271         }
272     } else {
273         param = parse_option_parameters("", drv->create_options, param);
274     }
275
276     /* Add size to parameters */
277     if (optind < argc) {
278         set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);
279     }
280
281     /* Add old-style options to parameters */
282     if (flags & BLOCK_FLAG_ENCRYPT) {
283         if (set_option_parameter(param, BLOCK_OPT_ENCRYPT, "on")) {
284             error("Encryption not supported for file format '%s'", fmt);
285         }
286     }
287     if (flags & BLOCK_FLAG_COMPAT6) {
288         if (set_option_parameter(param, BLOCK_OPT_COMPAT6, "on")) {
289             error("VMDK version 6 not supported for file format '%s'", fmt);
290         }
291     }
292
293     if (base_filename) {
294         if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE, base_filename)) {
295             error("Backing file not supported for file format '%s'", fmt);
296         }
297     }
298     if (base_fmt) {
299         if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
300             error("Backing file format not supported for file format '%s'", fmt);
301         }
302     }
303
304     // The size for the image must always be specified, with one exception:
305     // If we are using a backing file, we can obtain the size from there
306     if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == 0) {
307
308         QEMUOptionParameter *backing_file =
309             get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
310         QEMUOptionParameter *backing_fmt =
311             get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
312
313         if (backing_file && backing_file->value.s) {
314             BlockDriverState *bs;
315             uint64_t size;
316             const char *fmt = NULL;
317             char buf[32];
318
319             if (backing_fmt && backing_fmt->value.s) {
320                  if (bdrv_find_format(backing_fmt->value.s)) {
321                      fmt = backing_fmt->value.s;
322                 } else {
323                      error("Unknown backing file format '%s'",
324                         backing_fmt->value.s);
325                 }
326             }
327
328             bs = bdrv_new_open(backing_file->value.s, fmt);
329             bdrv_get_geometry(bs, &size);
330             size *= 512;
331             bdrv_delete(bs);
332
333             snprintf(buf, sizeof(buf), "%" PRId64, size);
334             set_option_parameter(param, BLOCK_OPT_SIZE, buf);
335         } else {
336             error("Image creation needs a size parameter");
337         }
338     }
339
340     printf("Formatting '%s', fmt=%s ", filename, fmt);
341     print_option_parameters(param);
342     puts("");
343
344     ret = bdrv_create(drv, filename, param);
345     free_option_parameters(param);
346
347     if (ret < 0) {
348         if (ret == -ENOTSUP) {
349             error("Formatting or formatting option not supported for file format '%s'", fmt);
350         } else if (ret == -EFBIG) {
351             error("The image size is too large for file format '%s'", fmt);
352         } else {
353             error("Error while formatting");
354         }
355     }
356     return 0;
357 }
358
359 static int img_check(int argc, char **argv)
360 {
361     int c, ret;
362     const char *filename, *fmt;
363     BlockDriver *drv;
364     BlockDriverState *bs;
365
366     fmt = NULL;
367     for(;;) {
368         c = getopt(argc, argv, "f:h");
369         if (c == -1)
370             break;
371         switch(c) {
372         case 'h':
373             help();
374             break;
375         case 'f':
376             fmt = optarg;
377             break;
378         }
379     }
380     if (optind >= argc)
381         help();
382     filename = argv[optind++];
383
384     bs = bdrv_new("");
385     if (!bs)
386         error("Not enough memory");
387     if (fmt) {
388         drv = bdrv_find_format(fmt);
389         if (!drv)
390             error("Unknown file format '%s'", fmt);
391     } else {
392         drv = NULL;
393     }
394     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
395         error("Could not open '%s'", filename);
396     }
397     ret = bdrv_check(bs);
398     switch(ret) {
399     case 0:
400         printf("No errors were found on the image.\n");
401         break;
402     case -ENOTSUP:
403         error("This image format does not support checks");
404         break;
405     default:
406         if (ret < 0) {
407             error("An error occurred during the check");
408         } else {
409             printf("%d errors were found on the image.\n", ret);
410         }
411         break;
412     }
413
414     bdrv_delete(bs);
415     return 0;
416 }
417
418 static int img_commit(int argc, char **argv)
419 {
420     int c, ret;
421     const char *filename, *fmt;
422     BlockDriver *drv;
423     BlockDriverState *bs;
424
425     fmt = NULL;
426     for(;;) {
427         c = getopt(argc, argv, "f:h");
428         if (c == -1)
429             break;
430         switch(c) {
431         case 'h':
432             help();
433             break;
434         case 'f':
435             fmt = optarg;
436             break;
437         }
438     }
439     if (optind >= argc)
440         help();
441     filename = argv[optind++];
442
443     bs = bdrv_new("");
444     if (!bs)
445         error("Not enough memory");
446     if (fmt) {
447         drv = bdrv_find_format(fmt);
448         if (!drv)
449             error("Unknown file format '%s'", fmt);
450     } else {
451         drv = NULL;
452     }
453     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
454         error("Could not open '%s'", filename);
455     }
456     ret = bdrv_commit(bs);
457     switch(ret) {
458     case 0:
459         printf("Image committed.\n");
460         break;
461     case -ENOENT:
462         error("No disk inserted");
463         break;
464     case -EACCES:
465         error("Image is read-only");
466         break;
467     case -ENOTSUP:
468         error("Image is already committed");
469         break;
470     default:
471         error("Error while committing image");
472         break;
473     }
474
475     bdrv_delete(bs);
476     return 0;
477 }
478
479 static int is_not_zero(const uint8_t *sector, int len)
480 {
481     int i;
482     len >>= 2;
483     for(i = 0;i < len; i++) {
484         if (((uint32_t *)sector)[i] != 0)
485             return 1;
486     }
487     return 0;
488 }
489
490 /*
491  * Returns true iff the first sector pointed to by 'buf' contains at least
492  * a non-NUL byte.
493  *
494  * 'pnum' is set to the number of sectors (including and immediately following
495  * the first one) that are known to be in the same allocated/unallocated state.
496  */
497 static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
498 {
499     int v, i;
500
501     if (n <= 0) {
502         *pnum = 0;
503         return 0;
504     }
505     v = is_not_zero(buf, 512);
506     for(i = 1; i < n; i++) {
507         buf += 512;
508         if (v != is_not_zero(buf, 512))
509             break;
510     }
511     *pnum = i;
512     return v;
513 }
514
515 #define IO_BUF_SIZE 65536
516
517 static int img_convert(int argc, char **argv)
518 {
519     int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
520     const char *fmt, *out_fmt, *out_baseimg, *out_filename;
521     BlockDriver *drv;
522     BlockDriverState **bs, *out_bs;
523     int64_t total_sectors, nb_sectors, sector_num, bs_offset;
524     uint64_t bs_sectors;
525     uint8_t buf[IO_BUF_SIZE];
526     const uint8_t *buf1;
527     BlockDriverInfo bdi;
528
529     fmt = NULL;
530     out_fmt = "raw";
531     out_baseimg = NULL;
532     flags = 0;
533     for(;;) {
534         c = getopt(argc, argv, "f:O:B:hce6");
535         if (c == -1)
536             break;
537         switch(c) {
538         case 'h':
539             help();
540             break;
541         case 'f':
542             fmt = optarg;
543             break;
544         case 'O':
545             out_fmt = optarg;
546             break;
547         case 'B':
548             out_baseimg = optarg;
549             break;
550         case 'c':
551             flags |= BLOCK_FLAG_COMPRESS;
552             break;
553         case 'e':
554             flags |= BLOCK_FLAG_ENCRYPT;
555             break;
556         case '6':
557             flags |= BLOCK_FLAG_COMPAT6;
558             break;
559         }
560     }
561
562     bs_n = argc - optind - 1;
563     if (bs_n < 1) help();
564
565     out_filename = argv[argc - 1];
566
567     if (bs_n > 1 && out_baseimg)
568         error("-B makes no sense when concatenating multiple input images");
569         
570     bs = calloc(bs_n, sizeof(BlockDriverState *));
571     if (!bs)
572         error("Out of memory");
573
574     total_sectors = 0;
575     for (bs_i = 0; bs_i < bs_n; bs_i++) {
576         bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
577         if (!bs[bs_i])
578             error("Could not open '%s'", argv[optind + bs_i]);
579         bdrv_get_geometry(bs[bs_i], &bs_sectors);
580         total_sectors += bs_sectors;
581     }
582
583     drv = bdrv_find_format(out_fmt);
584     if (!drv)
585         error("Unknown file format '%s'", out_fmt);
586     if (flags & BLOCK_FLAG_COMPRESS && strcmp(drv->format_name, "qcow") && strcmp(drv->format_name, "qcow2"))
587         error("Compression not supported for this file format");
588     if (flags & BLOCK_FLAG_ENCRYPT && strcmp(drv->format_name, "qcow") && strcmp(drv->format_name, "qcow2"))
589         error("Encryption not supported for this file format");
590     if (flags & BLOCK_FLAG_COMPAT6 && strcmp(drv->format_name, "vmdk"))
591         error("Alternative compatibility level not supported for this file format");
592     if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
593         error("Compression and encryption not supported at the same time");
594
595     ret = bdrv_create2(drv, out_filename, total_sectors, out_baseimg, NULL, flags);
596     if (ret < 0) {
597         if (ret == -ENOTSUP) {
598             error("Formatting not supported for file format '%s'", out_fmt);
599         } else if (ret == -EFBIG) {
600             error("The image size is too large for file format '%s'", out_fmt);
601         } else {
602             error("Error while formatting '%s'", out_filename);
603         }
604     }
605
606     out_bs = bdrv_new_open(out_filename, out_fmt);
607
608     bs_i = 0;
609     bs_offset = 0;
610     bdrv_get_geometry(bs[0], &bs_sectors);
611
612     if (flags & BLOCK_FLAG_COMPRESS) {
613         if (bdrv_get_info(out_bs, &bdi) < 0)
614             error("could not get block driver info");
615         cluster_size = bdi.cluster_size;
616         if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
617             error("invalid cluster size");
618         cluster_sectors = cluster_size >> 9;
619         sector_num = 0;
620         for(;;) {
621             int64_t bs_num;
622             int remainder;
623             uint8_t *buf2;
624
625             nb_sectors = total_sectors - sector_num;
626             if (nb_sectors <= 0)
627                 break;
628             if (nb_sectors >= cluster_sectors)
629                 n = cluster_sectors;
630             else
631                 n = nb_sectors;
632
633             bs_num = sector_num - bs_offset;
634             assert (bs_num >= 0);
635             remainder = n;
636             buf2 = buf;
637             while (remainder > 0) {
638                 int nlow;
639                 while (bs_num == bs_sectors) {
640                     bs_i++;
641                     assert (bs_i < bs_n);
642                     bs_offset += bs_sectors;
643                     bdrv_get_geometry(bs[bs_i], &bs_sectors);
644                     bs_num = 0;
645                     /* printf("changing part: sector_num=%lld, "
646                        "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
647                        sector_num, bs_i, bs_offset, bs_sectors); */
648                 }
649                 assert (bs_num < bs_sectors);
650
651                 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
652
653                 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0) 
654                     error("error while reading");
655
656                 buf2 += nlow * 512;
657                 bs_num += nlow;
658
659                 remainder -= nlow;
660             }
661             assert (remainder == 0);
662
663             if (n < cluster_sectors)
664                 memset(buf + n * 512, 0, cluster_size - n * 512);
665             if (is_not_zero(buf, cluster_size)) {
666                 if (bdrv_write_compressed(out_bs, sector_num, buf,
667                                           cluster_sectors) != 0)
668                     error("error while compressing sector %" PRId64,
669                           sector_num);
670             }
671             sector_num += n;
672         }
673         /* signal EOF to align */
674         bdrv_write_compressed(out_bs, 0, NULL, 0);
675     } else {
676         sector_num = 0; // total number of sectors converted so far
677         for(;;) {
678             nb_sectors = total_sectors - sector_num;
679             if (nb_sectors <= 0)
680                 break;
681             if (nb_sectors >= (IO_BUF_SIZE / 512))
682                 n = (IO_BUF_SIZE / 512);
683             else
684                 n = nb_sectors;
685
686             while (sector_num - bs_offset >= bs_sectors) {
687                 bs_i ++;
688                 assert (bs_i < bs_n);
689                 bs_offset += bs_sectors;
690                 bdrv_get_geometry(bs[bs_i], &bs_sectors);
691                 /* printf("changing part: sector_num=%lld, bs_i=%d, "
692                   "bs_offset=%lld, bs_sectors=%lld\n",
693                    sector_num, bs_i, bs_offset, bs_sectors); */
694             }
695
696             if (n > bs_offset + bs_sectors - sector_num)
697                 n = bs_offset + bs_sectors - sector_num;
698
699             if (strcmp(drv->format_name, "host_device")) {
700                 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
701                                        n, &n1)) {
702                     sector_num += n1;
703                     continue;
704                 }
705                 /* The next 'n1' sectors are allocated in the input image. Copy
706                    only those as they may be followed by unallocated sectors. */
707                 n = n1;
708             } else {
709                 n1 = n;
710             }
711
712             if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) 
713                 error("error while reading");
714             /* NOTE: at the same time we convert, we do not write zero
715                sectors to have a chance to compress the image. Ideally, we
716                should add a specific call to have the info to go faster */
717             buf1 = buf;
718             while (n > 0) {
719                 /* If the output image is being created as a copy on write image,
720                    copy all sectors even the ones containing only NUL bytes,
721                    because they may differ from the sectors in the base image.
722
723                    If the output is to a host device, we also write out
724                    sectors that are entirely 0, since whatever data was
725                    already there is garbage, not 0s. */
726                 if (strcmp(drv->format_name, "host_device") == 0 || out_baseimg ||
727                     is_allocated_sectors(buf1, n, &n1)) {
728                     if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
729                         error("error while writing");
730                 }
731                 sector_num += n1;
732                 n -= n1;
733                 buf1 += n1 * 512;
734             }
735         }
736     }
737     bdrv_delete(out_bs);
738     for (bs_i = 0; bs_i < bs_n; bs_i++)
739         bdrv_delete(bs[bs_i]);
740     free(bs);
741     return 0;
742 }
743
744 #ifdef _WIN32
745 static int64_t get_allocated_file_size(const char *filename)
746 {
747     typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
748     get_compressed_t get_compressed;
749     struct _stati64 st;
750
751     /* WinNT support GetCompressedFileSize to determine allocate size */
752     get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
753     if (get_compressed) {
754         DWORD high, low;
755         low = get_compressed(filename, &high);
756         if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
757             return (((int64_t) high) << 32) + low;
758     }
759
760     if (_stati64(filename, &st) < 0)
761         return -1;
762     return st.st_size;
763 }
764 #else
765 static int64_t get_allocated_file_size(const char *filename)
766 {
767     struct stat st;
768     if (stat(filename, &st) < 0)
769         return -1;
770     return (int64_t)st.st_blocks * 512;
771 }
772 #endif
773
774 static void dump_snapshots(BlockDriverState *bs)
775 {
776     QEMUSnapshotInfo *sn_tab, *sn;
777     int nb_sns, i;
778     char buf[256];
779
780     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
781     if (nb_sns <= 0)
782         return;
783     printf("Snapshot list:\n");
784     printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
785     for(i = 0; i < nb_sns; i++) {
786         sn = &sn_tab[i];
787         printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
788     }
789     qemu_free(sn_tab);
790 }
791
792 static int img_info(int argc, char **argv)
793 {
794     int c;
795     const char *filename, *fmt;
796     BlockDriver *drv;
797     BlockDriverState *bs;
798     char fmt_name[128], size_buf[128], dsize_buf[128];
799     uint64_t total_sectors;
800     int64_t allocated_size;
801     char backing_filename[1024];
802     char backing_filename2[1024];
803     BlockDriverInfo bdi;
804
805     fmt = NULL;
806     for(;;) {
807         c = getopt(argc, argv, "f:h");
808         if (c == -1)
809             break;
810         switch(c) {
811         case 'h':
812             help();
813             break;
814         case 'f':
815             fmt = optarg;
816             break;
817         }
818     }
819     if (optind >= argc)
820         help();
821     filename = argv[optind++];
822
823     bs = bdrv_new("");
824     if (!bs)
825         error("Not enough memory");
826     if (fmt) {
827         drv = bdrv_find_format(fmt);
828         if (!drv)
829             error("Unknown file format '%s'", fmt);
830     } else {
831         drv = NULL;
832     }
833     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
834         error("Could not open '%s'", filename);
835     }
836     bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
837     bdrv_get_geometry(bs, &total_sectors);
838     get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
839     allocated_size = get_allocated_file_size(filename);
840     if (allocated_size < 0)
841         snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
842     else
843         get_human_readable_size(dsize_buf, sizeof(dsize_buf),
844                                 allocated_size);
845     printf("image: %s\n"
846            "file format: %s\n"
847            "virtual size: %s (%" PRId64 " bytes)\n"
848            "disk size: %s\n",
849            filename, fmt_name, size_buf,
850            (total_sectors * 512),
851            dsize_buf);
852     if (bdrv_is_encrypted(bs))
853         printf("encrypted: yes\n");
854     if (bdrv_get_info(bs, &bdi) >= 0) {
855         if (bdi.cluster_size != 0)
856             printf("cluster_size: %d\n", bdi.cluster_size);
857     }
858     bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
859     if (backing_filename[0] != '\0') {
860         path_combine(backing_filename2, sizeof(backing_filename2),
861                      filename, backing_filename);
862         printf("backing file: %s (actual path: %s)\n",
863                backing_filename,
864                backing_filename2);
865     }
866     dump_snapshots(bs);
867     bdrv_delete(bs);
868     return 0;
869 }
870
871 #define SNAPSHOT_LIST   1
872 #define SNAPSHOT_CREATE 2
873 #define SNAPSHOT_APPLY  3
874 #define SNAPSHOT_DELETE 4
875
876 static void img_snapshot(int argc, char **argv)
877 {
878     BlockDriverState *bs;
879     QEMUSnapshotInfo sn;
880     char *filename, *snapshot_name = NULL;
881     int c, ret;
882     int action = 0;
883     qemu_timeval tv;
884
885     /* Parse commandline parameters */
886     for(;;) {
887         c = getopt(argc, argv, "la:c:d:h");
888         if (c == -1)
889             break;
890         switch(c) {
891         case 'h':
892             help();
893             return;
894         case 'l':
895             if (action) {
896                 help();
897                 return;
898             }
899             action = SNAPSHOT_LIST;
900             break;
901         case 'a':
902             if (action) {
903                 help();
904                 return;
905             }
906             action = SNAPSHOT_APPLY;
907             snapshot_name = optarg;
908             break;
909         case 'c':
910             if (action) {
911                 help();
912                 return;
913             }
914             action = SNAPSHOT_CREATE;
915             snapshot_name = optarg;
916             break;
917         case 'd':
918             if (action) {
919                 help();
920                 return;
921             }
922             action = SNAPSHOT_DELETE;
923             snapshot_name = optarg;
924             break;
925         }
926     }
927
928     if (optind >= argc)
929         help();
930     filename = argv[optind++];
931
932     /* Open the image */
933     bs = bdrv_new("");
934     if (!bs)
935         error("Not enough memory");
936
937     if (bdrv_open2(bs, filename, 0, NULL) < 0) {
938         error("Could not open '%s'", filename);
939     }
940
941     /* Perform the requested action */
942     switch(action) {
943     case SNAPSHOT_LIST:
944         dump_snapshots(bs);
945         break;
946
947     case SNAPSHOT_CREATE:
948         memset(&sn, 0, sizeof(sn));
949         pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
950
951         qemu_gettimeofday(&tv);
952         sn.date_sec = tv.tv_sec;
953         sn.date_nsec = tv.tv_usec * 1000;
954
955         ret = bdrv_snapshot_create(bs, &sn);
956         if (ret)
957             error("Could not create snapshot '%s': %d (%s)",
958                 snapshot_name, ret, strerror(-ret));
959         break;
960
961     case SNAPSHOT_APPLY:
962         ret = bdrv_snapshot_goto(bs, snapshot_name);
963         if (ret)
964             error("Could not apply snapshot '%s': %d (%s)",
965                 snapshot_name, ret, strerror(-ret));
966         break;
967
968     case SNAPSHOT_DELETE:
969         ret = bdrv_snapshot_delete(bs, snapshot_name);
970         if (ret)
971             error("Could not delete snapshot '%s': %d (%s)",
972                 snapshot_name, ret, strerror(-ret));
973         break;
974     }
975
976     /* Cleanup */
977     bdrv_delete(bs);
978 }
979
980 int main(int argc, char **argv)
981 {
982     const char *cmd;
983
984     bdrv_init();
985     if (argc < 2)
986         help();
987     cmd = argv[1];
988     argc--; argv++;
989     if (!strcmp(cmd, "create")) {
990         img_create(argc, argv);
991     } else if (!strcmp(cmd, "check")) {
992         img_check(argc, argv);
993     } else if (!strcmp(cmd, "commit")) {
994         img_commit(argc, argv);
995     } else if (!strcmp(cmd, "convert")) {
996         img_convert(argc, argv);
997     } else if (!strcmp(cmd, "info")) {
998         img_info(argc, argv);
999     } else if (!strcmp(cmd, "snapshot")) {
1000         img_snapshot(argc, argv);
1001     } else {
1002         help();
1003     }
1004     return 0;
1005 }