Add print to PowerPC qemu for failed DCR read/writes
[qemu-kvm/fedora.git] / qemu-img.c
blobb3190d469a04e15b801559776b88d7ae6e84914e
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] 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 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
93 " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
94 " and 'G' (gigabyte) are supported\n"
95 " 'output_filename' is the destination disk image filename\n"
96 " 'output_fmt' is the destination format\n"
97 " '-c' indicates that target image must be compressed (qcow format only)\n"
98 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
99 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
101 printf("\nSupported format:");
102 bdrv_iterate_format(format_print, NULL);
103 printf("\n");
104 exit(1);
107 #if defined(WIN32)
108 /* XXX: put correct support for win32 */
109 static int read_password(char *buf, int buf_size)
111 int c, i;
112 printf("Password: ");
113 fflush(stdout);
114 i = 0;
115 for(;;) {
116 c = getchar();
117 if (c == '\n')
118 break;
119 if (i < (buf_size - 1))
120 buf[i++] = c;
122 buf[i] = '\0';
123 return 0;
126 #else
128 #include <termios.h>
130 static struct termios oldtty;
132 static void term_exit(void)
134 tcsetattr (0, TCSANOW, &oldtty);
137 static void term_init(void)
139 struct termios tty;
141 tcgetattr (0, &tty);
142 oldtty = tty;
144 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
145 |INLCR|IGNCR|ICRNL|IXON);
146 tty.c_oflag |= OPOST;
147 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
148 tty.c_cflag &= ~(CSIZE|PARENB);
149 tty.c_cflag |= CS8;
150 tty.c_cc[VMIN] = 1;
151 tty.c_cc[VTIME] = 0;
153 tcsetattr (0, TCSANOW, &tty);
155 atexit(term_exit);
158 static int read_password(char *buf, int buf_size)
160 uint8_t ch;
161 int i, ret;
163 printf("password: ");
164 fflush(stdout);
165 term_init();
166 i = 0;
167 for(;;) {
168 ret = read(0, &ch, 1);
169 if (ret == -1) {
170 if (errno == EAGAIN || errno == EINTR) {
171 continue;
172 } else {
173 ret = -1;
174 break;
176 } else if (ret == 0) {
177 ret = -1;
178 break;
179 } else {
180 if (ch == '\r') {
181 ret = 0;
182 break;
184 if (i < (buf_size - 1))
185 buf[i++] = ch;
188 term_exit();
189 buf[i] = '\0';
190 printf("\n");
191 return ret;
193 #endif
195 static BlockDriverState *bdrv_new_open(const char *filename,
196 const char *fmt)
198 BlockDriverState *bs;
199 BlockDriver *drv;
200 char password[256];
202 bs = bdrv_new("");
203 if (!bs)
204 error("Not enough memory");
205 if (fmt) {
206 drv = bdrv_find_format(fmt);
207 if (!drv)
208 error("Unknown file format '%s'", fmt);
209 } else {
210 drv = NULL;
212 if (bdrv_open2(bs, filename, 0, drv) < 0) {
213 error("Could not open '%s'", filename);
215 if (bdrv_is_encrypted(bs)) {
216 printf("Disk image '%s' is encrypted.\n", filename);
217 if (read_password(password, sizeof(password)) < 0)
218 error("No password given");
219 if (bdrv_set_key(bs, password) < 0)
220 error("invalid password");
222 return bs;
225 static int img_create(int argc, char **argv)
227 int c, ret, flags;
228 const char *fmt = "raw";
229 const char *filename;
230 const char *base_filename = NULL;
231 uint64_t size;
232 const char *p;
233 BlockDriver *drv;
235 flags = 0;
236 for(;;) {
237 c = getopt(argc, argv, "b:f:he6");
238 if (c == -1)
239 break;
240 switch(c) {
241 case 'h':
242 help();
243 break;
244 case 'b':
245 base_filename = optarg;
246 break;
247 case 'f':
248 fmt = optarg;
249 break;
250 case 'e':
251 flags |= BLOCK_FLAG_ENCRYPT;
252 break;
253 case '6':
254 flags |= BLOCK_FLAG_COMPAT6;
255 break;
258 if (optind >= argc)
259 help();
260 filename = argv[optind++];
261 size = 0;
262 if (base_filename) {
263 BlockDriverState *bs;
264 bs = bdrv_new_open(base_filename, NULL);
265 bdrv_get_geometry(bs, &size);
266 size *= 512;
267 bdrv_delete(bs);
268 } else {
269 if (optind >= argc)
270 help();
271 p = argv[optind];
272 size = strtoul(p, (char **)&p, 0);
273 if (*p == 'M') {
274 size *= 1024 * 1024;
275 } else if (*p == 'G') {
276 size *= 1024 * 1024 * 1024;
277 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
278 size *= 1024;
279 } else {
280 help();
283 drv = bdrv_find_format(fmt);
284 if (!drv)
285 error("Unknown file format '%s'", fmt);
286 printf("Formatting '%s', fmt=%s",
287 filename, fmt);
288 if (flags & BLOCK_FLAG_ENCRYPT)
289 printf(", encrypted");
290 if (flags & BLOCK_FLAG_COMPAT6)
291 printf(", compatibility level=6");
292 if (base_filename) {
293 printf(", backing_file=%s",
294 base_filename);
296 printf(", size=%" PRIu64 " kB\n", size / 1024);
297 ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
298 if (ret < 0) {
299 if (ret == -ENOTSUP) {
300 error("Formatting or formatting option not supported for file format '%s'", fmt);
301 } else {
302 error("Error while formatting");
305 return 0;
308 static int img_commit(int argc, char **argv)
310 int c, ret;
311 const char *filename, *fmt;
312 BlockDriver *drv;
313 BlockDriverState *bs;
315 fmt = NULL;
316 for(;;) {
317 c = getopt(argc, argv, "f:h");
318 if (c == -1)
319 break;
320 switch(c) {
321 case 'h':
322 help();
323 break;
324 case 'f':
325 fmt = optarg;
326 break;
329 if (optind >= argc)
330 help();
331 filename = argv[optind++];
333 bs = bdrv_new("");
334 if (!bs)
335 error("Not enough memory");
336 if (fmt) {
337 drv = bdrv_find_format(fmt);
338 if (!drv)
339 error("Unknown file format '%s'", fmt);
340 } else {
341 drv = NULL;
343 if (bdrv_open2(bs, filename, 0, drv) < 0) {
344 error("Could not open '%s'", filename);
346 ret = bdrv_commit(bs);
347 switch(ret) {
348 case 0:
349 printf("Image committed.\n");
350 break;
351 case -ENOENT:
352 error("No disk inserted");
353 break;
354 case -EACCES:
355 error("Image is read-only");
356 break;
357 case -ENOTSUP:
358 error("Image is already committed");
359 break;
360 default:
361 error("Error while committing image");
362 break;
365 bdrv_delete(bs);
366 return 0;
369 static int is_not_zero(const uint8_t *sector, int len)
371 int i;
372 len >>= 2;
373 for(i = 0;i < len; i++) {
374 if (((uint32_t *)sector)[i] != 0)
375 return 1;
377 return 0;
380 static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
382 int v, i;
384 if (n <= 0) {
385 *pnum = 0;
386 return 0;
388 v = is_not_zero(buf, 512);
389 for(i = 1; i < n; i++) {
390 buf += 512;
391 if (v != is_not_zero(buf, 512))
392 break;
394 *pnum = i;
395 return v;
398 #define IO_BUF_SIZE 65536
400 static int img_convert(int argc, char **argv)
402 int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
403 const char *fmt, *out_fmt, *out_filename;
404 BlockDriver *drv;
405 BlockDriverState **bs, *out_bs;
406 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
407 uint64_t bs_sectors;
408 uint8_t buf[IO_BUF_SIZE];
409 const uint8_t *buf1;
410 BlockDriverInfo bdi;
412 fmt = NULL;
413 out_fmt = "raw";
414 flags = 0;
415 for(;;) {
416 c = getopt(argc, argv, "f:O:hce6");
417 if (c == -1)
418 break;
419 switch(c) {
420 case 'h':
421 help();
422 break;
423 case 'f':
424 fmt = optarg;
425 break;
426 case 'O':
427 out_fmt = optarg;
428 break;
429 case 'c':
430 flags |= BLOCK_FLAG_COMPRESS;
431 break;
432 case 'e':
433 flags |= BLOCK_FLAG_ENCRYPT;
434 break;
435 case '6':
436 flags |= BLOCK_FLAG_COMPAT6;
437 break;
441 bs_n = argc - optind - 1;
442 if (bs_n < 1) help();
444 out_filename = argv[argc - 1];
446 bs = calloc(bs_n, sizeof(BlockDriverState *));
447 if (!bs)
448 error("Out of memory");
450 total_sectors = 0;
451 for (bs_i = 0; bs_i < bs_n; bs_i++) {
452 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
453 if (!bs[bs_i])
454 error("Could not open '%s'", argv[optind + bs_i]);
455 bdrv_get_geometry(bs[bs_i], &bs_sectors);
456 total_sectors += bs_sectors;
459 drv = bdrv_find_format(out_fmt);
460 if (!drv)
461 error("Unknown file format '%s'", out_fmt);
462 if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
463 error("Compression not supported for this file format");
464 if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
465 error("Encryption not supported for this file format");
466 if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
467 error("Alternative compatibility level not supported for this file format");
468 if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
469 error("Compression and encryption not supported at the same time");
471 ret = bdrv_create(drv, out_filename, total_sectors, NULL, flags);
472 if (ret < 0) {
473 if (ret == -ENOTSUP) {
474 error("Formatting not supported for file format '%s'", fmt);
475 } else {
476 error("Error while formatting '%s'", out_filename);
480 out_bs = bdrv_new_open(out_filename, out_fmt);
482 bs_i = 0;
483 bs_offset = 0;
484 bdrv_get_geometry(bs[0], &bs_sectors);
486 if (flags & BLOCK_FLAG_COMPRESS) {
487 if (bdrv_get_info(out_bs, &bdi) < 0)
488 error("could not get block driver info");
489 cluster_size = bdi.cluster_size;
490 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
491 error("invalid cluster size");
492 cluster_sectors = cluster_size >> 9;
493 sector_num = 0;
494 for(;;) {
495 int64_t bs_num;
496 int remainder;
497 uint8_t *buf2;
499 nb_sectors = total_sectors - sector_num;
500 if (nb_sectors <= 0)
501 break;
502 if (nb_sectors >= cluster_sectors)
503 n = cluster_sectors;
504 else
505 n = nb_sectors;
507 bs_num = sector_num - bs_offset;
508 assert (bs_num >= 0);
509 remainder = n;
510 buf2 = buf;
511 while (remainder > 0) {
512 int nlow;
513 while (bs_num == bs_sectors) {
514 bs_i++;
515 assert (bs_i < bs_n);
516 bs_offset += bs_sectors;
517 bdrv_get_geometry(bs[bs_i], &bs_sectors);
518 bs_num = 0;
519 /* printf("changing part: sector_num=%lld, "
520 "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
521 sector_num, bs_i, bs_offset, bs_sectors); */
523 assert (bs_num < bs_sectors);
525 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
527 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0)
528 error("error while reading");
530 buf2 += nlow * 512;
531 bs_num += nlow;
533 remainder -= nlow;
535 assert (remainder == 0);
537 if (n < cluster_sectors)
538 memset(buf + n * 512, 0, cluster_size - n * 512);
539 if (is_not_zero(buf, cluster_size)) {
540 if (bdrv_write_compressed(out_bs, sector_num, buf,
541 cluster_sectors) != 0)
542 error("error while compressing sector %" PRId64,
543 sector_num);
545 sector_num += n;
547 /* signal EOF to align */
548 bdrv_write_compressed(out_bs, 0, NULL, 0);
549 } else {
550 sector_num = 0;
551 for(;;) {
552 nb_sectors = total_sectors - sector_num;
553 if (nb_sectors <= 0)
554 break;
555 if (nb_sectors >= (IO_BUF_SIZE / 512))
556 n = (IO_BUF_SIZE / 512);
557 else
558 n = nb_sectors;
560 while (sector_num - bs_offset >= bs_sectors) {
561 bs_i ++;
562 assert (bs_i < bs_n);
563 bs_offset += bs_sectors;
564 bdrv_get_geometry(bs[bs_i], &bs_sectors);
565 /* printf("changing part: sector_num=%lld, bs_i=%d, "
566 "bs_offset=%lld, bs_sectors=%lld\n",
567 sector_num, bs_i, bs_offset, bs_sectors); */
570 if (n > bs_offset + bs_sectors - sector_num)
571 n = bs_offset + bs_sectors - sector_num;
573 if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
574 error("error while reading");
575 /* NOTE: at the same time we convert, we do not write zero
576 sectors to have a chance to compress the image. Ideally, we
577 should add a specific call to have the info to go faster */
578 buf1 = buf;
579 while (n > 0) {
580 if (is_allocated_sectors(buf1, n, &n1)) {
581 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
582 error("error while writing");
584 sector_num += n1;
585 n -= n1;
586 buf1 += n1 * 512;
590 bdrv_delete(out_bs);
591 for (bs_i = 0; bs_i < bs_n; bs_i++)
592 bdrv_delete(bs[bs_i]);
593 free(bs);
594 return 0;
597 #ifdef _WIN32
598 static int64_t get_allocated_file_size(const char *filename)
600 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
601 get_compressed_t get_compressed;
602 struct _stati64 st;
604 /* WinNT support GetCompressedFileSize to determine allocate size */
605 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
606 if (get_compressed) {
607 DWORD high, low;
608 low = get_compressed(filename, &high);
609 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
610 return (((int64_t) high) << 32) + low;
613 if (_stati64(filename, &st) < 0)
614 return -1;
615 return st.st_size;
617 #else
618 static int64_t get_allocated_file_size(const char *filename)
620 struct stat st;
621 if (stat(filename, &st) < 0)
622 return -1;
623 return (int64_t)st.st_blocks * 512;
625 #endif
627 static void dump_snapshots(BlockDriverState *bs)
629 QEMUSnapshotInfo *sn_tab, *sn;
630 int nb_sns, i;
631 char buf[256];
633 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
634 if (nb_sns <= 0)
635 return;
636 printf("Snapshot list:\n");
637 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
638 for(i = 0; i < nb_sns; i++) {
639 sn = &sn_tab[i];
640 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
642 qemu_free(sn_tab);
645 static int img_info(int argc, char **argv)
647 int c;
648 const char *filename, *fmt;
649 BlockDriver *drv;
650 BlockDriverState *bs;
651 char fmt_name[128], size_buf[128], dsize_buf[128];
652 uint64_t total_sectors;
653 int64_t allocated_size;
654 char backing_filename[1024];
655 char backing_filename2[1024];
656 BlockDriverInfo bdi;
658 fmt = NULL;
659 for(;;) {
660 c = getopt(argc, argv, "f:h");
661 if (c == -1)
662 break;
663 switch(c) {
664 case 'h':
665 help();
666 break;
667 case 'f':
668 fmt = optarg;
669 break;
672 if (optind >= argc)
673 help();
674 filename = argv[optind++];
676 bs = bdrv_new("");
677 if (!bs)
678 error("Not enough memory");
679 if (fmt) {
680 drv = bdrv_find_format(fmt);
681 if (!drv)
682 error("Unknown file format '%s'", fmt);
683 } else {
684 drv = NULL;
686 if (bdrv_open2(bs, filename, 0, drv) < 0) {
687 error("Could not open '%s'", filename);
689 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
690 bdrv_get_geometry(bs, &total_sectors);
691 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
692 allocated_size = get_allocated_file_size(filename);
693 if (allocated_size < 0)
694 sprintf(dsize_buf, "unavailable");
695 else
696 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
697 allocated_size);
698 printf("image: %s\n"
699 "file format: %s\n"
700 "virtual size: %s (%" PRId64 " bytes)\n"
701 "disk size: %s\n",
702 filename, fmt_name, size_buf,
703 (total_sectors * 512),
704 dsize_buf);
705 if (bdrv_is_encrypted(bs))
706 printf("encrypted: yes\n");
707 if (bdrv_get_info(bs, &bdi) >= 0) {
708 if (bdi.cluster_size != 0)
709 printf("cluster_size: %d\n", bdi.cluster_size);
711 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
712 if (backing_filename[0] != '\0') {
713 path_combine(backing_filename2, sizeof(backing_filename2),
714 filename, backing_filename);
715 printf("backing file: %s (actual path: %s)\n",
716 backing_filename,
717 backing_filename2);
719 dump_snapshots(bs);
720 bdrv_delete(bs);
721 return 0;
724 int main(int argc, char **argv)
726 const char *cmd;
728 bdrv_init();
729 if (argc < 2)
730 help();
731 cmd = argv[1];
732 optind++;
733 if (!strcmp(cmd, "create")) {
734 img_create(argc, argv);
735 } else if (!strcmp(cmd, "commit")) {
736 img_commit(argc, argv);
737 } else if (!strcmp(cmd, "convert")) {
738 img_convert(argc, argv);
739 } else if (!strcmp(cmd, "info")) {
740 img_info(argc, argv);
741 } else {
742 help();
744 return 0;