Browse Source

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: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Max Reitz 12 years ago
parent
commit
6f176b48f9
6 changed files with 108 additions and 0 deletions
  1. 8 0
      block.c
  2. 2 0
      include/block/block.h
  3. 3 0
      include/block/block_int.h
  4. 6 0
      qemu-img-cmds.hx
  5. 84 0
      qemu-img.c
  6. 5 0
      qemu-img.texi

+ 8 - 0
block.c

@@ -4579,3 +4579,11 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
 {
 {
     notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
     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
include/block/block.h

@@ -241,6 +241,8 @@ typedef enum {
 
 
 int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
 int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
 
 
+int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options);
+
 /* async block I/O */
 /* async block I/O */
 typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
 typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
                                      int sector_num);
                                      int sector_num);

+ 3 - 0
include/block/block_int.h

@@ -188,6 +188,9 @@ struct BlockDriver {
     int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result,
     int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result,
         BdrvCheckMode fix);
         BdrvCheckMode fix);
 
 
+    int (*bdrv_amend_options)(BlockDriverState *bs,
+        QEMUOptionParameter *options);
+
     void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
     void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
 
 
     /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
     /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */

+ 6 - 0
qemu-img-cmds.hx

@@ -67,5 +67,11 @@ DEF("resize", img_resize,
     "resize [-q] filename [+ | -]size")
     "resize [-q] filename [+ | -]size")
 STEXI
 STEXI
 @item resize [-q] @var{filename} [+ | -]@var{size}
 @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
 @end table
 ETEXI
 ETEXI

+ 84 - 0
qemu-img.c

@@ -2525,6 +2525,90 @@ out:
     return 0;
     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[] = {
 static const img_cmd_t img_cmds[] = {
 #define DEF(option, callback, arg_string)        \
 #define DEF(option, callback, arg_string)        \
     { option, callback },
     { option, callback },

+ 5 - 0
qemu-img.texi

@@ -350,6 +350,11 @@ sizes accordingly.  Failure to do so will result in data loss!
 After using this command to grow a disk image, you must use file system and
 After using this command to grow a disk image, you must use file system and
 partitioning tools inside the VM to actually begin using the new space on the
 partitioning tools inside the VM to actually begin using the new space on the
 device.
 device.
+
+@item amend [-f @var{fmt}] -o @var{options} @var{filename}
+
+Amends the image format specific @var{options} for the image file
+@var{filename}. Not all file formats support this operation.
 @end table
 @end table
 @c man end
 @c man end