~vcs-imports/qemu/maemo

« back to all changes in this revision

Viewing changes to qemu-img.c

  • Committer: Riku Voipio
  • Date: 2009-06-08 15:31:58 UTC
  • mfrom: (6281.2.366)
  • mto: This revision was merged to the branch mainline in revision 6452.
  • Revision ID: git-v1:759b334a9739814df2883aa4c41b1c0f5670e90a
Merge commit 'gnu/master' into test

Epic merge

Conflicts:
        Makefile
        block.c
        block.h
        configure
        hw/boards.h
        hw/flash.h
        hw/integratorcp.c
        hw/nand.c
        hw/omap2.c
        hw/omap_i2c.c
        hw/sd.c
        hw/smc91c111.c
        hw/tsc2005.c
        hw/tusb6010.c
        hw/usb-musb.c
        linux-user/syscall.c
        target-arm/machine.c
        target-arm/translate.c

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 * THE SOFTWARE.
23
23
 */
24
24
#include "qemu-common.h"
 
25
#include "qemu-option.h"
25
26
#include "osdep.h"
26
27
#include "block_int.h"
27
 
#include <assert.h>
28
28
#include <stdio.h>
29
29
 
30
30
#ifdef _WIN32
31
31
#include <windows.h>
32
32
#endif
33
33
 
 
34
typedef struct img_cmd_t {
 
35
    const char *name;
 
36
    int (*handler)(int argc, char **argv);
 
37
} img_cmd_t;
 
38
 
34
39
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
35
40
#define BRDV_O_FLAGS BDRV_O_CACHE_WB
36
41
 
58
63
           "QEMU disk image utility\n"
59
64
           "\n"
60
65
           "Command syntax:\n"
61
 
           "  check [-f fmt] filename\n"
62
 
           "  create [-e] [-6] [-F fmt] [-b base_image] [-f fmt] filename [size]\n"
63
 
           "  commit [-f fmt] filename\n"
64
 
           "  convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
65
 
           "  info [-f fmt] filename\n"
66
 
           "  snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename\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
67
71
           "\n"
68
72
           "Command parameters:\n"
69
73
           "  'filename' is a disk image filename\n"
79
83
           "    supported any 'k' or 'K' is ignored\n"
80
84
           "  'output_filename' is the destination disk image filename\n"
81
85
           "  'output_fmt' is the destination format\n"
 
86
           "  'options' is a comma separated list of format specific options in a\n"
 
87
           "    name=value format. Use -o ? for an overview of the options supported by the\n"
 
88
           "    used format\n"
82
89
           "  '-c' indicates that target image must be compressed (qcow format only)\n"
83
 
           "  '-e' indicates that the target image must be encrypted (qcow format only)\n"
84
 
           "  '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
85
90
           "  '-h' with or without a command shows this help and lists the supported formats\n"
86
91
           "\n"
87
92
           "Parameters to snapshot subcommand:\n"
215
220
    return bs;
216
221
}
217
222
 
 
223
static void add_old_style_options(const char *fmt, QEMUOptionParameter *list,
 
224
    int flags, const char *base_filename, const char *base_fmt)
 
225
{
 
226
    if (flags & BLOCK_FLAG_ENCRYPT) {
 
227
        if (set_option_parameter(list, BLOCK_OPT_ENCRYPT, "on")) {
 
228
            error("Encryption not supported for file format '%s'", fmt);
 
229
        }
 
230
    }
 
231
    if (flags & BLOCK_FLAG_COMPAT6) {
 
232
        if (set_option_parameter(list, BLOCK_OPT_COMPAT6, "on")) {
 
233
            error("VMDK version 6 not supported for file format '%s'", fmt);
 
234
        }
 
235
    }
 
236
 
 
237
    if (base_filename) {
 
238
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
 
239
            error("Backing file not supported for file format '%s'", fmt);
 
240
        }
 
241
    }
 
242
    if (base_fmt) {
 
243
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
 
244
            error("Backing file format not supported for file format '%s'", fmt);
 
245
        }
 
246
    }
 
247
}
 
248
 
