All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/7] block: Add driver specific options
@ 2013-03-01 20:13 Kevin Wolf
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 1/7] block: Add options QDict to .bdrv_open() Kevin Wolf
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: Kevin Wolf @ 2013-03-01 20:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, armbru, stefanha

Instead of constantly keeping complaining that we need this big -blockdev
things, let's start attacking individual parts of the project. Here is the
first part, allowing block drivers to provide additional -drive options.

Any options that isn't processed by the block layer is passed to the driver
which can use them. If it doesn't, you get an error message like today. At the
end of this series you can specify:

  -drive file=test.qcow2,lazy_refcounts=on

This doesn't include a way to specify options for backing files yet, but
I don't think there's anything blocking such extensions on top.

Kevin Wolf (7):
  block: Add options QDict to .bdrv_open()
  block: Add options QDict to bdrv_open() prototype
  Add qdict_clone_shallow()
  block: Add options QDict to bdrv_open_common()
  qemu-option: Add qemu_opts_absorb_qdict()
  block: Support driver specific options in drive_init()
  qcow2: Allow lazy refcounts to be enabled on the command line

 block.c                   | 81 ++++++++++++++++++++++++++++++++++++-----------
 block/blkverify.c         |  2 +-
 block/bochs.c             |  2 +-
 block/cloop.c             |  2 +-
 block/cow.c               |  2 +-
 block/dmg.c               |  2 +-
 block/parallels.c         |  2 +-
 block/qcow.c              |  2 +-
 block/qcow2-cluster.c     |  2 +-
 block/qcow2.c             | 43 +++++++++++++++++++++++--
 block/qcow2.h             |  1 +
 block/qed.c               |  4 +--
 block/raw.c               |  2 +-
 block/vdi.c               |  2 +-
 block/vmdk.c              |  4 +--
 block/vpc.c               |  2 +-
 block/vvfat.c             |  2 +-
 blockdev.c                | 53 ++++++++++++++++++++++++++-----
 hw/xen_disk.c             |  2 +-
 include/block/block.h     |  4 +--
 include/block/block_int.h |  3 +-
 include/qapi/qmp/qdict.h  |  2 ++
 include/qemu/option.h     |  1 +
 qemu-img.c                |  6 ++--
 qemu-io.c                 |  2 +-
 qemu-nbd.c                |  2 +-
 qobject/qdict.c           | 22 +++++++++++++
 util/qemu-option.c        | 34 ++++++++++++++++++++
 28 files changed, 233 insertions(+), 55 deletions(-)

-- 
1.8.1.2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 1/7] block: Add options QDict to .bdrv_open()
  2013-03-01 20:13 [Qemu-devel] [PATCH 0/7] block: Add driver specific options Kevin Wolf
@ 2013-03-01 20:13 ` Kevin Wolf
  2013-03-01 21:15   ` Eric Blake
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 2/7] block: Add options QDict to bdrv_open() prototype Kevin Wolf
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Kevin Wolf @ 2013-03-01 20:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, armbru, stefanha

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c                   | 4 ++--
 block/bochs.c             | 2 +-
 block/cloop.c             | 2 +-
 block/cow.c               | 2 +-
 block/dmg.c               | 2 +-
 block/parallels.c         | 2 +-
 block/qcow.c              | 2 +-
 block/qcow2.c             | 4 ++--
 block/qed.c               | 4 ++--
 block/raw.c               | 2 +-
 block/vdi.c               | 2 +-
 block/vmdk.c              | 2 +-
 block/vpc.c               | 2 +-
 include/block/block_int.h | 2 +-
 14 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/block.c b/block.c
index 4582961..7f7e28e 100644
--- a/block.c
+++ b/block.c
@@ -710,7 +710,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
     } else {
         assert(file != NULL);
         bs->file = file;
-        ret = drv->bdrv_open(bs, open_flags);
+        ret = drv->bdrv_open(bs, NULL, open_flags);
     }
 
     if (ret < 0) {
@@ -3188,7 +3188,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
     if (bs->file) {
         drv->bdrv_close(bs);
         ret = bdrv_snapshot_goto(bs->file, snapshot_id);
-        open_ret = drv->bdrv_open(bs, bs->open_flags);
+        open_ret = drv->bdrv_open(bs, NULL, bs->open_flags);
         if (open_ret < 0) {
             bdrv_delete(bs->file);
             bs->drv = NULL;
diff --git a/block/bochs.c b/block/bochs.c
index a6eb33d..d7078c0 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -108,7 +108,7 @@ static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
     return 0;
 }
 
-static int bochs_open(BlockDriverState *bs, int flags)
+static int bochs_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVBochsState *s = bs->opaque;
     int i;
diff --git a/block/cloop.c b/block/cloop.c
index 8fe13e9..6ea7cf4 100644
--- a/block/cloop.c
+++ b/block/cloop.c
@@ -53,7 +53,7 @@ static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
     return 0;
 }
 
-static int cloop_open(BlockDriverState *bs, int flags)
+static int cloop_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVCloopState *s = bs->opaque;
     uint32_t offsets_size, max_compressed_block_size = 1, i;
diff --git a/block/cow.c b/block/cow.c
index 4baf904..d73e08c 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -58,7 +58,7 @@ static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
         return 0;
 }
 
-static int cow_open(BlockDriverState *bs, int flags)
+static int cow_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVCowState *s = bs->opaque;
     struct cow_header_v2 cow_header;
diff --git a/block/dmg.c b/block/dmg.c
index 6d85801..c1066df 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -85,7 +85,7 @@ static int read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
     return 0;
 }
 
-static int dmg_open(BlockDriverState *bs, int flags)
+static int dmg_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVDMGState *s = bs->opaque;
     uint64_t info_begin,info_end,last_in_offset,last_out_offset;
diff --git a/block/parallels.c b/block/parallels.c
index 8688f6c..18b3ac0 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -68,7 +68,7 @@ static int parallels_probe(const uint8_t *buf, int buf_size, const char *filenam
     return 0;
 }
 
-static int parallels_open(BlockDriverState *bs, int flags)
+static int parallels_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVParallelsState *s = bs->opaque;
     int i;
diff --git a/block/qcow.c b/block/qcow.c
index a7135ee..f6750a5 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -92,7 +92,7 @@ static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
         return 0;
 }
 
