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