218
249
static int img_create(int argc, char **argv)
219
250
{
220
251
    int c, ret, flags;
222
253
    const char *base_fmt = NULL;
223
254
    const char *filename;
224
255
    const char *base_filename = NULL;
225
 
    uint64_t size;
226
 
    double sizef;
227
 
    const char *p;
228
256
    BlockDriver *drv;
 
257
    QEMUOptionParameter *param = NULL;
 
258
    char *options = NULL;
229
259
 
230
260
    flags = 0;
231
261
    for(;;) {
232
 
        c = getopt(argc, argv, "F:b:f:he6");
 
262
        c = getopt(argc, argv, "F:b:f:he6o:");
233
263
        if (c == -1)
234
264
            break;
235
265
        switch(c) {
251
281
        case '6':
252
282
            flags |= BLOCK_FLAG_COMPAT6;
253
283
            break;
254
 
        }
255
 
    }
256
 
    if (optind >= argc)
257
 
        help();
258
 
    filename = argv[optind++];
259
 
    size = 0;
260
 
    if (base_filename) {
261
 
        BlockDriverState *bs;
262
 
        BlockDriver *base_drv = NULL;
263
 
 
264
 
        if (base_fmt) {
265
 
            base_drv = bdrv_find_format(base_fmt);
266
 
            if (base_drv == NULL)
267
 
                error("Unknown basefile format '%s'", base_fmt);
268
 
        }
269
 
 
270
 
        bs = bdrv_new_open(base_filename, base_fmt);
271
 
        bdrv_get_geometry(bs, &size);
272
 
        size *= 512;
273
 
        bdrv_delete(bs);
274
 
    } else {
275
 
        if (optind >= argc)
276
 
            help();
277
 
        p = argv[optind];
278
 
        sizef = strtod(p, (char **)&p);
279
 
        if (*p == 'M') {
280
 
            size = (uint64_t)(sizef * 1024 * 1024);
281
 
        } else if (*p == 'G') {
282
 
            size = (uint64_t)(sizef * 1024 * 1024 * 1024);
283
 
        } else if (*p == 'k' || *p == 'K' || *p == '\0') {
284
 
            size = (uint64_t)(sizef * 1024);
285
 
        } else {
286
 
            help();
287
 
        }
288
 
    }
 
284
        case 'o':
 
285
            options = optarg;
 
286
            break;
 
287
        }
 
288
    }
 
289
 
 
290
    /* Find driver and parse its options */
289
291
    drv = bdrv_find_format(fmt);
290
292
    if (!drv)
291
293
        error("Unknown file format '%s'", fmt);
292
 
    printf("Formatting '%s', fmt=%s",
293
 
           filename, fmt);
294
 
    if (flags & BLOCK_FLAG_ENCRYPT)
295
 
        printf(", encrypted");
296
 
    if (flags & BLOCK_FLAG_COMPAT6)
297
 
        printf(", compatibility level=6");
298
 
    if (base_filename) {
299
 
        printf(", backing_file=%s",
300
 
               base_filename);
301
 
         if (base_fmt)
302
 
             printf(", backing_fmt=%s",
303
 
                    base_fmt);
304
 
    }
305
 
    printf(", size=%" PRIu64 " kB\n", size / 1024);
306
 
    ret = bdrv_create2(drv, filename, size / 512, base_filename, base_fmt, flags);
 
294
 
 
295
    if (options && !strcmp(options, "?")) {
 
296
        print_option_help(drv->create_options);
 
297
        return 0;
 
298
    }
 
299
 
 
300
    if (options) {
 
301
        param = parse_option_parameters(options, drv->create_options, param);
 
302
        if (param == NULL) {
 
303
            error("Invalid options for file format '%s'.", fmt);
 
304
        }
 
305
    } else {
 
306
        param = parse_option_parameters("", drv->create_options, param);
 
307
    }
 
308
 
 
309
    /* Get the filename */
 
310
    if (optind >= argc)
 
311
        help();
 
312
    filename = argv[optind++];
 
313
 
 
314
    /* Add size to parameters */
 
315
    if (optind < argc) {
 
316
        set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);
 
317
    }
 
318
 
 
319
    /* Add old-style options to parameters */
 
320
    add_old_style_options(fmt, param, flags, base_filename, base_fmt);
 
321
 
 
322
    // The size for the image must always be specified, with one exception:
 
323
    // If we are using a backing file, we can obtain the size from there
 
