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