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