324
    if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == 0) {
 
325
 
 
326
        QEMUOptionParameter *backing_file =
 
327
            get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
 
328
        QEMUOptionParameter *backing_fmt =
 
329
            get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
 
330
 
 
331
        if (backing_file && backing_file->value.s) {
 
332
            BlockDriverState *bs;
 
333
            uint64_t size;
 
334
            const char *fmt = NULL;
 
335
            char buf[32];
 
336
 
 
337
            if (backing_fmt && backing_fmt->value.s) {
 
338
                 if (bdrv_find_format(backing_fmt->value.s)) {
 
339
                     fmt = backing_fmt->value.s;
 
340
                } else {
 
341
                     error("Unknown backing file format '%s'",
 
342
                        backing_fmt->value.s);
 
343
                }
 
344
            }
 
345
 
 
346
            bs = bdrv_new_open(backing_file->value.s, fmt);
 
347
            bdrv_get_geometry(bs, &size);
 
348
            size *= 512;
 
349
            bdrv_delete(bs);
 
350
 
 
351
            snprintf(buf, sizeof(buf), "%" PRId64, size);
 
352
            set_option_parameter(param, BLOCK_OPT_SIZE, buf);
 
353
        } else {
 
354
            error("Image creation needs a size parameter");
 
355
        }
 
356
    }
 
357
 
 
358
    printf("Formatting '%s', fmt=%s ", filename, fmt);
 
359
    print_option_parameters(param);
 
360
    puts("");
 
361
 
 
362
    ret = bdrv_create(drv, filename, param);
 
363
    free_option_parameters(param);
 
364
 
