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