-static int qcow_open(BlockDriverState *bs, int flags)
+static int qcow_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVQcowState *s = bs->opaque;
     int len, i, shift, ret;
diff --git a/block/qcow2.c b/block/qcow2.c
index 7610e56..4c501a5 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -285,7 +285,7 @@ static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
     return ret;
 }
 
-static int qcow2_open(BlockDriverState *bs, int flags)
+static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVQcowState *s = bs->opaque;
     int len, i, ret = 0;
@@ -912,7 +912,7 @@ static void qcow2_invalidate_cache(BlockDriverState *bs)
     qcow2_close(bs);
 
     memset(s, 0, sizeof(BDRVQcowState));
-    qcow2_open(bs, flags);
+    qcow2_open(bs, NULL, flags);
 
     if (crypt_method) {
         s->crypt_method = crypt_method;
diff --git a/block/qed.c b/block/qed.c
index b8515e5..46e12b3 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -373,7 +373,7 @@ static void bdrv_qed_rebind(BlockDriverState *bs)
     s->bs = bs;
 }
 
-static int bdrv_qed_open(BlockDriverState *bs, int flags)
+static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVQEDState *s = bs->opaque;
     QEDHeader le_header;
@@ -1526,7 +1526,7 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs)
 
     bdrv_qed_close(bs);
     memset(s, 0, sizeof(BDRVQEDState));
-    bdrv_qed_open(bs, bs->open_flags);
+    bdrv_qed_open(bs, NULL, bs->open_flags);
 }
 
 static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
diff --git a/block/raw.c b/block/raw.c
index 75812db..ce10422 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -3,7 +3,7 @@
 #include "block/block_int.h"
 #include "qemu/module.h"
 
-static int raw_open(BlockDriverState *bs, int flags)
+static int raw_open(BlockDriverState *bs, QDict *options, int flags)
 {
     bs->sg = bs->file->sg;
     return 0;
diff --git a/block/vdi.c b/block/vdi.c
index 87c691b..2662d89 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -364,7 +364,7 @@ static int vdi_probe(const uint8_t *buf, int buf_size, const char *filename)
     return result;
 }
 
-static int vdi_open(BlockDriverState *bs, int flags)
+static int vdi_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVVdiState *s = bs->opaque;
     VdiHeader header;
diff --git a/block/vmdk.c b/block/vmdk.c
index aef1abc..4a13fa6 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -723,7 +723,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
     return vmdk_parse_extents(buf, bs, bs->file->filename);
 }
 
-static int vmdk_open(BlockDriverState *bs, int flags)
+static int vmdk_open(BlockDriverState *bs, QDict *options, int flags)
 {
     int ret;
     BDRVVmdkState *s = bs->opaque;
diff --git a/block/vpc.c b/block/vpc.c
index 82229ef..3cad52e 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -155,7 +155,7 @@ static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
     return 0;
 }
 
-static int vpc_open(BlockDriverState *bs, int flags)
+static int vpc_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVVPCState *s = bs->opaque;
     int i;
diff --git a/include/block/block_int.h b/include/block/block_int.h
index eaad53e..4b659fa 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -82,7 +82,7 @@ struct BlockDriver {
     void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
     void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
 
-    int (*bdrv_open)(BlockDriverState *bs, int flags);
+    int (*bdrv_open)(BlockDriverState *bs, QDict *options, int flags);
     int (*bdrv_file_open)(BlockDriverState *bs, const char *filename, int flags);
     int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
                      uint8_t *buf, int nb_sectors);
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 2/7] block: Add options QDict to bdrv_open() prototype
  2013-03-01 20:13 [Qemu-devel] [PATCH 0/7] block: Add driver specific options Kevin Wolf
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 1/7] block: Add options QDict to .bdrv_open() Kevin Wolf
@ 2013-03-01 20:13 ` Kevin Wolf
  2013-03-01 21:53   ` Eric Blake
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 3/7] Add qdict_clone_shallow() Kevin Wolf
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Kevin Wolf @ 2013-03-01 20:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, armbru, stefanha

It doesn't do anything yet except storing the options QDict in the
BlockDriverState.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c                   | 47 +++++++++++++++++++++++++++++++++++------------
 block/blkverify.c         |  2 +-
 block/qcow2.c             |  2 +-
 block/vmdk.c              |  2 +-
 block/vvfat.c             |  2 +-
 blockdev.c                | 10 ++++++----
 hw/xen_disk.c             |  2 +-
 include/block/block.h     |  4 ++--
 include/block/block_int.h |  1 +
 qemu-img.c                |  6 +++---
 qemu-io.c                 |  2 +-
 qemu-nbd.c                |  2 +-
 12 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/block.c b/block.c
index 7f7e28e..bf93dd1 100644
--- a/block.c
+++ b/block.c
@@ -788,7 +788,8 @@ int bdrv_open_backing_file(BlockDriverState *bs)
     /* backing files always opened read-only */
     back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT);
 
