Annotation of qemu/qemu-img.c, revision 1.1.1.13
1.1 root 1: /*
1.1.1.3 root 2: * QEMU disk image utility
1.1.1.4 root 3: *
4: * Copyright (c) 2003-2008 Fabrice Bellard
5: *
1.1 root 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: */
1.1.1.4 root 24: #include "qemu-common.h"
1.1.1.8 root 25: #include "qemu-option.h"
1.1.1.12 root 26: #include "qemu-error.h"
1.1.1.5 root 27: #include "osdep.h"
1.1.1.12 root 28: #include "sysemu.h"
1.1.1.4 root 29: #include "block_int.h"
1.1.1.8 root 30: #include <stdio.h>
1.1 root 31:
1.1.1.2 root 32: #ifdef _WIN32
33: #include <windows.h>
34: #endif
35:
1.1.1.8 root 36: typedef struct img_cmd_t {
37: const char *name;
38: int (*handler)(int argc, char **argv);
39: } img_cmd_t;
40:
1.1.1.5 root 41: /* Default to cache=writeback as data integrity is not important for qemu-tcg. */
1.1.1.11 root 42: #define BDRV_O_FLAGS BDRV_O_CACHE_WB
1.1.1.13! root 43: #define BDRV_DEFAULT_CACHE "writeback"
1.1 root 44:
45: static void format_print(void *opaque, const char *name)
46: {
47: printf(" %s", name);
48: }
49:
1.1.1.5 root 50: /* Please keep in synch with qemu-img.texi */
1.1.1.4 root 51: static void help(void)
1.1 root 52: {
1.1.1.11 root 53: const char *help_msg =
54: "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
1.1 root 55: "usage: qemu-img command [command options]\n"
56: "QEMU disk image utility\n"
57: "\n"
58: "Command syntax:\n"
1.1.1.8 root 59: #define DEF(option, callback, arg_string) \
60: " " arg_string "\n"
61: #include "qemu-img-cmds.h"
62: #undef DEF
63: #undef GEN_DOCS
1.1 root 64: "\n"
65: "Command parameters:\n"
66: " 'filename' is a disk image filename\n"
67: " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
1.1.1.13! root 68: " 'cache' is the cache mode used to write the output disk image, the valid\n"
! 69: " options are: 'none', 'writeback' (default), 'writethrough' and 'unsafe'\n"
1.1.1.9 root 70: " 'size' is the disk image size in bytes. Optional suffixes\n"
71: " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
72: " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
1.1 root 73: " 'output_filename' is the destination disk image filename\n"
74: " 'output_fmt' is the destination format\n"
1.1.1.8 root 75: " 'options' is a comma separated list of format specific options in a\n"
76: " name=value format. Use -o ? for an overview of the options supported by the\n"
77: " used format\n"
1.1 root 78: " '-c' indicates that target image must be compressed (qcow format only)\n"
1.1.1.11 root 79: " '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
80: " match exactly. The image doesn't need a working backing file before\n"
81: " rebasing in this case (useful for renaming the backing file)\n"
1.1.1.5 root 82: " '-h' with or without a command shows this help and lists the supported formats\n"
1.1.1.13! root 83: " '-p' show progress of command (only certain commands)\n"
1.1.1.5 root 84: "\n"
85: "Parameters to snapshot subcommand:\n"
86: " 'snapshot' is the name of the snapshot to create, apply or delete\n"
87: " '-a' applies a snapshot (revert disk to saved state)\n"
88: " '-c' creates a snapshot\n"
89: " '-d' deletes a snapshot\n"
1.1.1.11 root 90: " '-l' lists all snapshots in the given image\n";
91:
92: printf("%s\nSupported formats:", help_msg);
1.1 root 93: bdrv_iterate_format(format_print, NULL);
94: printf("\n");
95: exit(1);
96: }
97:
98: #if defined(WIN32)
99: /* XXX: put correct support for win32 */
100: static int read_password(char *buf, int buf_size)
101: {
102: int c, i;
103: printf("Password: ");
104: fflush(stdout);
105: i = 0;
106: for(;;) {
107: c = getchar();
108: if (c == '\n')
109: break;
110: if (i < (buf_size - 1))
111: buf[i++] = c;
112: }
113: buf[i] = '\0';
114: return 0;
115: }
116:
117: #else
118:
119: #include <termios.h>
120:
121: static struct termios oldtty;
122:
123: static void term_exit(void)
124: {
125: tcsetattr (0, TCSANOW, &oldtty);
126: }
127:
128: static void term_init(void)
129: {
130: struct termios tty;
131:
132: tcgetattr (0, &tty);
133: oldtty = tty;
134:
135: tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
136: |INLCR|IGNCR|ICRNL|IXON);
137: tty.c_oflag |= OPOST;
138: tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
139: tty.c_cflag &= ~(CSIZE|PARENB);
140: tty.c_cflag |= CS8;
141: tty.c_cc[VMIN] = 1;
142: tty.c_cc[VTIME] = 0;
1.1.1.4 root 143:
1.1 root 144: tcsetattr (0, TCSANOW, &tty);
145:
146: atexit(term_exit);
147: }
148:
1.1.1.4 root 149: static int read_password(char *buf, int buf_size)
1.1 root 150: {
151: uint8_t ch;
152: int i, ret;
153:
154: printf("password: ");
155: fflush(stdout);
156: term_init();
157: i = 0;
158: for(;;) {
159: ret = read(0, &ch, 1);
160: if (ret == -1) {
161: if (errno == EAGAIN || errno == EINTR) {
162: continue;
163: } else {
164: ret = -1;
165: break;
166: }
167: } else if (ret == 0) {
168: ret = -1;
169: break;
170: } else {
171: if (ch == '\r') {
172: ret = 0;
173: break;
174: }
175: if (i < (buf_size - 1))
176: buf[i++] = ch;
177: }
178: }
179: term_exit();
180: buf[i] = '\0';
181: printf("\n");
182: return ret;
183: }
184: #endif
185:
1.1.1.13! root 186: static int set_cache_flag(const char *mode, int *flags)
! 187: {
! 188: *flags &= ~BDRV_O_CACHE_MASK;
! 189:
! 190: if (!strcmp(mode, "none") || !strcmp(mode, "off")) {
! 191: *flags |= BDRV_O_CACHE_WB;
! 192: *flags |= BDRV_O_NOCACHE;
! 193: } else if (!strcmp(mode, "writeback")) {
! 194: *flags |= BDRV_O_CACHE_WB;
! 195: } else if (!strcmp(mode, "unsafe")) {
! 196: *flags |= BDRV_O_CACHE_WB;
! 197: *flags |= BDRV_O_NO_FLUSH;
! 198: } else if (!strcmp(mode, "writethrough")) {
! 199: /* this is the default */
! 200: } else {
! 201: return -1;
! 202: }
! 203:
! 204: return 0;
! 205: }
! 206:
1.1.1.12 root 207: static int print_block_option_help(const char *filename, const char *fmt)
208: {
209: BlockDriver *drv, *proto_drv;
210: QEMUOptionParameter *create_options = NULL;
211:
212: /* Find driver and parse its options */
213: drv = bdrv_find_format(fmt);
214: if (!drv) {
215: error_report("Unknown file format '%s'", fmt);
216: return 1;
217: }
218:
219: proto_drv = bdrv_find_protocol(filename);
220: if (!proto_drv) {
221: error_report("Unknown protocol '%s'", filename);
222: return 1;
223: }
224:
225: create_options = append_option_parameters(create_options,
226: drv->create_options);
227: create_options = append_option_parameters(create_options,
228: proto_drv->create_options);
229: print_option_help(create_options);
230: free_option_parameters(create_options);
231: return 0;
232: }
233:
1.1 root 234: static BlockDriverState *bdrv_new_open(const char *filename,
1.1.1.11 root 235: const char *fmt,
236: int flags)
1.1 root 237: {
238: BlockDriverState *bs;
239: BlockDriver *drv;
240: char password[256];
1.1.1.12 root 241: int ret;
242:
243: bs = bdrv_new("image");
1.1 root 244:
245: if (fmt) {
246: drv = bdrv_find_format(fmt);
1.1.1.11 root 247: if (!drv) {
1.1.1.12 root 248: error_report("Unknown file format '%s'", fmt);
1.1.1.11 root 249: goto fail;
250: }
1.1 root 251: } else {
252: drv = NULL;
253: }
1.1.1.12 root 254:
255: ret = bdrv_open(bs, filename, flags, drv);
256: if (ret < 0) {
257: error_report("Could not open '%s': %s", filename, strerror(-ret));
1.1.1.11 root 258: goto fail;
1.1 root 259: }
1.1.1.12 root 260:
1.1 root 261: if (bdrv_is_encrypted(bs)) {
262: printf("Disk image '%s' is encrypted.\n", filename);
1.1.1.11 root 263: if (read_password(password, sizeof(password)) < 0) {
1.1.1.12 root 264: error_report("No password given");
1.1.1.11 root 265: goto fail;
266: }
267: if (bdrv_set_key(bs, password) < 0) {
1.1.1.12 root 268: error_report("invalid password");
1.1.1.11 root 269: goto fail;
270: }
1.1 root 271: }
272: return bs;
1.1.1.11 root 273: fail:
274: if (bs) {
275: bdrv_delete(bs);
276: }
277: return NULL;
1.1 root 278: }
279:
1.1.1.11 root 280: static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
1.1.1.12 root 281: const char *base_filename,
282: const char *base_fmt)
1.1.1.8 root 283: {
284: if (base_filename) {
285: if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
1.1.1.12 root 286: error_report("Backing file not supported for file format '%s'",
287: fmt);
1.1.1.11 root 288: return -1;
1.1.1.8 root 289: }
290: }
291: if (base_fmt) {
292: if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
1.1.1.12 root 293: error_report("Backing file format not supported for file "
294: "format '%s'", fmt);
1.1.1.11 root 295: return -1;
1.1.1.8 root 296: }
297: }
1.1.1.11 root 298: return 0;
1.1.1.8 root 299: }
300:
1.1 root 301: static int img_create(int argc, char **argv)
302: {
1.1.1.12 root 303: int c, ret = 0;
304: uint64_t img_size = -1;
1.1 root 305: const char *fmt = "raw";
1.1.1.8 root 306: const char *base_fmt = NULL;
1.1 root 307: const char *filename;
308: const char *base_filename = NULL;
1.1.1.8 root 309: char *options = NULL;
1.1.1.4 root 310:
1.1 root 311: for(;;) {
1.1.1.8 root 312: c = getopt(argc, argv, "F:b:f:he6o:");
1.1.1.12 root 313: if (c == -1) {
1.1 root 314: break;
1.1.1.12 root 315: }
1.1 root 316: switch(c) {
1.1.1.12 root 317: case '?':
1.1 root 318: case 'h':
319: help();
320: break;
1.1.1.8 root 321: case 'F':
322: base_fmt = optarg;
323: break;
1.1 root 324: case 'b':
325: base_filename = optarg;
326: break;
327: case 'f':
328: fmt = optarg;
329: break;
330: case 'e':
1.1.1.13! root 331: error_report("option -e is deprecated, please use \'-o "
1.1.1.12 root 332: "encryption\' instead!");
333: return 1;
1.1.1.4 root 334: case '6':
1.1.1.13! root 335: error_report("option -6 is deprecated, please use \'-o "
1.1.1.12 root 336: "compat6\' instead!");
337: return 1;
1.1.1.8 root 338: case 'o':
339: options = optarg;
340: break;
1.1 root 341: }
342: }
1.1.1.8 root 343:
1.1.1.11 root 344: /* Get the filename */
1.1.1.12 root 345: if (optind >= argc) {
1.1.1.11 root 346: help();
347: }
1.1.1.12 root 348: filename = argv[optind++];
1.1.1.11 root 349:
1.1.1.12 root 350: /* Get image size, if specified */
351: if (optind < argc) {
352: int64_t sval;
353: sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
354: if (sval < 0) {
355: error_report("Invalid image size specified! You may use k, M, G or "
356: "T suffixes for ");
357: error_report("kilobytes, megabytes, gigabytes and terabytes.");
1.1.1.11 root 358: ret = -1;
359: goto out;
1.1.1.8 root 360: }
1.1.1.12 root 361: img_size = (uint64_t)sval;
1.1.1.8 root 362: }
363:
1.1.1.12 root 364: if (options && !strcmp(options, "?")) {
365: ret = print_block_option_help(filename, fmt);
1.1.1.11 root 366: goto out;
367: }
1.1.1.8 root 368:
1.1.1.12 root 369: ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
370: options, img_size, BDRV_O_FLAGS);
1.1.1.11 root 371: out:
372: if (ret) {
373: return 1;
374: }
1.1 root 375: return 0;
376: }
377:
1.1.1.11 root 378: /*
379: * Checks an image for consistency. Exit codes:
380: *
381: * 0 - Check completed, image is good
382: * 1 - Check not completed because of internal errors
383: * 2 - Check completed, image is corrupted
384: * 3 - Check completed, image has leaked clusters, but is good otherwise
385: */
1.1.1.8 root 386: static int img_check(int argc, char **argv)
387: {
388: int c, ret;
389: const char *filename, *fmt;
390: BlockDriverState *bs;
1.1.1.11 root 391: BdrvCheckResult result;
1.1.1.8 root 392:
393: fmt = NULL;
394: for(;;) {
395: c = getopt(argc, argv, "f:h");
1.1.1.12 root 396: if (c == -1) {
1.1.1.8 root 397: break;
1.1.1.12 root 398: }
1.1.1.8 root 399: switch(c) {
1.1.1.12 root 400: case '?':
1.1.1.8 root 401: case 'h':
402: help();
403: break;
404: case 'f':
405: fmt = optarg;
406: break;
407: }
408: }
1.1.1.12 root 409: if (optind >= argc) {
1.1.1.8 root 410: help();
1.1.1.12 root 411: }
1.1.1.8 root 412: filename = argv[optind++];
413:
1.1.1.11 root 414: bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
415: if (!bs) {
416: return 1;
1.1.1.8 root 417: }
1.1.1.11 root 418: ret = bdrv_check(bs, &result);
419:
420: if (ret == -ENOTSUP) {
1.1.1.12 root 421: error_report("This image format does not support checks");
1.1.1.11 root 422: bdrv_delete(bs);
423: return 1;
1.1.1.8 root 424: }
1.1.1.11 root 425:
426: if (!(result.corruptions || result.leaks || result.check_errors)) {
1.1.1.8 root 427: printf("No errors were found on the image.\n");
1.1.1.11 root 428: } else {
429: if (result.corruptions) {
430: printf("\n%d errors were found on the image.\n"
431: "Data may be corrupted, or further writes to the image "
432: "may corrupt it.\n",
433: result.corruptions);
434: }
435:
436: if (result.leaks) {
437: printf("\n%d leaked clusters were found on the image.\n"
438: "This means waste of disk space, but no harm to data.\n",
439: result.leaks);
440: }
441:
442: if (result.check_errors) {
443: printf("\n%d internal errors have occurred during the check.\n",
444: result.check_errors);
1.1.1.8 root 445: }
446: }
447:
448: bdrv_delete(bs);
1.1.1.11 root 449:
450: if (ret < 0 || result.check_errors) {
451: printf("\nAn error has occurred during the check: %s\n"
452: "The check is not complete and may have missed error.\n",
453: strerror(-ret));
454: return 1;
455: }
456:
457: if (result.corruptions) {
458: return 2;
459: } else if (result.leaks) {
460: return 3;
461: } else {
462: return 0;
463: }
1.1.1.8 root 464: }
465:
1.1 root 466: static int img_commit(int argc, char **argv)
467: {
1.1.1.13! root 468: int c, ret, flags;
! 469: const char *filename, *fmt, *cache;
1.1 root 470: BlockDriverState *bs;
471:
472: fmt = NULL;
1.1.1.13! root 473: cache = BDRV_DEFAULT_CACHE;
1.1 root 474: for(;;) {
1.1.1.13! root 475: c = getopt(argc, argv, "f:ht:");
1.1.1.12 root 476: if (c == -1) {
1.1 root 477: break;
1.1.1.12 root 478: }
1.1 root 479: switch(c) {
1.1.1.12 root 480: case '?':
1.1 root 481: case 'h':
482: help();
483: break;
484: case 'f':
485: fmt = optarg;
486: break;
1.1.1.13! root 487: case 't':
! 488: cache = optarg;
! 489: break;
1.1 root 490: }
491: }
1.1.1.12 root 492: if (optind >= argc) {
1.1 root 493: help();
1.1.1.12 root 494: }
1.1 root 495: filename = argv[optind++];
496:
1.1.1.13! root 497: flags = BDRV_O_RDWR;
! 498: ret = set_cache_flag(cache, &flags);
! 499: if (ret < 0) {
! 500: error_report("Invalid cache option: %s", cache);
! 501: return -1;
! 502: }
! 503:
! 504: bs = bdrv_new_open(filename, fmt, flags);
1.1.1.11 root 505: if (!bs) {
506: return 1;
1.1 root 507: }
508: ret = bdrv_commit(bs);
509: switch(ret) {
510: case 0:
511: printf("Image committed.\n");
512: break;
513: case -ENOENT:
1.1.1.12 root 514: error_report("No disk inserted");
1.1 root 515: break;
516: case -EACCES:
1.1.1.12 root 517: error_report("Image is read-only");
1.1 root 518: break;
519: case -ENOTSUP:
1.1.1.12 root 520: error_report("Image is already committed");
1.1 root 521: break;
522: default:
1.1.1.12 root 523: error_report("Error while committing image");
1.1 root 524: break;
525: }
526:
527: bdrv_delete(bs);
1.1.1.11 root 528: if (ret) {
529: return 1;
530: }
1.1 root 531: return 0;
532: }
533:
1.1.1.13! root 534: /*
! 535: * Checks whether the sector is not a zero sector.
! 536: *
! 537: * Attention! The len must be a multiple of 4 * sizeof(long) due to
! 538: * restriction of optimizations in this function.
! 539: */
1.1 root 540: static int is_not_zero(const uint8_t *sector, int len)
541: {
1.1.1.13! root 542: /*
! 543: * Use long as the biggest available internal data type that fits into the
! 544: * CPU register and unroll the loop to smooth out the effect of memory
! 545: * latency.
! 546: */
! 547:
1.1 root 548: int i;
1.1.1.13! root 549: long d0, d1, d2, d3;
! 550: const long * const data = (const long *) sector;
! 551:
! 552: len /= sizeof(long);
! 553:
! 554: for(i = 0; i < len; i += 4) {
! 555: d0 = data[i + 0];
! 556: d1 = data[i + 1];
! 557: d2 = data[i + 2];
! 558: d3 = data[i + 3];
! 559:
! 560: if (d0 || d1 || d2 || d3) {
1.1 root 561: return 1;
1.1.1.13! root 562: }
1.1 root 563: }
1.1.1.13! root 564:
1.1 root 565: return 0;
566: }
567:
1.1.1.5 root 568: /*
569: * Returns true iff the first sector pointed to by 'buf' contains at least
570: * a non-NUL byte.
571: *
572: * 'pnum' is set to the number of sectors (including and immediately following
573: * the first one) that are known to be in the same allocated/unallocated state.
574: */
1.1 root 575: static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
576: {
577: int v, i;
578:
579: if (n <= 0) {
580: *pnum = 0;
581: return 0;
582: }
583: v = is_not_zero(buf, 512);
584: for(i = 1; i < n; i++) {
585: buf += 512;
586: if (v != is_not_zero(buf, 512))
587: break;
588: }
589: *pnum = i;
590: return v;
591: }
592:
1.1.1.11 root 593: /*
594: * Compares two buffers sector by sector. Returns 0 if the first sector of both
595: * buffers matches, non-zero otherwise.
596: *
597: * pnum is set to the number of sectors (including and immediately following
598: * the first one) that are known to have the same comparison result
599: */
600: static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
601: int *pnum)
602: {
603: int res, i;
604:
605: if (n <= 0) {
606: *pnum = 0;
607: return 0;
608: }
609:
610: res = !!memcmp(buf1, buf2, 512);
611: for(i = 1; i < n; i++) {
612: buf1 += 512;
613: buf2 += 512;
614:
615: if (!!memcmp(buf1, buf2, 512) != res) {
616: break;
617: }
618: }
619:
620: *pnum = i;
621: return res;
622: }
623:
1.1.1.9 root 624: #define IO_BUF_SIZE (2 * 1024 * 1024)
1.1 root 625:
626: static int img_convert(int argc, char **argv)
627: {
1.1.1.12 root 628: int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
1.1.1.13! root 629: int progress = 0, flags;
! 630: const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
1.1.1.11 root 631: BlockDriver *drv, *proto_drv;
632: BlockDriverState **bs = NULL, *out_bs = NULL;
1.1.1.4 root 633: int64_t total_sectors, nb_sectors, sector_num, bs_offset;
634: uint64_t bs_sectors;
1.1.1.11 root 635: uint8_t * buf = NULL;
1.1 root 636: const uint8_t *buf1;
1.1.1.3 root 637: BlockDriverInfo bdi;
1.1.1.11 root 638: QEMUOptionParameter *param = NULL, *create_options = NULL;
1.1.1.12 root 639: QEMUOptionParameter *out_baseimg_param;
1.1.1.8 root 640: char *options = NULL;
1.1.1.12 root 641: const char *snapshot_name = NULL;
1.1.1.13! root 642: float local_progress;
1.1 root 643:
644: fmt = NULL;
645: out_fmt = "raw";
1.1.1.13! root 646: cache = "unsafe";
1.1.1.5 root 647: out_baseimg = NULL;
1.1.1.12 root 648: compress = 0;
1.1 root 649: for(;;) {
1.1.1.13! root 650: c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
1.1.1.12 root 651: if (c == -1) {
1.1 root 652: break;
1.1.1.12 root 653: }
1.1 root 654: switch(c) {
1.1.1.12 root 655: case '?':
1.1 root 656: case 'h':
657: help();
658: break;
659: case 'f':
660: fmt = optarg;
661: break;
662: case 'O':
663: out_fmt = optarg;
664: break;
1.1.1.5 root 665: case 'B':
666: out_baseimg = optarg;
667: break;
1.1 root 668: case 'c':
1.1.1.12 root 669: compress = 1;
1.1 root 670: break;
671: case 'e':
1.1.1.13! root 672: error_report("option -e is deprecated, please use \'-o "
1.1.1.12 root 673: "encryption\' instead!");
674: return 1;
1.1.1.4 root 675: case '6':
1.1.1.13! root 676: error_report("option -6 is deprecated, please use \'-o "
1.1.1.12 root 677: "compat6\' instead!");
678: return 1;
1.1.1.8 root 679: case 'o':
680: options = optarg;
681: break;
1.1.1.12 root 682: case 's':
683: snapshot_name = optarg;
684: break;
1.1.1.13! root 685: case 'p':
! 686: progress = 1;
! 687: break;
! 688: case 't':
! 689: cache = optarg;
! 690: break;
1.1 root 691: }
692: }
1.1.1.4 root 693:
694: bs_n = argc - optind - 1;
1.1.1.12 root 695: if (bs_n < 1) {
696: help();
697: }
1.1.1.4 root 698:
699: out_filename = argv[argc - 1];
1.1.1.5 root 700:
1.1.1.12 root 701: if (options && !strcmp(options, "?")) {
702: ret = print_block_option_help(out_filename, out_fmt);
703: goto out;
704: }
705:
1.1.1.11 root 706: if (bs_n > 1 && out_baseimg) {
1.1.1.12 root 707: error_report("-B makes no sense when concatenating multiple input "
708: "images");
709: ret = -1;
710: goto out;
1.1.1.11 root 711: }
1.1.1.4 root 712:
1.1.1.13! root 713: qemu_progress_init(progress, 2.0);
! 714: qemu_progress_print(0, 100);
! 715:
1.1.1.12 root 716: bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
1.1.1.4 root 717:
718: total_sectors = 0;
719: for (bs_i = 0; bs_i < bs_n; bs_i++) {
1.1.1.11 root 720: bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
721: if (!bs[bs_i]) {
1.1.1.12 root 722: error_report("Could not open '%s'", argv[optind + bs_i]);
1.1.1.11 root 723: ret = -1;
724: goto out;
725: }
1.1.1.4 root 726: bdrv_get_geometry(bs[bs_i], &bs_sectors);
727: total_sectors += bs_sectors;
728: }
1.1 root 729:
1.1.1.12 root 730: if (snapshot_name != NULL) {
731: if (bs_n > 1) {
1.1.1.13! root 732: error_report("No support for concatenating multiple snapshot");
1.1.1.12 root 733: ret = -1;
734: goto out;
735: }
736: if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
1.1.1.13! root 737: error_report("Failed to load snapshot");
1.1.1.12 root 738: ret = -1;
739: goto out;
740: }
741: }
742:
1.1.1.8 root 743: /* Find driver and parse its options */
1.1 root 744: drv = bdrv_find_format(out_fmt);
1.1.1.11 root 745: if (!drv) {
1.1.1.12 root 746: error_report("Unknown file format '%s'", out_fmt);
1.1.1.11 root 747: ret = -1;
748: goto out;
749: }
750:
751: proto_drv = bdrv_find_protocol(out_filename);
752: if (!proto_drv) {
1.1.1.12 root 753: error_report("Unknown protocol '%s'", out_filename);
1.1.1.11 root 754: ret = -1;
755: goto out;
756: }
1.1.1.4 root 757:
1.1.1.11 root 758: create_options = append_option_parameters(create_options,
759: drv->create_options);
760: create_options = append_option_parameters(create_options,
761: proto_drv->create_options);
1.1.1.8 root 762:
763: if (options) {
1.1.1.11 root 764: param = parse_option_parameters(options, create_options, param);
1.1.1.8 root 765: if (param == NULL) {
1.1.1.12 root 766: error_report("Invalid options for file format '%s'.", out_fmt);
1.1.1.11 root 767: ret = -1;
768: goto out;
1.1.1.8 root 769: }
770: } else {
1.1.1.11 root 771: param = parse_option_parameters("", create_options, param);
1.1.1.8 root 772: }
773:
774: set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
1.1.1.12 root 775: ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
1.1.1.11 root 776: if (ret < 0) {
777: goto out;
778: }
1.1.1.8 root 779:
1.1.1.12 root 780: /* Get backing file name if -o backing_file was used */
781: out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
782: if (out_baseimg_param) {
783: out_baseimg = out_baseimg_param->value.s;
784: }
785:
1.1.1.8 root 786: /* Check if compression is supported */
1.1.1.12 root 787: if (compress) {
1.1.1.8 root 788: QEMUOptionParameter *encryption =
789: get_option_parameter(param, BLOCK_OPT_ENCRYPT);
790:
791: if (!drv->bdrv_write_compressed) {
1.1.1.12 root 792: error_report("Compression not supported for this file format");
1.1.1.11 root 793: ret = -1;
794: goto out;
1.1.1.8 root 795: }
796:
797: if (encryption && encryption->value.n) {
1.1.1.12 root 798: error_report("Compression and encryption not supported at "
799: "the same time");
1.1.1.11 root 800: ret = -1;
801: goto out;
1.1.1.8 root 802: }
803: }
804:
805: /* Create the new image */
806: ret = bdrv_create(drv, out_filename, param);
1.1 root 807: if (ret < 0) {
808: if (ret == -ENOTSUP) {
1.1.1.12 root 809: error_report("Formatting not supported for file format '%s'",
810: out_fmt);
1.1.1.7 root 811: } else if (ret == -EFBIG) {
1.1.1.12 root 812: error_report("The image size is too large for file format '%s'",
813: out_fmt);
1.1 root 814: } else {
1.1.1.12 root 815: error_report("%s: error while converting %s: %s",
816: out_filename, out_fmt, strerror(-ret));
1.1 root 817: }
1.1.1.11 root 818: goto out;
1.1 root 819: }
1.1.1.4 root 820:
1.1.1.13! root 821: flags = BDRV_O_RDWR;
! 822: ret = set_cache_flag(cache, &flags);
! 823: if (ret < 0) {
! 824: error_report("Invalid cache option: %s", cache);
! 825: return -1;
! 826: }
! 827:
! 828: out_bs = bdrv_new_open(out_filename, out_fmt, flags);
1.1.1.11 root 829: if (!out_bs) {
830: ret = -1;
831: goto out;
832: }
1.1 root 833:
1.1.1.4 root 834: bs_i = 0;
835: bs_offset = 0;
836: bdrv_get_geometry(bs[0], &bs_sectors);
1.1.1.10 root 837: buf = qemu_malloc(IO_BUF_SIZE);
1.1.1.4 root 838:
1.1.1.12 root 839: if (compress) {
1.1.1.11 root 840: ret = bdrv_get_info(out_bs, &bdi);
841: if (ret < 0) {
1.1.1.12 root 842: error_report("could not get block driver info");
1.1.1.11 root 843: goto out;
844: }
1.1.1.3 root 845: cluster_size = bdi.cluster_size;
1.1.1.11 root 846: if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
1.1.1.12 root 847: error_report("invalid cluster size");
1.1.1.11 root 848: ret = -1;
849: goto out;
850: }
1.1 root 851: cluster_sectors = cluster_size >> 9;
852: sector_num = 0;
1.1.1.13! root 853:
! 854: nb_sectors = total_sectors;
! 855: local_progress = (float)100 /
! 856: (nb_sectors / MIN(nb_sectors, cluster_sectors));
! 857:
1.1 root 858: for(;;) {
1.1.1.4 root 859: int64_t bs_num;
860: int remainder;
861: uint8_t *buf2;
862:
1.1 root 863: nb_sectors = total_sectors - sector_num;
864: if (nb_sectors <= 0)
865: break;
866: if (nb_sectors >= cluster_sectors)
867: n = cluster_sectors;
868: else
869: n = nb_sectors;
1.1.1.4 root 870:
871: bs_num = sector_num - bs_offset;
872: assert (bs_num >= 0);
873: remainder = n;
874: buf2 = buf;
875: while (remainder > 0) {
876: int nlow;
877: while (bs_num == bs_sectors) {
878: bs_i++;
879: assert (bs_i < bs_n);
880: bs_offset += bs_sectors;
881: bdrv_get_geometry(bs[bs_i], &bs_sectors);
882: bs_num = 0;
1.1.1.11 root 883: /* printf("changing part: sector_num=%" PRId64 ", "
884: "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
885: "\n", sector_num, bs_i, bs_offset, bs_sectors); */
1.1.1.4 root 886: }
887: assert (bs_num < bs_sectors);
888:
889: nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
890:
1.1.1.11 root 891: ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
892: if (ret < 0) {
1.1.1.12 root 893: error_report("error while reading");
1.1.1.11 root 894: goto out;
895: }
1.1.1.4 root 896:
897: buf2 += nlow * 512;
898: bs_num += nlow;
899:
900: remainder -= nlow;
901: }
902: assert (remainder == 0);
903:
1.1.1.12 root 904: if (n < cluster_sectors) {
1.1 root 905: memset(buf + n * 512, 0, cluster_size - n * 512);
1.1.1.12 root 906: }
1.1 root 907: if (is_not_zero(buf, cluster_size)) {
1.1.1.11 root 908: ret = bdrv_write_compressed(out_bs, sector_num, buf,
909: cluster_sectors);
910: if (ret != 0) {
1.1.1.12 root 911: error_report("error while compressing sector %" PRId64,
1.1.1.2 root 912: sector_num);
1.1.1.11 root 913: goto out;
914: }
1.1 root 915: }
916: sector_num += n;
1.1.1.13! root 917: qemu_progress_print(local_progress, 100);
1.1 root 918: }
1.1.1.3 root 919: /* signal EOF to align */
920: bdrv_write_compressed(out_bs, 0, NULL, 0);
1.1 root 921: } else {
1.1.1.11 root 922: int has_zero_init = bdrv_has_zero_init(out_bs);
923:
1.1.1.5 root 924: sector_num = 0; // total number of sectors converted so far
1.1.1.13! root 925: nb_sectors = total_sectors - sector_num;
! 926: local_progress = (float)100 /
! 927: (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
! 928:
1.1 root 929: for(;;) {
930: nb_sectors = total_sectors - sector_num;
1.1.1.12 root 931: if (nb_sectors <= 0) {
1.1 root 932: break;
1.1.1.12 root 933: }
934: if (nb_sectors >= (IO_BUF_SIZE / 512)) {
1.1 root 935: n = (IO_BUF_SIZE / 512);
1.1.1.12 root 936: } else {
1.1 root 937: n = nb_sectors;
1.1.1.12 root 938: }
1.1.1.4 root 939:
940: while (sector_num - bs_offset >= bs_sectors) {
941: bs_i ++;
942: assert (bs_i < bs_n);
943: bs_offset += bs_sectors;
944: bdrv_get_geometry(bs[bs_i], &bs_sectors);
1.1.1.11 root 945: /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
946: "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
1.1.1.4 root 947: sector_num, bs_i, bs_offset, bs_sectors); */
948: }
949:
1.1.1.12 root 950: if (n > bs_offset + bs_sectors - sector_num) {
1.1.1.4 root 951: n = bs_offset + bs_sectors - sector_num;
1.1.1.12 root 952: }
1.1.1.4 root 953:
1.1.1.11 root 954: if (has_zero_init) {
1.1.1.8 root 955: /* If the output image is being created as a copy on write image,
956: assume that sectors which are unallocated in the input image
957: are present in both the output's and input's base images (no
958: need to copy them). */
959: if (out_baseimg) {
960: if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
961: n, &n1)) {
962: sector_num += n1;
963: continue;
964: }
965: /* The next 'n1' sectors are allocated in the input image. Copy
966: only those as they may be followed by unallocated sectors. */
967: n = n1;
968: }
969: } else {
970: n1 = n;
1.1.1.5 root 971: }
972:
1.1.1.11 root 973: ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
974: if (ret < 0) {
1.1.1.12 root 975: error_report("error while reading");
1.1.1.11 root 976: goto out;
977: }
1.1 root 978: /* NOTE: at the same time we convert, we do not write zero
979: sectors to have a chance to compress the image. Ideally, we
980: should add a specific call to have the info to go faster */
981: buf1 = buf;
982: while (n > 0) {
1.1.1.5 root 983: /* If the output image is being created as a copy on write image,
984: copy all sectors even the ones containing only NUL bytes,
1.1.1.8 root 985: because they may differ from the sectors in the base image.
986:
987: If the output is to a host device, we also write out
988: sectors that are entirely 0, since whatever data was
989: already there is garbage, not 0s. */
1.1.1.11 root 990: if (!has_zero_init || out_baseimg ||
1.1.1.8 root 991: is_allocated_sectors(buf1, n, &n1)) {
1.1.1.11 root 992: ret = bdrv_write(out_bs, sector_num, buf1, n1);
993: if (ret < 0) {
1.1.1.12 root 994: error_report("error while writing");
1.1.1.11 root 995: goto out;
996: }
1.1 root 997: }
998: sector_num += n1;
999: n -= n1;
1000: buf1 += n1 * 512;
1001: }
1.1.1.13! root 1002: qemu_progress_print(local_progress, 100);
1.1 root 1003: }
1004: }
1.1.1.11 root 1005: out:
1.1.1.13! root 1006: qemu_progress_end();
1.1.1.11 root 1007: free_option_parameters(create_options);
1008: free_option_parameters(param);
1.1.1.10 root 1009: qemu_free(buf);
1.1.1.11 root 1010: if (out_bs) {
1011: bdrv_delete(out_bs);
1012: }
1.1.1.12 root 1013: if (bs) {
1014: for (bs_i = 0; bs_i < bs_n; bs_i++) {
1015: if (bs[bs_i]) {
1016: bdrv_delete(bs[bs_i]);
1017: }
1.1.1.11 root 1018: }
1.1.1.12 root 1019: qemu_free(bs);
1.1.1.11 root 1020: }
1021: if (ret) {
1022: return 1;
1023: }
1.1 root 1024: return 0;
1025: }
1026:
1027:
1.1.1.3 root 1028: static void dump_snapshots(BlockDriverState *bs)
1029: {
1030: QEMUSnapshotInfo *sn_tab, *sn;
1031: int nb_sns, i;
1032: char buf[256];
1033:
1034: nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1035: if (nb_sns <= 0)
1036: return;
1037: printf("Snapshot list:\n");
1038: printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1039: for(i = 0; i < nb_sns; i++) {
1040: sn = &sn_tab[i];
1041: printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1042: }
1043: qemu_free(sn_tab);
1044: }
1045:
1.1 root 1046: static int img_info(int argc, char **argv)
1047: {
1048: int c;
1049: const char *filename, *fmt;
1050: BlockDriverState *bs;
1051: char fmt_name[128], size_buf[128], dsize_buf[128];
1.1.1.4 root 1052: uint64_t total_sectors;
1053: int64_t allocated_size;
1.1.1.3 root 1054: char backing_filename[1024];
1055: char backing_filename2[1024];
1056: BlockDriverInfo bdi;
1.1 root 1057:
1058: fmt = NULL;
1059: for(;;) {
1060: c = getopt(argc, argv, "f:h");
1.1.1.12 root 1061: if (c == -1) {
1.1 root 1062: break;
1.1.1.12 root 1063: }
1.1 root 1064: switch(c) {
1.1.1.12 root 1065: case '?':
1.1 root 1066: case 'h':
1067: help();
1068: break;
1069: case 'f':
1070: fmt = optarg;
1071: break;
1072: }
1073: }
1.1.1.12 root 1074: if (optind >= argc) {
1.1 root 1075: help();
1.1.1.12 root 1076: }
1.1 root 1077: filename = argv[optind++];
1078:
1.1.1.11 root 1079: bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
1080: if (!bs) {
1081: return 1;
1.1 root 1082: }
1083: bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1084: bdrv_get_geometry(bs, &total_sectors);
1085: get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
1.1.1.13! root 1086: allocated_size = bdrv_get_allocated_file_size(bs);
1.1.1.12 root 1087: if (allocated_size < 0) {
1.1.1.5 root 1088: snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1.1.1.12 root 1089: } else {
1.1.1.4 root 1090: get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1.1 root 1091: allocated_size);
1.1.1.12 root 1092: }
1.1 root 1093: printf("image: %s\n"
1094: "file format: %s\n"
1.1.1.2 root 1095: "virtual size: %s (%" PRId64 " bytes)\n"
1.1 root 1096: "disk size: %s\n",
1.1.1.4 root 1097: filename, fmt_name, size_buf,
1.1.1.2 root 1098: (total_sectors * 512),
1.1 root 1099: dsize_buf);
1.1.1.12 root 1100: if (bdrv_is_encrypted(bs)) {
1.1 root 1101: printf("encrypted: yes\n");
1.1.1.12 root 1102: }
1.1.1.3 root 1103: if (bdrv_get_info(bs, &bdi) >= 0) {
1.1.1.12 root 1104: if (bdi.cluster_size != 0) {
1.1.1.3 root 1105: printf("cluster_size: %d\n", bdi.cluster_size);
1.1.1.12 root 1106: }
1.1.1.3 root 1107: }
1108: bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1109: if (backing_filename[0] != '\0') {
1110: path_combine(backing_filename2, sizeof(backing_filename2),
1111: filename, backing_filename);
1.1.1.4 root 1112: printf("backing file: %s (actual path: %s)\n",
1.1.1.3 root 1113: backing_filename,
1114: backing_filename2);
1115: }
1116: dump_snapshots(bs);
1.1 root 1117: bdrv_delete(bs);
1118: return 0;
1119: }
1120:
1.1.1.5 root 1121: #define SNAPSHOT_LIST 1
1122: #define SNAPSHOT_CREATE 2
1123: #define SNAPSHOT_APPLY 3
1124: #define SNAPSHOT_DELETE 4
1125:
1.1.1.8 root 1126: static int img_snapshot(int argc, char **argv)
1.1.1.5 root 1127: {
1128: BlockDriverState *bs;
1129: QEMUSnapshotInfo sn;
1130: char *filename, *snapshot_name = NULL;
1.1.1.11 root 1131: int c, ret = 0, bdrv_oflags;
1.1.1.5 root 1132: int action = 0;
1133: qemu_timeval tv;
1134:
1.1.1.12 root 1135: bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
1.1.1.5 root 1136: /* Parse commandline parameters */
1137: for(;;) {
1138: c = getopt(argc, argv, "la:c:d:h");
1.1.1.12 root 1139: if (c == -1) {
1.1.1.5 root 1140: break;
1.1.1.12 root 1141: }
1.1.1.5 root 1142: switch(c) {
1.1.1.12 root 1143: case '?':
1.1.1.5 root 1144: case 'h':
1145: help();
1.1.1.8 root 1146: return 0;
1.1.1.5 root 1147: case 'l':
1148: if (action) {
1149: help();
1.1.1.8 root 1150: return 0;
1.1.1.5 root 1151: }
1152: action = SNAPSHOT_LIST;
1.1.1.11 root 1153: bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
1.1.1.5 root 1154: break;
1155: case 'a':
1156: if (action) {
1157: help();
1.1.1.8 root 1158: return 0;
1.1.1.5 root 1159: }
1160: action = SNAPSHOT_APPLY;
1161: snapshot_name = optarg;
1162: break;
1163: case 'c':
1164: if (action) {
1165: help();
1.1.1.8 root 1166: return 0;
1.1.1.5 root 1167: }
1168: action = SNAPSHOT_CREATE;
1169: snapshot_name = optarg;
1170: break;
1171: case 'd':
1172: if (action) {
1173: help();
1.1.1.8 root 1174: return 0;
1.1.1.5 root 1175: }
1176: action = SNAPSHOT_DELETE;
1177: snapshot_name = optarg;
1178: break;
1179: }
1180: }
1181:
1.1.1.12 root 1182: if (optind >= argc) {
1.1.1.5 root 1183: help();
1.1.1.12 root 1184: }
1.1.1.5 root 1185: filename = argv[optind++];
1186:
1187: /* Open the image */
1.1.1.11 root 1188: bs = bdrv_new_open(filename, NULL, bdrv_oflags);
1189: if (!bs) {
1190: return 1;
1.1.1.5 root 1191: }
1192:
1193: /* Perform the requested action */
1194: switch(action) {
1195: case SNAPSHOT_LIST:
1196: dump_snapshots(bs);
1197: break;
1198:
1199: case SNAPSHOT_CREATE:
1200: memset(&sn, 0, sizeof(sn));
1201: pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1202:
1203: qemu_gettimeofday(&tv);
1204: sn.date_sec = tv.tv_sec;
1205: sn.date_nsec = tv.tv_usec * 1000;
1206:
1207: ret = bdrv_snapshot_create(bs, &sn);
1.1.1.12 root 1208: if (ret) {
1209: error_report("Could not create snapshot '%s': %d (%s)",
1.1.1.5 root 1210: snapshot_name, ret, strerror(-ret));
1.1.1.12 root 1211: }
1.1.1.5 root 1212: break;
1213:
1214: case SNAPSHOT_APPLY:
1215: ret = bdrv_snapshot_goto(bs, snapshot_name);
1.1.1.12 root 1216: if (ret) {
1217: error_report("Could not apply snapshot '%s': %d (%s)",
1.1.1.5 root 1218: snapshot_name, ret, strerror(-ret));
1.1.1.12 root 1219: }
1.1.1.5 root 1220: break;
1221:
1222: case SNAPSHOT_DELETE:
1223: ret = bdrv_snapshot_delete(bs, snapshot_name);
1.1.1.12 root 1224: if (ret) {
1225: error_report("Could not delete snapshot '%s': %d (%s)",
1.1.1.5 root 1226: snapshot_name, ret, strerror(-ret));
1.1.1.12 root 1227: }
1.1.1.5 root 1228: break;
1229: }
1230:
1231: /* Cleanup */
1232: bdrv_delete(bs);
1.1.1.11 root 1233: if (ret) {
1234: return 1;
1235: }
1236: return 0;
1237: }
1238:
1239: static int img_rebase(int argc, char **argv)
1240: {
1241: BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
1242: BlockDriver *old_backing_drv, *new_backing_drv;
1243: char *filename;
1.1.1.13! root 1244: const char *fmt, *cache, *out_basefmt, *out_baseimg;
1.1.1.11 root 1245: int c, flags, ret;
1246: int unsafe = 0;
1.1.1.13! root 1247: int progress = 0;
1.1.1.11 root 1248:
1249: /* Parse commandline parameters */
1250: fmt = NULL;
1.1.1.13! root 1251: cache = BDRV_DEFAULT_CACHE;
1.1.1.11 root 1252: out_baseimg = NULL;
1253: out_basefmt = NULL;
1254: for(;;) {
1.1.1.13! root 1255: c = getopt(argc, argv, "uhf:F:b:pt:");
1.1.1.12 root 1256: if (c == -1) {
1.1.1.11 root 1257: break;
1.1.1.12 root 1258: }
1.1.1.11 root 1259: switch(c) {
1.1.1.12 root 1260: case '?':
1.1.1.11 root 1261: case 'h':
1262: help();
1263: return 0;
1264: case 'f':
1265: fmt = optarg;
1266: break;
1267: case 'F':
1268: out_basefmt = optarg;
1269: break;
1270: case 'b':
1271: out_baseimg = optarg;
1272: break;
1273: case 'u':
1274: unsafe = 1;
1275: break;
1.1.1.13! root 1276: case 'p':
! 1277: progress = 1;
! 1278: break;
! 1279: case 't':
! 1280: cache = optarg;
! 1281: break;
1.1.1.11 root 1282: }
1283: }
1284:
1.1.1.13! root 1285: if ((optind >= argc) || (!unsafe && !out_baseimg)) {
1.1.1.11 root 1286: help();
1.1.1.12 root 1287: }
1.1.1.11 root 1288: filename = argv[optind++];
1289:
1.1.1.13! root 1290: qemu_progress_init(progress, 2.0);
! 1291: qemu_progress_print(0, 100);
! 1292:
! 1293: flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
! 1294: ret = set_cache_flag(cache, &flags);
! 1295: if (ret < 0) {
! 1296: error_report("Invalid cache option: %s", cache);
! 1297: return -1;
! 1298: }
! 1299:
1.1.1.11 root 1300: /*
1301: * Open the images.
1302: *
1303: * Ignore the old backing file for unsafe rebase in case we want to correct
1304: * the reference to a renamed or moved backing file.
1305: */
1306: bs = bdrv_new_open(filename, fmt, flags);
1307: if (!bs) {
1308: return 1;
1309: }
1310:
1311: /* Find the right drivers for the backing files */
1312: old_backing_drv = NULL;
1313: new_backing_drv = NULL;
1314:
1315: if (!unsafe && bs->backing_format[0] != '\0') {
1316: old_backing_drv = bdrv_find_format(bs->backing_format);
1317: if (old_backing_drv == NULL) {
1.1.1.12 root 1318: error_report("Invalid format name: '%s'", bs->backing_format);
1.1.1.11 root 1319: ret = -1;
1320: goto out;
1321: }
1322: }
1323:
1324: if (out_basefmt != NULL) {
1325: new_backing_drv = bdrv_find_format(out_basefmt);
1326: if (new_backing_drv == NULL) {
1.1.1.12 root 1327: error_report("Invalid format name: '%s'", out_basefmt);
1.1.1.11 root 1328: ret = -1;
1329: goto out;
1330: }
1331: }
1332:
1333: /* For safe rebasing we need to compare old and new backing file */
1334: if (unsafe) {
1335: /* Make the compiler happy */
1336: bs_old_backing = NULL;
1337: bs_new_backing = NULL;
1338: } else {
1339: char backing_name[1024];
1340:
1341: bs_old_backing = bdrv_new("old_backing");
1342: bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
1343: ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1344: old_backing_drv);
1345: if (ret) {
1.1.1.12 root 1346: error_report("Could not open old backing file '%s'", backing_name);
1.1.1.11 root 1347: goto out;
1348: }
1349:
1350: bs_new_backing = bdrv_new("new_backing");
1351: ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
1352: new_backing_drv);
1353: if (ret) {
1.1.1.12 root 1354: error_report("Could not open new backing file '%s'", out_baseimg);
1.1.1.11 root 1355: goto out;
1356: }
1357: }
1358:
1359: /*
1360: * Check each unallocated cluster in the COW file. If it is unallocated,
1361: * accesses go to the backing file. We must therefore compare this cluster
1362: * in the old and new backing file, and if they differ we need to copy it
1363: * from the old backing file into the COW file.
1364: *
1365: * If qemu-img crashes during this step, no harm is done. The content of
1366: * the image is the same as the original one at any time.
1367: */
1368: if (!unsafe) {
1369: uint64_t num_sectors;
1370: uint64_t sector;
1371: int n;
1372: uint8_t * buf_old;
1373: uint8_t * buf_new;
1.1.1.13! root 1374: float local_progress;
1.1.1.11 root 1375:
1376: buf_old = qemu_malloc(IO_BUF_SIZE);
1377: buf_new = qemu_malloc(IO_BUF_SIZE);
1378:
1379: bdrv_get_geometry(bs, &num_sectors);
1380:
1.1.1.13! root 1381: local_progress = (float)100 /
! 1382: (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
1.1.1.11 root 1383: for (sector = 0; sector < num_sectors; sector += n) {
1384:
1385: /* How many sectors can we handle with the next read? */
1386: if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1387: n = (IO_BUF_SIZE / 512);
1388: } else {
1389: n = num_sectors - sector;
1390: }
1391:
1392: /* If the cluster is allocated, we don't need to take action */
1393: ret = bdrv_is_allocated(bs, sector, n, &n);
1394: if (ret) {
1395: continue;
1396: }
1397:
1398: /* Read old and new backing file */
1399: ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1400: if (ret < 0) {
1.1.1.12 root 1401: error_report("error while reading from old backing file");
1.1.1.11 root 1402: goto out;
1403: }
1404: ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1405: if (ret < 0) {
1.1.1.12 root 1406: error_report("error while reading from new backing file");
1.1.1.11 root 1407: goto out;
1408: }
1409:
1410: /* If they differ, we need to write to the COW file */
1411: uint64_t written = 0;
1412:
1413: while (written < n) {
1414: int pnum;
1415:
1416: if (compare_sectors(buf_old + written * 512,
1417: buf_new + written * 512, n - written, &pnum))
1418: {
1419: ret = bdrv_write(bs, sector + written,
1420: buf_old + written * 512, pnum);
1421: if (ret < 0) {
1.1.1.12 root 1422: error_report("Error while writing to COW image: %s",
1.1.1.11 root 1423: strerror(-ret));
1424: goto out;
1425: }
1426: }
1427:
1428: written += pnum;
1429: }
1.1.1.13! root 1430: qemu_progress_print(local_progress, 100);
1.1.1.11 root 1431: }
1432:
1433: qemu_free(buf_old);
1434: qemu_free(buf_new);
1435: }
1436:
1437: /*
1438: * Change the backing file. All clusters that are different from the old
1439: * backing file are overwritten in the COW file now, so the visible content
1440: * doesn't change when we switch the backing file.
1441: */
1442: ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1443: if (ret == -ENOSPC) {
1.1.1.12 root 1444: error_report("Could not change the backing file to '%s': No "
1445: "space left in the file header", out_baseimg);
1.1.1.11 root 1446: } else if (ret < 0) {
1.1.1.12 root 1447: error_report("Could not change the backing file to '%s': %s",
1.1.1.11 root 1448: out_baseimg, strerror(-ret));
1449: }
1450:
1.1.1.13! root 1451: qemu_progress_print(100, 0);
1.1.1.11 root 1452: /*
1453: * TODO At this point it is possible to check if any clusters that are
1454: * allocated in the COW file are the same in the backing file. If so, they
1455: * could be dropped from the COW file. Don't do this before switching the
1456: * backing file, in case of a crash this would lead to corruption.
1457: */
1458: out:
1.1.1.13! root 1459: qemu_progress_end();
1.1.1.11 root 1460: /* Cleanup */
1461: if (!unsafe) {
1.1.1.13! root 1462: if (bs_old_backing != NULL) {
! 1463: bdrv_delete(bs_old_backing);
! 1464: }
! 1465: if (bs_new_backing != NULL) {
! 1466: bdrv_delete(bs_new_backing);
! 1467: }
1.1.1.11 root 1468: }
1469:
1470: bdrv_delete(bs);
1471: if (ret) {
1472: return 1;
1473: }
1474: return 0;
1475: }
1476:
1477: static int img_resize(int argc, char **argv)
1478: {
1479: int c, ret, relative;
1480: const char *filename, *fmt, *size;
1481: int64_t n, total_size;
1.1.1.12 root 1482: BlockDriverState *bs = NULL;
1.1.1.11 root 1483: QEMUOptionParameter *param;
1484: QEMUOptionParameter resize_options[] = {
1485: {
1486: .name = BLOCK_OPT_SIZE,
1487: .type = OPT_SIZE,
1488: .help = "Virtual disk size"
1489: },
1490: { NULL }
1491: };
1492:
1.1.1.13! root 1493: /* Remove size from argv manually so that negative numbers are not treated
! 1494: * as options by getopt. */
! 1495: if (argc < 3) {
! 1496: help();
! 1497: return 1;
! 1498: }
! 1499:
! 1500: size = argv[--argc];
! 1501:
! 1502: /* Parse getopt arguments */
1.1.1.11 root 1503: fmt = NULL;
1504: for(;;) {
1505: c = getopt(argc, argv, "f:h");
1506: if (c == -1) {
1507: break;
1508: }
1509: switch(c) {
1.1.1.12 root 1510: case '?':
1.1.1.11 root 1511: case 'h':
1512: help();
1513: break;
1514: case 'f':
1515: fmt = optarg;
1516: break;
1517: }
1518: }
1.1.1.13! root 1519: if (optind >= argc) {
1.1.1.11 root 1520: help();
1521: }
1522: filename = argv[optind++];
1523:
1524: /* Choose grow, shrink, or absolute resize mode */
1525: switch (size[0]) {
1526: case '+':
1527: relative = 1;
1528: size++;
1529: break;
1530: case '-':
1531: relative = -1;
1532: size++;
1533: break;
1534: default:
1535: relative = 0;
1536: break;
1537: }
1538:
1539: /* Parse size */
1540: param = parse_option_parameters("", resize_options, NULL);
1541: if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1542: /* Error message already printed when size parsing fails */
1.1.1.12 root 1543: ret = -1;
1544: goto out;
1.1.1.11 root 1545: }
1546: n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1547: free_option_parameters(param);
1548:
1549: bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
1550: if (!bs) {
1.1.1.12 root 1551: ret = -1;
1552: goto out;
1.1.1.11 root 1553: }
1.1.1.8 root 1554:
1.1.1.11 root 1555: if (relative) {
1556: total_size = bdrv_getlength(bs) + n * relative;
1557: } else {
1558: total_size = n;
1559: }
1560: if (total_size <= 0) {
1.1.1.12 root 1561: error_report("New image size must be positive");
1.1.1.11 root 1562: ret = -1;
1563: goto out;
1564: }
1565:
1566: ret = bdrv_truncate(bs, total_size);
1567: switch (ret) {
1568: case 0:
1569: printf("Image resized.\n");
1570: break;
1571: case -ENOTSUP:
1.1.1.12 root 1572: error_report("This image format does not support resize");
1.1.1.11 root 1573: break;
1574: case -EACCES:
1.1.1.12 root 1575: error_report("Image is read-only");
1.1.1.11 root 1576: break;
1577: default:
1.1.1.12 root 1578: error_report("Error resizing image (%d)", -ret);
1.1.1.11 root 1579: break;
1580: }
1581: out:
1.1.1.12 root 1582: if (bs) {
1583: bdrv_delete(bs);
1584: }
1.1.1.11 root 1585: if (ret) {
1586: return 1;
1587: }
1.1.1.8 root 1588: return 0;
1.1.1.5 root 1589: }
1590:
1.1.1.8 root 1591: static const img_cmd_t img_cmds[] = {
1592: #define DEF(option, callback, arg_string) \
1593: { option, callback },
1594: #include "qemu-img-cmds.h"
1595: #undef DEF
1596: #undef GEN_DOCS
1597: { NULL, NULL, },
1598: };
1599:
1.1 root 1600: int main(int argc, char **argv)
1601: {
1.1.1.8 root 1602: const img_cmd_t *cmd;
1603: const char *cmdname;
1.1 root 1604:
1.1.1.12 root 1605: error_set_progname(argv[0]);
1606:
1.1 root 1607: bdrv_init();
1608: if (argc < 2)
1609: help();
1.1.1.8 root 1610: cmdname = argv[1];
1.1.1.5 root 1611: argc--; argv++;
1.1.1.8 root 1612:
1613: /* find the command */
1614: for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1615: if (!strcmp(cmdname, cmd->name)) {
1616: return cmd->handler(argc, argv);
1617: }
1.1 root 1618: }
1.1.1.8 root 1619:
1620: /* not found */
1621: help();
1.1 root 1622: return 0;
1623: }
unix.superglobalmegacorp.com