mirror_qemu/block
Markus Armbruster e5af0da1dc block: Fix -blockdev for certain non-string scalars
Configuration flows through the block subsystem in a rather peculiar
way.  Configuration made with -drive enters it as QemuOpts.
Configuration made with -blockdev / blockdev-add enters it as QAPI
type BlockdevOptions.  The block subsystem uses QDict, QemuOpts and
QAPI types internally.  The precise flow is next to impossible to
explain (I tried for this commit message, but gave up after wasting
several hours).  What I can explain is a flaw in the BlockDriver
interface that leads to this bug:

    $ qemu-system-x86_64 -blockdev node-name=n1,driver=nfs,server.type=inet,server.host=localhost,path=/foo/bar,user=1234
    qemu-system-x86_64: -blockdev node-name=n1,driver=nfs,server.type=inet,server.host=localhost,path=/foo/bar,user=1234: Internal error: parameter user invalid

QMP blockdev-add is broken the same way.

Here's what happens.  The block layer passes configuration represented
as flat QDict (with dotted keys) to BlockDriver methods
.bdrv_file_open().  The QDict's members are typed according to the
QAPI schema.

nfs_file_open() converts it to QAPI type BlockdevOptionsNfs, with
qdict_crumple() and a qobject input visitor.

This visitor comes in two flavors.  The plain flavor requires scalars
to be typed according to the QAPI schema.  That's the case here.  The
keyval flavor requires string scalars.  That's not the case here.
nfs_file_open() uses the latter, and promptly falls apart for members
@user, @group, @tcp-syn-count, @readahead-size, @page-cache-size,
@debug.

Switching to the plain flavor would fix -blockdev, but break -drive,
because there the scalars arrive in nfs_file_open() as strings.

The proper fix would be to replace the QDict by QAPI type
BlockdevOptions in the BlockDriver interface.  Sadly, that's beyond my
reach right now.

Next best would be to fix the block layer to always pass correctly
typed QDicts to the BlockDriver methods.  Also beyond my reach.

What I can do is throw another hack onto the pile: have
nfs_file_open() convert all members to string, so use of the keyval
flavor actually works, by replacing qdict_crumple() by new function
qdict_crumple_for_keyval_qiv().

The pattern "pass result of qdict_crumple() to
qobject_input_visitor_new_keyval()" occurs several times more:

* qemu_rbd_open()

  Same issue as nfs_file_open(), but since BlockdevOptionsRbd has only
  string members, its only a latent bug.  Fix it anyway.

* parallels_co_create_opts(), qcow_co_create_opts(),
  qcow2_co_create_opts(), bdrv_qed_co_create_opts(),
  sd_co_create_opts(), vhdx_co_create_opts(), vpc_co_create_opts()

  These work, because they create the QDict with
  qemu_opts_to_qdict_filtered(), which creates only string scalars.
  The function sports a TODO comment asking for better typing; that's
  going to be fun.  Use qdict_crumple_for_keyval_qiv() to be safe.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-06-15 14:49:44 +02:00
