kvm: testsuite: add test for mov ax, imm
[qemu-kvm/fedora.git] / qemu-img.c
blobe18032f93dd5629b60f151926a86802b098c659a
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 #ifdef _WIN32
35 void *qemu_memalign(size_t alignment, size_t size)
37 return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
40 #else
42 void *qemu_memalign(size_t alignment, size_t size)
44 #if defined(_POSIX_C_SOURCE)
45 int ret;
46 void *ptr;
47 ret = posix_memalign(&ptr, alignment, size);
48 if (ret != 0)
49 return NULL;
50 return ptr;
51 #elif defined(_BSD)
52 return valloc(size);
53 #else
54 return memalign(alignment, size);
55 #endif
58 #endif
60 static void __attribute__((noreturn)) error(const char *fmt, ...)
62 va_list ap;
63 va_start(ap, fmt);
64 fprintf(stderr, "qemu-img: ");
65 vfprintf(stderr, fmt, ap);
66 fprintf(stderr, "\n");
67 exit(1);
68 va_end(ap);
71 static void format_print(void *opaque, const char *name)
73 printf(" %s", name);
76 static void help(void)
78 printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
79 "usage: qemu-img command [command options]\n"
80 "QEMU disk image utility\n"
81 "\n"
82 "Command syntax:\n"
83 " create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
84 " commit [-f fmt] filename\n"
85 " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
86 " info [-f fmt] filename\n"
87 "\n"
88 "Command parameters:\n"
89 " 'filename' is a disk image filename\n"
90 " 'base_image' is the read-only disk image which is used as base for a copy on\n"
91 " write image; the copy on write image only stores the modified data\n"
92 " 'output_base_image' forces the output image to be created as a copy on write\n"
93 " image of the specified base image; 'output_base_image' should have the same\n"
94 " content as the input's base image, however the path, image format, etc may\n"
95 " differ\n"
96 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
97 " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
98 " and 'G' (gigabyte) are supported\n"
99 " 'output_filename' is the destination disk image filename\n"
100 " 'output_fmt' is the destination format\n"
101 " '-c' indicates that target image must be compressed (qcow format only)\n"
102 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
103 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
105 printf("\nSupported format:");
106 bdrv_iterate_format(format_print, NULL);
107 printf("\n");
108 exit(1);
111 #if defined(WIN32)
112 /* XXX: put correct support for win32 */
113 static int read_password(char *buf, int buf_size)
115 int c, i;
116 printf("Password: ");
117 fflush(stdout);
118 i = 0;
119 for(;;) {
120 c = getchar();
121 if (c == '\n')
122 break;
123 if (i < (buf_size - 1))
124 buf[i++] = c;
126 buf[i] = '\0';
127 return 0;
130 #else
132 #include <termios.h>
134 static struct termios oldtty;
136 static void term_exit(void)
138 tcsetattr (0, TCSANOW, &oldtty);
141 static void term_init(void)
143 struct termios tty;
145 tcgetattr (0, &tty);
146 oldtty = tty;
148 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
149 |INLCR|IGNCR|ICRNL|IXON);
150 tty.c_oflag |= OPOST;
151 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
152 tty.c_cflag &= ~(CSIZE|PARENB);
153 tty.c_cflag |= CS8;
154 tty.c_cc[VMIN] = 1;
155 tty.c_cc[VTIME] = 0;
157 tcsetattr (0, TCSANOW, &tty);
159 atexit(term_exit);
162 static int read_password(char *buf, int buf_size)
164 uint8_t ch;
165 int i, ret;
167 printf("password: ");
168 fflush(stdout);
169 term_init();
170 i = 0;
171 for(;;) {
172 ret = read(0, &ch, 1);
173 if (ret == -1) {
174 if (errno == EAGAIN || errno == EINTR) {
175 continue;
176 } else {
177 ret = -1;
178 break;
180 } else if (ret == 0) {
181 ret = -1;
182 break;
183 } else {
184 if (ch == '\r') {
185 ret = 0;
186 break;
188 if (i < (buf_size - 1))
189 buf[i++] = ch;
192 term_exit();
193 buf[i] = '\0';
194 printf("\n");
195 return ret;
197 #endif
199 static BlockDriverState *bdrv_new_open(const char *filename,
200 const char *fmt)
202 BlockDriverState *bs;
203 BlockDriver *drv;
204 char password[256];
206 bs = bdrv_new("");
207 if (!bs)
208 error("Not enough memory");
209 if (fmt) {
210 drv = bdrv_find_format(fmt);
211 if (!drv)
212 error("Unknown file format '%s'", fmt);
213 } else {
214 drv = NULL;
216 if (bdrv_open2(bs, filename, 0, drv) < 0) {
217 error("Could not open '%s'", filename);
219 if (bdrv_is_encrypted(bs)) {
220 printf("Disk image '%s' is encrypted.\n", filename);
221 if (read_password(password, sizeof(password)) < 0)
222 error("No password given");
223 if (bdrv_set_key(bs, password) < 0)
224 error("invalid password");
226 return bs;
229 static int img_create(int argc, char **argv)
231 int c, ret, flags;
232 const char *fmt = "raw";
233 const char *filename;
234 const char *base_filename = NULL;
235 uint64_t size;
236 const char *p;
237 BlockDriver *drv;
239 flags = 0;
240 for(;;) {
241 c = getopt(argc, argv, "b:f:he6");
242 if (c == -1)
243 break;
244 switch(c) {
245 case 'h':
246 help();
247 break;
248 case 'b':
249 base_filename = optarg;
250 break;
251 case 'f':
252 fmt = optarg;
253 break;
254 case 'e':
255 flags |= BLOCK_FLAG_ENCRYPT;
256 break;
257 case '6':
258 flags |= BLOCK_FLAG_COMPAT6;
259 break;
262 if (optind >= argc)
263 help();
264 filename = argv[optind++];
265 size = 0;
266 if (base_filename) {
267 BlockDriverState *bs;
268 bs = bdrv_new_open(base_filename, NULL);
269 bdrv_get_geometry(bs, &size);
270 size *= 512;
271 bdrv_delete(bs);
272 } else {
273 if (optind >= argc)
274 help();
275 p = argv[optind];
276 size = strtoul(p, (char **)&p, 0);
277 if (*p == 'M') {
278 size *= 1024 * 1024;
279 } else if (*p == 'G') {
280 size *= 1024 * 1024 * 1024;
281 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
282 size *= 1024;
283 } else {
284 help();
287 drv = bdrv_find_format(fmt);
288 if (!drv)
289 error("Unknown file format '%s'", fmt);
290 printf("Formatting '%s', fmt=%s",
291 filename, fmt);
292 if (flags & BLOCK_FLAG_ENCRYPT)
293 printf(", encrypted");
294 if (flags & BLOCK_FLAG_COMPAT6)
295 printf(", compatibility level=6");
296 if (base_filename) {
297 printf(", backing_file=%s",
298 base_filename);
300 printf(", size=%" PRIu64 " kB\n", size / 1024);
301 ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
302 if (ret < 0) {
303 if (ret == -ENOTSUP) {
304 error("Formatting or formatting option not supported for file format '%s'", fmt);
305 } else {
306 error("Error while formatting");
309 return 0;
312 static int img_commit(int argc, char **argv)
314 int c, ret;
315 const char *filename, *fmt;
316 BlockDriver *drv;
317 BlockDriverState *bs;
319 fmt = NULL;
320 for(;;) {
321 c = getopt(argc, argv, "f:h");
322 if (c == -1)
323 break;
324 switch(c) {
325 case 'h':
326 help();
327 break;
328 case 'f':
329 fmt = optarg;
330 break;
333 if (optind >= argc)
334 help();
335 filename = argv[optind++];
337 bs = bdrv_new("");
338 if (!bs)
339 error("Not enough memory");
340 if (fmt) {
341 drv = bdrv_find_format(fmt);
342 if (!drv)
343 error("Unknown file format '%s'", fmt);
344 } else {
345 drv = NULL;
347 if (bdrv_open2(bs, filename, 0, drv) < 0) {
348 error("Could not open '%s'", filename);
350 ret = bdrv_commit(bs);
351 switch(ret) {
352 case 0:
353 printf("Image committed.\n");
354 break;
355 case -ENOENT:
356 error("No disk inserted");
357 break;
358 case -EACCES:
359 error("Image is read-only");
360 break;
361 case -ENOTSUP:
362 error("Image is already committed");
363 break;
364 default:
365 error("Error while committing image");
366 break;
369 bdrv_delete(bs);
370 return 0;
373 static int is_not_zero(const uint8_t *sector, int len)
375 int i;
376 len >>= 2;
377 for(i = 0;i < len; i++) {
378 if (((uint32_t *)sector)[i] != 0)
379 return 1;
381 return 0;
385 * Returns true iff the first sector pointed to by 'buf' contains at least
386 * a non-NUL byte.
388 * 'pnum' is set to the number of sectors (including and immediately following
389 * the first one) that are known to be in the same allocated/unallocated state.
391 static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
393 int v, i;
395 if (n <= 0) {
396 *pnum = 0;
397 return 0;
399 v = is_not_zero(buf, 512);
400 for(i = 1; i < n; i++) {
401 buf += 512;
402 if (v != is_not_zero(buf, 512))
403 break;
405 *pnum = i;
406 return v;
409 #define IO_BUF_SIZE 65536
411 static int img_convert(int argc, char **argv)
413 int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
414 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
415 BlockDriver *drv;
416 BlockDriverState **bs, *out_bs;
417 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
418 uint64_t bs_sectors;
419 uint8_t buf[IO_BUF_SIZE];
420 const uint8_t *buf1;
421 BlockDriverInfo bdi;
423 fmt = NULL;
424 out_fmt = "raw";
425 out_baseimg = NULL;
426 flags = 0;
427 for(;;) {
428 c = getopt(argc, argv, "f:O:B:hce6");
429 if (c == -1)
430 break;
431 switch(c) {
432 case 'h':
433 help();
434 break;
435 case 'f':
436 fmt = optarg;
437 break;
438 case 'O':
439 out_fmt = optarg;
440 break;
441 case 'B':
442 out_baseimg = optarg;
443 break;
444 case 'c':
445 flags |= BLOCK_FLAG_COMPRESS;
446 break;
447 case 'e':
448 flags |= BLOCK_FLAG_ENCRYPT;
449 break;
450 case '6':
451 flags |= BLOCK_FLAG_COMPAT6;
452 break;
456 bs_n = argc - optind - 1;
457 if (bs_n < 1) help();
459 out_filename = argv[argc - 1];
461 if (bs_n > 1 && out_baseimg)
462 error("-B makes no sense when concatenating multiple input images");
464 bs = calloc(bs_n, sizeof(BlockDriverState *));
465 if (!bs)
466 error("Out of memory");
468 total_sectors = 0;
469 for (bs_i = 0; bs_i < bs_n; bs_i++) {
470 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
471 if (!bs[bs_i])
472 error("Could not open '%s'", argv[optind + bs_i]);
473 bdrv_get_geometry(bs[bs_i], &bs_sectors);
474 total_sectors += bs_sectors;
477 drv = bdrv_find_format(out_fmt);
478 if (!drv)
479 error("Unknown file format '%s'", out_fmt);
480 if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
481 error("Compression not supported for this file format");
482 if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
483 error("Encryption not supported for this file format");
484 if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
485 error("Alternative compatibility level not supported for this file format");
486 if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
487 error("Compression and encryption not supported at the same time");
489 ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
490 if (ret < 0) {
491 if (ret == -ENOTSUP) {
492 error("Formatting not supported for file format '%s'", fmt);
493 } else {
494 error("Error while formatting '%s'", out_filename);
498 out_bs = bdrv_new_open(out_filename, out_fmt);
500 bs_i = 0;
501 bs_offset = 0;
502 bdrv_get_geometry(bs[0], &bs_sectors);
504 if (flags & BLOCK_FLAG_COMPRESS) {
505 if (bdrv_get_info(out_bs, &bdi) < 0)
506 error("could not get block driver info");
507 cluster_size = bdi.cluster_size;
508 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
509 error("invalid cluster size");
510 cluster_sectors = cluster_size >> 9;
511 sector_num = 0;
512 for(;;) {
513 int64_t bs_num;
514 int remainder;
515 uint8_t *buf2;
517 nb_sectors = total_sectors - sector_num;
518 if (nb_sectors <= 0)
519 break;
520 if (nb_sectors >= cluster_sectors)
521 n = cluster_sectors;
522 else
523 n = nb_sectors;
525 bs_num = sector_num - bs_offset;
526 assert (bs_num >= 0);
527 remainder = n;
528 buf2 = buf;
529 while (remainder > 0) {
530 int nlow;
531 while (bs_num == bs_sectors) {
532 bs_i++;
533 assert (bs_i < bs_n);
534 bs_offset += bs_sectors;
535 bdrv_get_geometry(bs[bs_i], &bs_sectors);
536 bs_num = 0;
537 /* printf("changing part: sector_num=%lld, "
538 "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
539 sector_num, bs_i, bs_offset, bs_sectors); */
541 assert (bs_num < bs_sectors);
543 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
545 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0)
546 error("error while reading");
548 buf2 += nlow * 512;
549 bs_num += nlow;
551 remainder -= nlow;
553 assert (remainder == 0);
555 if (n < cluster_sectors)
556 memset(buf + n * 512, 0, cluster_size - n * 512);
557 if (is_not_zero(buf, cluster_size)) {
558 if (bdrv_write_compressed(out_bs, sector_num, buf,
559 cluster_sectors) != 0)
560 error("error while compressing sector %" PRId64,
561 sector_num);
563 sector_num += n;
565 /* signal EOF to align */
566 bdrv_write_compressed(out_bs, 0, NULL, 0);
567 } else {
568 sector_num = 0; // total number of sectors converted so far
569 for(;;) {
570 nb_sectors = total_sectors - sector_num;
571 if (nb_sectors <= 0)
572 break;
573 if (nb_sectors >= (IO_BUF_SIZE / 512))
574 n = (IO_BUF_SIZE / 512);
575 else
576 n = nb_sectors;
578 while (sector_num - bs_offset >= bs_sectors) {
579 bs_i ++;
580 assert (bs_i < bs_n);
581 bs_offset += bs_sectors;
582 bdrv_get_geometry(bs[bs_i], &bs_sectors);
583 /* printf("changing part: sector_num=%lld, bs_i=%d, "
584 "bs_offset=%lld, bs_sectors=%lld\n",
585 sector_num, bs_i, bs_offset, bs_sectors); */
588 if (n > bs_offset + bs_sectors - sector_num)
589 n = bs_offset + bs_sectors - sector_num;
591 /* If the output image is being created as a copy on write image,
592 assume that sectors which are unallocated in the input image
593 are present in both the output's and input's base images (no
594 need to copy them). */
595 if (out_baseimg) {
596 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) {
597 sector_num += n1;
598 continue;
600 /* The next 'n1' sectors are allocated in the input image. Copy
601 only those as they may be followed by unallocated sectors. */
602 n = n1;
605 if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
606 error("error while reading");
607 /* NOTE: at the same time we convert, we do not write zero
608 sectors to have a chance to compress the image. Ideally, we
609 should add a specific call to have the info to go faster */
610 buf1 = buf;
611 while (n > 0) {
612 /* If the output image is being created as a copy on write image,
613 copy all sectors even the ones containing only NUL bytes,
614 because they may differ from the sectors in the base image. */
615 if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) {
616 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
617 error("error while writing");
619 sector_num += n1;
620 n -= n1;
621 buf1 += n1 * 512;
625 bdrv_delete(out_bs);
626 for (bs_i = 0; bs_i < bs_n; bs_i++)
627 bdrv_delete(bs[bs_i]);
628 free(bs);
629 return 0;
632 #ifdef _WIN32
633 static int64_t get_allocated_file_size(const char *filename)
635 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
636 get_compressed_t get_compressed;
637 struct _stati64 st;
639 /* WinNT support GetCompressedFileSize to determine allocate size */
640 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
641 if (get_compressed) {
642 DWORD high, low;
643 low = get_compressed(filename, &high);
644 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
645 return (((int64_t) high) << 32) + low;
648 if (_stati64(filename, &st) < 0)
649 return -1;
650 return st.st_size;
652 #else
653 static int64_t get_allocated_file_size(const char *filename)
655 struct stat st;
656 if (stat(filename, &st) < 0)
657 return -1;
658 return (int64_t)st.st_blocks * 512;
660 #endif
662 static void dump_snapshots(BlockDriverState *bs)
664 QEMUSnapshotInfo *sn_tab, *sn;
665 int nb_sns, i;
666 char buf[256];
668 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
669 if (nb_sns <= 0)
670 return;
671 printf("Snapshot list:\n");
672 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
673 for(i = 0; i < nb_sns; i++) {
674 sn = &sn_tab[i];
675 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
677 qemu_free(sn_tab);
680 static int img_info(int argc, char **argv)
682 int c;
683 const char *filename, *fmt;
684 BlockDriver *drv;
685 BlockDriverState *bs;
686 char fmt_name[128], size_buf[128], dsize_buf[128];
687 uint64_t total_sectors;
688 int64_t allocated_size;
689 char backing_filename[1024];
690 char backing_filename2[1024];
691 BlockDriverInfo bdi;
693 fmt = NULL;
694 for(;;) {
695 c = getopt(argc, argv, "f:h");
696 if (c == -1)
697 break;
698 switch(c) {
699 case 'h':
700 help();
701 break;
702 case 'f':
703 fmt = optarg;
704 break;
707 if (optind >= argc)
708 help();
709 filename = argv[optind++];
711 bs = bdrv_new("");
712 if (!bs)
713 error("Not enough memory");
714 if (fmt) {
715 drv = bdrv_find_format(fmt);
716 if (!drv)
717 error("Unknown file format '%s'", fmt);
718 } else {
719 drv = NULL;
721 if (bdrv_open2(bs, filename, 0, drv) < 0) {
722 error("Could not open '%s'", filename);
724 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
725 bdrv_get_geometry(bs, &total_sectors);
726 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
727 allocated_size = get_allocated_file_size(filename);
728 if (allocated_size < 0)
729 sprintf(dsize_buf, "unavailable");
730 else
731 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
732 allocated_size);
733 printf("image: %s\n"
734 "file format: %s\n"
735 "virtual size: %s (%" PRId64 " bytes)\n"
736 "disk size: %s\n",
737 filename, fmt_name, size_buf,
738 (total_sectors * 512),
739 dsize_buf);
740 if (bdrv_is_encrypted(bs))
741 printf("encrypted: yes\n");
742 if (bdrv_get_info(bs, &bdi) >= 0) {
743 if (bdi.cluster_size != 0)
744 printf("cluster_size: %d\n", bdi.cluster_size);
746 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
747 if (backing_filename[0] != '\0') {
748 path_combine(backing_filename2, sizeof(backing_filename2),
749 filename, backing_filename);
750 printf("backing file: %s (actual path: %s)\n",
751 backing_filename,
752 backing_filename2);
754 dump_snapshots(bs);
755 bdrv_delete(bs);
756 return 0;
759 int main(int argc, char **argv)
761 const char *cmd;
763 bdrv_init();
764 if (argc < 2)
765 help();
766 cmd = argv[1];
767 optind++;
768 if (!strcmp(cmd, "create")) {
769 img_create(argc, argv);
770 } else if (!strcmp(cmd, "commit")) {
771 img_commit(argc, argv);
772 } else if (!strcmp(cmd, "convert")) {
773 img_convert(argc, argv);
774 } else if (!strcmp(cmd, "info")) {
775 img_info(argc, argv);
776 } else {
777 help();
779 return 0;