Commit 6f176b48 authored by Max Reitz's avatar Max Reitz Committed by Kevin Wolf
Browse files

block: Image file option amendment



This patch adds the "amend" option to qemu-img which allows changing
image options on existing image files. It also adds the generic bdrv
implementation which is basically just a wrapper for the image format
specific function.

Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 56e023af
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -4579,3 +4579,11 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
{
    notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
}

int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options)
{
    if (bs->drv->bdrv_amend_options == NULL) {
        return -ENOTSUP;
    }
    return bs->drv->bdrv_amend_options(bs, options);
}
+2 −0
Original line number Diff line number Diff line
@@ -241,6 +241,8 @@ typedef enum {

int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);

int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options);

/* async block I/O */
typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
                                     int sector_num);
+3 −0
Original line number Diff line number Diff line
@@ -188,6 +188,9 @@ struct BlockDriver {
    int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result,
        BdrvCheckMode fix);

    int (*bdrv_amend_options)(BlockDriverState *bs,
        QEMUOptionParameter *options);

    void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);

    /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
+6 −0
Original line number Diff line number Diff line
@@ -67,5 +67,11 @@ DEF("resize", img_resize,
    "resize [-q] filename [+ | -]size")
STEXI
@item resize [-q] @var{filename} [+ | -]@var{size}
ETEXI

DEF("amend", img_amend,
    "amend [-q] [-f fmt] -o options filename")
STEXI
@item amend [-q] [-f @var{fmt}] -o @var{options} @var{filename}
@end table
ETEXI
+84 −0
Original line number Diff line number Diff line
@@ -2525,6 +2525,90 @@ out:
    return 0;
}

static int img_amend(int argc, char **argv)
{
    int c, ret = 0;
    char *options = NULL;
    QEMUOptionParameter *create_options = NULL, *options_param = NULL;
    const char *fmt = NULL, *filename;
    bool quiet = false;
    BlockDriverState *bs = NULL;

    for (;;) {
        c = getopt(argc, argv, "hqf:o:");
        if (c == -1) {
            break;
        }

        switch (c) {
            case 'h':
            case '?':
                help();
                break;
            case 'o':
                options = optarg;
                break;
            case 'f':
                fmt = optarg;
                break;
            case 'q':
                quiet = true;
                break;
        }
    }

    if (optind != argc - 1) {
        help();
    }

    if (!options) {
        help();
    }

    filename = argv[argc - 1];

    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
    if (!bs) {
        error_report("Could not open image '%s'", filename);
        ret = -1;
        goto out;
    }

    fmt = bs->drv->format_name;

    if (is_help_option(options)) {
        ret = print_block_option_help(filename, fmt);
        goto out;
    }

    create_options = append_option_parameters(create_options,
            bs->drv->create_options);
    options_param = parse_option_parameters(options, create_options,
            options_param);
    if (options_param == NULL) {
        error_report("Invalid options for file format '%s'", fmt);
        ret = -1;
        goto out;
    }

    ret = bdrv_amend_options(bs, options_param);
    if (ret < 0) {
        error_report("Error while amending options: %s", strerror(-ret));
        goto out;
    }

out:
    if (bs) {
        bdrv_unref(bs);
    }
    free_option_parameters(create_options);
    free_option_parameters(options_param);
    if (ret) {
        return 1;
    }
    return 0;
}

static const img_cmd_t img_cmds[] = {
#define DEF(option, callback, arg_string)        \
    { option, callback },
Loading