..
Makefile.objs block: Add COR filter driver 2018-05-15 16:15:21 +02:00
accounting.c block/accounting: introduce latency histogram 2018-03-19 14:58:37 -05:00
backup.c job: Add error message for failing jobs 2018-05-30 13:31:01 +02:00
blkdebug.c block: Support BDRV_REQ_WRITE_UNCHANGED in filters 2018-05-15 16:15:21 +02:00
blkreplay.c block: Support BDRV_REQ_WRITE_UNCHANGED in filters 2018-05-15 16:15:21 +02:00
blkverify.c block: Support BDRV_REQ_WRITE_UNCHANGED in filters 2018-05-15 16:15:21 +02:00
block-backend.c block-backend: Add blk_co_copy_range 2018-06-01 14:41:48 +01:00
bochs.c block: Deprecate bdrv_set_read_only() and users 2017-11-17 13:35:59 +01:00
cloop.c block: Deprecate bdrv_set_read_only() and users 2017-11-17 13:35:59 +01:00
commit.c job: Add error message for failing jobs 2018-05-30 13:31:01 +02:00
copy-on-read.c block: Support BDRV_REQ_WRITE_UNCHANGED in filters 2018-05-15 16:15:21 +02:00
create.c block/create: Mark blockdev-create stable 2018-05-30 13:31:18 +02:00
crypto.c block: use local path for local headers 2018-05-31 04:16:06 +03:00
crypto.h qcow: convert QCow to use QCryptoBlock for encryption 2017-07-11 17:44:56 +02:00
curl.c Move include qemu/option.h from qemu-common.h to actual users 2018-02-09 13:52:16 +01:00
dirty-bitmap.c qapi: add x-block-dirty-bitmap-merge 2018-06-11 14:53:32 -04:00
dmg-bz2.c dmg: Move libbz2 code to dmg-bz2.so 2016-10-07 14:14:06 +02:00
dmg.c block: Deprecate bdrv_set_read_only() and users 2017-11-17 13:35:59 +01:00
dmg.h block: remove "qemu/osdep.h" from header file 2017-12-18 17:07:02 +03:00
file-posix.c block/file-posix: File locking during creation 2018-06-11 16:18:45 +02:00
file-win32.c file-win32: Switch to byte-based callbacks 2018-05-15 16:11:41 +02:00
gluster.c block: Add block-specific QDict header 2018-06-15 14:49:44 +02:00
io.c block: Introduce API for copy offloading 2018-06-01 14:41:47 +01:00
iscsi-opts.c Move include qemu/option.h from qemu-common.h to actual users 2018-02-09 13:52:16 +01:00
iscsi.c block: Add block-specific QDict header 2018-06-15 14:49:44 +02:00
linux-aio.c block: explicitly acquire aiocontext in aio callbacks that need it 2017-02-21 11:39:39 +00:00
mirror.c job: Add error message for failing jobs 2018-05-30 13:31:01 +02:00
nbd-client.c nbd/client: Relax handling of large NBD_CMD_BLOCK_STATUS reply 2018-05-04 08:23:39 -05:00
nbd-client.h nbd: BLOCK_STATUS for standard get_block_status function: client part 2018-03-13 15:43:48 -05:00
nbd.c block: Add block-specific QDict header 2018-06-15 14:49:44 +02:00
nfs.c block: Fix -blockdev for certain non-string scalars 2018-06-15 14:49:44 +02:00
null.c null: Switch to byte-based read/write 2018-05-15 16:11:41 +02:00
nvme.c qobject: Modify qobject_ref() to return obj 2018-05-04 08:27:53 +02:00
parallels.c block: Fix -blockdev for certain non-string scalars 2018-06-15 14:49:44 +02:00
parallels.h Clean up includes 2018-02-09 05:05:11 +01:00
qapi.c qobject: Replace qobject_incref/QINCREF qobject_decref/QDECREF 2018-05-04 08:27:53 +02:00
qcow.c block: Fix -blockdev for certain non-string scalars 2018-06-15 14:49:44 +02:00
qcow2-bitmap.c block/qcow2-bitmap: fix free_bitmap_clusters 2018-06-11 16:18:45 +02:00
qcow2-cache.c qcow2: Allow configuring the L2 slice size 2018-02-13 17:00:00 +01:00
qcow2-cluster.c block: use local path for local headers 2018-05-31 04:16:06 +03:00
qcow2-refcount.c qcow2: Repair OFLAG_COPIED when fixing leaks 2018-06-11 16:18:45 +02:00
qcow2-snapshot.c block: use local path for local headers 2018-05-31 04:16:06 +03:00
qcow2.c block: Fix -blockdev for certain non-string scalars 2018-06-15 14:49:44 +02:00
qcow2.h qcow2: Give the refcount cache the minimum possible size by default 2018-05-15 16:15:21 +02:00
qed-check.c block: convert bdrv_check callback to coroutine_fn 2018-03-09 15:17:47 +01:00
qed-cluster.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed-l2-cache.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed-table.c block: convert bdrv_check callback to coroutine_fn 2018-03-09 15:17:47 +01:00
qed.c block: Fix -blockdev for certain non-string scalars 2018-06-15 14:49:44 +02:00
qed.h qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
quorum.c block: Add block-specific QDict header 2018-06-15 14:49:44 +02:00
raw-format.c raw: Implement copy offloading 2018-06-01 14:41:47 +01:00
rbd.c block: Fix -blockdev for certain non-string scalars 2018-06-15 14:49:44 +02:00
replication.c job: Move completion and cancellation to Job 2018-05-23 14:30:51 +02:00
sheepdog.c block: Fix -blockdev for certain non-string scalars 2018-06-15 14:49:44 +02:00
snapshot.c block: Add block-specific QDict header 2018-06-15 14:49:44 +02:00
ssh.c block: Add block-specific QDict header 2018-06-15 14:49:44 +02:00
stream.c job: Add error message for failing jobs 2018-05-30 13:31:01 +02:00
throttle-groups.c Include less of the generated modular QAPI headers 2018-03-02 13:45:50 -06:00
throttle.c throttle: Fix crash on reopen 2018-06-11 16:18:45 +02:00
trace-events job: Move completion and cancellation to Job 2018-05-23 14:30:51 +02:00
vdi.c vdi: Fix vdi_co_do_create() return value 2018-05-29 22:19:57 +02:00
vhdx-endian.c block: use local path for local headers 2018-05-31 04:16:06 +03:00
vhdx-log.c block: use local path for local headers 2018-05-31 04:16:06 +03:00
vhdx.c block: Fix -blockdev for certain non-string scalars 2018-06-15 14:49:44 +02:00
vhdx.h block: vhdx - update PAYLOAD_BLOCK_UNMAPPED value to match 1.00 spec 2014-12-12 15:42:22 +00:00
vmdk.c vmdk: return ERROR when cluster sector is larger than vmdk limitation 2018-03-26 21:17:24 +02:00
vpc.c block: Fix -blockdev for certain non-string scalars 2018-06-15 14:49:44 +02:00
vvfat.c block: Add block-specific QDict header 2018-06-15 14:49:44 +02:00
vxhs.c block: Add block-specific QDict header 2018-06-15 14:49:44 +02:00
win32-aio.c file-win32: Switch to byte-based callbacks 2018-05-15 16:11:41 +02:00
write-threshold.c Include less of the generated modular QAPI headers 2018-03-02 13:45:50 -06:00