ia64/xen-unstable

view tools/ioemu/qemu-img.c @ 15841:c5f735271e22

[IA64] Foreign p2m: Fix vti domain builder.

It should set arch_domain::convmem_end.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Thu Sep 06 13:48:43 2007 -0600 (2007-09-06)
parents 00618037d37d
children 633099ff88a8
line source
1 /*
2 * QEMU disk image utility
3 *
4 * Copyright (c) 2003-2007 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 "vl.h"
26 #ifdef _WIN32
27 #include <windows.h>
28 #endif
30 void *get_mmap_addr(unsigned long size)
31 {
32 return NULL;
33 }
35 void qemu_free(void *ptr)
36 {
37 free(ptr);
38 }
40 void *qemu_malloc(size_t size)
41 {
42 return malloc(size);
43 }
45 void *qemu_mallocz(size_t size)
46 {
47 void *ptr;
48 ptr = qemu_malloc(size);
49 if (!ptr)
50 return NULL;
51 memset(ptr, 0, size);
52 return ptr;
53 }
55 char *qemu_strdup(const char *str)
56 {
57 char *ptr;
58 ptr = qemu_malloc(strlen(str) + 1);
59 if (!ptr)
60 return NULL;
61 strcpy(ptr, str);
62 return ptr;
63 }
65 void term_printf(const char *fmt, ...)
66 {
67 va_list ap;
68 va_start(ap, fmt);
69 vprintf(fmt, ap);
70 va_end(ap);
71 }
73 void term_print_filename(const char *filename)
74 {
75 term_printf(filename);
76 }
78 void __attribute__((noreturn)) error(const char *fmt, ...)
79 {
80 va_list ap;
81 va_start(ap, fmt);
82 fprintf(stderr, "qemu-img: ");
83 vfprintf(stderr, fmt, ap);
84 fprintf(stderr, "\n");
85 exit(1);
86 va_end(ap);
87 }
89 static void format_print(void *opaque, const char *name)
90 {
91 printf(" %s", name);
92 }
94 void help(void)
95 {
96 printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2007 Fabrice Bellard\n"
97 "usage: qemu-img command [command options]\n"
98 "QEMU disk image utility\n"
99 "\n"
100 "Command syntax:\n"
101 " create [-e] [-b base_image] [-f fmt] filename [size]\n"
102 " commit [-f fmt] filename\n"
103 " convert [-c] [-e] [-f fmt] filename [-O output_fmt] output_filename\n"
104 " info [-f fmt] filename\n"
105 "\n"
106 "Command parameters:\n"
107 " 'filename' is a disk image filename\n"
108 " 'base_image' is the read-only disk image which is used as base for a copy on\n"
109 " write image; the copy on write image only stores the modified data\n"
110 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
111 " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
112 " and 'G' (gigabyte) are supported\n"
113 " 'output_filename' is the destination disk image filename\n"
114 " 'output_fmt' is the destination format\n"
115 " '-c' indicates that target image must be compressed (qcow format only)\n"
116 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
117 );
118 printf("\nSupported format:");
119 bdrv_iterate_format(format_print, NULL);
120 printf("\n");
121 exit(1);
122 }
124 #if defined(WIN32)
125 /* XXX: put correct support for win32 */
126 static int read_password(char *buf, int buf_size)
127 {
128 int c, i;
129 printf("Password: ");
130 fflush(stdout);
131 i = 0;
132 for(;;) {
133 c = getchar();
134 if (c == '\n')
135 break;
136 if (i < (buf_size - 1))
137 buf[i++] = c;
138 }
139 buf[i] = '\0';
140 return 0;
141 }
143 #else
145 #include <termios.h>
147 static struct termios oldtty;
149 static void term_exit(void)
150 {
151 tcsetattr (0, TCSANOW, &oldtty);
152 }
154 static void term_init(void)
155 {
156 struct termios tty;
158 tcgetattr (0, &tty);
159 oldtty = tty;
161 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
162 |INLCR|IGNCR|ICRNL|IXON);
163 tty.c_oflag |= OPOST;
164 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
165 tty.c_cflag &= ~(CSIZE|PARENB);
166 tty.c_cflag |= CS8;
167 tty.c_cc[VMIN] = 1;
168 tty.c_cc[VTIME] = 0;
170 tcsetattr (0, TCSANOW, &tty);
172 atexit(term_exit);
173 }
175 int read_password(char *buf, int buf_size)
176 {
177 uint8_t ch;
178 int i, ret;
180 printf("password: ");
181 fflush(stdout);
182 term_init();
183 i = 0;
184 for(;;) {
185 ret = read(0, &ch, 1);
186 if (ret == -1) {
187 if (errno == EAGAIN || errno == EINTR) {
188 continue;
189 } else {
190 ret = -1;
191 break;
192 }
193 } else if (ret == 0) {
194 ret = -1;
195 break;
196 } else {
197 if (ch == '\r') {
198 ret = 0;
199 break;
200 }
201 if (i < (buf_size - 1))
202 buf[i++] = ch;
203 }
204 }
205 term_exit();
206 buf[i] = '\0';
207 printf("\n");
208 return ret;
209 }
210 #endif
212 static BlockDriverState *bdrv_new_open(const char *filename,
213 const char *fmt)
214 {
215 BlockDriverState *bs;
216 BlockDriver *drv;
217 char password[256];
219 bs = bdrv_new("");
220 if (!bs)
221 error("Not enough memory");
222 if (fmt) {
223 drv = bdrv_find_format(fmt);
224 if (!drv)
225 error("Unknown file format '%s'", fmt);
226 } else {
227 drv = NULL;
228 }
229 if (bdrv_open2(bs, filename, 0, drv) < 0) {
230 error("Could not open '%s'", filename);
231 }
232 if (bdrv_is_encrypted(bs)) {
233 printf("Disk image '%s' is encrypted.\n", filename);
234 if (read_password(password, sizeof(password)) < 0)
235 error("No password given");
236 if (bdrv_set_key(bs, password) < 0)
237 error("invalid password");
238 }
239 return bs;
240 }
242 static int img_create(int argc, char **argv)
243 {
244 int c, ret, encrypted;
245 const char *fmt = "raw";
246 const char *filename;
247 const char *base_filename = NULL;
248 int64_t size;
249 const char *p;
250 BlockDriver *drv;
252 encrypted = 0;
253 for(;;) {
254 c = getopt(argc, argv, "b:f:he");
255 if (c == -1)
256 break;
257 switch(c) {
258 case 'h':
259 help();
260 break;
261 case 'b':
262 base_filename = optarg;
263 break;
264 case 'f':
265 fmt = optarg;
266 break;
267 case 'e':
268 encrypted = 1;
269 break;
270 }
271 }
272 if (optind >= argc)
273 help();
274 filename = argv[optind++];
275 size = 0;
276 if (base_filename) {
277 BlockDriverState *bs;
278 bs = bdrv_new_open(base_filename, NULL);
279 bdrv_get_geometry(bs, &size);
280 size *= 512;
281 bdrv_delete(bs);
282 } else {
283 if (optind >= argc)
284 help();
285 p = argv[optind];
286 size = strtoul(p, (char **)&p, 0);
287 if (*p == 'M') {
288 size *= 1024 * 1024;
289 } else if (*p == 'G') {
290 size *= 1024 * 1024 * 1024;
291 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
292 size *= 1024;
293 } else {
294 help();
295 }
296 }
297 drv = bdrv_find_format(fmt);
298 if (!drv)
299 error("Unknown file format '%s'", fmt);
300 printf("Formating '%s', fmt=%s",
301 filename, fmt);
302 if (encrypted)
303 printf(", encrypted");
304 if (base_filename) {
305 printf(", backing_file=%s",
306 base_filename);
307 }
308 printf(", size=%" PRId64 " kB\n", (int64_t) (size / 1024));
309 ret = bdrv_create(drv, filename, size / 512, base_filename, encrypted);
310 if (ret < 0) {
311 if (ret == -ENOTSUP) {
312 error("Formatting or formatting option not supported for file format '%s'", fmt);
313 } else {
314 error("Error while formatting");
315 }
316 }
317 return 0;
318 }
320 static int img_commit(int argc, char **argv)
321 {
322 int c, ret;
323 const char *filename, *fmt;
324 BlockDriver *drv;
325 BlockDriverState *bs;
327 fmt = NULL;
328 for(;;) {
329 c = getopt(argc, argv, "f:h");
330 if (c == -1)
331 break;
332 switch(c) {
333 case 'h':
334 help();
335 break;
336 case 'f':
337 fmt = optarg;
338 break;
339 }
340 }
341 if (optind >= argc)
342 help();
343 filename = argv[optind++];
345 bs = bdrv_new("");
346 if (!bs)
347 error("Not enough memory");
348 if (fmt) {
349 drv = bdrv_find_format(fmt);
350 if (!drv)
351 error("Unknown file format '%s'", fmt);
352 } else {
353 drv = NULL;
354 }
355 if (bdrv_open2(bs, filename, 0, drv) < 0) {
356 error("Could not open '%s'", filename);
357 }
358 ret = bdrv_commit(bs);
359 switch(ret) {
360 case 0:
361 printf("Image committed.\n");
362 break;
363 case -ENOENT:
364 error("No disk inserted");
365 break;
366 case -EACCES:
367 error("Image is read-only");
368 break;
369 case -ENOTSUP:
370 error("Image is already committed");
371 break;
372 default:
373 error("Error while committing image");
374 break;
375 }
377 bdrv_delete(bs);
378 return 0;
379 }
381 static int is_not_zero(const uint8_t *sector, int len)
382 {
383 int i;
384 len >>= 2;
385 for(i = 0;i < len; i++) {
386 if (((uint32_t *)sector)[i] != 0)
387 return 1;
388 }
389 return 0;
390 }
392 static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
393 {
394 int v, i;
396 if (n <= 0) {
397 *pnum = 0;
398 return 0;
399 }
400 v = is_not_zero(buf, 512);
401 for(i = 1; i < n; i++) {
402 buf += 512;
403 if (v != is_not_zero(buf, 512))
404 break;
405 }
406 *pnum = i;
407 return v;
408 }
410 #define IO_BUF_SIZE 65536
412 static int img_convert(int argc, char **argv)
413 {
414 int c, ret, n, n1, compress, cluster_size, cluster_sectors, encrypt;
415 const char *filename, *fmt, *out_fmt, *out_filename;
416 BlockDriver *drv;
417 BlockDriverState *bs, *out_bs;
418 int64_t total_sectors, nb_sectors, sector_num;
419 uint8_t buf[IO_BUF_SIZE];
420 const uint8_t *buf1;
421 BlockDriverInfo bdi;
423 fmt = NULL;
424 out_fmt = "raw";
425 compress = 0;
426 encrypt = 0;
427 for(;;) {
428 c = getopt(argc, argv, "f:O:hce");
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 'c':
442 compress = 1;
443 break;
444 case 'e':
445 encrypt = 1;
446 break;
447 }
448 }
449 if (optind >= argc)
450 help();
451 filename = argv[optind++];
452 if (optind >= argc)
453 help();
454 out_filename = argv[optind++];
456 bs = bdrv_new_open(filename, fmt);
458 drv = bdrv_find_format(out_fmt);
459 if (!drv)
460 error("Unknown file format '%s'", fmt);
461 if (compress && drv != &bdrv_qcow && drv != &bdrv_qcow2)
462 error("Compression not supported for this file format");
463 if (encrypt && drv != &bdrv_qcow && drv != &bdrv_qcow2)
464 error("Encryption not supported for this file format");
465 if (compress && encrypt)
466 error("Compression and encryption not supported at the same time");
467 bdrv_get_geometry(bs, &total_sectors);
468 ret = bdrv_create(drv, out_filename, total_sectors, NULL, encrypt);
469 if (ret < 0) {
470 if (ret == -ENOTSUP) {
471 error("Formatting not supported for file format '%s'", fmt);
472 } else {
473 error("Error while formatting '%s'", out_filename);
474 }
475 }
477 out_bs = bdrv_new_open(out_filename, out_fmt);
479 if (compress) {
480 if (bdrv_get_info(out_bs, &bdi) < 0)
481 error("could not get block driver info");
482 cluster_size = bdi.cluster_size;
483 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
484 error("invalid cluster size");
485 cluster_sectors = cluster_size >> 9;
486 sector_num = 0;
487 for(;;) {
488 nb_sectors = total_sectors - sector_num;
489 if (nb_sectors <= 0)
490 break;
491 if (nb_sectors >= cluster_sectors)
492 n = cluster_sectors;
493 else
494 n = nb_sectors;
495 if (bdrv_read(bs, sector_num, buf, n) < 0)
496 error("error while reading");
497 if (n < cluster_sectors)
498 memset(buf + n * 512, 0, cluster_size - n * 512);
499 if (is_not_zero(buf, cluster_size)) {
500 if (bdrv_write_compressed(out_bs, sector_num, buf,
501 cluster_sectors) != 0)
502 error("error while compressing sector %" PRId64,
503 sector_num);
504 }
505 sector_num += n;
506 }
507 /* signal EOF to align */
508 bdrv_write_compressed(out_bs, 0, NULL, 0);
509 } else {
510 sector_num = 0;
511 for(;;) {
512 nb_sectors = total_sectors - sector_num;
513 if (nb_sectors <= 0)
514 break;
515 if (nb_sectors >= (IO_BUF_SIZE / 512))
516 n = (IO_BUF_SIZE / 512);
517 else
518 n = nb_sectors;
519 if (bdrv_read(bs, sector_num, buf, n) < 0)
520 error("error while reading");
521 /* NOTE: at the same time we convert, we do not write zero
522 sectors to have a chance to compress the image. Ideally, we
523 should add a specific call to have the info to go faster */
524 buf1 = buf;
525 while (n > 0) {
526 if (is_allocated_sectors(buf1, n, &n1)) {
527 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
528 error("error while writing");
529 }
530 sector_num += n1;
531 n -= n1;
532 buf1 += n1 * 512;
533 }
534 }
535 }
536 bdrv_delete(out_bs);
537 bdrv_delete(bs);
538 return 0;
539 }
541 #ifdef _WIN32
542 static int64_t get_allocated_file_size(const char *filename)
543 {
544 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
545 get_compressed_t get_compressed;
546 struct _stati64 st;
548 /* WinNT support GetCompressedFileSize to determine allocate size */
549 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
550 if (get_compressed) {
551 DWORD high, low;
552 low = get_compressed(filename, &high);
553 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
554 return (((int64_t) high) << 32) + low;
555 }
557 if (_stati64(filename, &st) < 0)
558 return -1;
559 return st.st_size;
560 }
561 #else
562 static int64_t get_allocated_file_size(const char *filename)
563 {
564 struct stat st;
565 if (stat(filename, &st) < 0)
566 return -1;
567 return (int64_t)st.st_blocks * 512;
568 }
569 #endif
571 static void dump_snapshots(BlockDriverState *bs)
572 {
573 QEMUSnapshotInfo *sn_tab, *sn;
574 int nb_sns, i;
575 char buf[256];
577 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
578 if (nb_sns <= 0)
579 return;
580 printf("Snapshot list:\n");
581 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
582 for(i = 0; i < nb_sns; i++) {
583 sn = &sn_tab[i];
584 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
585 }
586 qemu_free(sn_tab);
587 }
589 static int img_info(int argc, char **argv)
590 {
591 int c;
592 const char *filename, *fmt;
593 BlockDriver *drv;
594 BlockDriverState *bs;
595 char fmt_name[128], size_buf[128], dsize_buf[128];
596 int64_t total_sectors, allocated_size;
597 char backing_filename[1024];
598 char backing_filename2[1024];
599 BlockDriverInfo bdi;
601 fmt = NULL;
602 for(;;) {
603 c = getopt(argc, argv, "f:h");
604 if (c == -1)
605 break;
606 switch(c) {
607 case 'h':
608 help();
609 break;
610 case 'f':
611 fmt = optarg;
612 break;
613 }
614 }
615 if (optind >= argc)
616 help();
617 filename = argv[optind++];
619 bs = bdrv_new("");
620 if (!bs)
621 error("Not enough memory");
622 if (fmt) {
623 drv = bdrv_find_format(fmt);
624 if (!drv)
625 error("Unknown file format '%s'", fmt);
626 } else {
627 drv = NULL;
628 }
629 if (bdrv_open2(bs, filename, 0, drv) < 0) {
630 error("Could not open '%s'", filename);
631 }
632 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
633 bdrv_get_geometry(bs, &total_sectors);
634 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
635 allocated_size = get_allocated_file_size(filename);
636 if (allocated_size < 0)
637 sprintf(dsize_buf, "unavailable");
638 else
639 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
640 allocated_size);
641 printf("image: %s\n"
642 "file format: %s\n"
643 "virtual size: %s (%" PRId64 " bytes)\n"
644 "disk size: %s\n",
645 filename, fmt_name, size_buf,
646 (total_sectors * 512),
647 dsize_buf);
648 if (bdrv_is_encrypted(bs))
649 printf("encrypted: yes\n");
650 if (bdrv_get_info(bs, &bdi) >= 0) {
651 if (bdi.cluster_size != 0)
652 printf("cluster_size: %d\n", bdi.cluster_size);
653 }
654 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
655 if (backing_filename[0] != '\0') {
656 path_combine(backing_filename2, sizeof(backing_filename2),
657 filename, backing_filename);
658 printf("backing file: %s (actual path: %s)\n",
659 backing_filename,
660 backing_filename2);
661 }
662 dump_snapshots(bs);
663 bdrv_delete(bs);
664 return 0;
665 }
667 int main(int argc, char **argv)
668 {
669 const char *cmd;
671 bdrv_init();
672 if (argc < 2)
673 help();
674 cmd = argv[1];
675 optind++;
676 if (!strcmp(cmd, "create")) {
677 img_create(argc, argv);
678 } else if (!strcmp(cmd, "commit")) {
679 img_commit(argc, argv);
680 } else if (!strcmp(cmd, "convert")) {
681 img_convert(argc, argv);
682 } else if (!strcmp(cmd, "info")) {
683 img_info(argc, argv);
684 } else {
685 help();
686 }
687 return 0;
688 }