Attached patch fixes a series of this warning
[qemu/mini2440.git] / qemu-img.c
blob70c24038725486d9eb4ddc65cb3642f91bf641c2
1 /*
2 * QEMU disk image utility
4 * Copyright (c) 2003-2008 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
24 #include "qemu-common.h"
25 #include "block_int.h"
26 #include <assert.h>
28 #ifdef _WIN32
29 #define WIN32_LEAN_AND_MEAN
30 #include <windows.h>
31 #endif
33 static void __attribute__((noreturn)) error(const char *fmt, ...)
35 va_list ap;
36 va_start(ap, fmt);
37 fprintf(stderr, "qemu-img: ");
38 vfprintf(stderr, fmt, ap);
39 fprintf(stderr, "\n");
40 exit(1);
41 va_end(ap);
44 static void format_print(void *opaque, const char *name)
46 printf(" %s", name);
49 static void help(void)
51 printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
52 "usage: qemu-img command [command options]\n"
53 "QEMU disk image utility\n"
54 "\n"
55 "Command syntax:\n"
56 " create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
57 " commit [-f fmt] filename\n"
58 " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
59 " info [-f fmt] filename\n"
60 "\n"
61 "Command parameters:\n"
62 " 'filename' is a disk image filename\n"
63 " 'base_image' is the read-only disk image which is used as base for a copy on\n"
64 " write image; the copy on write image only stores the modified data\n"
65 " 'output_base_image' forces the output image to be created as a copy on write\n"
66 " image of the specified base image; 'output_base_image' should have the same\n"
67 " content as the input's base image, however the path, image format, etc may\n"
68 " differ\n"
69 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
70 " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
71 " and 'G' (gigabyte) are supported\n"
72 " 'output_filename' is the destination disk image filename\n"
73 " 'output_fmt' is the destination format\n"
74 " '-c' indicates that target image must be compressed (qcow format only)\n"
75 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
76 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
78 printf("\nSupported format:");
79 bdrv_iterate_format(format_print, NULL);
80 printf("\n");
81 exit(1);
84 #if defined(WIN32)
85 /* XXX: put correct support for win32 */
86 static int read_password(char *buf, int buf_size)
88 int c, i;
89 printf("Password: ");
90 fflush(stdout);
91 i = 0;
92 for(;;) {
93 c = getchar();
94 if (c == '\n')
95 break;
96 if (i < (buf_size - 1))
97 buf[i++] = c;
99 buf[i] = '\0';
100 return 0;
103 #else
105 #include <termios.h>
107 static struct termios oldtty;
109 static void term_exit(void)
111 tcsetattr (0, TCSANOW, &oldtty);
114 static void term_init(void)
116 struct termios tty;
118 tcgetattr (0, &tty);
119 oldtty = tty;
121 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
122 |INLCR|IGNCR|ICRNL|IXON);
123 tty.c_oflag |= OPOST;
124 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
125 tty.c_cflag &= ~(CSIZE|PARENB);
126 tty.c_cflag |= CS8;
127 tty.c_cc[VMIN] = 1;
128 tty.c_cc[VTIME] = 0;
130 tcsetattr (0, TCSANOW, &tty);
132 atexit(term_exit);
135 static int read_password(char *buf, int buf_size)
137 uint8_t ch;
138 int i, ret;
140 printf("password: ");
141 fflush(stdout);
142 term_init();
143 i = 0;
144 for(;;) {
145 ret = read(0, &ch, 1);
146 if (ret == -1) {
147 if (errno == EAGAIN || errno == EINTR) {
148 continue;
149 } else {
150 ret = -1;
151 break;
153 } else if (ret == 0) {
154 ret = -1;
155 break;
156 } else {
157 if (ch == '\r') {
158 ret = 0;
159 break;
161 if (i < (buf_size - 1))
162 buf[i++] = ch;
165 term_exit();
166 buf[i] = '\0';
167 printf("\n");
168 return ret;
170 #endif
172 static BlockDriverState *bdrv_new_open(const char *filename,
173 const char *fmt)
175 BlockDriverState *bs;
176 BlockDriver *drv;
177 char password[256];
179 bs = bdrv_new("");
180 if (!bs)
181 error("Not enough memory");
182 if (fmt) {
183 drv = bdrv_find_format(fmt);
184 if (!drv)
185 error("Unknown file format '%s'", fmt);
186 } else {
187 drv = NULL;
189 if (bdrv_open2(bs, filename, 0, drv) < 0) {
190 error("Could not open '%s'", filename);
192 if (bdrv_is_encrypted(bs)) {
193 printf("Disk image '%s' is encrypted.\n", filename);
194 if (read_password(password, sizeof(password)) < 0)
195 error("No password given");
196 if (bdrv_set_key(bs, password) < 0)
197 error("invalid password");
199 return bs;
202 static int img_create(int argc, char **argv)
204 int c, ret, flags;
205 const char *fmt = "raw";
206 const char *filename;
207 const char *base_filename = NULL;
208 uint64_t size;
209 const char *p;
210 BlockDriver *drv;
212 flags = 0;
213 for(;;) {
214 c = getopt(argc, argv, "b:f:he6");
215 if (c == -1)
216 break;
217 switch(c) {
218 case 'h':
219 help();
220 break;
221 case 'b':
222 base_filename = optarg;
223 break;
224 case 'f':
225 fmt = optarg;
226 break;
227 case 'e':
228 flags |= BLOCK_FLAG_ENCRYPT;
229 break;
230 case '6':
231 flags |= BLOCK_FLAG_COMPAT6;
232 break;
235 if (optind >= argc)
236 help();
237 filename = argv[optind++];
238 size = 0;
239 if (base_filename) {
240 BlockDriverState *bs;
241 bs = bdrv_new_open(base_filename, NULL);
242 bdrv_get_geometry(bs, &size);
243 size *= 512;
244 bdrv_delete(bs);
245 } else {
246 if (optind >= argc)
247 help();
248 p = argv[optind];
249 size = strtoul(p, (char **)&p, 0);
250 if (*p == 'M') {
251 size *= 1024 * 1024;
252 } else if (*p == 'G') {
253 size *= 1024 * 1024 * 1024;
254 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
255 size *= 1024;
256 } else {
257 help();
260 drv = bdrv_find_format(fmt);
261 if (!drv)
262 error("Unknown file format '%s'", fmt);
263 printf("Formatting '%s', fmt=%s",
264 filename, fmt);
265 if (flags & BLOCK_FLAG_ENCRYPT)
266 printf(", encrypted");
267 if (flags & BLOCK_FLAG_COMPAT6)
268 printf(", compatibility level=6");
269 if (base_filename) {
270 printf(", backing_file=%s",
271 base_filename);
273 printf(", size=%" PRIu64 " kB\n", size / 1024);
274 ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
275 if (ret < 0) {
276 if (ret == -ENOTSUP) {
277 error("Formatting or formatting option not supported for file format '%s'", fmt);
278 } else {
279 error("Error while formatting");
282 return 0;
285 static int img_commit(int argc, char **argv)
287 int c, ret;
288 const char *filename, *fmt;
289 BlockDriver *drv;
290 BlockDriverState *bs;
292 fmt = NULL;
293 for(;;) {
294 c = getopt(argc, argv, "f:h");
295 if (c == -1)
296 break;
297 switch(c) {
298 case 'h':
299 help();
300 break;
301 case 'f':
302 fmt = optarg;
303 break;
306 if (optind >= argc)
307 help();
308 filename = argv[optind++];
310 bs = bdrv_new("");
311 if (!bs)
312 error("Not enough memory");
313 if (fmt) {
314 drv = bdrv_find_format(fmt);
315 if (!drv)
316 error("Unknown file format '%s'", fmt);
317 } else {
318 drv = NULL;
320 if (bdrv_open2(bs, filename, 0, drv) < 0) {
321 error("Could not open '%s'", filename);
323 ret = bdrv_commit(bs);
324 switch(ret) {
325 case 0:
326 printf("Image committed.\n");
327 break;
328 case -ENOENT:
329 error("No disk inserted");
330 break;
331 case -EACCES:
332 error("Image is read-only");
333 break;
334 case -ENOTSUP:
335 error("Image is already committed");
336 break;
337 default:
338 error("Error while committing image");
339 break;
342 bdrv_delete(bs);
343 return 0;
346 static int is_not_zero(const uint8_t *sector, int len)
348 int i;
349 len >>= 2;
350 for(i = 0;i < len; i++) {
351 if (((uint32_t *)sector)[i] != 0)
352 return 1;
354 return 0;
358 * Returns true iff the first sector pointed to by 'buf' contains at least
359 * a non-NUL byte.
361 * 'pnum' is set to the number of sectors (including and immediately following
362 * the first one) that are known to be in the same allocated/unallocated state.
364 static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
366 int v, i;
368 if (n <= 0) {
369 *pnum = 0;
370 return 0;
372 v = is_not_zero(buf, 512);
373 for(i = 1; i < n; i++) {
374 buf += 512;
375 if (v != is_not_zero(buf, 512))
376 break;
378 *pnum = i;
379 return v;
382 #define IO_BUF_SIZE 65536
384 static int img_convert(int argc, char **argv)
386 int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
387 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
388 BlockDriver *drv;
389 BlockDriverState **bs, *out_bs;
390 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
391 uint64_t bs_sectors;
392 uint8_t buf[IO_BUF_SIZE];
393 const uint8_t *buf1;
394 BlockDriverInfo bdi;
396 fmt = NULL;
397 out_fmt = "raw";
398 out_baseimg = NULL;
399 flags = 0;
400 for(;;) {
401 c = getopt(argc, argv, "f:O:B:hce6");
402 if (c == -1)
403 break;
404 switch(c) {
405 case 'h':
406 help();
407 break;
408 case 'f':
409 fmt = optarg;
410 break;
411 case 'O':
412 out_fmt = optarg;
413 break;
414 case 'B':
415 out_baseimg = optarg;
416 break;
417 case 'c':
418 flags |= BLOCK_FLAG_COMPRESS;
419 break;
420 case 'e':
421 flags |= BLOCK_FLAG_ENCRYPT;
422 break;
423 case '6':
424 flags |= BLOCK_FLAG_COMPAT6;
425 break;
429 bs_n = argc - optind - 1;
430 if (bs_n < 1) help();
432 out_filename = argv[argc - 1];
434 if (bs_n > 1 && out_baseimg)
435 error("-B makes no sense when concatenating multiple input images");
437 bs = calloc(bs_n, sizeof(BlockDriverState *));
438 if (!bs)
439 error("Out of memory");
441 total_sectors = 0;
442 for (bs_i = 0; bs_i < bs_n; bs_i++) {
443 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
444 if (!bs[bs_i])
445 error("Could not open '%s'", argv[optind + bs_i]);
446 bdrv_get_geometry(bs[bs_i], &bs_sectors);
447 total_sectors += bs_sectors;
450 drv = bdrv_find_format(out_fmt);
451 if (!drv)
452 error("Unknown file format '%s'", out_fmt);
453 if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
454 error("Compression not supported for this file format");
455 if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
456 error("Encryption not supported for this file format");
457 if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
458 error("Alternative compatibility level not supported for this file format");
459 if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
460 error("Compression and encryption not supported at the same time");
462 ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
463 if (ret < 0) {
464 if (ret == -ENOTSUP) {
465 error("Formatting not supported for file format '%s'", fmt);
466 } else {
467 error("Error while formatting '%s'", out_filename);
471 out_bs = bdrv_new_open(out_filename, out_fmt);
473 bs_i = 0;
474 bs_offset = 0;
475 bdrv_get_geometry(bs[0], &bs_sectors);
477 if (flags & BLOCK_FLAG_COMPRESS) {
478 if (bdrv_get_info(out_bs, &bdi) < 0)
479 error("could not get block driver info");
480 cluster_size = bdi.cluster_size;
481 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
482 error("invalid cluster size");
483 cluster_sectors = cluster_size >> 9;
484 sector_num = 0;
485 for(;;) {
486 int64_t bs_num;
487 int remainder;
488 uint8_t *buf2;
490 nb_sectors = total_sectors - sector_num;
491 if (nb_sectors <= 0)
492 break;
493 if (nb_sectors >= cluster_sectors)
494 n = cluster_sectors;
495 else
496 n = nb_sectors;
498 bs_num = sector_num - bs_offset;
499 assert (bs_num >= 0);
500 remainder = n;
501 buf2 = buf;
502 while (remainder > 0) {
503 int nlow;
504 while (bs_num == bs_sectors) {
505 bs_i++;
506 assert (bs_i < bs_n);
507 bs_offset += bs_sectors;
508 bdrv_get_geometry(bs[bs_i], &bs_sectors);
509 bs_num = 0;
510 /* printf("changing part: sector_num=%lld, "
511 "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
512 sector_num, bs_i, bs_offset, bs_sectors); */
514 assert (bs_num < bs_sectors);
516 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
518 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0)
519 error("error while reading");
521 buf2 += nlow * 512;
522 bs_num += nlow;
524 remainder -= nlow;
526 assert (remainder == 0);
528 if (n < cluster_sectors)
529 memset(buf + n * 512, 0, cluster_size - n * 512);
530 if (is_not_zero(buf, cluster_size)) {
531 if (bdrv_write_compressed(out_bs, sector_num, buf,
532 cluster_sectors) != 0)
533 error("error while compressing sector %" PRId64,
534 sector_num);
536 sector_num += n;
538 /* signal EOF to align */
539 bdrv_write_compressed(out_bs, 0, NULL, 0);
540 } else {
541 sector_num = 0; // total number of sectors converted so far
542 for(;;) {
543 nb_sectors = total_sectors - sector_num;
544 if (nb_sectors <= 0)
545 break;
546 if (nb_sectors >= (IO_BUF_SIZE / 512))
547 n = (IO_BUF_SIZE / 512);
548 else
549 n = nb_sectors;
551 while (sector_num - bs_offset >= bs_sectors) {
552 bs_i ++;
553 assert (bs_i < bs_n);
554 bs_offset += bs_sectors;
555 bdrv_get_geometry(bs[bs_i], &bs_sectors);
556 /* printf("changing part: sector_num=%lld, bs_i=%d, "
557 "bs_offset=%lld, bs_sectors=%lld\n",
558 sector_num, bs_i, bs_offset, bs_sectors); */
561 if (n > bs_offset + bs_sectors - sector_num)
562 n = bs_offset + bs_sectors - sector_num;
564 /* If the output image is being created as a copy on write image,
565 assume that sectors which are unallocated in the input image
566 are present in both the output's and input's base images (no
567 need to copy them). */
568 if (out_baseimg) {
569 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) {
570 sector_num += n1;
571 continue;
573 /* The next 'n1' sectors are allocated in the input image. Copy
574 only those as they may be followed by unallocated sectors. */
575 n = n1;
578 if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
579 error("error while reading");
580 /* NOTE: at the same time we convert, we do not write zero
581 sectors to have a chance to compress the image. Ideally, we
582 should add a specific call to have the info to go faster */
583 buf1 = buf;
584 while (n > 0) {
585 /* If the output image is being created as a copy on write image,
586 copy all sectors even the ones containing only NUL bytes,
587 because they may differ from the sectors in the base image. */
588 if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) {
589 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
590 error("error while writing");
592 sector_num += n1;
593 n -= n1;
594 buf1 += n1 * 512;
598 bdrv_delete(out_bs);
599 for (bs_i = 0; bs_i < bs_n; bs_i++)
600 bdrv_delete(bs[bs_i]);
601 free(bs);
602 return 0;
605 #ifdef _WIN32
606 static int64_t get_allocated_file_size(const char *filename)
608 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
609 get_compressed_t get_compressed;
610 struct _stati64 st;
612 /* WinNT support GetCompressedFileSize to determine allocate size */
613 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
614 if (get_compressed) {
615 DWORD high, low;
616 low = get_compressed(filename, &high);
617 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
618 return (((int64_t) high) << 32) + low;
621 if (_stati64(filename, &st) < 0)
622 return -1;
623 return st.st_size;
625 #else
626 static int64_t get_allocated_file_size(const char *filename)
628 struct stat st;
629 if (stat(filename, &st) < 0)
630 return -1;
631 return (int64_t)st.st_blocks * 512;
633 #endif
635 static void dump_snapshots(BlockDriverState *bs)
637 QEMUSnapshotInfo *sn_tab, *sn;
638 int nb_sns, i;
639 char buf[256];
641 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
642 if (nb_sns <= 0)
643 return;
644 printf("Snapshot list:\n");
645 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
646 for(i = 0; i < nb_sns; i++) {
647 sn = &sn_tab[i];
648 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
650 qemu_free(sn_tab);
653 static int img_info(int argc, char **argv)
655 int c;
656 const char *filename, *fmt;
657 BlockDriver *drv;
658 BlockDriverState *bs;
659 char fmt_name[128], size_buf[128], dsize_buf[128];
660 uint64_t total_sectors;
661 int64_t allocated_size;
662 char backing_filename[1024];
663 char backing_filename2[1024];
664 BlockDriverInfo bdi;
666 fmt = NULL;
667 for(;;) {
668 c = getopt(argc, argv, "f:h");
669 if (c == -1)
670 break;
671 switch(c) {
672 case 'h':
673 help();
674 break;
675 case 'f':
676 fmt = optarg;
677 break;
680 if (optind >= argc)
681 help();
682 filename = argv[optind++];
684 bs = bdrv_new("");
685 if (!bs)
686 error("Not enough memory");
687 if (fmt) {
688 drv = bdrv_find_format(fmt);
689 if (!drv)
690 error("Unknown file format '%s'", fmt);
691 } else {
692 drv = NULL;
694 if (bdrv_open2(bs, filename, 0, drv) < 0) {
695 error("Could not open '%s'", filename);
697 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
698 bdrv_get_geometry(bs, &total_sectors);
699 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
700 allocated_size = get_allocated_file_size(filename);
701 if (allocated_size < 0)
702 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
703 else
704 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
705 allocated_size);
706 printf("image: %s\n"
707 "file format: %s\n"
708 "virtual size: %s (%" PRId64 " bytes)\n"
709 "disk size: %s\n",
710 filename, fmt_name, size_buf,
711 (total_sectors * 512),
712 dsize_buf);
713 if (bdrv_is_encrypted(bs))
714 printf("encrypted: yes\n");
715 if (bdrv_get_info(bs, &bdi) >= 0) {
716 if (bdi.cluster_size != 0)
717 printf("cluster_size: %d\n", bdi.cluster_size);
719 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
720 if (backing_filename[0] != '\0') {
721 path_combine(backing_filename2, sizeof(backing_filename2),
722 filename, backing_filename);
723 printf("backing file: %s (actual path: %s)\n",
724 backing_filename,
725 backing_filename2);
727 dump_snapshots(bs);
728 bdrv_delete(bs);
729 return 0;
732 int main(int argc, char **argv)
734 const char *cmd;
736 bdrv_init();
737 if (argc < 2)
738 help();
739 cmd = argv[1];
740 optind++;
741 if (!strcmp(cmd, "create")) {
742 img_create(argc, argv);
743 } else if (!strcmp(cmd, "commit")) {
744 img_commit(argc, argv);
745 } else if (!strcmp(cmd, "convert")) {
746 img_convert(argc, argv);
747 } else if (!strcmp(cmd, "info")) {
748 img_info(argc, argv);
749 } else {
750 help();
752 return 0;