Revision 926c2d23 qemu-img.c

b/qemu-img.c
23 23
 */
24 24
#include "vl.h"
25 25
#include "block_int.h"
26
#include <assert.h>
26 27

  
27 28
#ifdef _WIN32
28 29
#include <windows.h>
......
101 102
           "Command syntax:\n"
102 103
           "  create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
103 104
           "  commit [-f fmt] filename\n"
104
           "  convert [-c] [-e] [-6] [-f fmt] filename [-O output_fmt] output_filename\n"
105
           "  convert [-c] [-e] [-6] [-f fmt] filename [filename2 [...]] [-O output_fmt] output_filename\n"
105 106
           "  info [-f fmt] filename\n"
106 107
           "\n"
107 108
           "Command parameters:\n"
......
418 419

  
419 420
static int img_convert(int argc, char **argv)
420 421
{
421
    int c, ret, n, n1, flags, cluster_size, cluster_sectors;
422
    const char *filename, *fmt, *out_fmt, *out_filename;
422
    int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
423
    const char *fmt, *out_fmt, *out_filename;
423 424
    BlockDriver *drv;
424
    BlockDriverState *bs, *out_bs;
425
    int64_t total_sectors, nb_sectors, sector_num;
425
    BlockDriverState **bs, *out_bs;
426
    int64_t total_sectors, nb_sectors, sector_num, bs_offset, bs_sectors;
426 427
    uint8_t buf[IO_BUF_SIZE];
427 428
    const uint8_t *buf1;
428 429
    BlockDriverInfo bdi;
......
455 456
            break;
456 457
        }
457 458
    }
458
    if (optind >= argc)
459
        help();
460
    filename = argv[optind++];
461
    if (optind >= argc)
462
        help();
463
    out_filename = argv[optind++];
464 459

  
465
    bs = bdrv_new_open(filename, fmt);
460
    bs_n = argc - optind - 1;
461
    if (bs_n < 1) help();
462

  
463
    out_filename = argv[argc - 1];
464
        
465
    bs = calloc(bs_n, sizeof(BlockDriverState *));
466
    if (!bs)
467
        error("Out of memory");
468

  
469
    total_sectors = 0;
470
    for (bs_i = 0; bs_i < bs_n; bs_i++) {
471
        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
472
        if (!bs[bs_i])
473
            error("Could not open '%s'", argv[optind + bs_i]);
474
        bdrv_get_geometry(bs[bs_i], &bs_sectors);
475
        total_sectors += bs_sectors;
476
    }
466 477

  
467 478
    drv = bdrv_find_format(out_fmt);
468 479
    if (!drv)
......
475 486
        error("Alternative compatibility level not supported for this file format");
476 487
    if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
477 488
        error("Compression and encryption not supported at the same time");
478
    bdrv_get_geometry(bs, &total_sectors);
489

  
479 490
    ret = bdrv_create(drv, out_filename, total_sectors, NULL, flags);
480 491
    if (ret < 0) {
481 492
        if (ret == -ENOTSUP) {
......
487 498

  
488 499
    out_bs = bdrv_new_open(out_filename, out_fmt);
489 500

  
490
    if (flags && BLOCK_FLAG_COMPRESS) {
501
    bs_i = 0;
502
    bs_offset = 0;
503
    bdrv_get_geometry(bs[0], &bs_sectors);
504

  
505
    if (flags & BLOCK_FLAG_COMPRESS) {
491 506
        if (bdrv_get_info(out_bs, &bdi) < 0)
492 507
            error("could not get block driver info");
493 508
        cluster_size = bdi.cluster_size;
......
496 511
        cluster_sectors = cluster_size >> 9;
497 512
        sector_num = 0;
498 513
        for(;;) {
514
            int64_t bs_num;
515
            int remainder;
516
            uint8_t *buf2;
517

  
499 518
            nb_sectors = total_sectors - sector_num;
500 519
            if (nb_sectors <= 0)
501 520
                break;
......
503 522
                n = cluster_sectors;
504 523
            else
505 524
                n = nb_sectors;
506
            if (bdrv_read(bs, sector_num, buf, n) < 0)
507
                error("error while reading");
525

  
526
            bs_num = sector_num - bs_offset;
527
            assert (bs_num >= 0);
528
            remainder = n;
529
            buf2 = buf;
530
            while (remainder > 0) {
531
                int nlow;
532
                while (bs_num == bs_sectors) {
533
                    bs_i++;
534
                    assert (bs_i < bs_n);
535
                    bs_offset += bs_sectors;
536
                    bdrv_get_geometry(bs[bs_i], &bs_sectors);
537
                    bs_num = 0;
538
                    /* printf("changing part: sector_num=%lld, "
539
                       "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
540
                       sector_num, bs_i, bs_offset, bs_sectors); */
541
                }
542
                assert (bs_num < bs_sectors);
543

  
544
                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
545

  
546
                if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0) 
547
                    error("error while reading");
548

  
549
                buf2 += nlow * 512;
550
                bs_num += nlow;
551

  
552
                remainder -= nlow;
553
            }
554
            assert (remainder == 0);
555

  
508 556
            if (n < cluster_sectors)
509 557
                memset(buf + n * 512, 0, cluster_size - n * 512);
510 558
            if (is_not_zero(buf, cluster_size)) {
......
527 575
                n = (IO_BUF_SIZE / 512);
528 576
            else
529 577
                n = nb_sectors;
530
            if (bdrv_read(bs, sector_num, buf, n) < 0)
578

  
579
            while (sector_num - bs_offset >= bs_sectors) {
580
                bs_i ++;
581
                assert (bs_i < bs_n);
582
                bs_offset += bs_sectors;
583
                bdrv_get_geometry(bs[bs_i], &bs_sectors);
584
                /* printf("changing part: sector_num=%lld, bs_i=%d, "
585
                  "bs_offset=%lld, bs_sectors=%lld\n",
586
                   sector_num, bs_i, bs_offset, bs_sectors); */
587
            }
588

  
589
            if (n > bs_offset + bs_sectors - sector_num)
590
                n = bs_offset + bs_sectors - sector_num;
591

  
592
            if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) 
531 593
                error("error while reading");
532 594
            /* NOTE: at the same time we convert, we do not write zero
533 595
               sectors to have a chance to compress the image. Ideally, we
......
545 607
        }
546 608
    }
547 609
    bdrv_delete(out_bs);
548
    bdrv_delete(bs);
610
    for (bs_i = 0; bs_i < bs_n; bs_i++)
611
        bdrv_delete(bs[bs_i]);
612
    free(bs);
549 613
    return 0;
550 614
}
551 615

  

Also available in: Unified diff