-    ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
+    ret = bdrv_open(bs->backing_hd, backing_filename, NULL,
+                    back_flags, back_drv);
     if (ret < 0) {
         bdrv_delete(bs->backing_hd);
         bs->backing_hd = NULL;
@@ -800,15 +801,28 @@ int bdrv_open_backing_file(BlockDriverState *bs)
 
 /*
  * Opens a disk image (raw, qcow2, vmdk, ...)
+ *
+ * options is a QDict of options to pass to the block drivers, or NULL for an
+ * empty set of options. The reference to the QDict belongs to the block layer
+ * after the call (even on failure), so if the caller intends to reuse the
+ * dictionary, it needs to use QINCREF() before calling bdrv_open.
  */
-int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
-              BlockDriver *drv)
+int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
+              int flags, BlockDriver *drv)
 {
     int ret;
     /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
     char tmp_filename[PATH_MAX + 1];
     BlockDriverState *file = NULL;
 
+    /* NULL means an empty set of options */
+    if (options == NULL) {
+        options = qdict_new();
+    }
+
+    bs->options = options;
+
+    /* For snapshot=on, create a temporary qcow2 overlay */
     if (flags & BDRV_O_SNAPSHOT) {
         BlockDriverState *bs1;
         int64_t total_size;
@@ -822,10 +836,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
 
         /* if there is a backing file, use it */
         bs1 = bdrv_new("");
-        ret = bdrv_open(bs1, filename, 0, drv);
+        ret = bdrv_open(bs1, filename, NULL, 0, drv);
         if (ret < 0) {
             bdrv_delete(bs1);
-            return ret;
+            goto fail;
         }
         total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
 
@@ -836,15 +850,17 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
 
         ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
         if (ret < 0) {
-            return ret;
+            goto fail;
         }
 
         /* Real path is meaningless for protocols */
-        if (is_protocol)
+        if (is_protocol) {
             snprintf(backing_filename, sizeof(backing_filename),
                      "%s", filename);
-        else if (!realpath(filename, backing_filename))
-            return -errno;
+        } else if (!realpath(filename, backing_filename)) {
+            ret = -errno;
+            goto fail;
+        }
 
         bdrv_qcow2 = bdrv_find_format("qcow2");
         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
@@ -859,7 +875,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
         free_option_parameters(options);
         if (ret < 0) {
-            return ret;
+            goto fail;
         }
 
         filename = tmp_filename;
@@ -874,7 +890,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
 
     ret = bdrv_file_open(&file, filename, bdrv_open_flags(bs, flags));
     if (ret < 0) {
-        return ret;
+        goto fail;
     }
 
     /* Find the right image format driver */
@@ -924,6 +940,10 @@ unlink_and_fail:
     if (bs->is_temporary) {
         unlink(filename);
     }
+fail:
+    QDECREF(bs->options);
+    bs->options = NULL;
+
     return ret;
 }
 
@@ -1193,6 +1213,8 @@ void bdrv_close(BlockDriverState *bs)
         bs->valid_key = 0;
         bs->sg = 0;
         bs->growable = 0;
+        QDECREF(bs->options);
+        bs->options = NULL;
 
         if (bs->file != NULL) {
             bdrv_delete(bs->file);
@@ -4592,7 +4614,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
 
             bs = bdrv_new("");
 
-            ret = bdrv_open(bs, backing_file->value.s, back_flags, backing_drv);
+            ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
+                            backing_drv);
             if (ret < 0) {
                 error_setg_errno(errp, -ret, "Could not open '%s'",
                                  backing_file->value.s);
diff --git a/block/blkverify.c b/block/blkverify.c
index a7dd459..2086d97 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -98,7 +98,7 @@ static int blkverify_open(BlockDriverState *bs, const char *filename, int flags)
 
     /* Open the test file */
     s->test_file = bdrv_new("");
-    ret = bdrv_open(s->test_file, filename, flags, NULL);
+    ret = bdrv_open(s->test_file, filename, NULL, flags, NULL);
     if (ret < 0) {
         bdrv_delete(s->test_file);
         s->test_file = NULL;
diff --git a/block/qcow2.c b/block/qcow2.c
index 4c501a5..f5e4269 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1265,7 +1265,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
      */
     BlockDriver* drv = bdrv_find_format("qcow2");
     assert(drv != NULL);
-    ret = bdrv_open(bs, filename,
+    ret = bdrv_open(bs, filename, NULL,
         BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv);
     if (ret < 0) {
         goto out;
diff --git a/block/vmdk.c b/block/vmdk.c
index 4a13fa6..e92104a 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1527,7 +1527,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
     if (backing_file) {
         char parent_filename[PATH_MAX];
         BlockDriverState *bs = bdrv_new("");
-        ret = bdrv_open(bs, backing_file, 0, NULL);
+        ret = bdrv_open(bs, backing_file, NULL, 0, NULL);
         if (ret != 0) {
             bdrv_delete(bs);
             return ret;
diff --git a/block/vvfat.c b/block/vvfat.c
index 06e6654..b8eb38a 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2830,7 +2830,7 @@ static int enable_write_target(BDRVVVFATState *s)
         return -1;
     }
 
-    ret = bdrv_open(s->qcow, s->qcow_filename,
+    ret = bdrv_open(s->qcow, s->qcow_filename, NULL,
             BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow);
     if (ret < 0) {
 	return ret;
diff --git a/blockdev.c b/blockdev.c
index 0e67d06..d679174 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -635,7 +635,7 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
         error_report("warning: disabling copy_on_read on readonly drive");
     }
 
-    ret = bdrv_open(dinfo->bdrv, file, bdrv_flags, drv);
+    ret = bdrv_open(dinfo->bdrv, file, NULL, bdrv_flags, drv);
     if (ret < 0) {
         if (ret == -EMEDIUMTYPE) {
             error_report("could not open disk image %s: not in %s format",
@@ -820,7 +820,9 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
 
         /* We will manually add the backing_hd field to the bs later */
         states->new_bs = bdrv_new("");
-        ret = bdrv_open(states->new_bs, new_image_file,
+        /* TODO Inherit bs->options or only take explicit options with an
+         * extended QMP command? */
+        ret = bdrv_open(states->new_bs, new_image_file, NULL,
                         flags | BDRV_O_NO_BACKING, drv);
         if (ret != 0) {
             error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);
@@ -921,7 +923,7 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
                                     int bdrv_flags, BlockDriver *drv,
                                     const char *password, Error **errp)
 {
-    if (bdrv_open(bs, filename, bdrv_flags, drv) < 0) {
+    if (bdrv_open(bs, filename, NULL, bdrv_flags, drv) < 0) {
         error_set(errp, QERR_OPEN_FILE_FAILED, filename);
         return;
     }
@@ -1330,7 +1332,7 @@ void qmp_drive_mirror(const char *device, const char *target,
      * file.
      */
     target_bs = bdrv_new("");
-    ret = bdrv_open(target_bs, target, flags | BDRV_O_NO_BACKING, drv);
+    ret = bdrv_open(target_bs, target, NULL, flags | BDRV_O_NO_BACKING, drv);
 
     if (ret < 0) {
         bdrv_delete(target_bs);
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 7fea871..171d873 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -763,7 +763,7 @@ static int blk_init(struct XenDevice *xendev)
         xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
         blkdev->bs = bdrv_new(blkdev->dev);
         if (blkdev->bs) {
-            if (bdrv_open(blkdev->bs, blkdev->filename, qflags,
+            if (bdrv_open(blkdev->bs, blkdev->filename, NULL, qflags,
                         bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) {
                 bdrv_delete(blkdev->bs);
                 blkdev->bs = NULL;
diff --git a/include/block/block.h b/include/block/block.h
index 0f750d7..d4f34d6 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -137,8 +137,8 @@ int bdrv_parse_cache_flags(const char *mode, int *flags);
 int bdrv_parse_discard_flags(const char *mode, int *flags);
 int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
 int bdrv_open_backing_file(BlockDriverState *bs);
-int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
-              BlockDriver *drv);
+int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
+              int flags, BlockDriver *drv);
 BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
                                     BlockDriverState *bs, int flags);
 int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 4b659fa..baf80e3 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -286,6 +286,7 @@ struct BlockDriverState {
     /* long-running background operation */
     BlockJob *job;
 
+    QDict *options;
 };
 
 int get_tmp_filename(char *filename, int size);
diff --git a/qemu-img.c b/qemu-img.c
index 471de7d..31627b0 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -276,7 +276,7 @@ static BlockDriverState *bdrv_new_open(const char *filename,
         drv = NULL;
     }
 
-    ret = bdrv_open(bs, filename, flags, drv);
+    ret = bdrv_open(bs, filename, NULL, flags, drv);
     if (ret < 0) {
         error_report("Could not open '%s': %s", filename, strerror(-ret));
         goto fail;
@@ -2156,7 +2156,7 @@ static int img_rebase(int argc, char **argv)
 
         bs_old_backing = bdrv_new("old_backing");
         bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
-        ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
+        ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS,
                         old_backing_drv);
         if (ret) {
             error_report("Could not open old backing file '%s'", backing_name);
@@ -2164,7 +2164,7 @@ static int img_rebase(int argc, char **argv)
         }
         if (out_baseimg[0]) {
             bs_new_backing = bdrv_new("new_backing");
-            ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
+            ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS,
                         new_backing_drv);
             if (ret) {
                 error_report("Could not open new backing file '%s'",
diff --git a/qemu-io.c b/qemu-io.c
index 7b3de42..79be516 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1773,7 +1773,7 @@ static int openfile(char *name, int flags, int growable)
     } else {
         bs = bdrv_new("hda");
 
-        if (bdrv_open(bs, name, flags, NULL) < 0) {
+        if (bdrv_open(bs, name, NULL, flags, NULL) < 0) {
             fprintf(stderr, "%s: can't open device %s\n", progname, name);
             bdrv_delete(bs);
             bs = NULL;
diff --git a/qemu-nbd.c b/qemu-nbd.c
index e7268d0..ca722ed 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -557,7 +557,7 @@ int main(int argc, char **argv)
 
     bs = bdrv_new("hda");
     srcpath = argv[optind];
-    if ((ret = bdrv_open(bs, srcpath, flags, NULL)) < 0) {
+    if ((ret = bdrv_open(bs, srcpath, NULL, flags, NULL)) < 0) {
         errno = -ret;
         err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
     }
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 3/7] Add qdict_clone_shallow()
  2013-03-01 20:13 [Qemu-devel] [PATCH 0/7] block: Add driver specific options Kevin Wolf
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 1/7] block: Add options QDict to .bdrv_open() Kevin Wolf
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 2/7] block: Add options QDict to bdrv_open() prototype Kevin Wolf
@ 2013-03-01 20:13 ` Kevin Wolf
  2013-03-01 21:55   ` Eric Blake
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 4/7] block: Add options QDict to bdrv_open_common() Kevin Wolf
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Kevin Wolf @ 2013-03-01 20:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, armbru, stefanha

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 include/qapi/qmp/qdict.h |  2 ++
 qobject/qdict.c          | 22 ++++++++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 6d9a4be..685b2e3 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -64,4 +64,6 @@ int64_t qdict_get_try_int(const QDict *qdict, const char *key,
 int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value);
 const char *qdict_get_try_str(const QDict *qdict, const char *key);
 
+QDict *qdict_clone_shallow(const QDict *src);
+
 #endif /* QDICT_H */
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 7543ccc..ed381f9 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -401,6 +401,28 @@ const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
 }
 
 /**
+ * qdict_clone_shallow(): Clones a given QDict. Its entries are not copied, but
+ * another reference is added.
+ */
+QDict *qdict_clone_shallow(const QDict *src)
+{
+    QDict *dest;
+    QDictEntry *entry;
+    int i;
+
+    dest = qdict_new();
+
+    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
+        QLIST_FOREACH(entry, &src->table[i], next) {
+            qobject_incref(entry->value);
+            qdict_put_obj(dest, entry->key, entry->value);
+        }
+    }
+
+    return dest;
+}
+
+/**
  * qentry_destroy(): Free all the memory allocated by a QDictEntry
  */
 static void qentry_destroy(QDictEntry *e)
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 4/7] block: Add options QDict to bdrv_open_common()
  2013-03-01 20:13 [Qemu-devel] [PATCH 0/7] block: Add driver specific options Kevin Wolf
                   ` (2 preceding siblings ...)
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 3/7] Add qdict_clone_shallow() Kevin Wolf
@ 2013-03-01 20:13 ` Kevin Wolf
  2013-03-01 22:01   ` Eric Blake
  2013-03-04  9:28   ` Stefan Hajnoczi
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 5/7] qemu-option: Add qemu_opts_absorb_qdict() Kevin Wolf
                   ` (3 subsequent siblings)
  7 siblings, 2 replies; 17+ messages in thread
From: Kevin Wolf @ 2013-03-01 20:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, armbru, stefanha

The options are passed down to the block drivers, which are supposed to
remove all options they have processed. Anything that is left over in
the end is an unknown option and results in an error.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/block.c b/block.c
index bf93dd1..e0e3b99 100644
--- a/block.c
+++ b/block.c
@@ -665,15 +665,18 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
 
 /*
  * Common part for opening disk images and files
+ *
+ * Removes all processed options from *options.
  */
 static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
-    const char *filename,
+    const char *filename, QDict *options,
     int flags, BlockDriver *drv)
 {
     int ret, open_flags;
 
     assert(drv != NULL);
     assert(bs->file == NULL);
+    assert(options == NULL || bs->options != options);
 
     trace_bdrv_open_common(bs, filename, flags, drv->format_name);
 
@@ -710,7 +713,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
     } else {
         assert(file != NULL);
         bs->file = file;
-        ret = drv->bdrv_open(bs, NULL, open_flags);
+        ret = drv->bdrv_open(bs, options, open_flags);
     }
 
     if (ret < 0) {
@@ -752,7 +755,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
     }
 
     bs = bdrv_new("");
-    ret = bdrv_open_common(bs, NULL, filename, flags, drv);
+    ret = bdrv_open_common(bs, NULL, filename, NULL, flags, drv);
     if (ret < 0) {
         bdrv_delete(bs);
         return ret;
@@ -821,6 +824,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
     }
 
     bs->options = options;
+    options = qdict_clone_shallow(options);
 
     /* For snapshot=on, create a temporary qcow2 overlay */
     if (flags & BDRV_O_SNAPSHOT) {
@@ -903,7 +907,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
     }
 
     /* Open the image */
-    ret = bdrv_open_common(bs, file, filename, flags, drv);
+    ret = bdrv_open_common(bs, file, filename, options, flags, drv);
     if (ret < 0) {
         goto unlink_and_fail;
     }
@@ -917,11 +921,22 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
     if ((flags & BDRV_O_NO_BACKING) == 0) {
         ret = bdrv_open_backing_file(bs);
         if (ret < 0) {
-            bdrv_close(bs);
-            return ret;
+            goto close_and_fail;
         }
     }
 
+    /* Check if any unknown options were used */
+    if (qdict_size(options) != 0) {
+        const QDictEntry *entry = qdict_first(options);
+        qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by "
+            "device '%s' doesn't support the option '%s'",
+            drv->format_name, bs->device_name, entry->key);
+
+        ret = -EINVAL;
+        goto close_and_fail;
+    }
+    QDECREF(options);
+
     if (!bdrv_key_required(bs)) {
         bdrv_dev_change_media_cb(bs, true);
     }
@@ -942,8 +957,13 @@ unlink_and_fail:
     }
 fail:
     QDECREF(bs->options);
+    QDECREF(options);
     bs->options = NULL;
+    return ret;
 
+close_and_fail:
+    bdrv_close(bs);
+    QDECREF(options);
     return ret;
 }
 
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 5/7] qemu-option: Add qemu_opts_absorb_qdict()
  2013-03-01 20:13 [Qemu-devel] [PATCH 0/7] block: Add driver specific options Kevin Wolf
                   ` (3 preceding siblings ...)
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 4/7] block: Add options QDict to bdrv_open_common() Kevin Wolf
@ 2013-03-01 20:13 ` Kevin Wolf
  2013-03-01 22:14   ` Eric Blake
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 6/7] block: Support driver specific options in drive_init() Kevin Wolf
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Kevin Wolf @ 2013-03-01 20:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, armbru, stefanha

This adds a function that adds all entries of a QDict to a QemuOpts if
the keys are known, and leaves only the rest in the QDict.

This way a single QDict of -drive options can be processed in multiple
places (generic block layer, block driver, backing file block driver,
etc.), where each part picks the options it knows. If at the end of the
process the QDict isn't empty, the user specified an invalid option.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 include/qemu/option.h |  1 +
 util/qemu-option.c    | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index ba197cd..bdb6d21 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -149,6 +149,7 @@ void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
 QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
                                Error **errp);
 QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
+void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
 
 typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
 int qemu_opts_print(QemuOpts *opts, void *dummy);
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 5a1d03c..8b74bf1 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -1067,6 +1067,40 @@ QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
 }
 
 /*
+ * Adds all QDict entries to the QemuOpts that can be added and removes them
+ * from the QDict. When this function returns, the QDict contains only those
+ * entries that couldn't be added to the QemuOpts.
+ */
+void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
+{
+    const QDictEntry *entry, *next;
+
+    entry = qdict_first(qdict);
+
+    while (entry != NULL) {
+        Error *local_err = NULL;
+        OptsFromQDictState state = {
+            .errp = &local_err,
+            .opts = opts,
+        };
+
+        next = qdict_next(qdict, entry);
+
+        if (find_desc_by_name(opts->list->desc, entry->key)) {
+            qemu_opts_from_qdict_1(entry->key, entry->value, &state);
+            if (error_is_set(&local_err)) {
+                error_propagate(errp, local_err);
+                return;
+            } else {
+                qdict_del(qdict, entry->key);
+            }
+        }
+
+        entry = next;
+    }
+}
+
+/*
  * Convert from QemuOpts to QDict.
  * The QDict values are of type QString.
  * TODO We'll want to use types appropriate for opt->desc->type, but
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 6/7] block: Support driver specific options in drive_init()
  2013-03-01 20:13 [Qemu-devel] [PATCH 0/7] block: Add driver specific options Kevin Wolf
                   ` (4 preceding siblings ...)
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 5/7] qemu-option: Add qemu_opts_absorb_qdict() Kevin Wolf
@ 2013-03-01 20:13 ` Kevin Wolf
  2013-03-01 22:26   ` Eric Blake
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 7/7] qcow2: Allow lazy refcounts to be enabled on the command line Kevin Wolf
  2013-03-04  9:29 ` [Qemu-devel] [PATCH 0/7] block: Add driver specific options Stefan Hajnoczi
  7 siblings, 1 reply; 17+ messages in thread
From: Kevin Wolf @ 2013-03-01 20:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, armbru, stefanha

Any non-default -drive options are now passed down to the block drivers.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 blockdev.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index d679174..1f896ca 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -22,6 +22,7 @@
 #include "sysemu/arch_init.h"
 
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
+extern QemuOptsList qemu_common_drive_opts;
 
 static const char *const if_name[IF_COUNT] = {
     [IF_NONE] = "none",
@@ -287,7 +288,7 @@ static bool do_check_io_limits(BlockIOLimit *io_limits, Error **errp)
     return true;
 }
 
-DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
+DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
 {
     const char *buf;
     const char *file = NULL;
@@ -310,10 +311,25 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
     bool copy_on_read;
     int ret;
     Error *error = NULL;
+    QemuOpts *opts;
+    QDict *bs_opts;
 
     translation = BIOS_ATA_TRANSLATION_AUTO;
     media = MEDIA_DISK;
 
+    /* Check common options by copying from all_opts to opts, all other options
+     * are stored in bs_opts. */
+    opts = qemu_opts_create_nofail(&qemu_common_drive_opts);
+
+    bs_opts = qdict_new();
+    qemu_opts_to_qdict(all_opts, bs_opts);
+    qemu_opts_absorb_qdict(opts, bs_opts, &error);
+    if (error_is_set(&error)) {
+        qerror_report_err(error);
+        error_free(error);
+        return NULL;
+    }
+
     /* extract parameters */
     bus_id  = qemu_opt_get_number(opts, "bus", 0);
     unit_id = qemu_opt_get_number(opts, "unit", -1);
@@ -564,7 +580,7 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
     dinfo->heads = heads;
     dinfo->secs = secs;
     dinfo->trans = translation;
-    dinfo->opts = opts;
+    dinfo->opts = all_opts;
     dinfo->refcount = 1;
     dinfo->serial = serial;
     QTAILQ_INSERT_TAIL(&drives, dinfo, next);
@@ -635,7 +651,9 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
         error_report("warning: disabling copy_on_read on readonly drive");
     }
 
-    ret = bdrv_open(dinfo->bdrv, file, NULL, bdrv_flags, drv);
+    ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, drv);
+    bs_opts = NULL;
+
     if (ret < 0) {
         if (ret == -EMEDIUMTYPE) {
             error_report("could not open disk image %s: not in %s format",
@@ -649,9 +667,14 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
 
     if (bdrv_key_required(dinfo->bdrv))
         autostart = 0;
+
+    qemu_opts_del(opts);
+
     return dinfo;
 
 err:
+    qemu_opts_del(opts);
+    QDECREF(bs_opts);
     bdrv_delete(dinfo->bdrv);
     g_free(dinfo->id);
     QTAILQ_REMOVE(&drives, dinfo, next);
@@ -1461,9 +1484,9 @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp)
     return dummy.next;
 }
 
-QemuOptsList qemu_drive_opts = {
+QemuOptsList qemu_common_drive_opts = {
     .name = "drive",
-    .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
     .desc = {
         {
             .name = "bus",
@@ -1582,3 +1605,15 @@ QemuOptsList qemu_drive_opts = {
         { /* end of list */ }
     },
 };
+
+QemuOptsList qemu_drive_opts = {
+    .name = "drive",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
+    .desc = {
+        /*
+         * no elements => accept any params
+         * validation will happen later
+         */
+        { /* end of list */ }
+    },
+};
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 7/7] qcow2: Allow lazy refcounts to be enabled on the command line
  2013-03-01 20:13 [Qemu-devel] [PATCH 0/7] block: Add driver specific options Kevin Wolf
                   ` (5 preceding siblings ...)
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 6/7] block: Support driver specific options in drive_init() Kevin Wolf
@ 2013-03-01 20:13 ` Kevin Wolf
  2013-03-01 22:28   ` Eric Blake
  2013-03-04  9:29 ` [Qemu-devel] [PATCH 0/7] block: Add driver specific options Stefan Hajnoczi
  7 siblings, 1 reply; 17+ messages in thread
From: Kevin Wolf @ 2013-03-01 20:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, armbru, stefanha

qcow2 images now accept a boolean lazy_refcounts options. Use it like
this:

  -drive file=test.qcow2,lazy_refcounts=on

If the option is specified on the command line, it overrides the default
specified by the qcow2 header flags that were set when creating the
image.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2-cluster.c |  2 +-
 block/qcow2.c         | 37 +++++++++++++++++++++++++++++++++++++
 block/qcow2.h         |  1 +
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 56fccf9..ff9ae18 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -668,7 +668,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
     }
 
     /* Update L2 table. */
-    if (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS) {
+    if (s->use_lazy_refcounts) {
         qcow2_mark_dirty(bs);
     }
     if (qcow2_need_accurate_refcounts(s)) {
diff --git a/block/qcow2.c b/block/qcow2.c
index f5e4269..ad43a13 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -285,11 +285,26 @@ static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
     return ret;
 }
 
+static QemuOptsList qcow2_runtime_opts = {
+    .name = "qcow2",
+    .head = QTAILQ_HEAD_INITIALIZER(qcow2_runtime_opts.head),
+    .desc = {
+        {
+            .name = "lazy_refcounts",
+            .type = QEMU_OPT_BOOL,
+            .help = "Postpone refcount updates",
+        },
+        { /* end of list */ }
+    },
+};
+
 static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
 {
     BDRVQcowState *s = bs->opaque;
     int len, i, ret = 0;
     QCowHeader header;
+    QemuOpts *opts;
+    Error *local_err = NULL;
     uint64_t ext_end;
 
     ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
@@ -495,6 +510,28 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
         }
     }
 
+    /* Enable lazy_refcounts according to image and command line options */
+    opts = qemu_opts_create_nofail(&qcow2_runtime_opts);
+    qemu_opts_absorb_qdict(opts, options, &local_err);
+    if (error_is_set(&local_err)) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        ret = -EINVAL;
+        goto fail;
+    }
+
+    s->use_lazy_refcounts = qemu_opt_get_bool(opts, "lazy_refcounts",
+        (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS));
+
+    qemu_opts_del(opts);
+
+    if (s->use_lazy_refcounts && s->qcow_version < 3) {
+        qerror_report(ERROR_CLASS_GENERIC_ERROR, "Lazy refcounts require "
+            "a qcow2 image with at least qemu 1.1 compatibility level");
+        ret = -EINVAL;
+        goto fail;
+    }
+
 #ifdef DEBUG_ALLOC
     {
         BdrvCheckResult result = {0};
diff --git a/block/qcow2.h b/block/qcow2.h
index 718b52b..103abdb 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -173,6 +173,7 @@ typedef struct BDRVQcowState {
 
     int flags;
     int qcow_version;
+    bool use_lazy_refcounts;
 
     uint64_t incompatible_features;
     uint64_t compatible_features;
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 1/7] block: Add options QDict to .bdrv_open()
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 1/7] block: Add options QDict to .bdrv_open() Kevin Wolf
@ 2013-03-01 21:15   ` Eric Blake
  0 siblings, 0 replies; 17+ messages in thread
From: Eric Blake @ 2013-03-01 21:15 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, stefanha, armbru

[-- Attachment #1: Type: text/plain, Size: 836 bytes --]

On 03/01/2013 01:13 PM, Kevin Wolf wrote:
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  block.c                   | 4 ++--
>  block/bochs.c             | 2 +-
>  block/cloop.c             | 2 +-
>  block/cow.c               | 2 +-
>  block/dmg.c               | 2 +-
>  block/parallels.c         | 2 +-
>  block/qcow.c              | 2 +-
>  block/qcow2.c             | 4 ++--
>  block/qed.c               | 4 ++--
>  block/raw.c               | 2 +-
>  block/vdi.c               | 2 +-
>  block/vmdk.c              | 2 +-
>  block/vpc.c               | 2 +-
>  include/block/block_int.h | 2 +-
>  14 files changed, 17 insertions(+), 17 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] block: Add options QDict to bdrv_open() prototype
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 2/7] block: Add options QDict to bdrv_open() prototype Kevin Wolf
@ 2013-03-01 21:53   ` Eric Blake
  0 siblings, 0 replies; 17+ messages in thread
From: Eric Blake @ 2013-03-01 21:53 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, stefanha, armbru

[-- Attachment #1: Type: text/plain, Size: 921 bytes --]

On 03/01/2013 01:13 PM, Kevin Wolf wrote:
> It doesn't do anything yet except storing the options QDict in the
> BlockDriverState.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  block.c                   | 47 +++++++++++++++++++++++++++++++++++------------
>  block/blkverify.c         |  2 +-
>  block/qcow2.c             |  2 +-
>  block/vmdk.c              |  2 +-
>  block/vvfat.c             |  2 +-
>  blockdev.c                | 10 ++++++----
>  hw/xen_disk.c             |  2 +-
>  include/block/block.h     |  4 ++--
>  include/block/block_int.h |  1 +
>  qemu-img.c                |  6 +++---
>  qemu-io.c                 |  2 +-
>  qemu-nbd.c                |  2 +-
>  12 files changed, 54 insertions(+), 28 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 3/7] Add qdict_clone_shallow()
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 3/7] Add qdict_clone_shallow() Kevin Wolf
@ 2013-03-01 21:55   ` Eric Blake
  0 siblings, 0 replies; 17+ messages in thread
From: Eric Blake @ 2013-03-01 21:55 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, stefanha, armbru

[-- Attachment #1: Type: text/plain, Size: 388 bytes --]

On 03/01/2013 01:13 PM, Kevin Wolf wrote:
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  include/qapi/qmp/qdict.h |  2 ++
>  qobject/qdict.c          | 22 ++++++++++++++++++++++
>  2 files changed, 24 insertions(+)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 4/7] block: Add options QDict to bdrv_open_common()
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 4/7] block: Add options QDict to bdrv_open_common() Kevin Wolf
@ 2013-03-01 22:01   ` Eric Blake
  2013-03-04  9:28   ` Stefan Hajnoczi
  1 sibling, 0 replies; 17+ messages in thread
From: Eric Blake @ 2013-03-01 22:01 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, stefanha, armbru

[-- Attachment #1: Type: text/plain, Size: 568 bytes --]

On 03/01/2013 01:13 PM, Kevin Wolf wrote:
> The options are passed down to the block drivers, which are supposed to
> remove all options they have processed. Anything that is left over in
> the end is an unknown option and results in an error.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  block.c | 32 ++++++++++++++++++++++++++------
>  1 file changed, 26 insertions(+), 6 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 5/7] qemu-option: Add qemu_opts_absorb_qdict()
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 5/7] qemu-option: Add qemu_opts_absorb_qdict() Kevin Wolf
@ 2013-03-01 22:14   ` Eric Blake
  0 siblings, 0 replies; 17+ messages in thread
From: Eric Blake @ 2013-03-01 22:14 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, stefanha, armbru

[-- Attachment #1: Type: text/plain, Size: 831 bytes --]

On 03/01/2013 01:13 PM, Kevin Wolf wrote:
> This adds a function that adds all entries of a QDict to a QemuOpts if
> the keys are known, and leaves only the rest in the QDict.
> 
> This way a single QDict of -drive options can be processed in multiple
> places (generic block layer, block driver, backing file block driver,
> etc.), where each part picks the options it knows. If at the end of the
> process the QDict isn't empty, the user specified an invalid option.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  include/qemu/option.h |  1 +
>  util/qemu-option.c    | 34 ++++++++++++++++++++++++++++++++++
>  2 files changed, 35 insertions(+)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 6/7] block: Support driver specific options in drive_init()
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 6/7] block: Support driver specific options in drive_init() Kevin Wolf
@ 2013-03-01 22:26   ` Eric Blake
  0 siblings, 0 replies; 17+ messages in thread
From: Eric Blake @ 2013-03-01 22:26 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, stefanha, armbru

[-- Attachment #1: Type: text/plain, Size: 455 bytes --]

On 03/01/2013 01:13 PM, Kevin Wolf wrote:
> Any non-default -drive options are now passed down to the block drivers.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  blockdev.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 40 insertions(+), 5 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 7/7] qcow2: Allow lazy refcounts to be enabled on the command line
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 7/7] qcow2: Allow lazy refcounts to be enabled on the command line Kevin Wolf
@ 2013-03-01 22:28   ` Eric Blake
  0 siblings, 0 replies; 17+ messages in thread
From: Eric Blake @ 2013-03-01 22:28 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, stefanha, armbru

[-- Attachment #1: Type: text/plain, Size: 742 bytes --]

On 03/01/2013 01:13 PM, Kevin Wolf wrote:
> qcow2 images now accept a boolean lazy_refcounts options. Use it like
> this:
> 
>   -drive file=test.qcow2,lazy_refcounts=on
> 
> If the option is specified on the command line, it overrides the default
> specified by the qcow2 header flags that were set when creating the
> image.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  block/qcow2-cluster.c |  2 +-
>  block/qcow2.c         | 37 +++++++++++++++++++++++++++++++++++++
>  block/qcow2.h         |  1 +
>  3 files changed, 39 insertions(+), 1 deletion(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 4/7] block: Add options QDict to bdrv_open_common()
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 4/7] block: Add options QDict to bdrv_open_common() Kevin Wolf
  2013-03-01 22:01   ` Eric Blake
@ 2013-03-04  9:28   ` Stefan Hajnoczi
  1 sibling, 0 replies; 17+ messages in thread
From: Stefan Hajnoczi @ 2013-03-04  9:28 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, stefanha, armbru

On Fri, Mar 01, 2013 at 09:13:38PM +0100, Kevin Wolf wrote:
> diff --git a/block.c b/block.c
> index bf93dd1..e0e3b99 100644
> --- a/block.c
> +++ b/block.c
> @@ -665,15 +665,18 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
>  
>  /*
>   * Common part for opening disk images and files
> + *
> + * Removes all processed options from *options.
>   */
>  static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
> -    const char *filename,
> +    const char *filename, QDict *options,

The function already has an "options" local variable which will shadow:

    /* For snapshot=on, create a temporary qcow2 overlay */
    if (flags & BDRV_O_SNAPSHOT) {
        BlockDriverState *bs1;
        int64_t total_size;
        int is_protocol = 0;
        BlockDriver *bdrv_qcow2;
        QEMUOptionParameter *options;

This could be fixed in a follow-up patch.

Stefan

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 0/7] block: Add driver specific options
  2013-03-01 20:13 [Qemu-devel] [PATCH 0/7] block: Add driver specific options Kevin Wolf
                   ` (6 preceding siblings ...)
  2013-03-01 20:13 ` [Qemu-devel] [PATCH 7/7] qcow2: Allow lazy refcounts to be enabled on the command line Kevin Wolf
@ 2013-03-04  9:29 ` Stefan Hajnoczi
  7 siblings, 0 replies; 17+ messages in thread
From: Stefan Hajnoczi @ 2013-03-04  9:29 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, stefanha, armbru

On Fri, Mar 01, 2013 at 09:13:34PM +0100, Kevin Wolf wrote:
> Instead of constantly keeping complaining that we need this big -blockdev
> things, let's start attacking individual parts of the project. Here is the
> first part, allowing block drivers to provide additional -drive options.
> 
> Any options that isn't processed by the block layer is passed to the driver
> which can use them. If it doesn't, you get an error message like today. At the
> end of this series you can specify:
> 
>   -drive file=test.qcow2,lazy_refcounts=on
> 
> This doesn't include a way to specify options for backing files yet, but
> I don't think there's anything blocking such extensions on top.
> 
> Kevin Wolf (7):
>   block: Add options QDict to .bdrv_open()
>   block: Add options QDict to bdrv_open() prototype
>   Add qdict_clone_shallow()
>   block: Add options QDict to bdrv_open_common()
>   qemu-option: Add qemu_opts_absorb_qdict()
>   block: Support driver specific options in drive_init()
>   qcow2: Allow lazy refcounts to be enabled on the command line
> 
>  block.c                   | 81 ++++++++++++++++++++++++++++++++++++-----------
>  block/blkverify.c         |  2 +-
>  block/bochs.c             |  2 +-
>  block/cloop.c             |  2 +-
>  block/cow.c               |  2 +-
>  block/dmg.c               |  2 +-
>  block/parallels.c         |  2 +-
>  block/qcow.c              |  2 +-
>  block/qcow2-cluster.c     |  2 +-
>  block/qcow2.c             | 43 +++++++++++++++++++++++--
>  block/qcow2.h             |  1 +
>  block/qed.c               |  4 +--
>  block/raw.c               |  2 +-
>  block/vdi.c               |  2 +-
>  block/vmdk.c              |  4 +--
>  block/vpc.c               |  2 +-
>  block/vvfat.c             |  2 +-
>  blockdev.c                | 53 ++++++++++++++++++++++++++-----
>  hw/xen_disk.c             |  2 +-
>  include/block/block.h     |  4 +--
>  include/block/block_int.h |  3 +-
>  include/qapi/qmp/qdict.h  |  2 ++
>  include/qemu/option.h     |  1 +
>  qemu-img.c                |  6 ++--
>  qemu-io.c                 |  2 +-
>  qemu-nbd.c                |  2 +-
>  qobject/qdict.c           | 22 +++++++++++++
>  util/qemu-option.c        | 34 ++++++++++++++++++++
>  28 files changed, 233 insertions(+), 55 deletions(-)
> 
> -- 
> 1.8.1.2
> 
> 

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2013-03-04  9:29 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-01 20:13 [Qemu-devel] [PATCH 0/7] block: Add driver specific options Kevin Wolf
2013-03-01 20:13 ` [Qemu-devel] [PATCH 1/7] block: Add options QDict to .bdrv_open() Kevin Wolf
2013-03-01 21:15   ` Eric Blake
2013-03-01 20:13 ` [Qemu-devel] [PATCH 2/7] block: Add options QDict to bdrv_open() prototype Kevin Wolf
2013-03-01 21:53   ` Eric Blake
2013-03-01 20:13 ` [Qemu-devel] [PATCH 3/7] Add qdict_clone_shallow() Kevin Wolf
2013-03-01 21:55   ` Eric Blake
2013-03-01 20:13 ` [Qemu-devel] [PATCH 4/7] block: Add options QDict to bdrv_open_common() Kevin Wolf
2013-03-01 22:01   ` Eric Blake
2013-03-04  9:28   ` Stefan Hajnoczi
2013-03-01 20:13 ` [Qemu-devel] [PATCH 5/7] qemu-option: Add qemu_opts_absorb_qdict() Kevin Wolf
2013-03-01 22:14   ` Eric Blake
2013-03-01 20:13 ` [Qemu-devel] [PATCH 6/7] block: Support driver specific options in drive_init() Kevin Wolf
2013-03-01 22:26   ` Eric Blake
2013-03-01 20:13 ` [Qemu-devel] [PATCH 7/7] qcow2: Allow lazy refcounts to be enabled on the command line Kevin Wolf
2013-03-01 22:28   ` Eric Blake
2013-03-04  9:29 ` [Qemu-devel] [PATCH 0/7] block: Add driver specific options Stefan Hajnoczi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.