1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include "qemu-common.h"
25: #include "block_int.h"
26: #include <assert.h>
27:
28: #ifdef _WIN32
29: #define WIN32_LEAN_AND_MEAN
30: #include <windows.h>
31: #endif
32:
33: void *get_mmap_addr(unsigned long size)
34: {
35: return NULL;
36: }
37:
38: void qemu_free(void *ptr)
39: {
40: free(ptr);
41: }
42:
43: void *qemu_malloc(size_t size)
44: {
45: return malloc(size);
46: }
47:
48: void *qemu_mallocz(size_t size)
49: {
50: void *ptr;
51: ptr = qemu_malloc(size);
52: if (!ptr)
53: return NULL;
54: memset(ptr, 0, size);
55: return ptr;
56: }
57:
58: char *qemu_strdup(const char *str)
59: {
60: char *ptr;
61: ptr = qemu_malloc(strlen(str) + 1);
62: if (!ptr)
63: return NULL;
64: strcpy(ptr, str);
65: return ptr;
66: }
67:
68: static void __attribute__((noreturn)) error(const char *fmt, ...)
69: {
70: va_list ap;
71: va_start(ap, fmt);
72: fprintf(stderr, "qemu-img: ");
73: vfprintf(stderr, fmt, ap);
74: fprintf(stderr, "\n");
75: exit(1);
76: va_end(ap);
77: }
78:
79: static void format_print(void *opaque, const char *name)
80: {
81: printf(" %s", name);
82: }
83:
84: static void help(void)
85: {
86: printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
87: "usage: qemu-img command [command options]\n"
88: "QEMU disk image utility\n"
89: "\n"
90: "Command syntax:\n"
91: " create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
92: " commit [-f fmt] filename\n"
93: " convert [-c] [-e] [-6] [-f fmt] filename [filename2 [...]] [-O output_fmt] output_filename\n"
94: " info [-f fmt] filename\n"
95: "\n"
96: "Command parameters:\n"
97: " 'filename' is a disk image filename\n"
98: " 'base_image' is the read-only disk image which is used as base for a copy on\n"
99: " write image; the copy on write image only stores the modified data\n"
100: " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
101: " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
102: " and 'G' (gigabyte) are supported\n"
103: " 'output_filename' is the destination disk image filename\n"
104: " 'output_fmt' is the destination format\n"
105: " '-c' indicates that target image must be compressed (qcow format only)\n"
106: " '-e' indicates that the target image must be encrypted (qcow format only)\n"
107: " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
108: );
109: printf("\nSupported format:");
110: bdrv_iterate_format(format_print, NULL);
111: printf("\n");
112: exit(1);
113: }
114:
115: #if defined(WIN32)
116:
117: static int read_password(char *buf, int buf_size)
118: {
119: int c, i;
120: printf("Password: ");
121: fflush(stdout);
122: i = 0;
123: for(;;) {
124: c = getchar();
125: if (c == '\n')
126: break;
127: if (i < (buf_size - 1))
128: buf[i++] = c;
129: }
130: buf[i] = '\0';
131: return 0;
132: }
133:
134: #else
135:
136: #include <termios.h>
137:
138: static struct termios oldtty;
139:
140: static void term_exit(void)
141: {
142: tcsetattr (0, TCSANOW, &oldtty);
143: }
144:
145: static void term_init(void)
146: {
147: struct termios tty;
148:
149: tcgetattr (0, &tty);
150: oldtty = tty;
151:
152: tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
153: |INLCR|IGNCR|ICRNL|IXON);
154: tty.c_oflag |= OPOST;
155: tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
156: tty.c_cflag &= ~(CSIZE|PARENB);
157: tty.c_cflag |= CS8;
158: tty.c_cc[VMIN] = 1;
159: tty.c_cc[VTIME] = 0;
160:
161: tcsetattr (0, TCSANOW, &tty);
162:
163: atexit(term_exit);
164: }
165:
166: static int read_password(char *buf, int buf_size)
167: {
168: uint8_t ch;
169: int i, ret;
170:
171: printf("password: ");
172: fflush(stdout);
173: term_init();
174: i = 0;
175: for(;;) {
176: ret = read(0, &ch, 1);
177: if (ret == -1) {
178: if (errno == EAGAIN || errno == EINTR) {
179: continue;
180: } else {
181: ret = -1;
182: break;
183: }
184: } else if (ret == 0) {
185: ret = -1;
186: break;
187: } else {
188: if (ch == '\r') {
189: ret = 0;
190: break;
191: }
192: if (i < (buf_size - 1))
193: buf[i++] = ch;
194: }
195: }
196: term_exit();
197: buf[i] = '\0';
198: printf("\n");
199: return ret;
200: }
201: #endif
202:
203: static BlockDriverState *bdrv_new_open(const char *filename,
204: const char *fmt)
205: {
206: BlockDriverState *bs;
207: BlockDriver *drv;
208: char password[256];
209:
210: bs = bdrv_new("");
211: if (!bs)
212: error("Not enough memory");
213: if (fmt) {
214: drv = bdrv_find_format(fmt);
215: if (!drv)
216: error("Unknown file format '%s'", fmt);
217: } else {
218: drv = NULL;
219: }
220: if (bdrv_open2(bs, filename, 0, drv) < 0) {
221: error("Could not open '%s'", filename);
222: }
223: if (bdrv_is_encrypted(bs)) {
224: printf("Disk image '%s' is encrypted.\n", filename);
225: if (read_password(password, sizeof(password)) < 0)
226: error("No password given");
227: if (bdrv_set_key(bs, password) < 0)
228: error("invalid password");
229: }
230: return bs;
231: }
232:
233: static int img_create(int argc, char **argv)
234: {
235: int c, ret, flags;
236: const char *fmt = "raw";
237: const char *filename;
238: const char *base_filename = NULL;
239: uint64_t size;
240: const char *p;
241: BlockDriver *drv;
242:
243: flags = 0;
244: for(;;) {
245: c = getopt(argc, argv, "b:f:he6");
246: if (c == -1)
247: break;
248: switch(c) {
249: case 'h':
250: help();
251: break;
252: case 'b':
253: base_filename = optarg;
254: break;
255: case 'f':
256: fmt = optarg;
257: break;
258: case 'e':
259: flags |= BLOCK_FLAG_ENCRYPT;
260: break;
261: case '6':
262: flags |= BLOCK_FLAG_COMPAT6;
263: break;
264: }
265: }
266: if (optind >= argc)
267: help();
268: filename = argv[optind++];
269: size = 0;
270: if (base_filename) {
271: BlockDriverState *bs;
272: bs = bdrv_new_open(base_filename, NULL);
273: bdrv_get_geometry(bs, &size);
274: size *= 512;
275: bdrv_delete(bs);
276: } else {
277: if (optind >= argc)
278: help();
279: p = argv[optind];
280: size = strtoul(p, (char **)&p, 0);
281: if (*p == 'M') {
282: size *= 1024 * 1024;
283: } else if (*p == 'G') {
284: size *= 1024 * 1024 * 1024;
285: } else if (*p == 'k' || *p == 'K' || *p == '\0') {
286: size *= 1024;
287: } else {
288: help();
289: }
290: }
291: drv = bdrv_find_format(fmt);
292: if (!drv)
293: error("Unknown file format '%s'", fmt);
294: printf("Formatting '%s', fmt=%s",
295: filename, fmt);
296: if (flags & BLOCK_FLAG_ENCRYPT)
297: printf(", encrypted");
298: if (flags & BLOCK_FLAG_COMPAT6)
299: printf(", compatibility level=6");
300: if (base_filename) {
301: printf(", backing_file=%s",
302: base_filename);
303: }
304: printf(", size=%" PRIu64 " kB\n", size / 1024);
305: ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
306: if (ret < 0) {
307: if (ret == -ENOTSUP) {
308: error("Formatting or formatting option not supported for file format '%s'", fmt);
309: } else {
310: error("Error while formatting");
311: }
312: }
313: return 0;
314: }
315:
316: static int img_commit(int argc, char **argv)
317: {
318: int c, ret;
319: const char *filename, *fmt;
320: BlockDriver *drv;
321: BlockDriverState *bs;
322:
323: fmt = NULL;
324: for(;;) {
325: c = getopt(argc, argv, "f:h");
326: if (c == -1)
327: break;
328: switch(c) {
329: case 'h':
330: help();
331: break;
332: case 'f':
333: fmt = optarg;
334: break;
335: }
336: }
337: if (optind >= argc)
338: help();
339: filename = argv[optind++];
340:
341: bs = bdrv_new("");
342: if (!bs)
343: error("Not enough memory");
344: if (fmt) {
345: drv = bdrv_find_format(fmt);
346: if (!drv)
347: error("Unknown file format '%s'", fmt);
348: } else {
349: drv = NULL;
350: }
351: if (bdrv_open2(bs, filename, 0, drv) < 0) {
352: error("Could not open '%s'", filename);
353: }
354: ret = bdrv_commit(bs);
355: switch(ret) {
356: case 0:
357: printf("Image committed.\n");
358: break;
359: case -ENOENT:
360: error("No disk inserted");
361: break;
362: case -EACCES:
363: error("Image is read-only");
364: break;
365: case -ENOTSUP:
366: error("Image is already committed");
367: break;
368: default:
369: error("Error while committing image");
370: break;
371: }
372:
373: bdrv_delete(bs);
374: return 0;
375: }
376:
377: static int is_not_zero(const uint8_t *sector, int len)
378: {
379: int i;
380: len >>= 2;
381: for(i = 0;i < len; i++) {
382: if (((uint32_t *)sector)[i] != 0)
383: return 1;
384: }
385: return 0;
386: }
387:
388: static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
389: {
390: int v, i;
391:
392: if (n <= 0) {
393: *pnum = 0;
394: return 0;
395: }
396: v = is_not_zero(buf, 512);
397: for(i = 1; i < n; i++) {
398: buf += 512;
399: if (v != is_not_zero(buf, 512))
400: break;
401: }
402: *pnum = i;
403: return v;
404: }
405:
406: #define IO_BUF_SIZE 65536
407:
408: static int img_convert(int argc, char **argv)
409: {
410: int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
411: const char *fmt, *out_fmt, *out_filename;
412: BlockDriver *drv;
413: BlockDriverState **bs, *out_bs;
414: int64_t total_sectors, nb_sectors, sector_num, bs_offset;
415: uint64_t bs_sectors;
416: uint8_t buf[IO_BUF_SIZE];
417: const uint8_t *buf1;
418: BlockDriverInfo bdi;
419:
420: fmt = NULL;
421: out_fmt = "raw";
422: flags = 0;
423: for(;;) {
424: c = getopt(argc, argv, "f:O:hce6");
425: if (c == -1)
426: break;
427: switch(c) {
428: case 'h':
429: help();
430: break;
431: case 'f':
432: fmt = optarg;
433: break;
434: case 'O':
435: out_fmt = optarg;
436: break;
437: case 'c':
438: flags |= BLOCK_FLAG_COMPRESS;
439: break;
440: case 'e':
441: flags |= BLOCK_FLAG_ENCRYPT;
442: break;
443: case '6':
444: flags |= BLOCK_FLAG_COMPAT6;
445: break;
446: }
447: }
448:
449: bs_n = argc - optind - 1;
450: if (bs_n < 1) help();
451:
452: out_filename = argv[argc - 1];
453:
454: bs = calloc(bs_n, sizeof(BlockDriverState *));
455: if (!bs)
456: error("Out of memory");
457:
458: total_sectors = 0;
459: for (bs_i = 0; bs_i < bs_n; bs_i++) {
460: bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
461: if (!bs[bs_i])
462: error("Could not open '%s'", argv[optind + bs_i]);
463: bdrv_get_geometry(bs[bs_i], &bs_sectors);
464: total_sectors += bs_sectors;
465: }
466:
467: drv = bdrv_find_format(out_fmt);
468: if (!drv)
469: error("Unknown file format '%s'", out_fmt);
470: if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
471: error("Compression not supported for this file format");
472: if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
473: error("Encryption not supported for this file format");
474: if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
475: error("Alternative compatibility level not supported for this file format");
476: if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
477: error("Compression and encryption not supported at the same time");
478:
479: ret = bdrv_create(drv, out_filename, total_sectors, NULL, flags);
480: if (ret < 0) {
481: if (ret == -ENOTSUP) {
482: error("Formatting not supported for file format '%s'", fmt);
483: } else {
484: error("Error while formatting '%s'", out_filename);
485: }
486: }
487:
488: out_bs = bdrv_new_open(out_filename, out_fmt);
489:
490: bs_i = 0;
491: bs_offset = 0;
492: bdrv_get_geometry(bs[0], &bs_sectors);
493:
494: if (flags & BLOCK_FLAG_COMPRESS) {
495: if (bdrv_get_info(out_bs, &bdi) < 0)
496: error("could not get block driver info");
497: cluster_size = bdi.cluster_size;
498: if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
499: error("invalid cluster size");
500: cluster_sectors = cluster_size >> 9;
501: sector_num = 0;
502: for(;;) {
503: int64_t bs_num;
504: int remainder;
505: uint8_t *buf2;
506:
507: nb_sectors = total_sectors - sector_num;
508: if (nb_sectors <= 0)
509: break;
510: if (nb_sectors >= cluster_sectors)
511: n = cluster_sectors;
512: else
513: n = nb_sectors;
514:
515: bs_num = sector_num - bs_offset;
516: assert (bs_num >= 0);
517: remainder = n;
518: buf2 = buf;
519: while (remainder > 0) {
520: int nlow;
521: while (bs_num == bs_sectors) {
522: bs_i++;
523: assert (bs_i < bs_n);
524: bs_offset += bs_sectors;
525: bdrv_get_geometry(bs[bs_i], &bs_sectors);
526: bs_num = 0;
527:
528:
529:
530: }
531: assert (bs_num < bs_sectors);
532:
533: nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
534:
535: if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0)
536: error("error while reading");
537:
538: buf2 += nlow * 512;
539: bs_num += nlow;
540:
541: remainder -= nlow;
542: }
543: assert (remainder == 0);
544:
545: if (n < cluster_sectors)
546: memset(buf + n * 512, 0, cluster_size - n * 512);
547: if (is_not_zero(buf, cluster_size)) {
548: if (bdrv_write_compressed(out_bs, sector_num, buf,
549: cluster_sectors) != 0)
550: error("error while compressing sector %" PRId64,
551: sector_num);
552: }
553: sector_num += n;
554: }
555:
556: bdrv_write_compressed(out_bs, 0, NULL, 0);
557: } else {
558: sector_num = 0;
559: for(;;) {
560: nb_sectors = total_sectors - sector_num;
561: if (nb_sectors <= 0)
562: break;
563: if (nb_sectors >= (IO_BUF_SIZE / 512))
564: n = (IO_BUF_SIZE / 512);
565: else
566: n = nb_sectors;
567:
568: while (sector_num - bs_offset >= bs_sectors) {
569: bs_i ++;
570: assert (bs_i < bs_n);
571: bs_offset += bs_sectors;
572: bdrv_get_geometry(bs[bs_i], &bs_sectors);
573:
574:
575:
576: }
577:
578: if (n > bs_offset + bs_sectors - sector_num)
579: n = bs_offset + bs_sectors - sector_num;
580:
581: if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
582: error("error while reading");
583:
584:
585:
586: buf1 = buf;
587: while (n > 0) {
588: if (is_allocated_sectors(buf1, n, &n1)) {
589: if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
590: error("error while writing");
591: }
592: sector_num += n1;
593: n -= n1;
594: buf1 += n1 * 512;
595: }
596: }
597: }
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;
603: }
604:
605: #ifdef _WIN32
606: static int64_t get_allocated_file_size(const char *filename)
607: {
608: typedef DWORD