307
365
    if (ret < 0) {
308
366
        if (ret == -ENOTSUP) {
309
367
            error("Formatting or formatting option not supported for file format '%s'", fmt);
485
543
    uint8_t buf[IO_BUF_SIZE];
486
544
    const uint8_t *buf1;
487
545
    BlockDriverInfo bdi;
 
546
    QEMUOptionParameter *param = NULL;
 
547
    char *options = NULL;
488
548
 
489
549
    fmt = NULL;
490
550
    out_fmt = "raw";
491
551
    out_baseimg = NULL;
492
552
    flags = 0;
493
553
    for(;;) {
494
 
        c = getopt(argc, argv, "f:O:B:hce6");
 
554
        c = getopt(argc, argv, "f:O:B:hce6o:");
495
555
        if (c == -1)
496
556
            break;
497
557
        switch(c) {
516
576
        case '6':
517
577
            flags |= BLOCK_FLAG_COMPAT6;
518
578
            break;
 
579
        case 'o':
 
580
            options = optarg;
 
581
            break;
519
582
        }
520
583
    }
521
584
 
540
603
        total_sectors += bs_sectors;
541
604
    }
542
605
 
 
606
    /* Find driver and parse its options */
543
607
    drv = bdrv_find_format(out_fmt);
544
608
    if (!drv)
545
609
        error("Unknown file format '%s'", out_fmt);
546
 
    if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
547
 
        error("Compression not supported for this file format");
548
 
    if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
549
 
        error("Encryption not supported for this file format");
550
 
    if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
551
 
        error("Alternative compatibility level not supported for this file format");
552
 
    if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
553
 
        error("Compression and encryption not supported at the same time");
554
 
 
555
 
    ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
 
610
 
 
611
    if (options && !strcmp(options, "?")) {
 
612
        print_option_help(drv->create_options);
 
613
        return 0;
 
614
    }
 
615
 
 
616
    if (options) {
 
617
        param = parse_option_parameters(options, drv->create_options, param);
 
618
        if (param == NULL) {
 
619
            error("Invalid options for file format '%s'.", out_fmt);
 
620
        }
 
621
    } else {
 
622
        param = parse_option_parameters("", drv->create_options, param);
 
623
    }
 
624
 
 
625
    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
 
626
    add_old_style_options(out_fmt, param, flags, out_baseimg, NULL);
 
627
 
 
628
    /* Check if compression is supported */
 
629
    if (flags & BLOCK_FLAG_COMPRESS) {
 
630
        QEMUOptionParameter *encryption =
 
631
            get_option_parameter(param, BLOCK_OPT_ENCRYPT);
 
632
 
 
633
        if (!drv->bdrv_write_compressed) {
 
634
            error("Compression not supported for this file format");
 
635
        }
 
636
 
 
637
        if (encryption && encryption->value.n) {
 
638
            error("Compression and encryption not supported at the same time");
 
639
        }
 
640
    }
 
641
 
 
642
    /* Create the new image */
 
643
    ret = bdrv_create(drv, out_filename, param);
 
644
    free_option_parameters(param);
 
645
 
556
646
    if (ret < 0) {
557
647
        if (ret == -ENOTSUP) {
558
648
            error("Formatting not supported for file format '%s'", out_fmt);
656
746
            if (n > bs_offset + bs_sectors - sector_num)
657
747
                n = bs_offset + bs_sectors - sector_num;
658
748
 
659
 
            if (drv != &bdrv_host_device) {
 
749
            if (strcmp(drv->format_name, "host_device")) {
660
750
                if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
661
751
                                       n, &n1)) {
662
752
                    sector_num += n1;
683
773
                   If the output is to a host device, we also write out
684
774
                   sectors that are entirely 0, since whatever data was
685
775
                   already there is garbage, not 0s. */
686
 
                if (drv == &bdrv_host_device || out_baseimg ||
 
776
                if (strcmp(drv->format_name, "host_device") == 0 || out_baseimg ||
687
777
                    is_allocated_sectors(buf1, n, &n1)) {
688
778
                    if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
689
779
                        error("error while writing");
833
923
#define SNAPSHOT_APPLY  3
834
924
#define SNAPSHOT_DELETE 4
835
925
 
836
 
static void img_snapshot(int argc, char **argv)
 
926
static int img_snapshot(int argc, char **argv)
837
927
{
838
928
    BlockDriverState *bs;
839
929
    QEMUSnapshotInfo sn;
850
940
        switch(c) {
851
941
        case 'h':
852
942
            help();
853
 
            return;
 
943
            return 0;
854
944
        case 'l':
855
945
            if (action) {
856
946
                help();
857
 
                return;
 
947
                return 0;
858
948
            }
859
949
            action = SNAPSHOT_LIST;
860
950
            break;
861
951
        case 'a':
862
952
            if (action) {
863
953
                help();
864
 
                return;
 
954
                return 0;
865
955
            }
866
956
            action = SNAPSHOT_APPLY;
867
957
            snapshot_name = optarg;
869
959
        case 'c':
870
960
            if (action) {
871
961
                help();
872
 
                return;
 
962
                return 0;
873
963
            }
874
964
            action = SNAPSHOT_CREATE;
875
965
            snapshot_name = optarg;
877
967
        case 'd':
878
968
            if (action) {
879
969
                help();
880
 
                return;
 
970
                return 0;
881
971
            }
882
972
            action = SNAPSHOT_DELETE;
883
973
            snapshot_name = optarg;
935
1025
 
936
1026
    /* Cleanup */
937
1027
    bdrv_delete(bs);
 
1028
 
 
1029
    return 0;
938
1030
}
939
1031
 
 
1032
static const img_cmd_t img_cmds[] = {
 
1033
#define DEF(option, callback, arg_string)        \
 
1034
    { option, callback },
 
1035
#include "qemu-img-cmds.h"
 
1036
#undef DEF
 
1037
#undef GEN_DOCS
 
1038
    { NULL, NULL, },
 
1039
};
 
1040
 
940
1041
int main(int argc, char **argv)
941
1042
{
942
 
    const char *cmd;
 
1043
    const img_cmd_t *cmd;
 
1044
    const char *cmdname;
943
1045
 
944
1046
    bdrv_init();
945
1047
    if (argc < 2)
946
1048
        help();
947
 
    cmd = argv[1];
 
1049
    cmdname = argv[1];
948
1050
    argc--; argv++;
949
 
    if (!strcmp(cmd, "create")) {
950
 
        img_create(argc, argv);
951
 
    } else if (!strcmp(cmd, "check")) {
952
 
        img_check(argc, argv);
953
 
    } else if (!strcmp(cmd, "commit")) {
954
 
        img_commit(argc, argv);
955
 
    } else if (!strcmp(cmd, "convert")) {
956
 
        img_convert(argc, argv);
957
 
    } else if (!strcmp(cmd, "info")) {
958
 
        img_info(argc, argv);
959
 
    } else if (!strcmp(cmd, "snapshot")) {
960
 
        img_snapshot(argc, argv);
961
 
    } else {
962
 
        help();
 
1051
 
 
1052
    /* find the command */
 
1053
    for(cmd = img_cmds; cmd->name != NULL; cmd++) {
 
1054
        if (!strcmp(cmdname, cmd->name)) {
 
1055
            return cmd->handler(argc, argv);
 
1056
        }
963
1057
    }
 
1058
 
 
1059
    /* not found */
 
1060
    help();
964
1061
    return 0;
965
1062
}