* [Qemu-devel] [PATCH 01/13] block: Add options QDict to .bdrv_open()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 02/13] block: Add options QDict to bdrv_open() prototype Kevin Wolf
` (11 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@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 124a9eb..01cee87 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) {
@@ -3190,7 +3190,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.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 02/13] block: Add options QDict to bdrv_open() prototype
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 01/13] block: Add options QDict to .bdrv_open() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 03/13] Add qdict_clone_shallow() Kevin Wolf
` (10 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
It doesn't do anything yet except storing the options QDict in the
BlockDriverState.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@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 01cee87..761ea86 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);
@@ -4594,7 +4616,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 cc09a2f..83329e2 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.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 03/13] Add qdict_clone_shallow()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 01/13] block: Add options QDict to .bdrv_open() Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 02/13] block: Add options QDict to bdrv_open() prototype Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 04/13] block: Add options QDict to bdrv_open_common() Kevin Wolf
` (9 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@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.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 04/13] block: Add options QDict to bdrv_open_common()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (2 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 03/13] Add qdict_clone_shallow() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 05/13] qemu-option: Add qemu_opts_absorb_qdict() Kevin Wolf
` (8 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
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>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/block.c b/block.c
index 761ea86..0ab164d 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.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 05/13] qemu-option: Add qemu_opts_absorb_qdict()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (3 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 04/13] block: Add options QDict to bdrv_open_common() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 06/13] block: Support driver specific options in drive_init() Kevin Wolf
` (7 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
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>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@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.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 06/13] block: Support driver specific options in drive_init()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (4 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 05/13] qemu-option: Add qemu_opts_absorb_qdict() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-14 21:11 ` Anthony Liguori
2013-03-12 14:41 ` [Qemu-devel] [PATCH 07/13] qcow2: Allow lazy refcounts to be enabled on the command line Kevin Wolf
` (6 subsequent siblings)
12 siblings, 1 reply; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
Any non-default -drive options are now passed down to the block drivers.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
blockdev.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 59 insertions(+), 10 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index d679174..d0fd1e2 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,36 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
bool copy_on_read;
int ret;
Error *error = NULL;
+ QemuOpts *opts;
+ QDict *bs_opts;
+ const char *id;
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. */
+ id = qemu_opts_id(all_opts);
+ opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error);
+ if (error_is_set(&error)) {
+ qerror_report_err(error);
+ error_free(error);
+ return NULL;
+ }
+
+ 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;
+ }
+
+ if (id) {
+ qdict_del(bs_opts, "id");
+ }
+
/* extract parameters */
bus_id = qemu_opt_get_number(opts, "bus", 0);
unit_id = qemu_opt_get_number(opts, "unit", -1);
@@ -564,7 +591,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);
@@ -587,17 +614,20 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
case IF_MTD:
break;
case IF_VIRTIO:
+ {
/* add virtio block device */
- opts = qemu_opts_create_nofail(qemu_find_opts("device"));
+ QemuOpts *devopts;
+ devopts = qemu_opts_create_nofail(qemu_find_opts("device"));
if (arch_type == QEMU_ARCH_S390X) {
- qemu_opt_set(opts, "driver", "virtio-blk-s390");
+ qemu_opt_set(devopts, "driver", "virtio-blk-s390");
} else {
- qemu_opt_set(opts, "driver", "virtio-blk-pci");
+ qemu_opt_set(devopts, "driver", "virtio-blk-pci");
}
- qemu_opt_set(opts, "drive", dinfo->id);
+ qemu_opt_set(devopts, "drive", dinfo->id);
if (devaddr)
- qemu_opt_set(opts, "addr", devaddr);
+ qemu_opt_set(devopts, "addr", devaddr);
break;
+ }
default:
abort();
}
@@ -635,7 +665,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 +681,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 +1498,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 +1619,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.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [Qemu-devel] [PATCH 06/13] block: Support driver specific options in drive_init()
2013-03-12 14:41 ` [Qemu-devel] [PATCH 06/13] block: Support driver specific options in drive_init() Kevin Wolf
@ 2013-03-14 21:11 ` Anthony Liguori
0 siblings, 0 replies; 19+ messages in thread
From: Anthony Liguori @ 2013-03-14 21:11 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=us-ascii, Size: 23808 bytes --]
Kevin Wolf <kwolf@redhat.com> writes:
> Any non-default -drive options are now passed down to the block drivers.
>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
According to git-bisect, this breaks virtio-blk serial property. Here's
the output from qemu-test:
Using RANDOM seed 26105
Formatting '.tmp-32392/disk.img', fmt=qcow2 size=10737418240 encryption=off cluster_size=65536 lazy_refcounts=off
/home/aliguori/build/qemu/x86_64-softmmu/qemu-system-x86_64 -kernel /usr/local/share/qemu-jeos/kernel-x86_64-pc -initrd .tmp-32392/initramfs-32392.img.gz -device isa-debug-exit -append console=ttyS0 seed=26105 -nographic -enable-kvm -drive file=.tmp-32392/disk.img,if=none,id=drive-virtio-disk0,format=raw,cache=none,serial=0123456789abcdefghi -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0 -pidfile .tmp-32392/pidfile-32392.pid -qmp unix:.tmp-32392/qmpsock-32392.sock,server,nowait
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Linux version 3.4.0 (root@ccnode4) (gcc version 4.6.4 20120830 (prerelease) (GCC) ) #2 SMP Mon Dec 3 19:40:41 CST 2012
[ 0.000000] Command line: console=ttyS0 seed=26105
[ 0.000000] BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
[ 0.000000] BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
[ 0.000000] BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
[ 0.000000] BIOS-e820: 0000000000100000 - 0000000007ffe000 (usable)
[ 0.000000] BIOS-e820: 0000000007ffe000 - 0000000008000000 (reserved)
[ 0.000000] BIOS-e820: 00000000feffc000 - 00000000ff000000 (reserved)
[ 0.000000] BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)
[ 0.000000] NX (Execute Disable) protection: active
[ 0.000000] DMI 2.4 present.
[ 0.000000] No AGP bridge found
[ 0.000000] last_pfn = 0x7ffe max_arch_pfn = 0x400000000
[ 0.000000] PAT not supported by CPU.
[ 0.000000] found SMP MP-table at [ffff8800000fdaf0] fdaf0
[ 0.000000] init_memory_mapping: 0000000000000000-0000000007ffe000
[ 0.000000] RAMDISK: 07f58000 - 07ff0000
[ 0.000000] ACPI: RSDP 00000000000fd990 00014 (v00 BOCHS )
[ 0.000000] ACPI: RSDT 0000000007ffe4b0 00034 (v01 BOCHS BXPCRSDT 00000001 BXPC 00000001)
[ 0.000000] ACPI: FACP 0000000007ffff80 00074 (v01 BOCHS BXPCFACP 00000001 BXPC 00000001)
[ 0.000000] ACPI: DSDT 0000000007ffe4f0 011A9 (v01 BXPC BXDSDT 00000001 INTL 20100528)
[ 0.000000] ACPI: FACS 0000000007ffff40 00040
[ 0.000000] ACPI: SSDT 0000000007fff800 00735 (v01 BOCHS BXPCSSDT 00000001 BXPC 00000001)
[ 0.000000] ACPI: APIC 0000000007fff6e0 00078 (v01 BOCHS BXPCAPIC 00000001 BXPC 00000001)
[ 0.000000] ACPI: HPET 0000000007fff6a0 00038 (v01 BOCHS BXPCHPET 00000001 BXPC 00000001)
[ 0.000000] No NUMA configuration found
[ 0.000000] Faking a node at 0000000000000000-0000000007ffe000
[ 0.000000] Initmem setup node 0 0000000000000000-0000000007ffe000
[ 0.000000] NODE_DATA [0000000007ff7000 - 0000000007ffafff]
[ 0.000000] Zone PFN ranges:
[ 0.000000] DMA 0x00000010 -> 0x00001000
[ 0.000000] DMA32 0x00001000 -> 0x00100000
[ 0.000000] Normal empty
[ 0.000000] Movable zone start PFN for each node
[ 0.000000] Early memory PFN ranges
[ 0.000000] 0: 0x00000010 -> 0x0000009f
[ 0.000000] 0: 0x00000100 -> 0x00007ffe
[ 0.000000] ACPI: PM-Timer IO Port: 0xb008
[ 0.000000] ACPI: LAPIC (acpi_id[0x00] lapic_id[0x00] enabled)
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0xff] dfl dfl lint[0x1])
[ 0.000000] ACPI: IOAPIC (id[0x00] address[0xfec00000] gsi_base[0])
[ 0.000000] IOAPIC[0]: apic_id 0, version 17, address 0xfec00000, GSI 0-23
[ 0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[ 0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 5 global_irq 5 high level)
[ 0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
[ 0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 10 global_irq 10 high level)
[ 0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 11 global_irq 11 high level)
[ 0.000000] Using ACPI (MADT) for SMP configuration information
[ 0.000000] ACPI: HPET id: 0x8086a201 base: 0xfed00000
[ 0.000000] SMP: Allowing 1 CPUs, 0 hotplug CPUs
[ 0.000000] PM: Registered nosave memory: 000000000009f000 - 00000000000a0000
[ 0.000000] PM: Registered nosave memory: 00000000000a0000 - 00000000000f0000
[ 0.000000] PM: Registered nosave memory: 00000000000f0000 - 0000000000100000
[ 0.000000] Allocating PCI resources starting at 8000000 (gap: 8000000:f6ffc000)
[ 0.000000] setup_percpu: NR_CPUS:64 nr_cpumask_bits:64 nr_cpu_ids:1 nr_node_ids:1
[ 0.000000] PERCPU: Embedded 26 pages/cpu @ffff880007c00000 s77056 r8192 d21248 u2097152
[ 0.000000] Built 1 zonelists in Node order, mobility grouping on. Total pages: 32136
[ 0.000000] Policy zone: DMA32
[ 0.000000] Kernel command line: console=ttyS0 seed=26105
[ 0.000000] PID hash table entries: 512 (order: 0, 4096 bytes)
[ 0.000000] Checking aperture...
[ 0.000000] No AGP bridge found
[ 0.000000] Memory: 113188k/131064k available (7532k kernel code, 452k absent, 17424k reserved, 5454k data, 584k init)
[ 0.000000] SLUB: Genslabs=15, HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] Hierarchical RCU implementation.
[ 0.000000] NR_IRQS:4352 nr_irqs:256 16
[ 0.000000] Console: colour VGA+ 80x25
[ 0.000000] console [ttyS0] enabled
[ 0.000000] Fast TSC calibration using PIT
[ 0.000000] Detected 2933.141 MHz processor.
[ 0.003001] Calibrating delay loop (skipped), value calculated using timer frequency.. 5866.28 BogoMIPS (lpj=2933141)
[ 0.004335] pid_max: default: 32768 minimum: 301
[ 0.005029] Security Framework initialized
[ 0.005539] SELinux: Initializing.
[ 0.006026] Dentry cache hash table entries: 16384 (order: 5, 131072 bytes)
[ 0.007027] Inode-cache hash table entries: 8192 (order: 4, 65536 bytes)
[ 0.007817] Mount-cache hash table entries: 256
[ 0.008122] Initializing cgroup subsys cpuacct
[ 0.009002] Initializing cgroup subsys freezer
[ 0.009567] mce: CPU supports 10 MCE banks
[ 0.010206] SMP alternatives: switching to UP code
[ 0.019659] Freeing SMP alternatives: 24k freed
[ 0.020008] ACPI: Core revision 20120320
[ 0.022372] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[ 0.033188] CPU0: Intel QEMU Virtual CPU version 1.4.50 stepping 03
[ 0.033997] Performance Events: unsupported p6 CPU model 2 no PMU driver, software events only.
[ 0.034065] Brought up 1 CPUs
[ 0.034407] Total of 1 processors activated (5866.28 BogoMIPS).
[ 0.035380] kworker/u:0 used greatest stack depth: 6368 bytes left
[ 0.036066] RTC time: 5:32:36, date: 03/15/13
[ 0.036595] NET: Registered protocol family 16
[ 0.037246] ACPI: bus type pci registered
[ 0.038049] kworker/u:0 used greatest stack depth: 6304 bytes left
[ 0.039011] PCI: Using configuration type 1 for base access
[ 0.039870] kworker/u:0 used greatest stack depth: 5968 bytes left
[ 0.040276] kworker/u:0 used greatest stack depth: 5536 bytes left
[ 0.046505] bio: create slab <bio-0> at 0
[ 0.047133] ACPI: Added _OSI(Module Device)
[ 0.047623] ACPI: Added _OSI(Processor Device)
[ 0.048001] ACPI: Added _OSI(3.0 _SCP Extensions)
[ 0.048534] ACPI: Added _OSI(Processor Aggregator Device)
[ 0.050713] ACPI: Interpreter enabled
[ 0.050999] ACPI: (supports S0 S3 S4 S5)
[ 0.051525] ACPI: Using IOAPIC for interrupt routing
[ 0.055088] ACPI: No dock devices found.
[ 0.055537] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[ 0.056065] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[ 0.057083] pci_root PNP0A03:00: host bridge window [io 0x0000-0x0cf7]
[ 0.058011] pci_root PNP0A03:00: host bridge window [io 0x0d00-0xffff]
[ 0.059000] pci_root PNP0A03:00: host bridge window [mem 0x000a0000-0x000bffff]
[ 0.059826] pci_root PNP0A03:00: host bridge window [mem 0x80000000-0xfebfffff]
[ 0.060033] PCI host bridge to bus 0000:00
[ 0.061006] pci_bus 0000:00: root bus resource [io 0x0000-0x0cf7]
[ 0.061997] pci_bus 0000:00: root bus resource [io 0x0d00-0xffff]
[ 0.062692] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff]
[ 0.062996] pci_bus 0000:00: root bus resource [mem 0x80000000-0xfebfffff]
[ 0.069435] pci 0000:00:01.3: quirk: [io 0xb000-0xb03f] claimed by PIIX4 ACPI
[ 0.070009] pci 0000:00:01.3: quirk: [io 0xb100-0xb10f] claimed by PIIX4 SMB
[ 0.094617] pci0000:00: Unable to request _OSC control (_OSC support mask: 0x1e)
[ 0.097206] ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
[ 0.098028] ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
[ 0.098799] ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
[ 0.099248] ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)
[ 0.100225] ACPI: PCI Interrupt Link [LNKS] (IRQs *9)
[ 0.101133] vgaarb: device added: PCI:0000:00:02.0,decodes=io+mem,owns=io+mem,locks=none
[ 0.101997] vgaarb: loaded
[ 0.102314] vgaarb: bridge control possible 0000:00:02.0
[ 0.103078] SCSI subsystem initialized
[ 0.103682] usbcore: registered new interface driver usbfs
[ 0.104027] usbcore: registered new interface driver hub
[ 0.105033] usbcore: registered new device driver usb
[ 0.105750] Advanced Linux Sound Architecture Driver Version 1.0.25.
[ 0.105997] PCI: Using ACPI for IRQ routing
[ 0.107288] cfg80211: Calling CRDA to update world regulatory domain
[ 0.108086] NetLabel: Initializing
[ 0.108482] NetLabel: domain hash size = 128
[ 0.108999] NetLabel: protocols = UNLABELED CIPSOv4
[ 0.109572] NetLabel: unlabeled traffic allowed by default
[ 0.110073] HPET: 3 timers in total, 0 timers will be used for per-cpu timer
[ 0.111012] hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0
[ 0.112028] hpet0: 3 comparators, 64-bit 100.000000 MHz counter
[ 0.118003] Switching to clocksource hpet
[ 0.119594] pnp: PnP ACPI init
[ 0.119953] ACPI: bus type pnp registered
[ 0.121314] pnp: PnP ACPI: found 8 devices
[ 0.121817] ACPI: ACPI bus type pnp unregistered
[ 0.130081] NET: Registered protocol family 2
[ 0.130657] IP route cache hash table entries: 1024 (order: 1, 8192 bytes)
[ 0.131565] TCP established hash table entries: 4096 (order: 4, 65536 bytes)
[ 0.132452] TCP bind hash table entries: 4096 (order: 4, 65536 bytes)
[ 0.133220] TCP: Hash tables configured (established 4096 bind 4096)
[ 0.133937] TCP: reno registered
[ 0.134345] UDP hash table entries: 128 (order: 0, 4096 bytes)
[ 0.135085] UDP-Lite hash table entries: 128 (order: 0, 4096 bytes)
[ 0.135831] NET: Registered protocol family 1
[ 0.136464] RPC: Registered named UNIX socket transport module.
[ 0.137180] RPC: Registered udp transport module.
[ 0.137757] RPC: Registered tcp transport module.
[ 0.138326] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 0.139129] pci 0000:00:00.0: Limiting direct PCI/PCI transfers
[ 0.139814] pci 0000:00:01.0: PIIX3: Enabling Passive Release
[ 0.140565] pci 0000:00:01.0: Activating ISA DMA hang workarounds
[ 0.141380] Trying to unpack rootfs image as initramfs...
[ 0.150640] Freeing initrd memory: 608k freed
[ 0.151590] microcode: CPU0 sig=0x623, pf=0x0, revision=0x1
[ 0.152307] microcode: Microcode Update Driver: v2.00 <tigran@aivazian.fsnet.co.uk>, Peter Oruba
[ 0.153645] audit: initializing netlink socket (disabled)
[ 0.154311] type=2000 audit(1363325556.153:1): initialized
[ 0.172729] HugeTLB registered 2 MB page size, pre-allocated 0 pages
[ 0.176730] VFS: Disk quotas dquot_6.5.2
[ 0.177317] Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[ 0.178637] NFS: Registering the id_resolver key type
[ 0.179501] msgmni has been set to 222
[ 0.180358] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[ 0.181246] io scheduler noop registered
[ 0.181705] io scheduler deadline registered
[ 0.182316] io scheduler cfq registered (default)
[ 0.182968] pci_hotplug: PCI Hot Plug PCI Core version: 0.5
[ 0.183688] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
[ 0.184528] acpiphp: Slot [3] registered
[ 0.185069] acpiphp: Slot [4] registered
[ 0.185572] acpiphp: Slot [5] registered
[ 0.186110] acpiphp: Slot [6] registered
[ 0.186616] acpiphp: Slot [7] registered
[ 0.187154] acpiphp: Slot [8] registered
[ 0.187657] acpiphp: Slot [9] registered
[ 0.188195] acpiphp: Slot [10] registered
[ 0.188709] acpiphp: Slot [11] registered
[ 0.189257] acpiphp: Slot [12] registered
[ 0.189816] acpiphp: Slot [13] registered
[ 0.190362] acpiphp: Slot [14] registered
[ 0.190878] acpiphp: Slot [15] registered
[ 0.191477] acpiphp: Slot [16] registered
[ 0.191987] acpiphp: Slot [17] registered
[ 0.192540] acpiphp: Slot [18] registered
[ 0.193086] acpiphp: Slot [19] registered
[ 0.193640] acpiphp: Slot [20] registered
[ 0.194187] acpiphp: Slot [21] registered
[ 0.194742] acpiphp: Slot [22] registered
[ 0.195290] acpiphp: Slot [23] registered
[ 0.195797] acpiphp: Slot [24] registered
[ 0.196346] acpiphp: Slot [25] registered
[ 0.196861] acpiphp: Slot [26] registered
[ 0.197452] acpiphp: Slot [27] registered
[ 0.197962] acpiphp: Slot [28] registered
[ 0.198517] acpiphp: Slot [29] registered
[ 0.199068] acpiphp: Slot [30] registered
[ 0.199580] acpiphp: Slot [31] registered
[ 0.200289] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
[ 0.201178] ACPI: Power Button [PWRF]
[ 0.203226] ACPI: PCI Interrupt Link [LNKD] enabled at IRQ 11
[ 0.205056] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[ 0.471590] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 0.496552] 00:06: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 0.497596] Non-volatile memory driver v1.3
[ 0.498115] Linux agpgart interface v0.103
[ 0.498758] [drm] Initialized drm 1.1.0 20060810
[ 0.499330] [drm:i915_init] *ERROR* drm/i915 can't work without intel_agp module!
[ 0.501775] brd: module loaded
[ 0.503062] loop: module loaded
[ 0.506804] vda: unknown partition table
[ 0.508880] DC390: clustering now enabled by default. If you get problems load
[ 0.510423] with "disable_clustering=1" and report to maintainers
[ 0.511723] megasas: 00.00.06.14-rc1 Fri. Jan. 6 17:00:00 PDT 2012
[ 0.513783] scsi0 : ata_piix
[ 0.514260] scsi1 : ata_piix
[ 0.514674] ata1: PATA max MWDMA2 cmd 0x1f0 ctl 0x3f6 bmdma 0xc080 irq 14
[ 0.515490] ata2: PATA max MWDMA2 cmd 0x170 ctl 0x376 bmdma 0xc088 irq 15
[ 0.517372] pcnet32: pcnet32.c:v1.35 21.Apr.2008 tsbogend@alpha.franken.de
[ 0.518267] e100: Intel(R) PRO/100 Network Driver, 3.5.24-k2-NAPI
[ 0.518999] e100: Copyright(c) 1999-2006 Intel Corporation
[ 0.519692] e1000: Intel(R) PRO/1000 Network Driver - version 7.3.21-k8-NAPI
[ 0.520570] e1000: Copyright (c) 1999-2006 Intel Corporation.
[ 0.521348] ACPI: PCI Interrupt Link [LNKC] enabled at IRQ 10
[ 0.818823] ata2.00: ATAPI: QEMU DVD-ROM, 1.4.50, max UDMA/100
[ 0.819915] ata2.00: configured for MWDMA2
[ 0.820892] scsi 1:0:0:0: CD-ROM QEMU QEMU DVD-ROM 1.4. PQ: 0 ANSI: 5
[ 0.822640] sr0: scsi3-mmc drive: 4x/4x cd/rw xa/form2 tray
[ 0.823315] cdrom: Uniform CD-ROM driver Revision: 3.20
[ 0.824467] sr 1:0:0:0: Attached scsi generic sg0 type 5
[ 0.850040] e1000 0000:00:03.0: eth0: (PCI:33MHz:32-bit) 52:54:00:12:34:56
[ 0.850891] e1000 0000:00:03.0: eth0: Intel(R) PRO/1000 Network Connection
[ 0.851750] sky2: driver version 1.30
[ 0.852495] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.853319] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[ 0.854106] uhci_hcd: USB Universal Host Controller Interface driver
[ 0.854910] usbcore: registered new interface driver usblp
[ 0.855617] Initializing USB Mass Storage driver...
[ 0.856242] usbcore: registered new interface driver usb-storage
[ 0.856921] USB Mass Storage support registered.
[ 0.857567] usbcore: registered new interface driver libusual
[ 0.858337] i8042: PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
[ 0.859890] serio: i8042 KBD port at 0x60,0x64 irq 1
[ 0.860503] serio: i8042 AUX port at 0x60,0x64 irq 12
[ 0.861260] mousedev: PS/2 mouse device common for all mice
[ 0.862317] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input1
[ 0.863440] rtc_cmos 00:01: RTC can wake from S4
[ 0.866320] rtc_cmos 00:01: rtc core: registered rtc_cmos as rtc0
[ 0.867146] rtc0: alarms up to one day, 114 bytes nvram, hpet irqs
[ 0.868095] device-mapper: ioctl: 4.22.0-ioctl (2011-10-19) initialised: dm-devel@redhat.com
[ 0.869143] cpuidle: using governor ladder
[ 0.869618] cpuidle: using governor menu
[ 0.870103] EFI Variables Facility v0.08 2004-May-17
[ 0.871534] usbcore: registered new interface driver usbhid
[ 0.872203] usbhid: USB HID core driver
[ 0.873144] Netfilter messages via NETLINK v0.30.
[ 0.873690] nf_conntrack version 0.5.0 (889 buckets, 3556 max)
[ 0.874481] ctnetlink v0.93: registering with nfnetlink.
[ 0.875199] ip_tables: (C) 2000-2006 Netfilter Core Team
[ 0.875822] TCP: cubic registered
[ 0.876243] Initializing XFRM netlink socket
[ 0.876940] NET: Registered protocol family 10
[ 0.877667] ip6_tables: (C) 2000-2006 Netfilter Core Team
[ 0.878329] IPv6 over IPv4 tunneling driver
[ 0.878955] NET: Registered protocol family 17
[ 0.879504] Registering the dns_resolver key type
[ 0.880219] registered taskstats version 1
[ 0.880864] Magic number: 5:114:517
[ 0.881356] console [netcon0] enabled
[ 0.881782] netconsole: network logging started
[ 0.882361] ALSA device list:
[ 0.882723] No soundcards found.
[ 0.884214] Freeing unused kernel memory: 584k freed
[ 0.884907] Write protecting the kernel read-only data: 12288k
[ 0.887218] Freeing unused kernel memory: 640k freed
[ 0.891939] Freeing unused kernel memory: 1724k freed
Setting guest RANDOM seed to 26105
*** Running tests ***
[1;32m/tests/virtio-blk-drive-serial.sh[0m
Running test /tests/virtio-blk-drive-serial.sh...drive has wrong serial!
Expected '0123456789abcdefghi', got '8\x05\x7f'
FAILED (2)
Regards,
Anthony Liguori
> ---
> blockdev.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 59 insertions(+), 10 deletions(-)
>
> diff --git a/blockdev.c b/blockdev.c
> index d679174..d0fd1e2 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,36 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
> bool copy_on_read;
> int ret;
> Error *error = NULL;
> + QemuOpts *opts;
> + QDict *bs_opts;
> + const char *id;
>
> 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. */
> + id = qemu_opts_id(all_opts);
> + opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error);
> + if (error_is_set(&error)) {
> + qerror_report_err(error);
> + error_free(error);
> + return NULL;
> + }
> +
> + 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;
> + }
> +
> + if (id) {
> + qdict_del(bs_opts, "id");
> + }
> +
> /* extract parameters */
> bus_id = qemu_opt_get_number(opts, "bus", 0);
> unit_id = qemu_opt_get_number(opts, "unit", -1);
> @@ -564,7 +591,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);
> @@ -587,17 +614,20 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
> case IF_MTD:
> break;
> case IF_VIRTIO:
> + {
> /* add virtio block device */
> - opts = qemu_opts_create_nofail(qemu_find_opts("device"));
> + QemuOpts *devopts;
> + devopts = qemu_opts_create_nofail(qemu_find_opts("device"));
> if (arch_type == QEMU_ARCH_S390X) {
> - qemu_opt_set(opts, "driver", "virtio-blk-s390");
> + qemu_opt_set(devopts, "driver", "virtio-blk-s390");
> } else {
> - qemu_opt_set(opts, "driver", "virtio-blk-pci");
> + qemu_opt_set(devopts, "driver", "virtio-blk-pci");
> }
> - qemu_opt_set(opts, "drive", dinfo->id);
> + qemu_opt_set(devopts, "drive", dinfo->id);
> if (devaddr)
> - qemu_opt_set(opts, "addr", devaddr);
> + qemu_opt_set(devopts, "addr", devaddr);
> break;
> + }
> default:
> abort();
> }
> @@ -635,7 +665,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 +681,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 +1498,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 +1619,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.4
^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 07/13] qcow2: Allow lazy refcounts to be enabled on the command line
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (5 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 06/13] block: Support driver specific options in drive_init() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-14 14:45 ` Eric Blake
2013-03-12 14:41 ` [Qemu-devel] [PATCH 08/13] qcow2: flush refcount cache correctly in alloc_refcount_block() Kevin Wolf
` (5 subsequent siblings)
12 siblings, 1 reply; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
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>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@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.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [Qemu-devel] [PATCH 07/13] qcow2: Allow lazy refcounts to be enabled on the command line
2013-03-12 14:41 ` [Qemu-devel] [PATCH 07/13] qcow2: Allow lazy refcounts to be enabled on the command line Kevin Wolf
@ 2013-03-14 14:45 ` Eric Blake
2013-03-14 15:00 ` Kevin Wolf
0 siblings, 1 reply; 19+ messages in thread
From: Eric Blake @ 2013-03-14 14:45 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel, anthony
[-- Attachment #1: Type: text/plain, Size: 672 bytes --]
On 03/12/2013 08:41 AM, 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.
Question - how would I get at the lazy_refcounts option when hotplugging
a drive after the fact? In other words, we need to wire up access to
per-format options into QMP, to match what we have done on the command line.
--
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] 19+ messages in thread
* Re: [Qemu-devel] [PATCH 07/13] qcow2: Allow lazy refcounts to be enabled on the command line
2013-03-14 14:45 ` Eric Blake
@ 2013-03-14 15:00 ` Kevin Wolf
0 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-14 15:00 UTC (permalink / raw)
To: Eric Blake; +Cc: qemu-devel, anthony
Am 14.03.2013 um 15:45 hat Eric Blake geschrieben:
> On 03/12/2013 08:41 AM, 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.
>
> Question - how would I get at the lazy_refcounts option when hotplugging
> a drive after the fact? In other words, we need to wire up access to
> per-format options into QMP, to match what we have done on the command line.
We do and I hope I'll get to it soon. Maybe we should create a wiki page
for all open -blockdev tasks.
Another thing that is yet unclear is how to make these options
discoverable. At the moment you just have to know that qcow2 accepts a
lazy_refcounts option.
Kevin
^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 08/13] qcow2: flush refcount cache correctly in alloc_refcount_block()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (6 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 07/13] qcow2: Allow lazy refcounts to be enabled on the command line Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 09/13] qcow2: flush refcount cache correctly in qcow2_write_snapshots() Kevin Wolf
` (4 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Stefan Hajnoczi <stefanha@redhat.com>
update_refcount() affects the refcount cache, it does not write to disk.
Therefore bdrv_flush(bs->file) does nothing. We need to flush the
refcount cache in order to write out the refcount updates!
While we're here also add error returns when qcow2_cache_flush() fails.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-refcount.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 55543ed..e8b5d0a 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -201,7 +201,10 @@ static int alloc_refcount_block(BlockDriverState *bs,
*refcount_block = NULL;
/* We write to the refcount table, so we might depend on L2 tables */
- qcow2_cache_flush(bs, s->l2_table_cache);
+ ret = qcow2_cache_flush(bs, s->l2_table_cache);
+ if (ret < 0) {
+ return ret;
+ }
/* Allocate the refcount block itself and mark it as used */
int64_t new_block = alloc_clusters_noref(bs, s->cluster_size);
@@ -237,7 +240,10 @@ static int alloc_refcount_block(BlockDriverState *bs,
goto fail_block;
}
- bdrv_flush(bs->file);
+ ret = qcow2_cache_flush(bs, s->refcount_block_cache);
+ if (ret < 0) {
+ goto fail_block;
+ }
/* Initialize the new refcount block only after updating its refcount,
* update_refcount uses the refcount cache itself */
--
1.8.1.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 09/13] qcow2: flush refcount cache correctly in qcow2_write_snapshots()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (7 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 08/13] qcow2: flush refcount cache correctly in alloc_refcount_block() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 10/13] qcow2: set L2 cache dependency in qcow2_alloc_bytes() Kevin Wolf
` (3 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Stefan Hajnoczi <stefanha@redhat.com>
Since qcow2 metadata is cached we need to flush the caches, not just the
underlying file. Use bdrv_flush(bs) instead of bdrv_flush(bs->file).
Also add the error return path when bdrv_flush() fails and move the
flush after checking for qcow2_alloc_clusters() failure so that the
qcow2_alloc_clusters() error return value takes precedence.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-snapshot.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index eb8fcd5..f4719d9 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -180,11 +180,14 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
/* Allocate space for the new snapshot list */
snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);
- bdrv_flush(bs->file);
offset = snapshots_offset;
if (offset < 0) {
return offset;
}
+ ret = bdrv_flush(bs);
+ if (ret < 0) {
+ return ret;
+ }
/* Write all snapshots to the new list */
for(i = 0; i < s->nb_snapshots; i++) {
--
1.8.1.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 10/13] qcow2: set L2 cache dependency in qcow2_alloc_bytes()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (8 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 09/13] qcow2: flush refcount cache correctly in qcow2_write_snapshots() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 11/13] qcow2: flush in qcow2_update_snapshot_refcount() Kevin Wolf
` (2 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Stefan Hajnoczi <stefanha@redhat.com>
Compressed writes use qcow2_alloc_bytes() to allocate space with byte
granularity. The affected clusters' refcounts will be incremented but
we do not need to flush yet.
Set a L2 cache dependency on the refcount block cache, so that the
refcounts get written out before the L2 updates.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-refcount.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index e8b5d0a..4d9df5f 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -669,7 +669,11 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
}
}
- bdrv_flush(bs->file);
+ /* The cluster refcount was incremented, either by qcow2_alloc_clusters()
+ * or explicitly by update_cluster_refcount(). Refcount blocks must be
+ * flushed before the caller's L2 table updates.
+ */
+ qcow2_cache_set_dependency(bs, s->l2_table_cache, s->refcount_block_cache);
return offset;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 11/13] qcow2: flush in qcow2_update_snapshot_refcount()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (9 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 10/13] qcow2: set L2 cache dependency in qcow2_alloc_bytes() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 12/13] qcow2: drop flush in update_cluster_refcount() Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 13/13] qcow2: drop unnecessary flush in qcow2_update_snapshot_refcount() Kevin Wolf
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Stefan Hajnoczi <stefanha@redhat.com>
Users of qcow2_update_snapshot_refcount() do not flush consistently.
qcow2_snapshot_create() flushes but qcow2_snapshot_goto() and
qcow2_snapshot_delete() do not.
Solve this by moving the bdrv_flush() into
qcow2_update_snapshot_refcount().
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-refcount.c | 2 +-
block/qcow2-snapshot.c | 5 -----
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 4d9df5f..3d29d30 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -851,7 +851,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
}
}
- ret = 0;
+ ret = bdrv_flush(bs);
fail:
if (l2_table) {
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index f4719d9..992a5c8 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -381,11 +381,6 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
goto fail;
}
- ret = bdrv_flush(bs);
- if (ret < 0) {
- goto fail;
- }
-
/* Append the new snapshot to the snapshot list */
new_snapshot_list = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
if (s->snapshots) {
--
1.8.1.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 12/13] qcow2: drop flush in update_cluster_refcount()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (10 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 11/13] qcow2: flush in qcow2_update_snapshot_refcount() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
2013-03-12 14:41 ` [Qemu-devel] [PATCH 13/13] qcow2: drop unnecessary flush in qcow2_update_snapshot_refcount() Kevin Wolf
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Stefan Hajnoczi <stefanha@redhat.com>
The update_cluster_refcount() function increments/decrements a cluster's
refcount and then returns the new refcount value.
There is no need to flush since both update_cluster_refcount() callers
already take care of this:
1. qcow2_alloc_bytes() calls update_cluster_refcount() when compressed
sectors will be appended to an existing cluster with enough free
space. qcow2_alloc_bytes() already flushes so there is no need to do
so in update_cluster_refcount().
2. qcow2_update_snapshot_refcount() sets a cache dependency on refcounts
if it needs to update L2 entries. It also flushes before completing.
Removing this flush significantly speeds up qcow2 snapshot creation:
$ qemu-img create -f qcow2 test.qcow2 -o size=50G,preallocation=metadata
$ time qemu-img snapshot -c new test.qcow2
Time drops from more than 3 minutes to under 1 second.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-refcount.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 3d29d30..92519ea 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -532,8 +532,6 @@ static int update_cluster_refcount(BlockDriverState *bs,
return ret;
}
- bdrv_flush(bs->file);
-
return get_refcount(bs, cluster_index);
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 13/13] qcow2: drop unnecessary flush in qcow2_update_snapshot_refcount()
2013-03-12 14:41 [Qemu-devel] [PULL 00/13] Block patches Kevin Wolf
` (11 preceding siblings ...)
2013-03-12 14:41 ` [Qemu-devel] [PATCH 12/13] qcow2: drop flush in update_cluster_refcount() Kevin Wolf
@ 2013-03-12 14:41 ` Kevin Wolf
12 siblings, 0 replies; 19+ messages in thread
From: Kevin Wolf @ 2013-03-12 14:41 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Stefan Hajnoczi <stefanha@redhat.com>
We already flush when the function completes. There is no need to flush
after every compressed cluster.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-refcount.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 92519ea..9bfb390 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -790,10 +790,6 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
if (ret < 0) {
goto fail;
}
-
- /* TODO Flushing once for the whole function should
- * be enough */
- bdrv_flush(bs->file);
}
/* compressed clusters are never modified */
refcount = 2;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 19+ messages in thread