* [PULL 00/29] Block layer patches
@ 2020-03-06 17:14 Kevin Wolf
2020-03-06 17:14 ` [PULL 01/29] qcow2: Fix alloc_cluster_abort() for pre-existing clusters Kevin Wolf
` (30 more replies)
0 siblings, 31 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
The following changes since commit f4c4357fbfca0fb14e477bf661ae7384b4b9b283:
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-docs-20200306' into staging (2020-03-06 11:11:54 +0000)
are available in the Git repository at:
git://repo.or.cz/qemu/kevin.git tags/for-upstream
for you to fetch changes up to 1de6b45fb5c1489b450df7d1a4c692bba9678ce6:
block: bdrv_reopen() with backing file in different AioContext (2020-03-06 17:34:09 +0100)
----------------------------------------------------------------
Block layer patches:
- Add qemu-storage-daemon (still experimental)
- rbd: Add support for ceph namespaces
- Fix bdrv_reopen() with backing file in different AioContext
- qcow2: Fix read-write reopen with persistent dirty bitmaps
- qcow2: Fix alloc_cluster_abort() for pre-existing clusters
----------------------------------------------------------------
Florian Florensa (1):
block/rbd: Add support for ceph namespaces
Kevin Wolf (22):
qemu-storage-daemon: Add barebone tool
stubs: Add arch_type
block: Move system emulator QMP commands to block/qapi-sysemu.c
block: Move common QMP commands to block-core QAPI module
block: Move sysemu QMP commands to QAPI block module
qemu-storage-daemon: Add --blockdev option
qapi: Flatten object-add
qemu-storage-daemon: Add --object option
qemu-storage-daemon: Add --nbd-server option
blockdev-nbd: Boxed argument type for nbd-server-add
qemu-storage-daemon: Add --export option
qemu-storage-daemon: Add main loop
qemu-storage-daemon: Add --chardev option
stubs: Update monitor stubs for qemu-storage-daemon
qapi: Create 'pragma' module
monitor: Create QAPIfied monitor_init()
qmp: Fail gracefully if chardev is already in use
hmp: Fail gracefully if chardev is already in use
monitor: Add allow_hmp parameter to monitor_init()
qemu-storage-daemon: Add --monitor option
iotests: Refactor blockdev-reopen test for iothreads
block: bdrv_reopen() with backing file in different AioContext
Max Reitz (4):
qcow2: Fix alloc_cluster_abort() for pre-existing clusters
iotests/026: Test EIO on preallocated zero cluster
iotests/026: Test EIO on allocation in a data-file
block: Fix leak in bdrv_create_file_fallback()
Peter Krempa (2):
block: Introduce 'bdrv_reopen_commit_post' step
block/qcow2: Move bitmap reopen into bdrv_reopen_commit_post
qapi/block-core.json | 733 +++++++++++++++++------------------
qapi/block.json | 512 ++++++++++++++----------
qapi/control.json | 37 ++
qapi/pragma.json | 24 ++
qapi/qapi-schema.json | 25 +-
qapi/qom.json | 12 +-
qapi/transaction.json | 2 +-
docs/system/deprecated.rst | 5 +
configure | 2 +-
include/block/block_int.h | 1 +
include/block/nbd.h | 1 +
include/monitor/monitor.h | 6 +-
include/qom/object_interfaces.h | 7 +
include/sysemu/arch_init.h | 2 +
block.c | 44 ++-
block/qapi-sysemu.c | 590 ++++++++++++++++++++++++++++
block/qcow2-cluster.c | 2 +-
block/qcow2.c | 7 +-
block/rbd.c | 44 ++-
blockdev-nbd.c | 40 +-
blockdev.c | 559 --------------------------
chardev/char.c | 8 +-
gdbstub.c | 2 +-
hw/block/xen-block.c | 11 +-
monitor/hmp-cmds.c | 21 +-
monitor/hmp.c | 8 +-
monitor/misc.c | 2 +
monitor/monitor.c | 86 ++--
monitor/qmp-cmds.c | 2 +-
monitor/qmp.c | 11 +-
qemu-storage-daemon.c | 340 ++++++++++++++++
qom/qom-qmp-cmds.c | 42 +-
stubs/arch_type.c | 4 +
stubs/monitor-core.c | 21 +
stubs/monitor.c | 17 +-
tests/test-util-sockets.c | 4 +-
scripts/qapi/gen.py | 5 +
Makefile | 37 ++
Makefile.objs | 9 +
block/Makefile.objs | 4 +-
monitor/Makefile.objs | 2 +
qapi/Makefile.objs | 7 +-
qom/Makefile.objs | 1 +
storage-daemon/Makefile.objs | 1 +
storage-daemon/qapi/Makefile.objs | 1 +
storage-daemon/qapi/qapi-schema.json | 26 ++
stubs/Makefile.objs | 2 +
tests/qemu-iotests/026 | 53 +++
tests/qemu-iotests/026.out | 16 +
tests/qemu-iotests/026.out.nocache | 16 +
tests/qemu-iotests/245 | 45 ++-
tests/qemu-iotests/245.out | 4 +-
52 files changed, 2157 insertions(+), 1306 deletions(-)
create mode 100644 qapi/pragma.json
create mode 100644 block/qapi-sysemu.c
create mode 100644 qemu-storage-daemon.c
create mode 100644 stubs/arch_type.c
create mode 100644 stubs/monitor-core.c
create mode 100644 storage-daemon/Makefile.objs
create mode 100644 storage-daemon/qapi/Makefile.objs
create mode 100644 storage-daemon/qapi/qapi-schema.json
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PULL 01/29] qcow2: Fix alloc_cluster_abort() for pre-existing clusters
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 02/29] iotests/026: Test EIO on preallocated zero cluster Kevin Wolf
` (29 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
From: Max Reitz <mreitz@redhat.com>
handle_alloc() reuses preallocated zero clusters. If anything goes
wrong during the data write, we do not change their L2 entry, so we
must not let qcow2_alloc_cluster_abort() free them.
Fixes: 8b24cd141549b5b264baeddd4e72902cfb5de23b
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200225143130.111267-2-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-cluster.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 78c95dfa16..17f1363279 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1026,7 +1026,7 @@ err:
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
{
BDRVQcow2State *s = bs->opaque;
- if (!has_data_file(bs)) {
+ if (!has_data_file(bs) && !m->keep_old_clusters) {
qcow2_free_clusters(bs, m->alloc_offset,
m->nb_clusters << s->cluster_bits,
QCOW2_DISCARD_NEVER);
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 02/29] iotests/026: Test EIO on preallocated zero cluster
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
2020-03-06 17:14 ` [PULL 01/29] qcow2: Fix alloc_cluster_abort() for pre-existing clusters Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 03/29] iotests/026: Test EIO on allocation in a data-file Kevin Wolf
` (28 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
From: Max Reitz <mreitz@redhat.com>
Test what happens when writing data to a preallocated zero cluster, but
the data write fails.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200225143130.111267-3-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
tests/qemu-iotests/026 | 21 +++++++++++++++++++++
tests/qemu-iotests/026.out | 10 ++++++++++
tests/qemu-iotests/026.out.nocache | 10 ++++++++++
3 files changed, 41 insertions(+)
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
index a4aa74764f..0c1273c339 100755
--- a/tests/qemu-iotests/026
+++ b/tests/qemu-iotests/026
@@ -218,6 +218,27 @@ _make_test_img 64M
$QEMU_IO -c "write 0 1M" -c "write 0 1M" "$BLKDBG_TEST_IMG" | _filter_qemu_io
_check_test_img
+echo
+echo === Avoid freeing preallocated zero clusters on failure ===
+echo
+
+cat > "$TEST_DIR/blkdebug.conf" <<EOF
+[inject-error]
+event = "write_aio"
+errno = "5"
+once = "on"
+EOF
+
+_make_test_img $CLUSTER_SIZE
+# Create a preallocated zero cluster
+$QEMU_IO -c "write 0 $CLUSTER_SIZE" -c "write -z 0 $CLUSTER_SIZE" "$TEST_IMG" \
+ | _filter_qemu_io
+# Try to overwrite it (prompting an I/O error from blkdebug), thus
+# triggering the alloc abort code
+$QEMU_IO -c "write 0 $CLUSTER_SIZE" "$BLKDBG_TEST_IMG" | _filter_qemu_io
+
+_check_test_img
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
index ff0817b6f2..83989996ff 100644
--- a/tests/qemu-iotests/026.out
+++ b/tests/qemu-iotests/026.out
@@ -643,4 +643,14 @@ write failed: Input/output error
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
+
+=== Avoid freeing preallocated zero clusters on failure ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
+wrote 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+write failed: Input/output error
+No errors were found on the image.
*** done
diff --git a/tests/qemu-iotests/026.out.nocache b/tests/qemu-iotests/026.out.nocache
index 495d013007..9359d26d7e 100644
--- a/tests/qemu-iotests/026.out.nocache
+++ b/tests/qemu-iotests/026.out.nocache
@@ -651,4 +651,14 @@ write failed: Input/output error
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
+
+=== Avoid freeing preallocated zero clusters on failure ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
+wrote 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+write failed: Input/output error
+No errors were found on the image.
*** done
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 03/29] iotests/026: Test EIO on allocation in a data-file
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
2020-03-06 17:14 ` [PULL 01/29] qcow2: Fix alloc_cluster_abort() for pre-existing clusters Kevin Wolf
2020-03-06 17:14 ` [PULL 02/29] iotests/026: Test EIO on preallocated zero cluster Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 04/29] block: Fix leak in bdrv_create_file_fallback() Kevin Wolf
` (27 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
From: Max Reitz <mreitz@redhat.com>
Test what happens when writing data to an external data file, where the
write requires an L2 entry to be allocated, but the data write fails.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200225143130.111267-4-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
tests/qemu-iotests/026 | 32 ++++++++++++++++++++++++++++++
tests/qemu-iotests/026.out | 6 ++++++
tests/qemu-iotests/026.out.nocache | 6 ++++++
3 files changed, 44 insertions(+)
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
index 0c1273c339..b05a4692cf 100755
--- a/tests/qemu-iotests/026
+++ b/tests/qemu-iotests/026
@@ -30,6 +30,7 @@ _cleanup()
{
_cleanup_test_img
rm "$TEST_DIR/blkdebug.conf"
+ rm -f "$TEST_IMG.data_file"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -239,6 +240,37 @@ $QEMU_IO -c "write 0 $CLUSTER_SIZE" "$BLKDBG_TEST_IMG" | _filter_qemu_io
_check_test_img
+echo
+echo === Avoid freeing external data clusters on failure ===
+echo
+
+# Similar test as the last one, except we test what happens when there
+# is an error when writing to an external data file instead of when
+# writing to a preallocated zero cluster
+_make_test_img -o "data_file=$TEST_IMG.data_file" $CLUSTER_SIZE
+
+# Put blkdebug above the data-file, and a raw node on top of that so
+# that blkdebug will see a write_aio event and emit an error
+$QEMU_IO -c "write 0 $CLUSTER_SIZE" \
+ "json:{
+ 'driver': 'qcow2',
+ 'file': { 'driver': 'file', 'filename': '$TEST_IMG' },
+ 'data-file': {
+ 'driver': 'raw',
+ 'file': {
+ 'driver': 'blkdebug',
+ 'config': '$TEST_DIR/blkdebug.conf',
+ 'image': {
+ 'driver': 'file',
+ 'filename': '$TEST_IMG.data_file'
+ }
+ }
+ }
+ }" \
+ | _filter_qemu_io
+
+_check_test_img
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
index 83989996ff..c1b3b58482 100644
--- a/tests/qemu-iotests/026.out
+++ b/tests/qemu-iotests/026.out
@@ -653,4 +653,10 @@ wrote 1024/1024 bytes at offset 0
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write failed: Input/output error
No errors were found on the image.
+
+=== Avoid freeing external data clusters on failure ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024 data_file=TEST_DIR/t.IMGFMT.data_file
+write failed: Input/output error
+No errors were found on the image.
*** done
diff --git a/tests/qemu-iotests/026.out.nocache b/tests/qemu-iotests/026.out.nocache
index 9359d26d7e..8d5001648a 100644
--- a/tests/qemu-iotests/026.out.nocache
+++ b/tests/qemu-iotests/026.out.nocache
@@ -661,4 +661,10 @@ wrote 1024/1024 bytes at offset 0
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write failed: Input/output error
No errors were found on the image.
+
+=== Avoid freeing external data clusters on failure ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024 data_file=TEST_DIR/t.IMGFMT.data_file
+write failed: Input/output error
+No errors were found on the image.
*** done
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 04/29] block: Fix leak in bdrv_create_file_fallback()
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (2 preceding siblings ...)
2020-03-06 17:14 ` [PULL 03/29] iotests/026: Test EIO on allocation in a data-file Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 05/29] block: Introduce 'bdrv_reopen_commit_post' step Kevin Wolf
` (26 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
From: Max Reitz <mreitz@redhat.com>
@options is leaked by the first two return statements in this function.
Note that blk_new_open() takes the reference to @options even on
failure, so all we need to do to fix the leak is to move the QDict
allocation down to where we actually need it.
Reported-by: Coverity (CID 1419884)
Fixes: fd17146cd93d1704cd96d7c2757b325fc7aac6fd
("block: Generic file creation fallback")
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200225155618.133412-1-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/block.c b/block.c
index 1bdb9c679d..876bd45182 100644
--- a/block.c
+++ b/block.c
@@ -600,7 +600,7 @@ static int bdrv_create_file_fallback(const char *filename, BlockDriver *drv,
QemuOpts *opts, Error **errp)
{
BlockBackend *blk;
- QDict *options = qdict_new();
+ QDict *options;
int64_t size = 0;
char *buf = NULL;
PreallocMode prealloc;
@@ -623,6 +623,7 @@ static int bdrv_create_file_fallback(const char *filename, BlockDriver *drv,
return -ENOTSUP;
}
+ options = qdict_new();
qdict_put_str(options, "driver", drv->format_name);
blk = blk_new_open(filename, NULL, options,
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 05/29] block: Introduce 'bdrv_reopen_commit_post' step
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (3 preceding siblings ...)
2020-03-06 17:14 ` [PULL 04/29] block: Fix leak in bdrv_create_file_fallback() Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 06/29] block/qcow2: Move bitmap reopen into bdrv_reopen_commit_post Kevin Wolf
` (25 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
From: Peter Krempa <pkrempa@redhat.com>
Add another step in the reopen process where driver can execute code
after permission changes are comitted.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Message-Id: <adc02cf591c3cb34e98e33518eb1c540a0f27db1.1582893284.git.pkrempa@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
include/block/block_int.h | 1 +
block.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 6f9fd5e20e..f422c0bff0 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -122,6 +122,7 @@ struct BlockDriver {
int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
BlockReopenQueue *queue, Error **errp);
void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
+ void (*bdrv_reopen_commit_post)(BDRVReopenState *reopen_state);
void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
void (*bdrv_join_options)(QDict *options, QDict *old_options);
diff --git a/block.c b/block.c
index 876bd45182..aaa387504e 100644
--- a/block.c
+++ b/block.c
@@ -3695,6 +3695,15 @@ cleanup_perm:
}
}
}
+
+ if (ret == 0) {
+ QTAILQ_FOREACH_REVERSE(bs_entry, bs_queue, entry) {
+ BlockDriverState *bs = bs_entry->state.bs;
+
+ if (bs->drv->bdrv_reopen_commit_post)
+ bs->drv->bdrv_reopen_commit_post(&bs_entry->state);
+ }
+ }
cleanup:
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
if (ret) {
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 06/29] block/qcow2: Move bitmap reopen into bdrv_reopen_commit_post
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (4 preceding siblings ...)
2020-03-06 17:14 ` [PULL 05/29] block: Introduce 'bdrv_reopen_commit_post' step Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 07/29] qemu-storage-daemon: Add barebone tool Kevin Wolf
` (24 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
From: Peter Krempa <pkrempa@redhat.com>
The bitmap code requires writing the 'file' child when the qcow2 driver
is reopened in read-write mode.
If the 'file' child is being reopened due to a permissions change, the
modification is commited yet when qcow2_reopen_commit is called. This
means that any attempt to write the 'file' child will end with EBADFD
as the original fd was already closed.
Moving bitmap reopening to the new callback which is called after
permission modifications are commited fixes this as the file descriptor
will be replaced with the correct one.
The above problem manifests itself when reopening 'qcow2' format layer
which uses a 'file-posix' file child which was opened with the
'auto-read-only' property set.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Message-Id: <db118dbafe1955afbc0a18d3dd220931074ce349.1582893284.git.pkrempa@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index 3c754f616b..3640e8c07d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1884,6 +1884,11 @@ fail:
static void qcow2_reopen_commit(BDRVReopenState *state)
{
qcow2_update_options_commit(state->bs, state->opaque);
+ g_free(state->opaque);
+}
+
+static void qcow2_reopen_commit_post(BDRVReopenState *state)
+{
if (state->flags & BDRV_O_RDWR) {
Error *local_err = NULL;
@@ -1898,7 +1903,6 @@ static void qcow2_reopen_commit(BDRVReopenState *state)
bdrv_get_node_name(state->bs));
}
}
- g_free(state->opaque);
}
static void qcow2_reopen_abort(BDRVReopenState *state)
@@ -5534,6 +5538,7 @@ BlockDriver bdrv_qcow2 = {
.bdrv_close = qcow2_close,
.bdrv_reopen_prepare = qcow2_reopen_prepare,
.bdrv_reopen_commit = qcow2_reopen_commit,
+ .bdrv_reopen_commit_post = qcow2_reopen_commit_post,
.bdrv_reopen_abort = qcow2_reopen_abort,
.bdrv_join_options = qcow2_join_options,
.bdrv_child_perm = bdrv_format_default_perms,
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 07/29] qemu-storage-daemon: Add barebone tool
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (5 preceding siblings ...)
2020-03-06 17:14 ` [PULL 06/29] block/qcow2: Move bitmap reopen into bdrv_reopen_commit_post Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 08/29] stubs: Add arch_type Kevin Wolf
` (23 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
This adds a new binary qemu-storage-daemon that doesn't yet do more than
some typical initialisation for tools and parsing the basic command
options --version, --help and --trace.
Even though this doesn't add any options yet that create things (like
--object or --blockdev), already document that we're planning to process
them in the order they are given on the command line rather than trying
(and failing, like vl.c) to resolve dependencies between options
automatically.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-2-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
configure | 2 +-
qemu-storage-daemon.c | 127 ++++++++++++++++++++++++++++++++++++++++++
Makefile | 1 +
3 files changed, 129 insertions(+), 1 deletion(-)
create mode 100644 qemu-storage-daemon.c
diff --git a/configure b/configure
index fab6281eb7..cbf864bff1 100755
--- a/configure
+++ b/configure
@@ -6316,7 +6316,7 @@ tools=""
if test "$want_tools" = "yes" ; then
tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) qemu-edid\$(EXESUF) $tools"
if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
- tools="qemu-nbd\$(EXESUF) $tools"
+ tools="qemu-nbd\$(EXESUF) qemu-storage-daemon\$(EXESUF) $tools"
fi
if [ "$ivshmem" = "yes" ]; then
tools="ivshmem-client\$(EXESUF) ivshmem-server\$(EXESUF) $tools"
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
new file mode 100644
index 0000000000..fc4aef572b
--- /dev/null
+++ b/qemu-storage-daemon.c
@@ -0,0 +1,127 @@
+/*
+ * QEMU storage daemon
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2019 Kevin Wolf <kwolf@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+
+#include <getopt.h>
+
+#include "block/block.h"
+#include "crypto/init.h"
+
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "qemu-version.h"
+#include "qemu/config-file.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+
+#include "trace/control.h"
+
+static void help(void)
+{
+ printf(
+"Usage: %s [options]\n"
+"QEMU storage daemon\n"
+"\n"
+" -h, --help display this help and exit\n"
+" -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
+" specify tracing options\n"
+" -V, --version output version information and exit\n"
+"\n"
+QEMU_HELP_BOTTOM "\n",
+ error_get_progname());
+}
+
+static void process_options(int argc, char *argv[])
+{
+ int c;
+
+ static const struct option long_options[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"trace", required_argument, NULL, 'T'},
+ {"version", no_argument, NULL, 'V'},
+ {0, 0, 0, 0}
+ };
+
+ /*
+ * In contrast to the system emulator, options are processed in the order
+ * they are given on the command lines. This means that things must be
+ * defined first before they can be referenced in another option.
+ */
+ while ((c = getopt_long(argc, argv, "hT:V", long_options, NULL)) != -1) {
+ switch (c) {
+ case '?':
+ exit(EXIT_FAILURE);
+ case 'h':
+ help();
+ exit(EXIT_SUCCESS);
+ case 'T':
+ {
+ char *trace_file = trace_opt_parse(optarg);
+ trace_init_file(trace_file);
+ g_free(trace_file);
+ break;
+ }
+ case 'V':
+ printf("qemu-storage-daemon version "
+ QEMU_FULL_VERSION "\n" QEMU_COPYRIGHT "\n");
+ exit(EXIT_SUCCESS);
+ default:
+ g_assert_not_reached();
+ }
+ }
+ if (optind != argc) {
+ error_report("Unexpected argument: %s", argv[optind]);
+ exit(EXIT_FAILURE);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+#ifdef CONFIG_POSIX
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
+ error_init(argv[0]);
+ qemu_init_exec_dir(argv[0]);
+
+ module_call_init(MODULE_INIT_QOM);
+ module_call_init(MODULE_INIT_TRACE);
+ qemu_add_opts(&qemu_trace_opts);
+ qcrypto_init(&error_fatal);
+ bdrv_init();
+
+ if (!trace_init_backends()) {
+ return EXIT_FAILURE;
+ }
+ qemu_set_log(LOG_TRACE);
+
+ qemu_init_main_loop(&error_fatal);
+ process_options(argc, argv);
+
+ return EXIT_SUCCESS;
+}
diff --git a/Makefile b/Makefile
index 9d4b224126..2bf59d4f42 100644
--- a/Makefile
+++ b/Makefile
@@ -586,6 +586,7 @@ qemu-img.o: qemu-img-cmds.h
qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 08/29] stubs: Add arch_type
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (6 preceding siblings ...)
2020-03-06 17:14 ` [PULL 07/29] qemu-storage-daemon: Add barebone tool Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 09/29] block: Move system emulator QMP commands to block/qapi-sysemu.c Kevin Wolf
` (22 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
blockdev.c uses the arch_type constant, so before we can use the file in
tools (i.e. outside of the system emulator), we need to add a stub for
it. A new QEMU_ARCH_NONE is introduced for this case.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-3-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
include/sysemu/arch_init.h | 2 ++
stubs/arch_type.c | 4 ++++
stubs/Makefile.objs | 1 +
3 files changed, 7 insertions(+)
create mode 100644 stubs/arch_type.c
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 62c6fe4cf1..01392dc945 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -24,6 +24,8 @@ enum {
QEMU_ARCH_NIOS2 = (1 << 17),
QEMU_ARCH_HPPA = (1 << 18),
QEMU_ARCH_RISCV = (1 << 19),
+
+ QEMU_ARCH_NONE = (1 << 31),
};
extern const uint32_t arch_type;
diff --git a/stubs/arch_type.c b/stubs/arch_type.c
new file mode 100644
index 0000000000..fc5423bc98
--- /dev/null
+++ b/stubs/arch_type.c
@@ -0,0 +1,4 @@
+#include "qemu/osdep.h"
+#include "sysemu/arch_init.h"
+
+const uint32_t arch_type = QEMU_ARCH_NONE;
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 7afbe5fb61..24062ce7d9 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,3 +1,4 @@
+stub-obj-y += arch_type.o
stub-obj-y += bdrv-next-monitor-owned.o
stub-obj-y += blk-commit-all.o
stub-obj-y += blockdev-close-all-bdrv-states.o
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 09/29] block: Move system emulator QMP commands to block/qapi-sysemu.c
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (7 preceding siblings ...)
2020-03-06 17:14 ` [PULL 08/29] stubs: Add arch_type Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 10/29] block: Move common QMP commands to block-core QAPI module Kevin Wolf
` (21 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
These commands make only sense for system emulators and their
implementations call functions that don't exist in tools (e.g. to
resolve qdev IDs). Move them out so that blockdev.c can be linked to
qemu-storage-daemon.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-4-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qapi-sysemu.c | 590 ++++++++++++++++++++++++++++++++++++++++++++
blockdev.c | 559 -----------------------------------------
block/Makefile.objs | 2 +
3 files changed, 592 insertions(+), 559 deletions(-)
create mode 100644 block/qapi-sysemu.c
diff --git a/block/qapi-sysemu.c b/block/qapi-sysemu.c
new file mode 100644
index 0000000000..8498402ad4
--- /dev/null
+++ b/block/qapi-sysemu.c
@@ -0,0 +1,590 @@
+/*
+ * QMP command handlers specific to the system emulators
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qapi/qapi-commands-block.h"
+#include "qapi/qmp/qdict.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/blockdev.h"
+
+static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
+ Error **errp)
+{
+ BlockBackend *blk;
+
+ if (!blk_name == !qdev_id) {
+ error_setg(errp, "Need exactly one of 'device' and 'id'");
+ return NULL;
+ }
+
+ if (qdev_id) {
+ blk = blk_by_qdev_id(qdev_id, errp);
+ } else {
+ blk = blk_by_name(blk_name);
+ if (blk == NULL) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", blk_name);
+ }
+ }
+
+ return blk;
+}
+
+/*
+ * Attempt to open the tray of @device.
+ * If @force, ignore its tray lock.
+ * Else, if the tray is locked, don't open it, but ask the guest to open it.
+ * On error, store an error through @errp and return -errno.
+ * If @device does not exist, return -ENODEV.
+ * If it has no removable media, return -ENOTSUP.
+ * If it has no tray, return -ENOSYS.
+ * If the guest was asked to open the tray, return -EINPROGRESS.
+ * Else, return 0.
+ */
+static int do_open_tray(const char *blk_name, const char *qdev_id,
+ bool force, Error **errp)
+{
+ BlockBackend *blk;
+ const char *device = qdev_id ?: blk_name;
+ bool locked;
+
+ blk = qmp_get_blk(blk_name, qdev_id, errp);
+ if (!blk) {
+ return -ENODEV;
+ }
+
+ if (!blk_dev_has_removable_media(blk)) {
+ error_setg(errp, "Device '%s' is not removable", device);
+ return -ENOTSUP;
+ }
+
+ if (!blk_dev_has_tray(blk)) {
+ error_setg(errp, "Device '%s' does not have a tray", device);
+ return -ENOSYS;
+ }
+
+ if (blk_dev_is_tray_open(blk)) {
+ return 0;
+ }
+
+ locked = blk_dev_is_medium_locked(blk);
+ if (locked) {
+ blk_dev_eject_request(blk, force);
+ }
+
+ if (!locked || force) {
+ blk_dev_change_media_cb(blk, false, &error_abort);
+ }
+
+ if (locked && !force) {
+ error_setg(errp, "Device '%s' is locked and force was not specified, "
+ "wait for tray to open and try again", device);
+ return -EINPROGRESS;
+ }
+
+ return 0;
+}
+
+void qmp_blockdev_open_tray(bool has_device, const char *device,
+ bool has_id, const char *id,
+ bool has_force, bool force,
+ Error **errp)
+{
+ Error *local_err = NULL;
+ int rc;
+
+ if (!has_force) {
+ force = false;
+ }
+ rc = do_open_tray(has_device ? device : NULL,
+ has_id ? id : NULL,
+ force, &local_err);
+ if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ error_free(local_err);
+}
+
+void qmp_blockdev_close_tray(bool has_device, const char *device,
+ bool has_id, const char *id,
+ Error **errp)
+{
+ BlockBackend *blk;
+ Error *local_err = NULL;
+
+ device = has_device ? device : NULL;
+ id = has_id ? id : NULL;
+
+ blk = qmp_get_blk(device, id, errp);
+ if (!blk) {
+ return;
+ }
+
+ if (!blk_dev_has_removable_media(blk)) {
+ error_setg(errp, "Device '%s' is not removable", device ?: id);
+ return;
+ }
+
+ if (!blk_dev_has_tray(blk)) {
+ /* Ignore this command on tray-less devices */
+ return;
+ }
+
+ if (!blk_dev_is_tray_open(blk)) {
+ return;
+ }
+
+ blk_dev_change_media_cb(blk, true, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+}
+
+static void blockdev_remove_medium(bool has_device, const char *device,
+ bool has_id, const char *id, Error **errp)
+{
+ BlockBackend *blk;
+ BlockDriverState *bs;
+ AioContext *aio_context;
+ bool has_attached_device;
+
+ device = has_device ? device : NULL;
+ id = has_id ? id : NULL;
+
+ blk = qmp_get_blk(device, id, errp);
+ if (!blk) {
+ return;
+ }
+
+ /* For BBs without a device, we can exchange the BDS tree at will */
+ has_attached_device = blk_get_attached_dev(blk);
+
+ if (has_attached_device && !blk_dev_has_removable_media(blk)) {
+ error_setg(errp, "Device '%s' is not removable", device ?: id);
+ return;
+ }
+
+ if (has_attached_device && blk_dev_has_tray(blk) &&
+ !blk_dev_is_tray_open(blk))
+ {
+ error_setg(errp, "Tray of device '%s' is not open", device ?: id);
+ return;
+ }
+
+ bs = blk_bs(blk);
+ if (!bs) {
+ return;
+ }
+
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+
+ if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
+ goto out;
+ }
+
+ blk_remove_bs(blk);
+
+ if (!blk_dev_has_tray(blk)) {
+ /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
+ * called at all); therefore, the medium needs to be ejected here.
+ * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
+ * value passed here (i.e. false). */
+ blk_dev_change_media_cb(blk, false, &error_abort);
+ }
+
+out:
+ aio_context_release(aio_context);
+}
+
+void qmp_blockdev_remove_medium(const char *id, Error **errp)
+{
+ blockdev_remove_medium(false, NULL, true, id, errp);
+}
+
+static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
+ BlockDriverState *bs, Error **errp)
+{
+ Error *local_err = NULL;
+ bool has_device;
+ int ret;
+
+ /* For BBs without a device, we can exchange the BDS tree at will */
+ has_device = blk_get_attached_dev(blk);
+
+ if (has_device && !blk_dev_has_removable_media(blk)) {
+ error_setg(errp, "Device is not removable");
+ return;
+ }
+
+ if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
+ error_setg(errp, "Tray of the device is not open");
+ return;
+ }
+
+ if (blk_bs(blk)) {
+ error_setg(errp, "There already is a medium in the device");
+ return;
+ }
+
+ ret = blk_insert_bs(blk, bs, errp);
+ if (ret < 0) {
+ return;
+ }
+
+ if (!blk_dev_has_tray(blk)) {
+ /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
+ * called at all); therefore, the medium needs to be pushed into the
+ * slot here.
+ * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
+ * value passed here (i.e. true). */
+ blk_dev_change_media_cb(blk, true, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ blk_remove_bs(blk);
+ return;
+ }
+ }
+}
+
+static void blockdev_insert_medium(bool has_device, const char *device,
+ bool has_id, const char *id,
+ const char *node_name, Error **errp)
+{
+ BlockBackend *blk;
+ BlockDriverState *bs;
+
+ blk = qmp_get_blk(has_device ? device : NULL,
+ has_id ? id : NULL,
+ errp);
+ if (!blk) {
+ return;
+ }
+
+ bs = bdrv_find_node(node_name);
+ if (!bs) {
+ error_setg(errp, "Node '%s' not found", node_name);
+ return;
+ }
+
+ if (bdrv_has_blk(bs)) {
+ error_setg(errp, "Node '%s' is already in use", node_name);
+ return;
+ }
+
+ qmp_blockdev_insert_anon_medium(blk, bs, errp);
+}
+
+void qmp_blockdev_insert_medium(const char *id, const char *node_name,
+ Error **errp)
+{
+ blockdev_insert_medium(false, NULL, true, id, node_name, errp);
+}
+
+void qmp_blockdev_change_medium(bool has_device, const char *device,
+ bool has_id, const char *id,
+ const char *filename,
+ bool has_format, const char *format,
+ bool has_read_only,
+ BlockdevChangeReadOnlyMode read_only,
+ Error **errp)
+{
+ BlockBackend *blk;
+ BlockDriverState *medium_bs = NULL;
+ int bdrv_flags;
+ bool detect_zeroes;
+ int rc;
+ QDict *options = NULL;
+ Error *err = NULL;
+
+ blk = qmp_get_blk(has_device ? device : NULL,
+ has_id ? id : NULL,
+ errp);
+ if (!blk) {
+ goto fail;
+ }
+
+ if (blk_bs(blk)) {
+ blk_update_root_state(blk);
+ }
+
+ bdrv_flags = blk_get_open_flags_from_root_state(blk);
+ bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
+
+ if (!has_read_only) {
+ read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
+ }
+
+ switch (read_only) {
+ case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
+ break;
+
+ case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:
+ bdrv_flags &= ~BDRV_O_RDWR;
+ break;
+
+ case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:
+ bdrv_flags |= BDRV_O_RDWR;
+ break;
+
+ default:
+ abort();
+ }
+
+ options = qdict_new();
+ detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
+ qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
+
+ if (has_format) {
+ qdict_put_str(options, "driver", format);
+ }
+
+ medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
+ if (!medium_bs) {
+ goto fail;
+ }
+
+ rc = do_open_tray(has_device ? device : NULL,
+ has_id ? id : NULL,
+ false, &err);
+ if (rc && rc != -ENOSYS) {
+ error_propagate(errp, err);
+ goto fail;
+ }
+ error_free(err);
+ err = NULL;
+
+ blockdev_remove_medium(has_device, device, has_id, id, &err);
+ if (err) {
+ error_propagate(errp, err);
+ goto fail;
+ }
+
+ qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
+ if (err) {
+ error_propagate(errp, err);
+ goto fail;
+ }
+
+ qmp_blockdev_close_tray(has_device, device, has_id, id, errp);
+
+fail:
+ /* If the medium has been inserted, the device has its own reference, so
+ * ours must be relinquished; and if it has not been inserted successfully,
+ * the reference must be relinquished anyway */
+ bdrv_unref(medium_bs);
+}
+
+void qmp_eject(bool has_device, const char *device,
+ bool has_id, const char *id,
+ bool has_force, bool force, Error **errp)
+{
+ Error *local_err = NULL;
+ int rc;
+
+ if (!has_force) {
+ force = false;
+ }
+
+ rc = do_open_tray(has_device ? device : NULL,
+ has_id ? id : NULL,
+ force, &local_err);
+ if (rc && rc != -ENOSYS) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ error_free(local_err);
+
+ blockdev_remove_medium(has_device, device, has_id, id, errp);
+}
+
+/* throttling disk I/O limits */
+void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
+{
+ ThrottleConfig cfg;
+ BlockDriverState *bs;
+ BlockBackend *blk;
+ AioContext *aio_context;
+
+ blk = qmp_get_blk(arg->has_device ? arg->device : NULL,
+ arg->has_id ? arg->id : NULL,
+ errp);
+ if (!blk) {
+ return;
+ }
+
+ aio_context = blk_get_aio_context(blk);
+ aio_context_acquire(aio_context);
+
+ bs = blk_bs(blk);
+ if (!bs) {
+ error_setg(errp, "Device has no medium");
+ goto out;
+ }
+
+ throttle_config_init(&cfg);
+ cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
+ cfg.buckets[THROTTLE_BPS_READ].avg = arg->bps_rd;
+ cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
+
+ cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
+ cfg.buckets[THROTTLE_OPS_READ].avg = arg->iops_rd;
+ cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
+
+ if (arg->has_bps_max) {
+ cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
+ }
+ if (arg->has_bps_rd_max) {
+ cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
+ }
+ if (arg->has_bps_wr_max) {
+ cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
+ }
+ if (arg->has_iops_max) {
+ cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
+ }
+ if (arg->has_iops_rd_max) {
+ cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
+ }
+ if (arg->has_iops_wr_max) {
+ cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
+ }
+
+ if (arg->has_bps_max_length) {
+ cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
+ }
+ if (arg->has_bps_rd_max_length) {
+ cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
+ }
+ if (arg->has_bps_wr_max_length) {
+ cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
+ }
+ if (arg->has_iops_max_length) {
+ cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
+ }
+ if (arg->has_iops_rd_max_length) {
+ cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
+ }
+ if (arg->has_iops_wr_max_length) {
+ cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
+ }
+
+ if (arg->has_iops_size) {
+ cfg.op_size = arg->iops_size;
+ }
+
+ if (!throttle_is_valid(&cfg, errp)) {
+ goto out;
+ }
+
+ if (throttle_enabled(&cfg)) {
+ /* Enable I/O limits if they're not enabled yet, otherwise
+ * just update the throttling group. */
+ if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
+ blk_io_limits_enable(blk,
+ arg->has_group ? arg->group :
+ arg->has_device ? arg->device :
+ arg->id);
+ } else if (arg->has_group) {
+ blk_io_limits_update_group(blk, arg->group);
+ }
+ /* Set the new throttling configuration */
+ blk_set_io_limits(blk, &cfg);
+ } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
+ /* If all throttling settings are set to 0, disable I/O limits */
+ blk_io_limits_disable(blk);
+ }
+
+out:
+ aio_context_release(aio_context);
+}
+
+void qmp_block_latency_histogram_set(
+ const char *id,
+ bool has_boundaries, uint64List *boundaries,
+ bool has_boundaries_read, uint64List *boundaries_read,
+ bool has_boundaries_write, uint64List *boundaries_write,
+ bool has_boundaries_flush, uint64List *boundaries_flush,
+ Error **errp)
+{
+ BlockBackend *blk = qmp_get_blk(NULL, id, errp);
+ BlockAcctStats *stats;
+ int ret;
+
+ if (!blk) {
+ return;
+ }
+
+ stats = blk_get_stats(blk);
+
+ if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
+ !has_boundaries_flush)
+ {
+ block_latency_histograms_clear(stats);
+ return;
+ }
+
+ if (has_boundaries || has_boundaries_read) {
+ ret = block_latency_histogram_set(
+ stats, BLOCK_ACCT_READ,
+ has_boundaries_read ? boundaries_read : boundaries);
+ if (ret) {
+ error_setg(errp, "Device '%s' set read boundaries fail", id);
+ return;
+ }
+ }
+
+ if (has_boundaries || has_boundaries_write) {
+ ret = block_latency_histogram_set(
+ stats, BLOCK_ACCT_WRITE,
+ has_boundaries_write ? boundaries_write : boundaries);
+ if (ret) {
+ error_setg(errp, "Device '%s' set write boundaries fail", id);
+ return;
+ }
+ }
+
+ if (has_boundaries || has_boundaries_flush) {
+ ret = block_latency_histogram_set(
+ stats, BLOCK_ACCT_FLUSH,
+ has_boundaries_flush ? boundaries_flush : boundaries);
+ if (ret) {
+ error_setg(errp, "Device '%s' set flush boundaries fail", id);
+ return;
+ }
+ }
+}
diff --git a/blockdev.c b/blockdev.c
index 011dcfec27..3e44fa766b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -67,14 +67,6 @@
static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
-static int do_open_tray(const char *blk_name, const char *qdev_id,
- bool force, Error **errp);
-static void blockdev_remove_medium(bool has_device, const char *device,
- bool has_id, const char *id, Error **errp);
-static void blockdev_insert_medium(bool has_device, const char *device,
- bool has_id, const char *id,
- const char *node_name, Error **errp);
-
static const char *const if_name[IF_COUNT] = {
[IF_NONE] = "none",
[IF_IDE] = "ide",
@@ -1047,29 +1039,6 @@ static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp)
return bs;
}
-static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
- Error **errp)
-{
- BlockBackend *blk;
-
- if (!blk_name == !qdev_id) {
- error_setg(errp, "Need exactly one of 'device' and 'id'");
- return NULL;
- }
-
- if (qdev_id) {
- blk = blk_by_qdev_id(qdev_id, errp);
- } else {
- blk = blk_by_name(blk_name);
- if (blk == NULL) {
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Device '%s' not found", blk_name);
- }
- }
-
- return blk;
-}
-
void hmp_commit(Monitor *mon, const QDict *qdict)
{
const char *device = qdict_get_str(qdict, "device");
@@ -2508,29 +2477,6 @@ exit:
job_txn_unref(block_job_txn);
}
-void qmp_eject(bool has_device, const char *device,
- bool has_id, const char *id,
- bool has_force, bool force, Error **errp)
-{
- Error *local_err = NULL;
- int rc;
-
- if (!has_force) {
- force = false;
- }
-
- rc = do_open_tray(has_device ? device : NULL,
- has_id ? id : NULL,
- force, &local_err);
- if (rc && rc != -ENOSYS) {
- error_propagate(errp, local_err);
- return;
- }
- error_free(local_err);
-
- blockdev_remove_medium(has_device, device, has_id, id, errp);
-}
-
void qmp_block_passwd(bool has_device, const char *device,
bool has_node_name, const char *node_name,
const char *password, Error **errp)
@@ -2539,455 +2485,6 @@ void qmp_block_passwd(bool has_device, const char *device,
"Setting block passwords directly is no longer supported");
}
-/*
- * Attempt to open the tray of @device.
- * If @force, ignore its tray lock.
- * Else, if the tray is locked, don't open it, but ask the guest to open it.
- * On error, store an error through @errp and return -errno.
- * If @device does not exist, return -ENODEV.
- * If it has no removable media, return -ENOTSUP.
- * If it has no tray, return -ENOSYS.
- * If the guest was asked to open the tray, return -EINPROGRESS.
- * Else, return 0.
- */
-static int do_open_tray(const char *blk_name, const char *qdev_id,
- bool force, Error **errp)
-{
- BlockBackend *blk;
- const char *device = qdev_id ?: blk_name;
- bool locked;
-
- blk = qmp_get_blk(blk_name, qdev_id, errp);
- if (!blk) {
- return -ENODEV;
- }
-
- if (!blk_dev_has_removable_media(blk)) {
- error_setg(errp, "Device '%s' is not removable", device);
- return -ENOTSUP;
- }
-
- if (!blk_dev_has_tray(blk)) {
- error_setg(errp, "Device '%s' does not have a tray", device);
- return -ENOSYS;
- }
-
- if (blk_dev_is_tray_open(blk)) {
- return 0;
- }
-
- locked = blk_dev_is_medium_locked(blk);
- if (locked) {
- blk_dev_eject_request(blk, force);
- }
-
- if (!locked || force) {
- blk_dev_change_media_cb(blk, false, &error_abort);
- }
-
- if (locked && !force) {
- error_setg(errp, "Device '%s' is locked and force was not specified, "
- "wait for tray to open and try again", device);
- return -EINPROGRESS;
- }
-
- return 0;
-}
-
-void qmp_blockdev_open_tray(bool has_device, const char *device,
- bool has_id, const char *id,
- bool has_force, bool force,
- Error **errp)
-{
- Error *local_err = NULL;
- int rc;
-
- if (!has_force) {
- force = false;
- }
- rc = do_open_tray(has_device ? device : NULL,
- has_id ? id : NULL,
- force, &local_err);
- if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
- error_propagate(errp, local_err);
- return;
- }
- error_free(local_err);
-}
-
-void qmp_blockdev_close_tray(bool has_device, const char *device,
- bool has_id, const char *id,
- Error **errp)
-{
- BlockBackend *blk;
- Error *local_err = NULL;
-
- device = has_device ? device : NULL;
- id = has_id ? id : NULL;
-
- blk = qmp_get_blk(device, id, errp);
- if (!blk) {
- return;
- }
-
- if (!blk_dev_has_removable_media(blk)) {
- error_setg(errp, "Device '%s' is not removable", device ?: id);
- return;
- }
-
- if (!blk_dev_has_tray(blk)) {
- /* Ignore this command on tray-less devices */
- return;
- }
-
- if (!blk_dev_is_tray_open(blk)) {
- return;
- }
-
- blk_dev_change_media_cb(blk, true, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-}
-
-static void blockdev_remove_medium(bool has_device, const char *device,
- bool has_id, const char *id, Error **errp)
-{
- BlockBackend *blk;
- BlockDriverState *bs;
- AioContext *aio_context;
- bool has_attached_device;
-
- device = has_device ? device : NULL;
- id = has_id ? id : NULL;
-
- blk = qmp_get_blk(device, id, errp);
- if (!blk) {
- return;
- }
-
- /* For BBs without a device, we can exchange the BDS tree at will */
- has_attached_device = blk_get_attached_dev(blk);
-
- if (has_attached_device && !blk_dev_has_removable_media(blk)) {
- error_setg(errp, "Device '%s' is not removable", device ?: id);
- return;
- }
-
- if (has_attached_device && blk_dev_has_tray(blk) &&
- !blk_dev_is_tray_open(blk))
- {
- error_setg(errp, "Tray of device '%s' is not open", device ?: id);
- return;
- }
-
- bs = blk_bs(blk);
- if (!bs) {
- return;
- }
-
- aio_context = bdrv_get_aio_context(bs);
- aio_context_acquire(aio_context);
-
- if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
- goto out;
- }
-
- blk_remove_bs(blk);
-
- if (!blk_dev_has_tray(blk)) {
- /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
- * called at all); therefore, the medium needs to be ejected here.
- * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
- * value passed here (i.e. false). */
- blk_dev_change_media_cb(blk, false, &error_abort);
- }
-
-out:
- aio_context_release(aio_context);
-}
-
-void qmp_blockdev_remove_medium(const char *id, Error **errp)
-{
- blockdev_remove_medium(false, NULL, true, id, errp);
-}
-
-static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
- BlockDriverState *bs, Error **errp)
-{
- Error *local_err = NULL;
- bool has_device;
- int ret;
-
- /* For BBs without a device, we can exchange the BDS tree at will */
- has_device = blk_get_attached_dev(blk);
-
- if (has_device && !blk_dev_has_removable_media(blk)) {
- error_setg(errp, "Device is not removable");
- return;
- }
-
- if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
- error_setg(errp, "Tray of the device is not open");
- return;
- }
-
- if (blk_bs(blk)) {
- error_setg(errp, "There already is a medium in the device");
- return;
- }
-
- ret = blk_insert_bs(blk, bs, errp);
- if (ret < 0) {
- return;
- }
-
- if (!blk_dev_has_tray(blk)) {
- /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
- * called at all); therefore, the medium needs to be pushed into the
- * slot here.
- * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
- * value passed here (i.e. true). */
- blk_dev_change_media_cb(blk, true, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- blk_remove_bs(blk);
- return;
- }
- }
-}
-
-static void blockdev_insert_medium(bool has_device, const char *device,
- bool has_id, const char *id,
- const char *node_name, Error **errp)
-{
- BlockBackend *blk;
- BlockDriverState *bs;
-
- blk = qmp_get_blk(has_device ? device : NULL,
- has_id ? id : NULL,
- errp);
- if (!blk) {
- return;
- }
-
- bs = bdrv_find_node(node_name);
- if (!bs) {
- error_setg(errp, "Node '%s' not found", node_name);
- return;
- }
-
- if (bdrv_has_blk(bs)) {
- error_setg(errp, "Node '%s' is already in use", node_name);
- return;
- }
-
- qmp_blockdev_insert_anon_medium(blk, bs, errp);
-}
-
-void qmp_blockdev_insert_medium(const char *id, const char *node_name,
- Error **errp)
-{
- blockdev_insert_medium(false, NULL, true, id, node_name, errp);
-}
-
-void qmp_blockdev_change_medium(bool has_device, const char *device,
- bool has_id, const char *id,
- const char *filename,
- bool has_format, const char *format,
- bool has_read_only,
- BlockdevChangeReadOnlyMode read_only,
- Error **errp)
-{
- BlockBackend *blk;
- BlockDriverState *medium_bs = NULL;
- int bdrv_flags;
- bool detect_zeroes;
- int rc;
- QDict *options = NULL;
- Error *err = NULL;
-
- blk = qmp_get_blk(has_device ? device : NULL,
- has_id ? id : NULL,
- errp);
- if (!blk) {
- goto fail;
- }
-
- if (blk_bs(blk)) {
- blk_update_root_state(blk);
- }
-
- bdrv_flags = blk_get_open_flags_from_root_state(blk);
- bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
- BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
-
- if (!has_read_only) {
- read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
- }
-
- switch (read_only) {
- case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
- break;
-
- case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:
- bdrv_flags &= ~BDRV_O_RDWR;
- break;
-
- case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:
- bdrv_flags |= BDRV_O_RDWR;
- break;
-
- default:
- abort();
- }
-
- options = qdict_new();
- detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
- qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
-
- if (has_format) {
- qdict_put_str(options, "driver", format);
- }
-
- medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
- if (!medium_bs) {
- goto fail;
- }
-
- rc = do_open_tray(has_device ? device : NULL,
- has_id ? id : NULL,
- false, &err);
- if (rc && rc != -ENOSYS) {
- error_propagate(errp, err);
- goto fail;
- }
- error_free(err);
- err = NULL;
-
- blockdev_remove_medium(has_device, device, has_id, id, &err);
- if (err) {
- error_propagate(errp, err);
- goto fail;
- }
-
- qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
- if (err) {
- error_propagate(errp, err);
- goto fail;
- }
-
- qmp_blockdev_close_tray(has_device, device, has_id, id, errp);
-
-fail:
- /* If the medium has been inserted, the device has its own reference, so
- * ours must be relinquished; and if it has not been inserted successfully,
- * the reference must be relinquished anyway */
- bdrv_unref(medium_bs);
-}
-
-/* throttling disk I/O limits */
-void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
-{
- ThrottleConfig cfg;
- BlockDriverState *bs;
- BlockBackend *blk;
- AioContext *aio_context;
-
- blk = qmp_get_blk(arg->has_device ? arg->device : NULL,
- arg->has_id ? arg->id : NULL,
- errp);
- if (!blk) {
- return;
- }
-
- aio_context = blk_get_aio_context(blk);
- aio_context_acquire(aio_context);
-
- bs = blk_bs(blk);
- if (!bs) {
- error_setg(errp, "Device has no medium");
- goto out;
- }
-
- throttle_config_init(&cfg);
- cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
- cfg.buckets[THROTTLE_BPS_READ].avg = arg->bps_rd;
- cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
-
- cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
- cfg.buckets[THROTTLE_OPS_READ].avg = arg->iops_rd;
- cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
-
- if (arg->has_bps_max) {
- cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
- }
- if (arg->has_bps_rd_max) {
- cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
- }
- if (arg->has_bps_wr_max) {
- cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
- }
- if (arg->has_iops_max) {
- cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
- }
- if (arg->has_iops_rd_max) {
- cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
- }
- if (arg->has_iops_wr_max) {
- cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
- }
-
- if (arg->has_bps_max_length) {
- cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
- }
- if (arg->has_bps_rd_max_length) {
- cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
- }
- if (arg->has_bps_wr_max_length) {
- cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
- }
- if (arg->has_iops_max_length) {
- cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
- }
- if (arg->has_iops_rd_max_length) {
- cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
- }
- if (arg->has_iops_wr_max_length) {
- cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
- }
-
- if (arg->has_iops_size) {
- cfg.op_size = arg->iops_size;
- }
-
- if (!throttle_is_valid(&cfg, errp)) {
- goto out;
- }
-
- if (throttle_enabled(&cfg)) {
- /* Enable I/O limits if they're not enabled yet, otherwise
- * just update the throttling group. */
- if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
- blk_io_limits_enable(blk,
- arg->has_group ? arg->group :
- arg->has_device ? arg->device :
- arg->id);
- } else if (arg->has_group) {
- blk_io_limits_update_group(blk, arg->group);
- }
- /* Set the new throttling configuration */
- blk_set_io_limits(blk, &cfg);
- } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
- /* If all throttling settings are set to 0, disable I/O limits */
- blk_io_limits_disable(blk);
- }
-
-out:
- aio_context_release(aio_context);
-}
-
void qmp_block_dirty_bitmap_add(const char *node, const char *name,
bool has_granularity, uint32_t granularity,
bool has_persistent, bool persistent,
@@ -4595,62 +4092,6 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
aio_context_release(old_context);
}
-void qmp_block_latency_histogram_set(
- const char *id,
- bool has_boundaries, uint64List *boundaries,
- bool has_boundaries_read, uint64List *boundaries_read,
- bool has_boundaries_write, uint64List *boundaries_write,
- bool has_boundaries_flush, uint64List *boundaries_flush,
- Error **errp)
-{
- BlockBackend *blk = qmp_get_blk(NULL, id, errp);
- BlockAcctStats *stats;
- int ret;
-
- if (!blk) {
- return;
- }
-
- stats = blk_get_stats(blk);
-
- if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
- !has_boundaries_flush)
- {
- block_latency_histograms_clear(stats);
- return;
- }
-
- if (has_boundaries || has_boundaries_read) {
- ret = block_latency_histogram_set(
- stats, BLOCK_ACCT_READ,
- has_boundaries_read ? boundaries_read : boundaries);
- if (ret) {
- error_setg(errp, "Device '%s' set read boundaries fail", id);
- return;
- }
- }
-
- if (has_boundaries || has_boundaries_write) {
- ret = block_latency_histogram_set(
- stats, BLOCK_ACCT_WRITE,
- has_boundaries_write ? boundaries_write : boundaries);
- if (ret) {
- error_setg(errp, "Device '%s' set write boundaries fail", id);
- return;
- }
- }
-
- if (has_boundaries || has_boundaries_flush) {
- ret = block_latency_histogram_set(
- stats, BLOCK_ACCT_FLUSH,
- has_boundaries_flush ? boundaries_flush : boundaries);
- if (ret) {
- error_setg(errp, "Device '%s' set flush boundaries fail", id);
- return;
- }
- }
-}
-
QemuOptsList qemu_common_drive_opts = {
.name = "drive",
.head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
diff --git a/block/Makefile.objs b/block/Makefile.objs
index 3bcb35c81d..e06cf0b284 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -48,6 +48,8 @@ block-obj-y += filter-compress.o
common-obj-y += stream.o
+common-obj-y += qapi-sysemu.o
+
nfs.o-libs := $(LIBNFS_LIBS)
iscsi.o-cflags := $(LIBISCSI_CFLAGS)
iscsi.o-libs := $(LIBISCSI_LIBS)
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 10/29] block: Move common QMP commands to block-core QAPI module
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (8 preceding siblings ...)
2020-03-06 17:14 ` [PULL 09/29] block: Move system emulator QMP commands to block/qapi-sysemu.c Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 11/29] block: Move sysemu QMP commands to QAPI block module Kevin Wolf
` (20 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
block-core is for everything that isn't related to the system emulator.
Internal snapshots, the NBD server and quorum events make sense in the
tools, too, so move them to block-core.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-5-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/block-core.json | 283 ++++++++++++++++++++++++++++++++++++++++++
qapi/block.json | 284 -------------------------------------------
2 files changed, 283 insertions(+), 284 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 85e27bb61f..60860ead68 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -5447,3 +5447,286 @@
'data' : { 'node-name': 'str',
'iothread': 'StrOrNull',
'*force': 'bool' } }
+
+##
+# @nbd-server-start:
+#
+# Start an NBD server listening on the given host and port. Block
+# devices can then be exported using @nbd-server-add. The NBD
+# server will present them as named exports; for example, another
+# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
+#
+# @addr: Address on which to listen.
+# @tls-creds: ID of the TLS credentials object (since 2.6).
+# @tls-authz: ID of the QAuthZ authorization object used to validate
+# the client's x509 distinguished name. This object is
+# is only resolved at time of use, so can be deleted and
+# recreated on the fly while the NBD server is active.
+# If missing, it will default to denying access (since 4.0).
+#
+# Returns: error if the server is already running.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-start',
+ 'data': { 'addr': 'SocketAddressLegacy',
+ '*tls-creds': 'str',
+ '*tls-authz': 'str'} }
+
+##
+# @nbd-server-add:
+#
+# Export a block node to QEMU's embedded NBD server.
+#
+# @device: The device name or node name of the node to be exported
+#
+# @name: Export name. If unspecified, the @device parameter is used as the
+# export name. (Since 2.12)
+#
+# @description: Free-form description of the export, up to 4096 bytes.
+# (Since 5.0)
+#
+# @writable: Whether clients should be able to write to the device via the
+# NBD connection (default false).
+#
+# @bitmap: Also export the dirty bitmap reachable from @device, so the
+# NBD client can use NBD_OPT_SET_META_CONTEXT with
+# "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
+#
+# Returns: error if the server is not running, or export with the same name
+# already exists.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-add',
+ 'data': {'device': 'str', '*name': 'str', '*description': 'str',
+ '*writable': 'bool', '*bitmap': 'str' } }
+
+##
+# @NbdServerRemoveMode:
+#
+# Mode for removing an NBD export.
+#
+# @safe: Remove export if there are no existing connections, fail otherwise.
+#
+# @hard: Drop all connections immediately and remove export.
+#
+# Potential additional modes to be added in the future:
+#
+# hide: Just hide export from new clients, leave existing connections as is.
+# Remove export after all clients are disconnected.
+#
+# soft: Hide export from new clients, answer with ESHUTDOWN for all further
+# requests from existing clients.
+#
+# Since: 2.12
+##
+{'enum': 'NbdServerRemoveMode', 'data': ['safe', 'hard']}
+
+##
+# @nbd-server-remove:
+#
+# Remove NBD export by name.
+#
+# @name: Export name.
+#
+# @mode: Mode of command operation. See @NbdServerRemoveMode description.
+# Default is 'safe'.
+#
+# Returns: error if
+# - the server is not running
+# - export is not found
+# - mode is 'safe' and there are existing connections
+#
+# Since: 2.12
+##
+{ 'command': 'nbd-server-remove',
+ 'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} }
+
+##
+# @nbd-server-stop:
+#
+# Stop QEMU's embedded NBD server, and unregister all devices previously
+# added via @nbd-server-add.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-stop' }
+
+##
+# @QuorumOpType:
+#
+# An enumeration of the quorum operation types
+#
+# @read: read operation
+#
+# @write: write operation
+#
+# @flush: flush operation
+#
+# Since: 2.6
+##
+{ 'enum': 'QuorumOpType',
+ 'data': [ 'read', 'write', 'flush' ] }
+
+##
+# @QUORUM_FAILURE:
+#
+# Emitted by the Quorum block driver if it fails to establish a quorum
+#
+# @reference: device name if defined else node name
+#
+# @sector-num: number of the first sector of the failed read operation
+#
+# @sectors-count: failed read operation sector count
+#
+# Note: This event is rate-limited.
+#
+# Since: 2.0
+#
+# Example:
+#
+# <- { "event": "QUORUM_FAILURE",
+# "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 },
+# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
+#
+##
+{ 'event': 'QUORUM_FAILURE',
+ 'data': { 'reference': 'str', 'sector-num': 'int', 'sectors-count': 'int' } }
+
+##
+# @QUORUM_REPORT_BAD:
+#
+# Emitted to report a corruption of a Quorum file
+#
+# @type: quorum operation type (Since 2.6)
+#
+# @error: error message. Only present on failure. This field
+# contains a human-readable error message. There are no semantics other
+# than that the block layer reported an error and clients should not
+# try to interpret the error string.
+#
+# @node-name: the graph node name of the block driver state
+#
+# @sector-num: number of the first sector of the failed read operation
+#
+# @sectors-count: failed read operation sector count
+#
+# Note: This event is rate-limited.
+#
+# Since: 2.0
+#
+# Example:
+#
+# 1. Read operation
+#
+# { "event": "QUORUM_REPORT_BAD",
+# "data": { "node-name": "node0", "sector-num": 345435, "sectors-count": 5,
+# "type": "read" },
+# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
+#
+# 2. Flush operation
+#
+# { "event": "QUORUM_REPORT_BAD",
+# "data": { "node-name": "node0", "sector-num": 0, "sectors-count": 2097120,
+# "type": "flush", "error": "Broken pipe" },
+# "timestamp": { "seconds": 1456406829, "microseconds": 291763 } }
+#
+##
+{ 'event': 'QUORUM_REPORT_BAD',
+ 'data': { 'type': 'QuorumOpType', '*error': 'str', 'node-name': 'str',
+ 'sector-num': 'int', 'sectors-count': 'int' } }
+
+##
+# @BlockdevSnapshotInternal:
+#
+# @device: the device name or node-name of a root node to generate the snapshot
+# from
+#
+# @name: the name of the internal snapshot to be created
+#
+# Notes: In transaction, if @name is empty, or any snapshot matching @name
+# exists, the operation will fail. Only some image formats support it,
+# for example, qcow2, rbd, and sheepdog.
+#
+# Since: 1.7
+##
+{ 'struct': 'BlockdevSnapshotInternal',
+ 'data': { 'device': 'str', 'name': 'str' } }
+
+##
+# @blockdev-snapshot-internal-sync:
+#
+# Synchronously take an internal snapshot of a block device, when the
+# format of the image used supports it. If the name is an empty
+# string, or a snapshot with name already exists, the operation will
+# fail.
+#
+# For the arguments, see the documentation of BlockdevSnapshotInternal.
+#
+# Returns: - nothing on success
+# - If @device is not a valid block device, GenericError
+# - If any snapshot matching @name exists, or @name is empty,
+# GenericError
+# - If the format of the image used does not support it,
+# BlockFormatFeatureNotSupported
+#
+# Since: 1.7
+#
+# Example:
+#
+# -> { "execute": "blockdev-snapshot-internal-sync",
+# "arguments": { "device": "ide-hd0",
+# "name": "snapshot0" }
+# }
+# <- { "return": {} }
+#
+##
+{ 'command': 'blockdev-snapshot-internal-sync',
+ 'data': 'BlockdevSnapshotInternal' }
+
+##
+# @blockdev-snapshot-delete-internal-sync:
+#
+# Synchronously delete an internal snapshot of a block device, when the format
+# of the image used support it. The snapshot is identified by name or id or
+# both. One of the name or id is required. Return SnapshotInfo for the
+# successfully deleted snapshot.
+#
+# @device: the device name or node-name of a root node to delete the snapshot
+# from
+#
+# @id: optional the snapshot's ID to be deleted
+#
+# @name: optional the snapshot's name to be deleted
+#
+# Returns: - SnapshotInfo on success
+# - If @device is not a valid block device, GenericError
+# - If snapshot not found, GenericError
+# - If the format of the image used does not support it,
+# BlockFormatFeatureNotSupported
+# - If @id and @name are both not specified, GenericError
+#
+# Since: 1.7
+#
+# Example:
+#
+# -> { "execute": "blockdev-snapshot-delete-internal-sync",
+# "arguments": { "device": "ide-hd0",
+# "name": "snapshot0" }
+# }
+# <- { "return": {
+# "id": "1",
+# "name": "snapshot0",
+# "vm-state-size": 0,
+# "date-sec": 1000012,
+# "date-nsec": 10,
+# "vm-clock-sec": 100,
+# "vm-clock-nsec": 20
+# }
+# }
+#
+##
+{ 'command': 'blockdev-snapshot-delete-internal-sync',
+ 'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
+ 'returns': 'SnapshotInfo' }
diff --git a/qapi/block.json b/qapi/block.json
index da19834db4..d2f3fc01ed 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -60,23 +60,6 @@
{ 'enum': 'FloppyDriveType',
'data': ['144', '288', '120', 'none', 'auto']}
-##
-# @BlockdevSnapshotInternal:
-#
-# @device: the device name or node-name of a root node to generate the snapshot
-# from
-#
-# @name: the name of the internal snapshot to be created
-#
-# Notes: In transaction, if @name is empty, or any snapshot matching @name
-# exists, the operation will fail. Only some image formats support it,
-# for example, qcow2, rbd, and sheepdog.
-#
-# Since: 1.7
-##
-{ 'struct': 'BlockdevSnapshotInternal',
- 'data': { 'device': 'str', 'name': 'str' } }
-
##
# @PRManagerInfo:
#
@@ -104,84 +87,6 @@
{ 'command': 'query-pr-managers', 'returns': ['PRManagerInfo'],
'allow-preconfig': true }
-
-##
-# @blockdev-snapshot-internal-sync:
-#
-# Synchronously take an internal snapshot of a block device, when the
-# format of the image used supports it. If the name is an empty
-# string, or a snapshot with name already exists, the operation will
-# fail.
-#
-# For the arguments, see the documentation of BlockdevSnapshotInternal.
-#
-# Returns: - nothing on success
-# - If @device is not a valid block device, GenericError
-# - If any snapshot matching @name exists, or @name is empty,
-# GenericError
-# - If the format of the image used does not support it,
-# BlockFormatFeatureNotSupported
-#
-# Since: 1.7
-#
-# Example:
-#
-# -> { "execute": "blockdev-snapshot-internal-sync",
-# "arguments": { "device": "ide-hd0",
-# "name": "snapshot0" }
-# }
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-snapshot-internal-sync',
- 'data': 'BlockdevSnapshotInternal' }
-
-##
-# @blockdev-snapshot-delete-internal-sync:
-#
-# Synchronously delete an internal snapshot of a block device, when the format
-# of the image used support it. The snapshot is identified by name or id or
-# both. One of the name or id is required. Return SnapshotInfo for the
-# successfully deleted snapshot.
-#
-# @device: the device name or node-name of a root node to delete the snapshot
-# from
-#
-# @id: optional the snapshot's ID to be deleted
-#
-# @name: optional the snapshot's name to be deleted
-#
-# Returns: - SnapshotInfo on success
-# - If @device is not a valid block device, GenericError
-# - If snapshot not found, GenericError
-# - If the format of the image used does not support it,
-# BlockFormatFeatureNotSupported
-# - If @id and @name are both not specified, GenericError
-#
-# Since: 1.7
-#
-# Example:
-#
-# -> { "execute": "blockdev-snapshot-delete-internal-sync",
-# "arguments": { "device": "ide-hd0",
-# "name": "snapshot0" }
-# }
-# <- { "return": {
-# "id": "1",
-# "name": "snapshot0",
-# "vm-state-size": 0,
-# "date-sec": 1000012,
-# "date-nsec": 10,
-# "vm-clock-sec": 100,
-# "vm-clock-nsec": 20
-# }
-# }
-#
-##
-{ 'command': 'blockdev-snapshot-delete-internal-sync',
- 'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
- 'returns': 'SnapshotInfo' }
-
##
# @eject:
#
@@ -210,111 +115,6 @@
'*id': 'str',
'*force': 'bool' } }
-##
-# @nbd-server-start:
-#
-# Start an NBD server listening on the given host and port. Block
-# devices can then be exported using @nbd-server-add. The NBD
-# server will present them as named exports; for example, another
-# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
-#
-# @addr: Address on which to listen.
-# @tls-creds: ID of the TLS credentials object (since 2.6).
-# @tls-authz: ID of the QAuthZ authorization object used to validate
-# the client's x509 distinguished name. This object is
-# is only resolved at time of use, so can be deleted and
-# recreated on the fly while the NBD server is active.
-# If missing, it will default to denying access (since 4.0).
-#
-# Returns: error if the server is already running.
-#
-# Since: 1.3.0
-##
-{ 'command': 'nbd-server-start',
- 'data': { 'addr': 'SocketAddressLegacy',
- '*tls-creds': 'str',
- '*tls-authz': 'str'} }
-
-##
-# @nbd-server-add:
-#
-# Export a block node to QEMU's embedded NBD server.
-#
-# @device: The device name or node name of the node to be exported
-#
-# @name: Export name. If unspecified, the @device parameter is used as the
-# export name. (Since 2.12)
-#
-# @description: Free-form description of the export, up to 4096 bytes.
-# (Since 5.0)
-#
-# @writable: Whether clients should be able to write to the device via the
-# NBD connection (default false).
-#
-# @bitmap: Also export the dirty bitmap reachable from @device, so the
-# NBD client can use NBD_OPT_SET_META_CONTEXT with
-# "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
-#
-# Returns: error if the server is not running, or export with the same name
-# already exists.
-#
-# Since: 1.3.0
-##
-{ 'command': 'nbd-server-add',
- 'data': {'device': 'str', '*name': 'str', '*description': 'str',
- '*writable': 'bool', '*bitmap': 'str' } }
-
-##
-# @NbdServerRemoveMode:
-#
-# Mode for removing an NBD export.
-#
-# @safe: Remove export if there are no existing connections, fail otherwise.
-#
-# @hard: Drop all connections immediately and remove export.
-#
-# Potential additional modes to be added in the future:
-#
-# hide: Just hide export from new clients, leave existing connections as is.
-# Remove export after all clients are disconnected.
-#
-# soft: Hide export from new clients, answer with ESHUTDOWN for all further
-# requests from existing clients.
-#
-# Since: 2.12
-##
-{'enum': 'NbdServerRemoveMode', 'data': ['safe', 'hard']}
-
-##
-# @nbd-server-remove:
-#
-# Remove NBD export by name.
-#
-# @name: Export name.
-#
-# @mode: Mode of command operation. See @NbdServerRemoveMode description.
-# Default is 'safe'.
-#
-# Returns: error if
-# - the server is not running
-# - export is not found
-# - mode is 'safe' and there are existing connections
-#
-# Since: 2.12
-##
-{ 'command': 'nbd-server-remove',
- 'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} }
-
-##
-# @nbd-server-stop:
-#
-# Stop QEMU's embedded NBD server, and unregister all devices previously
-# added via @nbd-server-add.
-#
-# Since: 1.3.0
-##
-{ 'command': 'nbd-server-stop' }
-
##
# @DEVICE_TRAY_MOVED:
#
@@ -367,87 +167,3 @@
##
{ 'event': 'PR_MANAGER_STATUS_CHANGED',
'data': { 'id': 'str', 'connected': 'bool' } }
-
-##
-# @QuorumOpType:
-#
-# An enumeration of the quorum operation types
-#
-# @read: read operation
-#
-# @write: write operation
-#
-# @flush: flush operation
-#
-# Since: 2.6
-##
-{ 'enum': 'QuorumOpType',
- 'data': [ 'read', 'write', 'flush' ] }
-
-##
-# @QUORUM_FAILURE:
-#
-# Emitted by the Quorum block driver if it fails to establish a quorum
-#
-# @reference: device name if defined else node name
-#
-# @sector-num: number of the first sector of the failed read operation
-#
-# @sectors-count: failed read operation sector count
-#
-# Note: This event is rate-limited.
-#
-# Since: 2.0
-#
-# Example:
-#
-# <- { "event": "QUORUM_FAILURE",
-# "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 },
-# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
-#
-##
-{ 'event': 'QUORUM_FAILURE',
- 'data': { 'reference': 'str', 'sector-num': 'int', 'sectors-count': 'int' } }
-
-##
-# @QUORUM_REPORT_BAD:
-#
-# Emitted to report a corruption of a Quorum file
-#
-# @type: quorum operation type (Since 2.6)
-#
-# @error: error message. Only present on failure. This field
-# contains a human-readable error message. There are no semantics other
-# than that the block layer reported an error and clients should not
-# try to interpret the error string.
-#
-# @node-name: the graph node name of the block driver state
-#
-# @sector-num: number of the first sector of the failed read operation
-#
-# @sectors-count: failed read operation sector count
-#
-# Note: This event is rate-limited.
-#
-# Since: 2.0
-#
-# Example:
-#
-# 1. Read operation
-#
-# { "event": "QUORUM_REPORT_BAD",
-# "data": { "node-name": "node0", "sector-num": 345435, "sectors-count": 5,
-# "type": "read" },
-# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
-#
-# 2. Flush operation
-#
-# { "event": "QUORUM_REPORT_BAD",
-# "data": { "node-name": "node0", "sector-num": 0, "sectors-count": 2097120,
-# "type": "flush", "error": "Broken pipe" },
-# "timestamp": { "seconds": 1456406829, "microseconds": 291763 } }
-#
-##
-{ 'event': 'QUORUM_REPORT_BAD',
- 'data': { 'type': 'QuorumOpType', '*error': 'str', 'node-name': 'str',
- 'sector-num': 'int', 'sectors-count': 'int' } }
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 11/29] block: Move sysemu QMP commands to QAPI block module
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (9 preceding siblings ...)
2020-03-06 17:14 ` [PULL 10/29] block: Move common QMP commands to block-core QAPI module Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 12/29] qemu-storage-daemon: Add --blockdev option Kevin Wolf
` (19 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
QMP commands that are related to the system emulator and don't make
sense in the context of tools such as qemu-storage-daemon should live in
qapi/block.json rather than qapi/block-core.json. Move them there.
The associated data types are actually also used in code shared with the
tools, so they stay in block-core.json.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-6-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/block-core.json | 386 -------------------------------------------
qapi/block.json | 386 +++++++++++++++++++++++++++++++++++++++++++
monitor/qmp-cmds.c | 2 +-
3 files changed, 387 insertions(+), 387 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 60860ead68..b65b6a9f49 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -563,78 +563,6 @@
{ 'struct': 'BlockLatencyHistogramInfo',
'data': {'boundaries': ['uint64'], 'bins': ['uint64'] } }
-##
-# @block-latency-histogram-set:
-#
-# Manage read, write and flush latency histograms for the device.
-#
-# If only @id parameter is specified, remove all present latency histograms
-# for the device. Otherwise, add/reset some of (or all) latency histograms.
-#
-# @id: The name or QOM path of the guest device.
-#
-# @boundaries: list of interval boundary values (see description in
-# BlockLatencyHistogramInfo definition). If specified, all
-# latency histograms are removed, and empty ones created for all
-# io types with intervals corresponding to @boundaries (except for
-# io types, for which specific boundaries are set through the
-# following parameters).
-#
-# @boundaries-read: list of interval boundary values for read latency
-# histogram. If specified, old read latency histogram is
-# removed, and empty one created with intervals
-# corresponding to @boundaries-read. The parameter has higher
-# priority then @boundaries.
-#
-# @boundaries-write: list of interval boundary values for write latency
-# histogram.
-#
-# @boundaries-flush: list of interval boundary values for flush latency
-# histogram.
-#
-# Returns: error if device is not found or any boundary arrays are invalid.
-#
-# Since: 4.0
-#
-# Example: set new histograms for all io types with intervals
-# [0, 10), [10, 50), [50, 100), [100, +inf):
-#
-# -> { "execute": "block-latency-histogram-set",
-# "arguments": { "id": "drive0",
-# "boundaries": [10, 50, 100] } }
-# <- { "return": {} }
-#
-# Example: set new histogram only for write, other histograms will remain
-# not changed (or not created):
-#
-# -> { "execute": "block-latency-histogram-set",
-# "arguments": { "id": "drive0",
-# "boundaries-write": [10, 50, 100] } }
-# <- { "return": {} }
-#
-# Example: set new histograms with the following intervals:
-# read, flush: [0, 10), [10, 50), [50, 100), [100, +inf)
-# write: [0, 1000), [1000, 5000), [5000, +inf)
-#
-# -> { "execute": "block-latency-histogram-set",
-# "arguments": { "id": "drive0",
-# "boundaries": [10, 50, 100],
-# "boundaries-write": [1000, 5000] } }
-# <- { "return": {} }
-#
-# Example: remove all latency histograms:
-#
-# -> { "execute": "block-latency-histogram-set",
-# "arguments": { "id": "drive0" } }
-# <- { "return": {} }
-##
-{ 'command': 'block-latency-histogram-set',
- 'data': {'id': 'str',
- '*boundaries': ['uint64'],
- '*boundaries-read': ['uint64'],
- '*boundaries-write': ['uint64'],
- '*boundaries-flush': ['uint64'] } }
-
##
# @BlockInfo:
#
@@ -2356,78 +2284,6 @@
'*copy-mode': 'MirrorCopyMode',
'*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
-##
-# @block_set_io_throttle:
-#
-# Change I/O throttle limits for a block drive.
-#
-# Since QEMU 2.4, each device with I/O limits is member of a throttle
-# group.
-#
-# If two or more devices are members of the same group, the limits
-# will apply to the combined I/O of the whole group in a round-robin
-# fashion. Therefore, setting new I/O limits to a device will affect
-# the whole group.
-#
-# The name of the group can be specified using the 'group' parameter.
-# If the parameter is unset, it is assumed to be the current group of
-# that device. If it's not in any group yet, the name of the device
-# will be used as the name for its group.
-#
-# The 'group' parameter can also be used to move a device to a
-# different group. In this case the limits specified in the parameters
-# will be applied to the new group only.
-#
-# I/O limits can be disabled by setting all of them to 0. In this case
-# the device will be removed from its group and the rest of its
-# members will not be affected. The 'group' parameter is ignored.
-#
-# Returns: - Nothing on success
-# - If @device is not a valid block device, DeviceNotFound
-#
-# Since: 1.1
-#
-# Example:
-#
-# -> { "execute": "block_set_io_throttle",
-# "arguments": { "id": "virtio-blk-pci0/virtio-backend",
-# "bps": 0,
-# "bps_rd": 0,
-# "bps_wr": 0,
-# "iops": 512,
-# "iops_rd": 0,
-# "iops_wr": 0,
-# "bps_max": 0,
-# "bps_rd_max": 0,
-# "bps_wr_max": 0,
-# "iops_max": 0,
-# "iops_rd_max": 0,
-# "iops_wr_max": 0,
-# "bps_max_length": 0,
-# "iops_size": 0 } }
-# <- { "return": {} }
-#
-# -> { "execute": "block_set_io_throttle",
-# "arguments": { "id": "ide0-1-0",
-# "bps": 1000000,
-# "bps_rd": 0,
-# "bps_wr": 0,
-# "iops": 0,
-# "iops_rd": 0,
-# "iops_wr": 0,
-# "bps_max": 8000000,
-# "bps_rd_max": 0,
-# "bps_wr_max": 0,
-# "iops_max": 0,
-# "iops_rd_max": 0,
-# "iops_wr_max": 0,
-# "bps_max_length": 60,
-# "iops_size": 0 } }
-# <- { "return": {} }
-##
-{ 'command': 'block_set_io_throttle', 'boxed': true,
- 'data': 'BlockIOThrottle' }
-
##
# @BlockIOThrottle:
#
@@ -4757,248 +4613,6 @@
'data': { 'job-id': 'str',
'options': 'BlockdevCreateOptions' } }
-##
-# @blockdev-open-tray:
-#
-# Opens a block device's tray. If there is a block driver state tree inserted as
-# a medium, it will become inaccessible to the guest (but it will remain
-# associated to the block device, so closing the tray will make it accessible
-# again).
-#
-# If the tray was already open before, this will be a no-op.
-#
-# Once the tray opens, a DEVICE_TRAY_MOVED event is emitted. There are cases in
-# which no such event will be generated, these include:
-#
-# - if the guest has locked the tray, @force is false and the guest does not
-# respond to the eject request
-# - if the BlockBackend denoted by @device does not have a guest device attached
-# to it
-# - if the guest device does not have an actual tray
-#
-# @device: Block device name (deprecated, use @id instead)
-#
-# @id: The name or QOM path of the guest device (since: 2.8)
-#
-# @force: if false (the default), an eject request will be sent to
-# the guest if it has locked the tray (and the tray will not be opened
-# immediately); if true, the tray will be opened regardless of whether
-# it is locked
-#
-# Since: 2.5
-#
-# Example:
-#
-# -> { "execute": "blockdev-open-tray",
-# "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "timestamp": { "seconds": 1418751016,
-# "microseconds": 716996 },
-# "event": "DEVICE_TRAY_MOVED",
-# "data": { "device": "ide1-cd0",
-# "id": "ide0-1-0",
-# "tray-open": true } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-open-tray',
- 'data': { '*device': 'str',
- '*id': 'str',
- '*force': 'bool' } }
-
-##
-# @blockdev-close-tray:
-#
-# Closes a block device's tray. If there is a block driver state tree associated
-# with the block device (which is currently ejected), that tree will be loaded
-# as the medium.
-#
-# If the tray was already closed before, this will be a no-op.
-#
-# @device: Block device name (deprecated, use @id instead)
-#
-# @id: The name or QOM path of the guest device (since: 2.8)
-#
-# Since: 2.5
-#
-# Example:
-#
-# -> { "execute": "blockdev-close-tray",
-# "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "timestamp": { "seconds": 1418751345,
-# "microseconds": 272147 },
-# "event": "DEVICE_TRAY_MOVED",
-# "data": { "device": "ide1-cd0",
-# "id": "ide0-1-0",
-# "tray-open": false } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-close-tray',
- 'data': { '*device': 'str',
- '*id': 'str' } }
-
-##
-# @blockdev-remove-medium:
-#
-# Removes a medium (a block driver state tree) from a block device. That block
-# device's tray must currently be open (unless there is no attached guest
-# device).
-#
-# If the tray is open and there is no medium inserted, this will be a no-op.
-#
-# @id: The name or QOM path of the guest device
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "blockdev-remove-medium",
-# "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "error": { "class": "GenericError",
-# "desc": "Tray of device 'ide0-1-0' is not open" } }
-#
-# -> { "execute": "blockdev-open-tray",
-# "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "timestamp": { "seconds": 1418751627,
-# "microseconds": 549958 },
-# "event": "DEVICE_TRAY_MOVED",
-# "data": { "device": "ide1-cd0",
-# "id": "ide0-1-0",
-# "tray-open": true } }
-#
-# <- { "return": {} }
-#
-# -> { "execute": "blockdev-remove-medium",
-# "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-remove-medium',
- 'data': { 'id': 'str' } }
-
-##
-# @blockdev-insert-medium:
-#
-# Inserts a medium (a block driver state tree) into a block device. That block
-# device's tray must currently be open (unless there is no attached guest
-# device) and there must be no medium inserted already.
-#
-# @id: The name or QOM path of the guest device
-#
-# @node-name: name of a node in the block driver state graph
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "blockdev-add",
-# "arguments": {
-# "node-name": "node0",
-# "driver": "raw",
-# "file": { "driver": "file",
-# "filename": "fedora.iso" } } }
-# <- { "return": {} }
-#
-# -> { "execute": "blockdev-insert-medium",
-# "arguments": { "id": "ide0-1-0",
-# "node-name": "node0" } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-insert-medium',
- 'data': { 'id': 'str',
- 'node-name': 'str'} }
-
-
-##
-# @BlockdevChangeReadOnlyMode:
-#
-# Specifies the new read-only mode of a block device subject to the
-# @blockdev-change-medium command.
-#
-# @retain: Retains the current read-only mode
-#
-# @read-only: Makes the device read-only
-#
-# @read-write: Makes the device writable
-#
-# Since: 2.3
-#
-##
-{ 'enum': 'BlockdevChangeReadOnlyMode',
- 'data': ['retain', 'read-only', 'read-write'] }
-
-
-##
-# @blockdev-change-medium:
-#
-# Changes the medium inserted into a block device by ejecting the current medium
-# and loading a new image file which is inserted as the new medium (this command
-# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium
-# and blockdev-close-tray).
-#
-# @device: Block device name (deprecated, use @id instead)
-#
-# @id: The name or QOM path of the guest device
-# (since: 2.8)
-#
-# @filename: filename of the new image to be loaded
-#
-# @format: format to open the new image with (defaults to
-# the probed format)
-#
-# @read-only-mode: change the read-only mode of the device; defaults
-# to 'retain'
-#
-# Since: 2.5
-#
-# Examples:
-#
-# 1. Change a removable medium
-#
-# -> { "execute": "blockdev-change-medium",
-# "arguments": { "id": "ide0-1-0",
-# "filename": "/srv/images/Fedora-12-x86_64-DVD.iso",
-# "format": "raw" } }
-# <- { "return": {} }
-#
-# 2. Load a read-only medium into a writable drive
-#
-# -> { "execute": "blockdev-change-medium",
-# "arguments": { "id": "floppyA",
-# "filename": "/srv/images/ro.img",
-# "format": "raw",
-# "read-only-mode": "retain" } }
-#
-# <- { "error":
-# { "class": "GenericError",
-# "desc": "Could not open '/srv/images/ro.img': Permission denied" } }
-#
-# -> { "execute": "blockdev-change-medium",
-# "arguments": { "id": "floppyA",
-# "filename": "/srv/images/ro.img",
-# "format": "raw",
-# "read-only-mode": "read-only" } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-change-medium',
- 'data': { '*device': 'str',
- '*id': 'str',
- 'filename': 'str',
- '*format': 'str',
- '*read-only-mode': 'BlockdevChangeReadOnlyMode' } }
-
-
##
# @BlockErrorAction:
#
diff --git a/qapi/block.json b/qapi/block.json
index d2f3fc01ed..97bf52b7c7 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -115,6 +115,248 @@
'*id': 'str',
'*force': 'bool' } }
+##
+# @blockdev-open-tray:
+#
+# Opens a block device's tray. If there is a block driver state tree inserted as
+# a medium, it will become inaccessible to the guest (but it will remain
+# associated to the block device, so closing the tray will make it accessible
+# again).
+#
+# If the tray was already open before, this will be a no-op.
+#
+# Once the tray opens, a DEVICE_TRAY_MOVED event is emitted. There are cases in
+# which no such event will be generated, these include:
+#
+# - if the guest has locked the tray, @force is false and the guest does not
+# respond to the eject request
+# - if the BlockBackend denoted by @device does not have a guest device attached
+# to it
+# - if the guest device does not have an actual tray
+#
+# @device: Block device name (deprecated, use @id instead)
+#
+# @id: The name or QOM path of the guest device (since: 2.8)
+#
+# @force: if false (the default), an eject request will be sent to
+# the guest if it has locked the tray (and the tray will not be opened
+# immediately); if true, the tray will be opened regardless of whether
+# it is locked
+#
+# Since: 2.5
+#
+# Example:
+#
+# -> { "execute": "blockdev-open-tray",
+# "arguments": { "id": "ide0-1-0" } }
+#
+# <- { "timestamp": { "seconds": 1418751016,
+# "microseconds": 716996 },
+# "event": "DEVICE_TRAY_MOVED",
+# "data": { "device": "ide1-cd0",
+# "id": "ide0-1-0",
+# "tray-open": true } }
+#
+# <- { "return": {} }
+#
+##
+{ 'command': 'blockdev-open-tray',
+ 'data': { '*device': 'str',
+ '*id': 'str',
+ '*force': 'bool' } }
+
+##
+# @blockdev-close-tray:
+#
+# Closes a block device's tray. If there is a block driver state tree associated
+# with the block device (which is currently ejected), that tree will be loaded
+# as the medium.
+#
+# If the tray was already closed before, this will be a no-op.
+#
+# @device: Block device name (deprecated, use @id instead)
+#
+# @id: The name or QOM path of the guest device (since: 2.8)
+#
+# Since: 2.5
+#
+# Example:
+#
+# -> { "execute": "blockdev-close-tray",
+# "arguments": { "id": "ide0-1-0" } }
+#
+# <- { "timestamp": { "seconds": 1418751345,
+# "microseconds": 272147 },
+# "event": "DEVICE_TRAY_MOVED",
+# "data": { "device": "ide1-cd0",
+# "id": "ide0-1-0",
+# "tray-open": false } }
+#
+# <- { "return": {} }
+#
+##
+{ 'command': 'blockdev-close-tray',
+ 'data': { '*device': 'str',
+ '*id': 'str' } }
+
+##
+# @blockdev-remove-medium:
+#
+# Removes a medium (a block driver state tree) from a block device. That block
+# device's tray must currently be open (unless there is no attached guest
+# device).
+#
+# If the tray is open and there is no medium inserted, this will be a no-op.
+#
+# @id: The name or QOM path of the guest device
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "blockdev-remove-medium",
+# "arguments": { "id": "ide0-1-0" } }
+#
+# <- { "error": { "class": "GenericError",
+# "desc": "Tray of device 'ide0-1-0' is not open" } }
+#
+# -> { "execute": "blockdev-open-tray",
+# "arguments": { "id": "ide0-1-0" } }
+#
+# <- { "timestamp": { "seconds": 1418751627,
+# "microseconds": 549958 },
+# "event": "DEVICE_TRAY_MOVED",
+# "data": { "device": "ide1-cd0",
+# "id": "ide0-1-0",
+# "tray-open": true } }
+#
+# <- { "return": {} }
+#
+# -> { "execute": "blockdev-remove-medium",
+# "arguments": { "id": "ide0-1-0" } }
+#
+# <- { "return": {} }
+#
+##
+{ 'command': 'blockdev-remove-medium',
+ 'data': { 'id': 'str' } }
+
+##
+# @blockdev-insert-medium:
+#
+# Inserts a medium (a block driver state tree) into a block device. That block
+# device's tray must currently be open (unless there is no attached guest
+# device) and there must be no medium inserted already.
+#
+# @id: The name or QOM path of the guest device
+#
+# @node-name: name of a node in the block driver state graph
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "blockdev-add",
+# "arguments": {
+# "node-name": "node0",
+# "driver": "raw",
+# "file": { "driver": "file",
+# "filename": "fedora.iso" } } }
+# <- { "return": {} }
+#
+# -> { "execute": "blockdev-insert-medium",
+# "arguments": { "id": "ide0-1-0",
+# "node-name": "node0" } }
+#
+# <- { "return": {} }
+#
+##
+{ 'command': 'blockdev-insert-medium',
+ 'data': { 'id': 'str',
+ 'node-name': 'str'} }
+
+
+##
+# @BlockdevChangeReadOnlyMode:
+#
+# Specifies the new read-only mode of a block device subject to the
+# @blockdev-change-medium command.
+#
+# @retain: Retains the current read-only mode
+#
+# @read-only: Makes the device read-only
+#
+# @read-write: Makes the device writable
+#
+# Since: 2.3
+#
+##
+{ 'enum': 'BlockdevChangeReadOnlyMode',
+ 'data': ['retain', 'read-only', 'read-write'] }
+
+
+##
+# @blockdev-change-medium:
+#
+# Changes the medium inserted into a block device by ejecting the current medium
+# and loading a new image file which is inserted as the new medium (this command
+# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium
+# and blockdev-close-tray).
+#
+# @device: Block device name (deprecated, use @id instead)
+#
+# @id: The name or QOM path of the guest device
+# (since: 2.8)
+#
+# @filename: filename of the new image to be loaded
+#
+# @format: format to open the new image with (defaults to
+# the probed format)
+#
+# @read-only-mode: change the read-only mode of the device; defaults
+# to 'retain'
+#
+# Since: 2.5
+#
+# Examples:
+#
+# 1. Change a removable medium
+#
+# -> { "execute": "blockdev-change-medium",
+# "arguments": { "id": "ide0-1-0",
+# "filename": "/srv/images/Fedora-12-x86_64-DVD.iso",
+# "format": "raw" } }
+# <- { "return": {} }
+#
+# 2. Load a read-only medium into a writable drive
+#
+# -> { "execute": "blockdev-change-medium",
+# "arguments": { "id": "floppyA",
+# "filename": "/srv/images/ro.img",
+# "format": "raw",
+# "read-only-mode": "retain" } }
+#
+# <- { "error":
+# { "class": "GenericError",
+# "desc": "Could not open '/srv/images/ro.img': Permission denied" } }
+#
+# -> { "execute": "blockdev-change-medium",
+# "arguments": { "id": "floppyA",
+# "filename": "/srv/images/ro.img",
+# "format": "raw",
+# "read-only-mode": "read-only" } }
+#
+# <- { "return": {} }
+#
+##
+{ 'command': 'blockdev-change-medium',
+ 'data': { '*device': 'str',
+ '*id': 'str',
+ 'filename': 'str',
+ '*format': 'str',
+ '*read-only-mode': 'BlockdevChangeReadOnlyMode' } }
+
+
##
# @DEVICE_TRAY_MOVED:
#
@@ -167,3 +409,147 @@
##
{ 'event': 'PR_MANAGER_STATUS_CHANGED',
'data': { 'id': 'str', 'connected': 'bool' } }
+
+##
+# @block_set_io_throttle:
+#
+# Change I/O throttle limits for a block drive.
+#
+# Since QEMU 2.4, each device with I/O limits is member of a throttle
+# group.
+#
+# If two or more devices are members of the same group, the limits
+# will apply to the combined I/O of the whole group in a round-robin
+# fashion. Therefore, setting new I/O limits to a device will affect
+# the whole group.
+#
+# The name of the group can be specified using the 'group' parameter.
+# If the parameter is unset, it is assumed to be the current group of
+# that device. If it's not in any group yet, the name of the device
+# will be used as the name for its group.
+#
+# The 'group' parameter can also be used to move a device to a
+# different group. In this case the limits specified in the parameters
+# will be applied to the new group only.
+#
+# I/O limits can be disabled by setting all of them to 0. In this case
+# the device will be removed from its group and the rest of its
+# members will not be affected. The 'group' parameter is ignored.
+#
+# Returns: - Nothing on success
+# - If @device is not a valid block device, DeviceNotFound
+#
+# Since: 1.1
+#
+# Example:
+#
+# -> { "execute": "block_set_io_throttle",
+# "arguments": { "id": "virtio-blk-pci0/virtio-backend",
+# "bps": 0,
+# "bps_rd": 0,
+# "bps_wr": 0,
+# "iops": 512,
+# "iops_rd": 0,
+# "iops_wr": 0,
+# "bps_max": 0,
+# "bps_rd_max": 0,
+# "bps_wr_max": 0,
+# "iops_max": 0,
+# "iops_rd_max": 0,
+# "iops_wr_max": 0,
+# "bps_max_length": 0,
+# "iops_size": 0 } }
+# <- { "return": {} }
+#
+# -> { "execute": "block_set_io_throttle",
+# "arguments": { "id": "ide0-1-0",
+# "bps": 1000000,
+# "bps_rd": 0,
+# "bps_wr": 0,
+# "iops": 0,
+# "iops_rd": 0,
+# "iops_wr": 0,
+# "bps_max": 8000000,
+# "bps_rd_max": 0,
+# "bps_wr_max": 0,
+# "iops_max": 0,
+# "iops_rd_max": 0,
+# "iops_wr_max": 0,
+# "bps_max_length": 60,
+# "iops_size": 0 } }
+# <- { "return": {} }
+##
+{ 'command': 'block_set_io_throttle', 'boxed': true,
+ 'data': 'BlockIOThrottle' }
+
+##
+# @block-latency-histogram-set:
+#
+# Manage read, write and flush latency histograms for the device.
+#
+# If only @id parameter is specified, remove all present latency histograms
+# for the device. Otherwise, add/reset some of (or all) latency histograms.
+#
+# @id: The name or QOM path of the guest device.
+#
+# @boundaries: list of interval boundary values (see description in
+# BlockLatencyHistogramInfo definition). If specified, all
+# latency histograms are removed, and empty ones created for all
+# io types with intervals corresponding to @boundaries (except for
+# io types, for which specific boundaries are set through the
+# following parameters).
+#
+# @boundaries-read: list of interval boundary values for read latency
+# histogram. If specified, old read latency histogram is
+# removed, and empty one created with intervals
+# corresponding to @boundaries-read. The parameter has higher
+# priority then @boundaries.
+#
+# @boundaries-write: list of interval boundary values for write latency
+# histogram.
+#
+# @boundaries-flush: list of interval boundary values for flush latency
+# histogram.
+#
+# Returns: error if device is not found or any boundary arrays are invalid.
+#
+# Since: 4.0
+#
+# Example: set new histograms for all io types with intervals
+# [0, 10), [10, 50), [50, 100), [100, +inf):
+#
+# -> { "execute": "block-latency-histogram-set",
+# "arguments": { "id": "drive0",
+# "boundaries": [10, 50, 100] } }
+# <- { "return": {} }
+#
+# Example: set new histogram only for write, other histograms will remain
+# not changed (or not created):
+#
+# -> { "execute": "block-latency-histogram-set",
+# "arguments": { "id": "drive0",
+# "boundaries-write": [10, 50, 100] } }
+# <- { "return": {} }
+#
+# Example: set new histograms with the following intervals:
+# read, flush: [0, 10), [10, 50), [50, 100), [100, +inf)
+# write: [0, 1000), [1000, 5000), [5000, +inf)
+#
+# -> { "execute": "block-latency-histogram-set",
+# "arguments": { "id": "drive0",
+# "boundaries": [10, 50, 100],
+# "boundaries-write": [1000, 5000] } }
+# <- { "return": {} }
+#
+# Example: remove all latency histograms:
+#
+# -> { "execute": "block-latency-histogram-set",
+# "arguments": { "id": "drive0" } }
+# <- { "return": {} }
+##
+{ 'command': 'block-latency-histogram-set',
+ 'data': {'id': 'str',
+ '*boundaries': ['uint64'],
+ '*boundaries-read': ['uint64'],
+ '*boundaries-write': ['uint64'],
+ '*boundaries-flush': ['uint64'] } }
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index da7083087e..864cbfa32e 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -30,7 +30,7 @@
#include "sysemu/blockdev.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-block-core.h"
+#include "qapi/qapi-commands-block.h"
#include "qapi/qapi-commands-control.h"
#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-misc.h"
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 12/29] qemu-storage-daemon: Add --blockdev option
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (10 preceding siblings ...)
2020-03-06 17:14 ` [PULL 11/29] block: Move sysemu QMP commands to QAPI block module Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 13/29] qapi: Flatten object-add Kevin Wolf
` (18 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
This adds a --blockdev option to the storage daemon that works the same
as the -blockdev option of the system emulator.
In order to be able to link with blockdev.o, we also need to change
stream.o from common-obj to block-obj, which is where all other block
jobs already are.
In contrast to the system emulator, qemu-storage-daemon options will be
processed in the order they are given. The user needs to take care to
refer to other objects only after defining them.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-7-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qemu-storage-daemon.c | 31 +++++++++++++++++++++++++++++++
Makefile | 5 ++++-
Makefile.objs | 7 +++++++
block/Makefile.objs | 2 +-
4 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
index fc4aef572b..c30caaf59e 100644
--- a/qemu-storage-daemon.c
+++ b/qemu-storage-daemon.c
@@ -31,6 +31,10 @@
#include "crypto/init.h"
#include "qapi/error.h"
+#include "qapi/qapi-visit-block-core.h"
+#include "qapi/qapi-commands-block-core.h"
+#include "qapi/qobject-input-visitor.h"
+
#include "qemu-common.h"
#include "qemu-version.h"
#include "qemu/config-file.h"
@@ -52,15 +56,27 @@ static void help(void)
" specify tracing options\n"
" -V, --version output version information and exit\n"
"\n"
+" --blockdev [driver=]<driver>[,node-name=<N>][,discard=ignore|unmap]\n"
+" [,cache.direct=on|off][,cache.no-flush=on|off]\n"
+" [,read-only=on|off][,auto-read-only=on|off]\n"
+" [,force-share=on|off][,detect-zeroes=on|off|unmap]\n"
+" [,driver specific parameters...]\n"
+" configure a block backend\n"
+"\n"
QEMU_HELP_BOTTOM "\n",
error_get_progname());
}
+enum {
+ OPTION_BLOCKDEV = 256,
+};
+
static void process_options(int argc, char *argv[])
{
int c;
static const struct option long_options[] = {
+ {"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
{"help", no_argument, NULL, 'h'},
{"trace", required_argument, NULL, 'T'},
{"version", no_argument, NULL, 'V'},
@@ -90,6 +106,21 @@ static void process_options(int argc, char *argv[])
printf("qemu-storage-daemon version "
QEMU_FULL_VERSION "\n" QEMU_COPYRIGHT "\n");
exit(EXIT_SUCCESS);
+ case OPTION_BLOCKDEV:
+ {
+ Visitor *v;
+ BlockdevOptions *options;
+
+ v = qobject_input_visitor_new_str(optarg, "driver",
+ &error_fatal);
+
+ visit_type_BlockdevOptions(v, NULL, &options, &error_fatal);
+ visit_free(v);
+
+ qmp_blockdev_add(options, &error_fatal);
+ qapi_free_BlockdevOptions(options);
+ break;
+ }
default:
g_assert_not_reached();
}
diff --git a/Makefile b/Makefile
index 2bf59d4f42..7c75440182 100644
--- a/Makefile
+++ b/Makefile
@@ -450,6 +450,8 @@ dummy := $(call unnest-vars,, \
qga-vss-dll-obj-y \
block-obj-y \
block-obj-m \
+ storage-daemon-obj-y \
+ storage-daemon-obj-m \
crypto-obj-y \
qom-obj-y \
io-obj-y \
@@ -482,6 +484,7 @@ TARGET_DIRS_RULES := $(foreach t, all fuzz clean install, $(addsuffix /$(t), $(T
SOFTMMU_ALL_RULES=$(filter %-softmmu/all, $(TARGET_DIRS_RULES))
$(SOFTMMU_ALL_RULES): $(authz-obj-y)
$(SOFTMMU_ALL_RULES): $(block-obj-y)
+$(SOFTMMU_ALL_RULES): $(storage-daemon-obj-y)
$(SOFTMMU_ALL_RULES): $(chardev-obj-y)
$(SOFTMMU_ALL_RULES): $(crypto-obj-y)
$(SOFTMMU_ALL_RULES): $(io-obj-y)
@@ -586,7 +589,7 @@ qemu-img.o: qemu-img-cmds.h
qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
-qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
diff --git a/Makefile.objs b/Makefile.objs
index 8a1cbe8000..3db3a7db6e 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -27,6 +27,13 @@ io-obj-y = io/
endif # CONFIG_SOFTMMU or CONFIG_TOOLS
+#######################################################################
+# storage-daemon-obj-y is code used by qemu-storage-daemon (these objects are
+# used for system emulation, too, but specified separately there)
+
+storage-daemon-obj-y = block/
+storage-daemon-obj-y += blockdev.o iothread.o
+
######################################################################
# Target independent part of system emulation. The long term path is to
# suppress *all* target specific code in case of system emulation, i.e. a
diff --git a/block/Makefile.objs b/block/Makefile.objs
index e06cf0b284..cb36ae2503 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -46,7 +46,7 @@ block-obj-y += aio_task.o
block-obj-y += backup-top.o
block-obj-y += filter-compress.o
-common-obj-y += stream.o
+block-obj-y += stream.o
common-obj-y += qapi-sysemu.o
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 13/29] qapi: Flatten object-add
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (11 preceding siblings ...)
2020-03-06 17:14 ` [PULL 12/29] qemu-storage-daemon: Add --blockdev option Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-07-08 15:48 ` Paolo Bonzini
2020-03-06 17:14 ` [PULL 14/29] qemu-storage-daemon: Add --object option Kevin Wolf
` (17 subsequent siblings)
30 siblings, 1 reply; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Mapping object-add to the command line as is doesn't result in nice
syntax because of the nesting introduced with 'props'. This becomes
nicer and more consistent with device_add and netdev_add when we accept
properties for the object on the top level instead.
'props' is still accepted after this patch, but marked as deprecated.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-8-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/qom.json | 12 +++++++---
docs/system/deprecated.rst | 5 ++++
include/qom/object_interfaces.h | 7 ++++++
hw/block/xen-block.c | 11 ++++++++-
monitor/misc.c | 2 ++
qom/qom-qmp-cmds.c | 42 +++++++++++++++++++++++++++------
6 files changed, 68 insertions(+), 11 deletions(-)
diff --git a/qapi/qom.json b/qapi/qom.json
index ecc60c4401..8abe998962 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -210,7 +210,12 @@
#
# @id: the name of the new object
#
-# @props: a dictionary of properties to be passed to the backend
+# @props: a dictionary of properties to be passed to the backend. Deprecated
+# since 5.0, specify the properties on the top level instead. It is an
+# error to specify the same option both on the top level and in @props.
+#
+# Additional arguments depend on qom-type and are passed to the backend
+# unchanged.
#
# Returns: Nothing on success
# Error if @qom-type is not a valid class name
@@ -221,12 +226,13 @@
#
# -> { "execute": "object-add",
# "arguments": { "qom-type": "rng-random", "id": "rng1",
-# "props": { "filename": "/dev/hwrng" } } }
+# "filename": "/dev/hwrng" } }
# <- { "return": {} }
#
##
{ 'command': 'object-add',
- 'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'} }
+ 'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'},
+ 'gen': false } # so we can get the additional arguments
##
# @object-del:
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index 1eaa559079..6c1d9034d9 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -190,6 +190,11 @@ Use ``migrate-set-parameters`` instead.
Use ``migrate-set-parameters`` and ``query-migrate-parameters`` instead.
+``object-add`` option ``props`` (since 5.0)
+'''''''''''''''''''''''''''''''''''''''''''
+
+Specify the properties for the object as top-level arguments instead.
+
``query-block`` result field ``dirty-bitmaps[i].status`` (since 4.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index 3e4e1d928b..6f92f3cebb 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -162,4 +162,11 @@ void user_creatable_del(const char *id, Error **errp);
*/
void user_creatable_cleanup(void);
+/**
+ * qmp_object_add:
+ *
+ * QMP command handler for object-add. See the QAPI schema for documentation.
+ */
+void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp);
+
#endif
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 686bbc3f0d..3885464513 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -18,6 +18,7 @@
#include "qapi/visitor.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
+#include "qom/object_interfaces.h"
#include "hw/xen/xen_common.h"
#include "hw/block/xen_blkif.h"
#include "hw/qdev-properties.h"
@@ -858,10 +859,18 @@ static XenBlockIOThread *xen_block_iothread_create(const char *id,
{
XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1);
Error *local_err = NULL;
+ QDict *opts;
+ QObject *ret_data;
iothread->id = g_strdup(id);
- qmp_object_add(TYPE_IOTHREAD, id, false, NULL, &local_err);
+ opts = qdict_new();
+ qdict_put_str(opts, "qom-type", TYPE_IOTHREAD);
+ qdict_put_str(opts, "id", id);
+ qmp_object_add(opts, &ret_data, &local_err);
+ qobject_unref(opts);
+ qobject_unref(ret_data);
+
if (local_err) {
error_propagate(errp, local_err);
diff --git a/monitor/misc.c b/monitor/misc.c
index 6c41293102..1748ab3911 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -248,6 +248,8 @@ static void monitor_init_qmp_commands(void)
QCO_NO_OPTIONS);
qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
QCO_NO_OPTIONS);
+ qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
+ QCO_NO_OPTIONS);
QTAILQ_INIT(&qmp_cap_negotiation_commands);
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
index 6136efec16..49db926fcc 100644
--- a/qom/qom-qmp-cmds.c
+++ b/qom/qom-qmp-cmds.c
@@ -14,6 +14,7 @@
*/
#include "qemu/osdep.h"
+#include "block/qdict.h"
#include "hw/qdev-core.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-qdev.h"
@@ -240,13 +241,34 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
return prop_list;
}
-void qmp_object_add(const char *type, const char *id,
- bool has_props, QObject *props, Error **errp)
+void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
{
+ QObject *props;
QDict *pdict;
Visitor *v;
Object *obj;
+ const char *type;
+ const char *id;
+ type = qdict_get_try_str(qdict, "qom-type");
+ if (!type) {
+ error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
+ return;
+ } else {
+ type = g_strdup(type);
+ qdict_del(qdict, "qom-type");
+ }
+
+ id = qdict_get_try_str(qdict, "id");
+ if (!id) {
+ error_setg(errp, QERR_MISSING_PARAMETER, "id");
+ return;
+ } else {
+ id = g_strdup(id);
+ qdict_del(qdict, "id");
+ }
+
+ props = qdict_get(qdict, "props");
if (props) {
pdict = qobject_to(QDict, props);
if (!pdict) {
@@ -254,17 +276,23 @@ void qmp_object_add(const char *type, const char *id,
return;
}
qobject_ref(pdict);
- } else {
- pdict = qdict_new();
+ qdict_del(qdict, "props");
+ qdict_join(qdict, pdict, false);
+ if (qdict_size(pdict) != 0) {
+ error_setg(errp, "Option in 'props' conflicts with top level");
+ qobject_unref(pdict);
+ return;
+ }
+ qobject_unref(pdict);
}
- v = qobject_input_visitor_new(QOBJECT(pdict));
- obj = user_creatable_add_type(type, id, pdict, v, errp);
+ v = qobject_input_visitor_new(QOBJECT(qdict));
+ obj = user_creatable_add_type(type, id, qdict, v, errp);
visit_free(v);
if (obj) {
object_unref(obj);
}
- qobject_unref(pdict);
+ *ret_data = QOBJECT(qdict_new());
}
void qmp_object_del(const char *id, Error **errp)
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 14/29] qemu-storage-daemon: Add --object option
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (12 preceding siblings ...)
2020-03-06 17:14 ` [PULL 13/29] qapi: Flatten object-add Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 15/29] qemu-storage-daemon: Add --nbd-server option Kevin Wolf
` (16 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Add a command line option to create user-creatable QOM objects.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-9-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qemu-storage-daemon.c | 47 +++++++++++++++++++++++++++++++++++++++++++
Makefile.objs | 2 +-
qom/Makefile.objs | 1 +
3 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
index c30caaf59e..0cd8144c81 100644
--- a/qemu-storage-daemon.c
+++ b/qemu-storage-daemon.c
@@ -33,15 +33,19 @@
#include "qapi/error.h"
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qapi-commands-block-core.h"
+#include "qapi/qmp/qdict.h"
#include "qapi/qobject-input-visitor.h"
#include "qemu-common.h"
#include "qemu-version.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
+#include "qemu/help_option.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
+#include "qemu/option.h"
+#include "qom/object_interfaces.h"
#include "trace/control.h"
@@ -63,12 +67,31 @@ static void help(void)
" [,driver specific parameters...]\n"
" configure a block backend\n"
"\n"
+" --object help list object types that can be added\n"
+" --object <type>,help list properties for the given object type\n"
+" --object <type>[,<property>=<value>...]\n"
+" create a new object of type <type>, setting\n"
+" properties in the order they are specified. Note\n"
+" that the 'id' property must be set.\n"
+" See the qemu(1) man page for documentation of the\n"
+" objects that can be added.\n"
+"\n"
QEMU_HELP_BOTTOM "\n",
error_get_progname());
}
enum {
OPTION_BLOCKDEV = 256,
+ OPTION_OBJECT,
+};
+
+static QemuOptsList qemu_object_opts = {
+ .name = "object",
+ .implied_opt_name = "qom-type",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
+ .desc = {
+ { }
+ },
};
static void process_options(int argc, char *argv[])
@@ -78,6 +101,7 @@ static void process_options(int argc, char *argv[])
static const struct option long_options[] = {
{"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
{"help", no_argument, NULL, 'h'},
+ {"object", required_argument, NULL, OPTION_OBJECT},
{"trace", required_argument, NULL, 'T'},
{"version", no_argument, NULL, 'V'},
{0, 0, 0, 0}
@@ -121,6 +145,29 @@ static void process_options(int argc, char *argv[])
qapi_free_BlockdevOptions(options);
break;
}
+ case OPTION_OBJECT:
+ {
+ QemuOpts *opts;
+ const char *type;
+ QDict *args;
+ QObject *ret_data = NULL;
+
+ /* FIXME The keyval parser rejects 'help' arguments, so we must
+ * unconditionall try QemuOpts first. */
+ opts = qemu_opts_parse(&qemu_object_opts,
+ optarg, true, &error_fatal);
+ type = qemu_opt_get(opts, "qom-type");
+ if (type && user_creatable_print_help(type, opts)) {
+ exit(EXIT_SUCCESS);
+ }
+ qemu_opts_del(opts);
+
+ args = keyval_parse(optarg, "qom-type", &error_fatal);
+ qmp_object_add(args, &ret_data, &error_fatal);
+ qobject_unref(args);
+ qobject_unref(ret_data);
+ break;
+ }
default:
g_assert_not_reached();
}
diff --git a/Makefile.objs b/Makefile.objs
index 3db3a7db6e..b5d9e1e134 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -31,7 +31,7 @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS
# storage-daemon-obj-y is code used by qemu-storage-daemon (these objects are
# used for system emulation, too, but specified separately there)
-storage-daemon-obj-y = block/
+storage-daemon-obj-y = block/ qom/
storage-daemon-obj-y += blockdev.o iothread.o
######################################################################
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index f9d77350ac..1b45d104ba 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -2,3 +2,4 @@ qom-obj-y = object.o container.o qom-qobject.o
qom-obj-y += object_interfaces.o
common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o
+storage-daemon-obj-y += qom-qmp-cmds.o
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 15/29] qemu-storage-daemon: Add --nbd-server option
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (13 preceding siblings ...)
2020-03-06 17:14 ` [PULL 14/29] qemu-storage-daemon: Add --object option Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 16/29] blockdev-nbd: Boxed argument type for nbd-server-add Kevin Wolf
` (15 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Add a --nbd-server option to qemu-storage-daemon to start the built-in
NBD server right away. It maps the arguments for nbd-server-start to the
command line, with the exception that it uses SocketAddress instead of
SocketAddressLegacy: New interfaces shouldn't use legacy types, and the
additional nesting would be nasty on the command line.
Example (only with required options):
--nbd-server addr.type=inet,addr.host=localhost,addr.port=10809
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-10-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/block-core.json | 24 ++++++++++++++++++++++++
include/block/nbd.h | 1 +
blockdev-nbd.c | 5 +++++
qemu-storage-daemon.c | 26 +++++++++++++++++++++++++-
Makefile.objs | 2 +-
5 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index b65b6a9f49..f8888f06c8 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -5062,6 +5062,27 @@
'iothread': 'StrOrNull',
'*force': 'bool' } }
+##
+# @NbdServerOptions:
+#
+# @addr: Address on which to listen.
+# @tls-creds: ID of the TLS credentials object (since 2.6).
+# @tls-authz: ID of the QAuthZ authorization object used to validate
+# the client's x509 distinguished name. This object is
+# is only resolved at time of use, so can be deleted and
+# recreated on the fly while the NBD server is active.
+# If missing, it will default to denying access (since 4.0).
+#
+# Keep this type consistent with the nbd-server-start arguments. The only
+# intended difference is using SocketAddress instead of SocketAddressLegacy.
+#
+# Since: 4.2
+##
+{ 'struct': 'NbdServerOptions',
+ 'data': { 'addr': 'SocketAddress',
+ '*tls-creds': 'str',
+ '*tls-authz': 'str'} }
+
##
# @nbd-server-start:
#
@@ -5080,6 +5101,9 @@
#
# Returns: error if the server is already running.
#
+# Keep this type consistent with the NbdServerOptions type. The only intended
+# difference is using SocketAddressLegacy instead of SocketAddress.
+#
# Since: 1.3.0
##
{ 'command': 'nbd-server-start',
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 7f46932d80..20363280ae 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -353,6 +353,7 @@ void nbd_client_put(NBDClient *client);
void nbd_server_start(SocketAddress *addr, const char *tls_creds,
const char *tls_authz, Error **errp);
+void nbd_server_start_options(NbdServerOptions *arg, Error **errp);
/* nbd_read
* Reads @size bytes from @ioc. Returns 0 on success.
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index de2f2ff713..d8c892f7da 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -132,6 +132,11 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds,
nbd_server = NULL;
}
+void nbd_server_start_options(NbdServerOptions *arg, Error **errp)
+{
+ nbd_server_start(arg->addr, arg->tls_creds, arg->tls_authz, errp);
+}
+
void qmp_nbd_server_start(SocketAddressLegacy *addr,
bool has_tls_creds, const char *tls_creds,
bool has_tls_authz, const char *tls_authz,
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
index 0cd8144c81..276a412915 100644
--- a/qemu-storage-daemon.c
+++ b/qemu-storage-daemon.c
@@ -28,11 +28,14 @@
#include <getopt.h>
#include "block/block.h"
+#include "block/nbd.h"
#include "crypto/init.h"
#include "qapi/error.h"
-#include "qapi/qapi-visit-block-core.h"
+#include "qapi/qapi-commands-block.h"
#include "qapi/qapi-commands-block-core.h"
+#include "qapi/qapi-visit-block.h"
+#include "qapi/qapi-visit-block-core.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qobject-input-visitor.h"
@@ -67,6 +70,12 @@ static void help(void)
" [,driver specific parameters...]\n"
" configure a block backend\n"
"\n"
+" --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>\n"
+" [,tls-creds=<id>][,tls-authz=<id>]\n"
+" --nbd-server addr.type=unix,addr.path=<path>\n"
+" [,tls-creds=<id>][,tls-authz=<id>]\n"
+" start an NBD server for exporting block nodes\n"
+"\n"
" --object help list object types that can be added\n"
" --object <type>,help list properties for the given object type\n"
" --object <type>[,<property>=<value>...]\n"
@@ -82,6 +91,7 @@ QEMU_HELP_BOTTOM "\n",
enum {
OPTION_BLOCKDEV = 256,
+ OPTION_NBD_SERVER,
OPTION_OBJECT,
};
@@ -101,6 +111,7 @@ static void process_options(int argc, char *argv[])
static const struct option long_options[] = {
{"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
{"help", no_argument, NULL, 'h'},
+ {"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
{"object", required_argument, NULL, OPTION_OBJECT},
{"trace", required_argument, NULL, 'T'},
{"version", no_argument, NULL, 'V'},
@@ -145,6 +156,19 @@ static void process_options(int argc, char *argv[])
qapi_free_BlockdevOptions(options);
break;
}
+ case OPTION_NBD_SERVER:
+ {
+ Visitor *v;
+ NbdServerOptions *options;
+
+ v = qobject_input_visitor_new_str(optarg, NULL, &error_fatal);
+ visit_type_NbdServerOptions(v, NULL, &options, &error_fatal);
+ visit_free(v);
+
+ nbd_server_start_options(options, &error_fatal);
+ qapi_free_NbdServerOptions(options);
+ break;
+ }
case OPTION_OBJECT:
{
QemuOpts *opts;
diff --git a/Makefile.objs b/Makefile.objs
index b5d9e1e134..bacbdb55bc 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -32,7 +32,7 @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS
# used for system emulation, too, but specified separately there)
storage-daemon-obj-y = block/ qom/
-storage-daemon-obj-y += blockdev.o iothread.o
+storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o
######################################################################
# Target independent part of system emulation. The long term path is to
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 16/29] blockdev-nbd: Boxed argument type for nbd-server-add
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (14 preceding siblings ...)
2020-03-06 17:14 ` [PULL 15/29] qemu-storage-daemon: Add --nbd-server option Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 17/29] qemu-storage-daemon: Add --export option Kevin Wolf
` (14 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Move the arguments of nbd-server-add to a new struct BlockExportNbd and
convert the command to 'boxed': true. This makes it easier to share code
with the storage daemon.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-11-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/block-core.json | 18 ++++++++++++++----
blockdev-nbd.c | 35 ++++++++++++++++-------------------
monitor/hmp-cmds.c | 21 +++++++++++++++++----
3 files changed, 47 insertions(+), 27 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index f8888f06c8..cdc585385c 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -5112,9 +5112,9 @@
'*tls-authz': 'str'} }
##
-# @nbd-server-add:
+# @BlockExportNbd:
#
-# Export a block node to QEMU's embedded NBD server.
+# An NBD block export.
#
# @device: The device name or node name of the node to be exported
#
@@ -5131,14 +5131,24 @@
# NBD client can use NBD_OPT_SET_META_CONTEXT with
# "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
#
+# Since: 5.0
+##
+{ 'struct': 'BlockExportNbd',
+ 'data': {'device': 'str', '*name': 'str', '*description': 'str',
+ '*writable': 'bool', '*bitmap': 'str' } }
+
+##
+# @nbd-server-add:
+#
+# Export a block node to QEMU's embedded NBD server.
+#
# Returns: error if the server is not running, or export with the same name
# already exists.
#
# Since: 1.3.0
##
{ 'command': 'nbd-server-add',
- 'data': {'device': 'str', '*name': 'str', '*description': 'str',
- '*writable': 'bool', '*bitmap': 'str' } }
+ 'data': 'BlockExportNbd', 'boxed': true }
##
# @NbdServerRemoveMode:
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index d8c892f7da..1a95d89f00 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -148,10 +148,7 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr,
qapi_free_SocketAddress(addr_flat);
}
-void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
- bool has_description, const char *description,
- bool has_writable, bool writable,
- bool has_bitmap, const char *bitmap, Error **errp)
+void qmp_nbd_server_add(BlockExportNbd *arg, Error **errp)
{
BlockDriverState *bs = NULL;
BlockBackend *on_eject_blk;
@@ -164,28 +161,28 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
return;
}
- if (!has_name) {
- name = device;
+ if (!arg->has_name) {
+ arg->name = arg->device;
}
- if (strlen(name) > NBD_MAX_STRING_SIZE) {
- error_setg(errp, "export name '%s' too long", name);
+ if (strlen(arg->name) > NBD_MAX_STRING_SIZE) {
+ error_setg(errp, "export name '%s' too long", arg->name);
return;
}
- if (has_description && strlen(description) > NBD_MAX_STRING_SIZE) {
- error_setg(errp, "description '%s' too long", description);
+ if (arg->description && strlen(arg->description) > NBD_MAX_STRING_SIZE) {
+ error_setg(errp, "description '%s' too long", arg->description);
return;
}
- if (nbd_export_find(name)) {
- error_setg(errp, "NBD server already has export named '%s'", name);
+ if (nbd_export_find(arg->name)) {
+ error_setg(errp, "NBD server already has export named '%s'", arg->name);
return;
}
- on_eject_blk = blk_by_name(device);
+ on_eject_blk = blk_by_name(arg->device);
- bs = bdrv_lookup_bs(device, device, errp);
+ bs = bdrv_lookup_bs(arg->device, arg->device, errp);
if (!bs) {
return;
}
@@ -199,15 +196,15 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
goto out;
}
- if (!has_writable) {
- writable = false;
+ if (!arg->has_writable) {
+ arg->writable = false;
}
if (bdrv_is_read_only(bs)) {
- writable = false;
+ arg->writable = false;
}
- exp = nbd_export_new(bs, 0, len, name, description, bitmap,
- !writable, !writable,
+ exp = nbd_export_new(bs, 0, len, arg->name, arg->description, arg->bitmap,
+ !arg->writable, !arg->writable,
NULL, false, on_eject_blk, errp);
if (!exp) {
goto out;
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 30313858c2..fb4c2fd2a8 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -2341,6 +2341,7 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
Error *local_err = NULL;
BlockInfoList *block_list, *info;
SocketAddress *addr;
+ BlockExportNbd export;
if (writable && !all) {
error_setg(&local_err, "-w only valid together with -a");
@@ -2373,8 +2374,13 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
continue;
}
- qmp_nbd_server_add(info->value->device, false, NULL, false, NULL,
- true, writable, false, NULL, &local_err);
+ export = (BlockExportNbd) {
+ .device = info->value->device,
+ .has_writable = true,
+ .writable = writable,
+ };
+
+ qmp_nbd_server_add(&export, &local_err);
if (local_err != NULL) {
qmp_nbd_server_stop(NULL);
@@ -2395,8 +2401,15 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
bool writable = qdict_get_try_bool(qdict, "writable", false);
Error *local_err = NULL;
- qmp_nbd_server_add(device, !!name, name, false, NULL, true, writable,
- false, NULL, &local_err);
+ BlockExportNbd export = {
+ .device = (char *) device,
+ .has_name = !!name,
+ .name = (char *) name,
+ .has_writable = true,
+ .writable = writable,
+ };
+
+ qmp_nbd_server_add(&export, &local_err);
hmp_handle_error(mon, local_err);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 17/29] qemu-storage-daemon: Add --export option
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (15 preceding siblings ...)
2020-03-06 17:14 ` [PULL 16/29] blockdev-nbd: Boxed argument type for nbd-server-add Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 18/29] qemu-storage-daemon: Add main loop Kevin Wolf
` (13 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Add a --export option to qemu-storage-daemon to export a block node. For
now, only NBD exports are implemented. Apart from the 'type' option
(which is the implied key), it maps the arguments for nbd-server-add to
the command line. Example:
--export nbd,device=disk,name=test-export,writable=on
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-12-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/block-core.json | 27 +++++++++++++++++++++++++++
qemu-storage-daemon.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index cdc585385c..48631218fa 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -5201,6 +5201,33 @@
##
{ 'command': 'nbd-server-stop' }
+##
+# @BlockExportType:
+#
+# An enumeration of block export types
+#
+# @nbd: NBD export
+#
+# Since: 4.2
+##
+{ 'enum': 'BlockExportType',
+ 'data': [ 'nbd' ] }
+
+##
+# @BlockExport:
+#
+# Describes a block export, i.e. how single node should be exported on an
+# external interface.
+#
+# Since: 4.2
+##
+{ 'union': 'BlockExport',
+ 'base': { 'type': 'BlockExportType' },
+ 'discriminator': 'type',
+ 'data': {
+ 'nbd': 'BlockExportNbd'
+ } }
+
##
# @QuorumOpType:
#
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
index 276a412915..5904d3c5b4 100644
--- a/qemu-storage-daemon.c
+++ b/qemu-storage-daemon.c
@@ -70,6 +70,11 @@ static void help(void)
" [,driver specific parameters...]\n"
" configure a block backend\n"
"\n"
+" --export [type=]nbd,device=<node-name>[,name=<export-name>]\n"
+" [,writable=on|off][,bitmap=<name>]\n"
+" export the specified block node over NBD\n"
+" (requires --nbd-server)\n"
+"\n"
" --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>\n"
" [,tls-creds=<id>][,tls-authz=<id>]\n"
" --nbd-server addr.type=unix,addr.path=<path>\n"
@@ -91,6 +96,7 @@ QEMU_HELP_BOTTOM "\n",
enum {
OPTION_BLOCKDEV = 256,
+ OPTION_EXPORT,
OPTION_NBD_SERVER,
OPTION_OBJECT,
};
@@ -104,12 +110,24 @@ static QemuOptsList qemu_object_opts = {
},
};
+static void init_export(BlockExport *export, Error **errp)
+{
+ switch (export->type) {
+ case BLOCK_EXPORT_TYPE_NBD:
+ qmp_nbd_server_add(&export->u.nbd, errp);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
static void process_options(int argc, char *argv[])
{
int c;
static const struct option long_options[] = {
{"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
+ {"export", required_argument, NULL, OPTION_EXPORT},
{"help", no_argument, NULL, 'h'},
{"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
{"object", required_argument, NULL, OPTION_OBJECT},
@@ -156,6 +174,19 @@ static void process_options(int argc, char *argv[])
qapi_free_BlockdevOptions(options);
break;
}
+ case OPTION_EXPORT:
+ {
+ Visitor *v;
+ BlockExport *export;
+
+ v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
+ visit_type_BlockExport(v, NULL, &export, &error_fatal);
+ visit_free(v);
+
+ init_export(export, &error_fatal);
+ qapi_free_BlockExport(export);
+ break;
+ }
case OPTION_NBD_SERVER:
{
Visitor *v;
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 18/29] qemu-storage-daemon: Add main loop
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (16 preceding siblings ...)
2020-03-06 17:14 ` [PULL 17/29] qemu-storage-daemon: Add --export option Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 19/29] qemu-storage-daemon: Add --chardev option Kevin Wolf
` (12 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Instead of exiting after processing all command line options, start a
main loop and keep processing events until exit is requested with a
signal (e.g. SIGINT).
Now qemu-storage-daemon can be used as an alternative for qemu-nbd that
provides a few features that were previously only available from QMP,
such as access to options only available with -blockdev and the socket
types 'vsock' and 'fd'.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-13-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qemu-storage-daemon.c | 13 +++++++++++++
Makefile.objs | 2 ++
2 files changed, 15 insertions(+)
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
index 5904d3c5b4..14093ac3a0 100644
--- a/qemu-storage-daemon.c
+++ b/qemu-storage-daemon.c
@@ -50,8 +50,16 @@
#include "qemu/option.h"
#include "qom/object_interfaces.h"
+#include "sysemu/runstate.h"
#include "trace/control.h"
+static volatile bool exit_requested = false;
+
+void qemu_system_killed(int signal, pid_t pid)
+{
+ exit_requested = true;
+}
+
static void help(void)
{
printf(
@@ -241,6 +249,7 @@ int main(int argc, char *argv[])
error_init(argv[0]);
qemu_init_exec_dir(argv[0]);
+ os_setup_signal_handling();
module_call_init(MODULE_INIT_QOM);
module_call_init(MODULE_INIT_TRACE);
@@ -256,5 +265,9 @@ int main(int argc, char *argv[])
qemu_init_main_loop(&error_fatal);
process_options(argc, argv);
+ while (!exit_requested) {
+ main_loop_wait(false);
+ }
+
return EXIT_SUCCESS;
}
diff --git a/Makefile.objs b/Makefile.objs
index bacbdb55bc..2554e331d5 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -33,6 +33,8 @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS
storage-daemon-obj-y = block/ qom/
storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o
+storage-daemon-obj-$(CONFIG_WIN32) += os-win32.o
+storage-daemon-obj-$(CONFIG_POSIX) += os-posix.o
######################################################################
# Target independent part of system emulation. The long term path is to
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 19/29] qemu-storage-daemon: Add --chardev option
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (17 preceding siblings ...)
2020-03-06 17:14 ` [PULL 18/29] qemu-storage-daemon: Add main loop Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 20/29] stubs: Update monitor stubs for qemu-storage-daemon Kevin Wolf
` (11 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
This adds a --chardev option to the storage daemon that works the same
as the -chardev option of the system emulator.
The syntax of the --chardev option is still considered unstable. We want
to QAPIfy it and will potentially make changes to its syntax while
converting it. However, we haven't decided yet on a design for the
QAPIfication, so QemuOpts will have to do for now.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-14-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qemu-storage-daemon.c | 24 ++++++++++++++++++++++++
Makefile | 2 +-
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
index 14093ac3a0..82fe6cd5f2 100644
--- a/qemu-storage-daemon.c
+++ b/qemu-storage-daemon.c
@@ -29,6 +29,7 @@
#include "block/block.h"
#include "block/nbd.h"
+#include "chardev/char.h"
#include "crypto/init.h"
#include "qapi/error.h"
@@ -78,6 +79,9 @@ static void help(void)
" [,driver specific parameters...]\n"
" configure a block backend\n"
"\n"
+" --chardev <options> configure a character device backend\n"
+" (see the qemu(1) man page for possible options)\n"
+"\n"
" --export [type=]nbd,device=<node-name>[,name=<export-name>]\n"
" [,writable=on|off][,bitmap=<name>]\n"
" export the specified block node over NBD\n"
@@ -104,11 +108,14 @@ QEMU_HELP_BOTTOM "\n",
enum {
OPTION_BLOCKDEV = 256,
+ OPTION_CHARDEV,
OPTION_EXPORT,
OPTION_NBD_SERVER,
OPTION_OBJECT,
};
+extern QemuOptsList qemu_chardev_opts;
+
static QemuOptsList qemu_object_opts = {
.name = "object",
.implied_opt_name = "qom-type",
@@ -135,6 +142,7 @@ static void process_options(int argc, char *argv[])
static const struct option long_options[] = {
{"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
+ {"chardev", required_argument, NULL, OPTION_CHARDEV},
{"export", required_argument, NULL, OPTION_EXPORT},
{"help", no_argument, NULL, 'h'},
{"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
@@ -182,6 +190,22 @@ static void process_options(int argc, char *argv[])
qapi_free_BlockdevOptions(options);
break;
}
+ case OPTION_CHARDEV:
+ {
+ /* TODO This interface is not stable until we QAPIfy it */
+ QemuOpts *opts = qemu_opts_parse_noisily(&qemu_chardev_opts,
+ optarg, true);
+ if (opts == NULL) {
+ exit(EXIT_FAILURE);
+ }
+
+ if (!qemu_chr_new_from_opts(opts, NULL, &error_fatal)) {
+ /* No error, but NULL returned means help was printed */
+ exit(EXIT_SUCCESS);
+ }
+ qemu_opts_del(opts);
+ break;
+ }
case OPTION_EXPORT:
{
Visitor *v;
diff --git a/Makefile b/Makefile
index 7c75440182..05a74c77b2 100644
--- a/Makefile
+++ b/Makefile
@@ -589,7 +589,7 @@ qemu-img.o: qemu-img-cmds.h
qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
-qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
+qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(chardev-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 20/29] stubs: Update monitor stubs for qemu-storage-daemon
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (18 preceding siblings ...)
2020-03-06 17:14 ` [PULL 19/29] qemu-storage-daemon: Add --chardev option Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 21/29] qapi: Create 'pragma' module Kevin Wolf
` (10 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Before we can add the monitor to qemu-storage-daemon, we need to add a
stubs for monitor_fdsets_cleanup().
We also need to make sure that stubs that are actually implemented in
the monitor core aren't linked to qemu-storage-daemon so that we don't
get linker errors because of duplicate symbols. This is achieved by
moving the stubs in question to a new file stubs/monitor-core.c.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-15-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
stubs/monitor-core.c | 21 +++++++++++++++++++++
stubs/monitor.c | 15 ++-------------
stubs/Makefile.objs | 1 +
3 files changed, 24 insertions(+), 13 deletions(-)
create mode 100644 stubs/monitor-core.c
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
new file mode 100644
index 0000000000..403c00a6d0
--- /dev/null
+++ b/stubs/monitor-core.c
@@ -0,0 +1,21 @@
+#include "qemu/osdep.h"
+#include "monitor/monitor.h"
+#include "qemu-common.h"
+#include "qapi/qapi-emit-events.h"
+
+__thread Monitor *cur_mon;
+
+void monitor_init_qmp(Chardev *chr, bool pretty)
+{
+}
+
+void qapi_event_emit(QAPIEvent event, QDict *qdict)
+{
+}
+
+int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+{
+ abort();
+}
+
+
diff --git a/stubs/monitor.c b/stubs/monitor.c
index c3e9a2e4dc..9403f8e72c 100644
--- a/stubs/monitor.c
+++ b/stubs/monitor.c
@@ -1,14 +1,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "qapi/qapi-emit-events.h"
#include "monitor/monitor.h"
-
-__thread Monitor *cur_mon;
-
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
-{
- abort();
-}
+#include "../monitor/monitor-internal.h"
int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
{
@@ -16,14 +9,10 @@ int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
return -1;
}
-void monitor_init_qmp(Chardev *chr, bool pretty)
-{
-}
-
void monitor_init_hmp(Chardev *chr, bool use_readline)
{
}
-void qapi_event_emit(QAPIEvent event, QDict *qdict)
+void monitor_fdsets_cleanup(void)
{
}
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 24062ce7d9..45be5dc0ed 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -19,6 +19,7 @@ stub-obj-y += machine-init-done.o
stub-obj-y += migr-blocker.o
stub-obj-y += change-state-handler.o
stub-obj-y += monitor.o
+stub-obj-y += monitor-core.o
stub-obj-y += notify-event.o
stub-obj-y += qtest.o
stub-obj-y += replay.o
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 21/29] qapi: Create 'pragma' module
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (19 preceding siblings ...)
2020-03-06 17:14 ` [PULL 20/29] stubs: Update monitor stubs for qemu-storage-daemon Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 22/29] monitor: Create QAPIfied monitor_init() Kevin Wolf
` (9 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
We want to share the whitelists between the system emulator schema and
the storage daemon schema, so move all the pragmas from the main schema
file into a separate file that can be included from both.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-16-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/pragma.json | 24 ++++++++++++++++++++++++
qapi/qapi-schema.json | 25 +------------------------
qapi/Makefile.objs | 2 +-
3 files changed, 26 insertions(+), 25 deletions(-)
create mode 100644 qapi/pragma.json
diff --git a/qapi/pragma.json b/qapi/pragma.json
new file mode 100644
index 0000000000..cffae27666
--- /dev/null
+++ b/qapi/pragma.json
@@ -0,0 +1,24 @@
+{ 'pragma': { 'doc-required': true } }
+
+# Whitelists to permit QAPI rule violations; think twice before you
+# add to them!
+{ 'pragma': {
+ # Commands allowed to return a non-dictionary:
+ 'returns-whitelist': [
+ 'human-monitor-command',
+ 'qom-get',
+ 'query-migrate-cache-size',
+ 'query-tpm-models',
+ 'query-tpm-types',
+ 'ringbuf-read' ],
+ 'name-case-whitelist': [
+ 'ACPISlotType', # DIMM, visible through query-acpi-ospm-status
+ 'CpuInfoMIPS', # PC, visible through query-cpu
+ 'CpuInfoTricore', # PC, visible through query-cpu
+ 'BlockdevVmdkSubformat', # all members, to match VMDK spec spellings
+ 'BlockdevVmdkAdapterType', # legacyESX, to match VMDK spec spellings
+ 'QapiErrorClass', # all members, visible through errors
+ 'UuidInfo', # UUID, visible through query-uuid
+ 'X86CPURegister32', # all members, visible indirectly through qom-get
+ 'CpuInfo' # CPU, visible through query-cpu
+ ] } }
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index fe980ce437..43b0ba0dea 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -49,30 +49,7 @@
#
##
-{ 'pragma': { 'doc-required': true } }
-
-# Whitelists to permit QAPI rule violations; think twice before you
-# add to them!
-{ 'pragma': {
- # Commands allowed to return a non-dictionary:
- 'returns-whitelist': [
- 'human-monitor-command',
- 'qom-get',
- 'query-migrate-cache-size',
- 'query-tpm-models',
- 'query-tpm-types',
- 'ringbuf-read' ],
- 'name-case-whitelist': [
- 'ACPISlotType', # DIMM, visible through query-acpi-ospm-status
- 'CpuInfoMIPS', # PC, visible through query-cpu
- 'CpuInfoTricore', # PC, visible through query-cpu
- 'BlockdevVmdkSubformat', # all members, to match VMDK spec spellings
- 'BlockdevVmdkAdapterType', # legacyESX, to match VMDK spec spellings
- 'QapiErrorClass', # all members, visible through errors
- 'UuidInfo', # UUID, visible through query-uuid
- 'X86CPURegister32', # all members, visible indirectly through qom-get
- 'CpuInfo' # CPU, visible through query-cpu
- ] } }
+{ 'include': 'pragma.json' }
# Documentation generated with qapi-gen.py is in source order, with
# included sub-schemas inserted at the first include directive
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index 20fcc37c2c..cf33fd9cc0 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -7,7 +7,7 @@ util-obj-y += qapi-util.o
QAPI_COMMON_MODULES = audio authz block-core block char common control crypto
QAPI_COMMON_MODULES += dump error introspect job machine migration misc
-QAPI_COMMON_MODULES += net qdev qom rdma rocker run-state sockets tpm
+QAPI_COMMON_MODULES += net pragma qdev qom rdma rocker run-state sockets tpm
QAPI_COMMON_MODULES += trace transaction ui
QAPI_TARGET_MODULES = machine-target misc-target
QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES)
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 22/29] monitor: Create QAPIfied monitor_init()
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (20 preceding siblings ...)
2020-03-06 17:14 ` [PULL 21/29] qapi: Create 'pragma' module Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 23/29] qmp: Fail gracefully if chardev is already in use Kevin Wolf
` (8 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
This adds a new QAPI-based monitor_init() function. The existing
monitor_init_opts() is rewritten to simply put its QemuOpts parameter
into a visitor and pass the resulting QAPI object to monitor_init().
This will cause some change in those error messages for the monitor
options in the system emulator that are now generated by the visitor
rather than explicitly checked in monitor_init_opts().
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-17-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/control.json | 36 ++++++++++++++++++
include/monitor/monitor.h | 2 +
monitor/monitor.c | 77 +++++++++++++++++++++------------------
3 files changed, 80 insertions(+), 35 deletions(-)
diff --git a/qapi/control.json b/qapi/control.json
index 759c20e76f..3ee086aec7 100644
--- a/qapi/control.json
+++ b/qapi/control.json
@@ -216,3 +216,39 @@
# <- { "return": {} }
##
{ 'command': 'quit' }
+
+##
+# @MonitorMode:
+#
+# An enumeration of monitor modes.
+#
+# @readline: HMP monitor (human-oriented command line interface)
+#
+# @control: QMP monitor (JSON-based machine interface)
+#
+# Since: 5.0
+##
+{ 'enum': 'MonitorMode', 'data': [ 'readline', 'control' ] }
+
+##
+# @MonitorOptions:
+#
+# Options to be used for adding a new monitor.
+#
+# @id: Name of the monitor
+#
+# @mode: Selects the monitor mode (default: readline)
+#
+# @pretty: Enables pretty printing (QMP only)
+#
+# @chardev: Name of a character device to expose the monitor on
+#
+# Since: 5.0
+##
+{ 'struct': 'MonitorOptions',
+ 'data': {
+ '*id': 'str',
+ '*mode': 'MonitorMode',
+ '*pretty': 'bool',
+ 'chardev': 'str'
+ } }
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index b7bdd2bb2a..db1112552c 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -7,6 +7,7 @@
extern __thread Monitor *cur_mon;
typedef struct MonitorHMP MonitorHMP;
+typedef struct MonitorOptions MonitorOptions;
#define QMP_REQ_QUEUE_LEN_MAX 8
@@ -18,6 +19,7 @@ void monitor_init_globals(void);
void monitor_init_globals_core(void);
void monitor_init_qmp(Chardev *chr, bool pretty);
void monitor_init_hmp(Chardev *chr, bool use_readline);
+int monitor_init(MonitorOptions *opts, Error **errp);
int monitor_init_opts(QemuOpts *opts, Error **errp);
void monitor_cleanup(void);
diff --git a/monitor/monitor.c b/monitor/monitor.c
index c1a6c4460f..f8a6ef795b 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -25,7 +25,9 @@
#include "qemu/osdep.h"
#include "monitor-internal.h"
#include "qapi/error.h"
+#include "qapi/opts-visitor.h"
#include "qapi/qapi-emit-events.h"
+#include "qapi/qapi-visit-control.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "qemu/error-report.h"
@@ -609,50 +611,55 @@ void monitor_init_globals_core(void)
NULL);
}
-int monitor_init_opts(QemuOpts *opts, Error **errp)
+int monitor_init(MonitorOptions *opts, Error **errp)
{
Chardev *chr;
- bool qmp;
- bool pretty = false;
- const char *chardev;
- const char *mode;
-
- mode = qemu_opt_get(opts, "mode");
- if (mode == NULL) {
- mode = "readline";
- }
- if (strcmp(mode, "readline") == 0) {
- qmp = false;
- } else if (strcmp(mode, "control") == 0) {
- qmp = true;
- } else {
- error_setg(errp, "unknown monitor mode \"%s\"", mode);
+
+ chr = qemu_chr_find(opts->chardev);
+ if (chr == NULL) {
+ error_setg(errp, "chardev \"%s\" not found", opts->chardev);
return -1;
}
- if (!qmp && qemu_opt_get(opts, "pretty")) {
- warn_report("'pretty' is deprecated for HMP monitors, it has no effect "
- "and will be removed in future versions");
- }
- if (qemu_opt_get_bool(opts, "pretty", 0)) {
- pretty = true;
+ switch (opts->mode) {
+ case MONITOR_MODE_CONTROL:
+ monitor_init_qmp(chr, opts->pretty);
+ break;
+ case MONITOR_MODE_READLINE:
+ if (opts->pretty) {
+ warn_report("'pretty' is deprecated for HMP monitors, it has no "
+ "effect and will be removed in future versions");
+ }
+ monitor_init_hmp(chr, true);
+ break;
+ default:
+ g_assert_not_reached();
}
- chardev = qemu_opt_get(opts, "chardev");
- if (!chardev) {
- error_report("chardev is required");
- exit(1);
- }
- chr = qemu_chr_find(chardev);
- if (chr == NULL) {
- error_setg(errp, "chardev \"%s\" not found", chardev);
- return -1;
+ return 0;
+}
+
+int monitor_init_opts(QemuOpts *opts, Error **errp)
+{
+ Visitor *v;
+ MonitorOptions *options;
+ Error *local_err = NULL;
+
+ v = opts_visitor_new(opts);
+ visit_type_MonitorOptions(v, NULL, &options, &local_err);
+ visit_free(v);
+
+ if (local_err) {
+ goto out;
}
- if (qmp) {
- monitor_init_qmp(chr, pretty);
- } else {
- monitor_init_hmp(chr, true);
+ monitor_init(options, &local_err);
+ qapi_free_MonitorOptions(options);
+
+out:
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return -1;
}
return 0;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 23/29] qmp: Fail gracefully if chardev is already in use
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (21 preceding siblings ...)
2020-03-06 17:14 ` [PULL 22/29] monitor: Create QAPIfied monitor_init() Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 24/29] hmp: " Kevin Wolf
` (7 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Trying to attach a QMP monitor to a chardev that is already in use
results in a crash because monitor_init_qmp() passes &error_abort to
qemu_chr_fe_init():
$ ./x86_64-softmmu/qemu-system-x86_64 --chardev stdio,id=foo --mon foo,mode=control --mon foo,mode=control
Unexpected error in qemu_chr_fe_init() at chardev/char-fe.c:220:
qemu-system-x86_64: --mon foo,mode=control: Device 'foo' is in use
Abgebrochen (Speicherabzug geschrieben)
Fix this by allowing monitor_init_qmp() to return an error and passing
any error in qemu_chr_fe_init() to its caller instead of aborting.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-18-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
include/monitor/monitor.h | 2 +-
monitor/monitor.c | 7 ++++++-
monitor/qmp.c | 11 +++++++----
stubs/monitor-core.c | 2 +-
tests/test-util-sockets.c | 2 +-
5 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index db1112552c..e55a3b57e0 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -17,7 +17,7 @@ bool monitor_cur_is_qmp(void);
void monitor_init_globals(void);
void monitor_init_globals_core(void);
-void monitor_init_qmp(Chardev *chr, bool pretty);
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp);
void monitor_init_hmp(Chardev *chr, bool use_readline);
int monitor_init(MonitorOptions *opts, Error **errp);
int monitor_init_opts(QemuOpts *opts, Error **errp);
diff --git a/monitor/monitor.c b/monitor/monitor.c
index f8a6ef795b..00d287655e 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -614,6 +614,7 @@ void monitor_init_globals_core(void)
int monitor_init(MonitorOptions *opts, Error **errp)
{
Chardev *chr;
+ Error *local_err = NULL;
chr = qemu_chr_find(opts->chardev);
if (chr == NULL) {
@@ -623,7 +624,7 @@ int monitor_init(MonitorOptions *opts, Error **errp)
switch (opts->mode) {
case MONITOR_MODE_CONTROL:
- monitor_init_qmp(chr, opts->pretty);
+ monitor_init_qmp(chr, opts->pretty, &local_err);
break;
case MONITOR_MODE_READLINE:
if (opts->pretty) {
@@ -636,6 +637,10 @@ int monitor_init(MonitorOptions *opts, Error **errp)
g_assert_not_reached();
}
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return -1;
+ }
return 0;
}
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 8379c8f96e..f89e7daf27 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -395,10 +395,16 @@ static void monitor_qmp_setup_handlers_bh(void *opaque)
monitor_list_append(&mon->common);
}
-void monitor_init_qmp(Chardev *chr, bool pretty)
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
{
MonitorQMP *mon = g_new0(MonitorQMP, 1);
+ if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
+ g_free(mon);
+ return;
+ }
+ qemu_chr_fe_set_echo(&mon->common.chr, true);
+
/* Note: we run QMP monitor in I/O thread when @chr supports that */
monitor_data_init(&mon->common, true, false,
qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT));
@@ -408,9 +414,6 @@ void monitor_init_qmp(Chardev *chr, bool pretty)
qemu_mutex_init(&mon->qmp_queue_lock);
mon->qmp_requests = g_queue_new();
- qemu_chr_fe_init(&mon->common.chr, chr, &error_abort);
- qemu_chr_fe_set_echo(&mon->common.chr, true);
-
json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL);
if (mon->common.use_io_thread) {
/*
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
index 403c00a6d0..6cff1c4e1d 100644
--- a/stubs/monitor-core.c
+++ b/stubs/monitor-core.c
@@ -5,7 +5,7 @@
__thread Monitor *cur_mon;
-void monitor_init_qmp(Chardev *chr, bool pretty)
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
{
}
diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c
index 8ce55efe70..2edb4c539d 100644
--- a/tests/test-util-sockets.c
+++ b/tests/test-util-sockets.c
@@ -71,7 +71,7 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
*/
__thread Monitor *cur_mon;
int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
-void monitor_init_qmp(Chardev *chr, bool pretty) {}
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) {}
void monitor_init_hmp(Chardev *chr, bool use_readline) {}
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 24/29] hmp: Fail gracefully if chardev is already in use
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (22 preceding siblings ...)
2020-03-06 17:14 ` [PULL 23/29] qmp: Fail gracefully if chardev is already in use Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 25/29] monitor: Add allow_hmp parameter to monitor_init() Kevin Wolf
` (6 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Trying to attach a HMP monitor to a chardev that is already in use
results in a crash because monitor_init_hmp() passes &error_abort to
qemu_chr_fe_init():
$ ./x86_64-softmmu/qemu-system-x86_64 --chardev stdio,id=foo --mon foo --mon foo
QEMU 4.2.50 monitor - type 'help' for more information
(qemu) Unexpected error in qemu_chr_fe_init() at chardev/char-fe.c:220:
qemu-system-x86_64: --mon foo: Device 'foo' is in use
Abgebrochen (Speicherabzug geschrieben)
Fix this by allowing monitor_init_hmp() to return an error and passing
any error in qemu_chr_fe_init() to its caller instead of aborting.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-19-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
include/monitor/monitor.h | 2 +-
chardev/char.c | 8 +++++++-
gdbstub.c | 2 +-
monitor/hmp.c | 8 ++++++--
monitor/monitor.c | 2 +-
stubs/monitor.c | 2 +-
tests/test-util-sockets.c | 2 +-
7 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index e55a3b57e0..ad823b9edb 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -18,7 +18,7 @@ bool monitor_cur_is_qmp(void);
void monitor_init_globals(void);
void monitor_init_globals_core(void);
void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp);
-void monitor_init_hmp(Chardev *chr, bool use_readline);
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp);
int monitor_init(MonitorOptions *opts, Error **errp);
int monitor_init_opts(QemuOpts *opts, Error **errp);
void monitor_cleanup(void);
diff --git a/chardev/char.c b/chardev/char.c
index 87237568df..e77564060d 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -737,7 +737,13 @@ Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
if (qemu_opt_get_bool(opts, "mux", 0)) {
assert(permit_mux_mon);
- monitor_init_hmp(chr, true);
+ monitor_init_hmp(chr, true, &err);
+ if (err) {
+ error_report_err(err);
+ object_unparent(OBJECT(chr));
+ chr = NULL;
+ goto out;
+ }
}
out:
diff --git a/gdbstub.c b/gdbstub.c
index ce304ff482..22a2d630cd 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -3367,7 +3367,7 @@ int gdbserver_start(const char *device)
/* Initialize a monitor terminal for gdb */
mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
NULL, NULL, &error_abort);
- monitor_init_hmp(mon_chr, false);
+ monitor_init_hmp(mon_chr, false, &error_abort);
} else {
qemu_chr_fe_deinit(&s->chr, true);
mon_chr = s->mon_chr;
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 944fa9651e..d598dd02bb 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1399,12 +1399,16 @@ static void monitor_readline_flush(void *opaque)
monitor_flush(&mon->common);
}
-void monitor_init_hmp(Chardev *chr, bool use_readline)
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp)
{
MonitorHMP *mon = g_new0(MonitorHMP, 1);
+ if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
+ g_free(mon);
+ return;
+ }
+
monitor_data_init(&mon->common, false, false, false);
- qemu_chr_fe_init(&mon->common.chr, chr, &error_abort);
mon->use_readline = use_readline;
if (mon->use_readline) {
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 00d287655e..2282bf6780 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -631,7 +631,7 @@ int monitor_init(MonitorOptions *opts, Error **errp)
warn_report("'pretty' is deprecated for HMP monitors, it has no "
"effect and will be removed in future versions");
}
- monitor_init_hmp(chr, true);
+ monitor_init_hmp(chr, true, &local_err);
break;
default:
g_assert_not_reached();
diff --git a/stubs/monitor.c b/stubs/monitor.c
index 9403f8e72c..20786ac4ff 100644
--- a/stubs/monitor.c
+++ b/stubs/monitor.c
@@ -9,7 +9,7 @@ int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
return -1;
}
-void monitor_init_hmp(Chardev *chr, bool use_readline)
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp)
{
}
diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c
index 2edb4c539d..5fd947c7bf 100644
--- a/tests/test-util-sockets.c
+++ b/tests/test-util-sockets.c
@@ -72,7 +72,7 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
__thread Monitor *cur_mon;
int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) {}
-void monitor_init_hmp(Chardev *chr, bool use_readline) {}
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp) {}
static void test_socket_fd_pass_name_good(void)
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 25/29] monitor: Add allow_hmp parameter to monitor_init()
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (23 preceding siblings ...)
2020-03-06 17:14 ` [PULL 24/29] hmp: " Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 26/29] qemu-storage-daemon: Add --monitor option Kevin Wolf
` (5 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
Add a new parameter allow_hmp to monitor_init() so that the storage
daemon can disable HMP.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-20-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/control.json | 3 ++-
include/monitor/monitor.h | 2 +-
monitor/monitor.c | 12 ++++++++++--
3 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/qapi/control.json b/qapi/control.json
index 3ee086aec7..85b12fe0fb 100644
--- a/qapi/control.json
+++ b/qapi/control.json
@@ -237,7 +237,8 @@
#
# @id: Name of the monitor
#
-# @mode: Selects the monitor mode (default: readline)
+# @mode: Selects the monitor mode (default: readline in the system
+# emulator, control in qemu-storage-daemon)
#
# @pretty: Enables pretty printing (QMP only)
#
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index ad823b9edb..1018d754a6 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -19,7 +19,7 @@ void monitor_init_globals(void);
void monitor_init_globals_core(void);
void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp);
void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp);
-int monitor_init(MonitorOptions *opts, Error **errp);
+int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp);
int monitor_init_opts(QemuOpts *opts, Error **errp);
void monitor_cleanup(void);
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 2282bf6780..125494410a 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -611,7 +611,7 @@ void monitor_init_globals_core(void)
NULL);
}
-int monitor_init(MonitorOptions *opts, Error **errp)
+int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp)
{
Chardev *chr;
Error *local_err = NULL;
@@ -622,11 +622,19 @@ int monitor_init(MonitorOptions *opts, Error **errp)
return -1;
}
+ if (!opts->has_mode) {
+ opts->mode = allow_hmp ? MONITOR_MODE_READLINE : MONITOR_MODE_CONTROL;
+ }
+
switch (opts->mode) {
case MONITOR_MODE_CONTROL:
monitor_init_qmp(chr, opts->pretty, &local_err);
break;
case MONITOR_MODE_READLINE:
+ if (!allow_hmp) {
+ error_setg(errp, "Only QMP is supported");
+ return -1;
+ }
if (opts->pretty) {
warn_report("'pretty' is deprecated for HMP monitors, it has no "
"effect and will be removed in future versions");
@@ -658,7 +666,7 @@ int monitor_init_opts(QemuOpts *opts, Error **errp)
goto out;
}
- monitor_init(options, &local_err);
+ monitor_init(options, true, &local_err);
qapi_free_MonitorOptions(options);
out:
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 26/29] qemu-storage-daemon: Add --monitor option
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (24 preceding siblings ...)
2020-03-06 17:14 ` [PULL 25/29] monitor: Add allow_hmp parameter to monitor_init() Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 27/29] block/rbd: Add support for ceph namespaces Kevin Wolf
` (4 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
This adds and parses the --monitor option, so that a QMP monitor can be
used in the storage daemon. The monitor offers commands defined in the
QAPI schema at storage-daemon/qapi/qapi-schema.json.
The --monitor options currently allows to create multiple monitors with
the same ID. This part of the interface is considered unstable. We will
reject such configurations as soon as we have a design for the monitor
subsystem to perform these checks. (In the system emulator, we depend on
QemuOpts rejecting duplicate IDs.)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-21-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/transaction.json | 2 +-
qemu-storage-daemon.c | 47 ++++++++++++++++++++++++++--
scripts/qapi/gen.py | 5 +++
Makefile | 33 +++++++++++++++++++
Makefile.objs | 4 +--
monitor/Makefile.objs | 2 ++
qapi/Makefile.objs | 5 +++
storage-daemon/Makefile.objs | 1 +
storage-daemon/qapi/Makefile.objs | 1 +
storage-daemon/qapi/qapi-schema.json | 26 +++++++++++++++
10 files changed, 121 insertions(+), 5 deletions(-)
create mode 100644 storage-daemon/Makefile.objs
create mode 100644 storage-daemon/qapi/Makefile.objs
create mode 100644 storage-daemon/qapi/qapi-schema.json
diff --git a/qapi/transaction.json b/qapi/transaction.json
index 04301f1be7..b6c11158f0 100644
--- a/qapi/transaction.json
+++ b/qapi/transaction.json
@@ -5,7 +5,7 @@
# = Transactions
##
-{ 'include': 'block.json' }
+{ 'include': 'block-core.json' }
##
# @Abort:
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
index 82fe6cd5f2..dd128978cc 100644
--- a/qemu-storage-daemon.c
+++ b/qemu-storage-daemon.c
@@ -31,13 +31,15 @@
#include "block/nbd.h"
#include "chardev/char.h"
#include "crypto/init.h"
+#include "monitor/monitor.h"
+#include "monitor/monitor-internal.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-block.h"
-#include "qapi/qapi-commands-block-core.h"
#include "qapi/qapi-visit-block.h"
#include "qapi/qapi-visit-block-core.h"
+#include "qapi/qapi-visit-control.h"
#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qstring.h"
#include "qapi/qobject-input-visitor.h"
#include "qemu-common.h"
@@ -51,6 +53,9 @@
#include "qemu/option.h"
#include "qom/object_interfaces.h"
+#include "storage-daemon/qapi/qapi-commands.h"
+#include "storage-daemon/qapi/qapi-init-commands.h"
+
#include "sysemu/runstate.h"
#include "trace/control.h"
@@ -61,6 +66,11 @@ void qemu_system_killed(int signal, pid_t pid)
exit_requested = true;
}
+void qmp_quit(Error **errp)
+{
+ exit_requested = true;
+}
+
static void help(void)
{
printf(
@@ -87,6 +97,9 @@ static void help(void)
" export the specified block node over NBD\n"
" (requires --nbd-server)\n"
"\n"
+" --monitor [chardev=]name[,mode=control][,pretty[=on|off]]\n"
+" configure a QMP monitor\n"
+"\n"
" --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>\n"
" [,tls-creds=<id>][,tls-authz=<id>]\n"
" --nbd-server addr.type=unix,addr.path=<path>\n"
@@ -110,6 +123,7 @@ enum {
OPTION_BLOCKDEV = 256,
OPTION_CHARDEV,
OPTION_EXPORT,
+ OPTION_MONITOR,
OPTION_NBD_SERVER,
OPTION_OBJECT,
};
@@ -125,6 +139,17 @@ static QemuOptsList qemu_object_opts = {
},
};
+static void init_qmp_commands(void)
+{
+ qmp_init_marshal(&qmp_commands);
+ qmp_register_command(&qmp_commands, "query-qmp-schema",
+ qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
+
+ QTAILQ_INIT(&qmp_cap_negotiation_commands);
+ qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
+ qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG);
+}
+
static void init_export(BlockExport *export, Error **errp)
{
switch (export->type) {
@@ -145,6 +170,7 @@ static void process_options(int argc, char *argv[])
{"chardev", required_argument, NULL, OPTION_CHARDEV},
{"export", required_argument, NULL, OPTION_EXPORT},
{"help", no_argument, NULL, 'h'},
+ {"monitor", required_argument, NULL, OPTION_MONITOR},
{"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
{"object", required_argument, NULL, OPTION_OBJECT},
{"trace", required_argument, NULL, 'T'},
@@ -219,6 +245,21 @@ static void process_options(int argc, char *argv[])
qapi_free_BlockExport(export);
break;
}
+ case OPTION_MONITOR:
+ {
+ Visitor *v;
+ MonitorOptions *monitor;
+
+ v = qobject_input_visitor_new_str(optarg, "chardev",
+ &error_fatal);
+ visit_type_MonitorOptions(v, NULL, &monitor, &error_fatal);
+ visit_free(v);
+
+ /* TODO Catch duplicate monitor IDs */
+ monitor_init(monitor, false, &error_fatal);
+ qapi_free_MonitorOptions(monitor);
+ break;
+ }
case OPTION_NBD_SERVER:
{
Visitor *v;
@@ -280,6 +321,8 @@ int main(int argc, char *argv[])
qemu_add_opts(&qemu_trace_opts);
qcrypto_init(&error_fatal);
bdrv_init();
+ monitor_init_globals_core();
+ init_qmp_commands();
if (!trace_init_backends()) {
return EXIT_FAILURE;
diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index 33690bfa3b..bf5552a4e7 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -44,6 +44,11 @@ class QAPIGen:
return ''
def write(self, output_dir):
+ # Include paths starting with ../ are used to reuse modules of the main
+ # schema in specialised schemas. Don't overwrite the files that are
+ # already generated for the main schema.
+ if self.fname.startswith('../'):
+ return
pathname = os.path.join(output_dir, self.fname)
odir = os.path.dirname(pathname)
if odir:
diff --git a/Makefile b/Makefile
index 05a74c77b2..2e93068894 100644
--- a/Makefile
+++ b/Makefile
@@ -128,7 +128,28 @@ GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-events-%.c)
GENERATED_QAPI_FILES += qapi/qapi-introspect.c qapi/qapi-introspect.h
GENERATED_QAPI_FILES += qapi/qapi-doc.texi
+# The following list considers only the storage daemon main module. All other
+# modules are currently shared with the main schema, so we don't actually
+# generate additional files.
+
+GENERATED_STORAGE_DAEMON_QAPI_FILES = storage-daemon/qapi/qapi-commands.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-commands.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-emit-events.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-emit-events.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-events.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-events.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-init-commands.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-init-commands.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-introspect.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-introspect.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-types.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-types.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-visit.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-visit.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-doc.texi
+
generated-files-y += $(GENERATED_QAPI_FILES)
+generated-files-y += $(GENERATED_STORAGE_DAEMON_QAPI_FILES)
generated-files-y += trace/generated-tcg-tracers.h
@@ -651,6 +672,17 @@ qapi-gen-timestamp: $(qapi-modules) $(qapi-py)
"GEN","$(@:%-timestamp=%)")
@>$@
+qapi-modules-storage-daemon = \
+ $(SRC_PATH)/storage-daemon/qapi/qapi-schema.json \
+ $(QAPI_MODULES_STORAGE_DAEMON:%=$(SRC_PATH)/qapi/%.json)
+
+$(GENERATED_STORAGE_DAEMON_QAPI_FILES): storage-daemon/qapi/qapi-gen-timestamp ;
+storage-daemon/qapi/qapi-gen-timestamp: $(qapi-modules-storage-daemon) $(qapi-py)
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
+ -o "storage-daemon/qapi" $<, \
+ "GEN","$(@:%-timestamp=%)")
+ @>$@
+
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qapi-commands.h qga-qapi-init-commands.h)
$(qga-obj-y): $(QGALIB_GEN)
@@ -749,6 +781,7 @@ clean: recurse-clean
rm -f trace/generated-tracers-dtrace.h*
rm -f $(foreach f,$(generated-files-y),$(f) $(f)-timestamp)
rm -f qapi-gen-timestamp
+ rm -f storage-daemon/qapi/qapi-gen-timestamp
rm -rf qga/qapi-generated
rm -f config-all-devices.mak
diff --git a/Makefile.objs b/Makefile.objs
index 2554e331d5..e288663d89 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -31,8 +31,8 @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS
# storage-daemon-obj-y is code used by qemu-storage-daemon (these objects are
# used for system emulation, too, but specified separately there)
-storage-daemon-obj-y = block/ qom/
-storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o
+storage-daemon-obj-y = block/ monitor/ qapi/ qom/ storage-daemon/
+storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o job-qmp.o
storage-daemon-obj-$(CONFIG_WIN32) += os-win32.o
storage-daemon-obj-$(CONFIG_POSIX) += os-posix.o
diff --git a/monitor/Makefile.objs b/monitor/Makefile.objs
index 9244d90859..a8533c9dd7 100644
--- a/monitor/Makefile.objs
+++ b/monitor/Makefile.objs
@@ -2,3 +2,5 @@ obj-y += misc.o
common-obj-y += monitor.o qmp.o hmp.o
common-obj-y += qmp-cmds.o qmp-cmds-control.o
common-obj-y += hmp-cmds.o
+
+storage-daemon-obj-y += monitor.o qmp.o qmp-cmds-control.o
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index cf33fd9cc0..4673ab7490 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -31,3 +31,8 @@ obj-y += qapi-events.o
obj-y += $(QAPI_TARGET_MODULES:%=qapi-commands-%.o)
obj-y += qapi-commands.o
obj-y += qapi-init-commands.o
+
+QAPI_MODULES_STORAGE_DAEMON = block-core char common control crypto
+QAPI_MODULES_STORAGE_DAEMON += introspect job qom sockets pragma transaction
+
+storage-daemon-obj-y += $(QAPI_MODULES_STORAGE_DAEMON:%=qapi-commands-%.o)
diff --git a/storage-daemon/Makefile.objs b/storage-daemon/Makefile.objs
new file mode 100644
index 0000000000..cfe6beee52
--- /dev/null
+++ b/storage-daemon/Makefile.objs
@@ -0,0 +1 @@
+storage-daemon-obj-y += qapi/
diff --git a/storage-daemon/qapi/Makefile.objs b/storage-daemon/qapi/Makefile.objs
new file mode 100644
index 0000000000..8a4b220c96
--- /dev/null
+++ b/storage-daemon/qapi/Makefile.objs
@@ -0,0 +1 @@
+storage-daemon-obj-y += qapi-commands.o qapi-init-commands.o qapi-introspect.o
diff --git a/storage-daemon/qapi/qapi-schema.json b/storage-daemon/qapi/qapi-schema.json
new file mode 100644
index 0000000000..14f4f8fe61
--- /dev/null
+++ b/storage-daemon/qapi/qapi-schema.json
@@ -0,0 +1,26 @@
+# -*- Mode: Python -*-
+
+# Note that modules are shared with the QEMU main schema under the assumption
+# that the storage daemon schema is a subset of the main schema. For the shared
+# modules, no code is generated here, but we reuse the code files generated
+# from the main schema.
+#
+# If you wish to extend the storage daemon schema to contain things that are
+# not in the main schema, be aware that array types of types defined in shared
+# modules are only generated if an array of the respective type is already used
+# in the main schema. Therefore, if you use such arrays, you may need to define
+# the array type in the main schema, even if it is unused outside of the
+# storage daemon.
+
+{ 'include': '../../qapi/pragma.json' }
+
+{ 'include': '../../qapi/block-core.json' }
+{ 'include': '../../qapi/char.json' }
+{ 'include': '../../qapi/common.json' }
+{ 'include': '../../qapi/control.json' }
+{ 'include': '../../qapi/crypto.json' }
+{ 'include': '../../qapi/introspect.json' }
+{ 'include': '../../qapi/job.json' }
+{ 'include': '../../qapi/qom.json' }
+{ 'include': '../../qapi/sockets.json' }
+{ 'include': '../../qapi/transaction.json' }
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 27/29] block/rbd: Add support for ceph namespaces
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (25 preceding siblings ...)
2020-03-06 17:14 ` [PULL 26/29] qemu-storage-daemon: Add --monitor option Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 28/29] iotests: Refactor blockdev-reopen test for iothreads Kevin Wolf
` (3 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
From: Florian Florensa <fflorensa@online.net>
Starting from ceph Nautilus, RBD has support for namespaces, allowing
for finer grain ACLs on images inside a pool, and tenant isolation.
In the rbd cli tool documentation, the new image-spec and snap-spec are :
- [pool-name/[namespace-name/]]image-name
- [pool-name/[namespace-name/]]image-name@snap-name
When using an non namespace's enabled qemu, it complains about not
finding the image called namespace-name/image-name, thus we only need to
parse the image once again to find if there is a '/' in its name, and if
there is, use what is before it as the name of the namespace to later
pass it to rados_ioctx_set_namespace.
rados_ioctx_set_namespace if called with en empty string or a null
pointer as the namespace parameters pretty much does nothing, as it then
defaults to the default namespace.
The namespace is extracted inside qemu_rbd_parse_filename, stored in the
qdict, and used in qemu_rbd_connect to make it work with both qemu-img,
and qemu itself.
Signed-off-by: Florian Florensa <fflorensa@online.net>
Message-Id: <20200110111513.321728-2-fflorensa@online.net>
Reviewed-by: Jason Dillaman <dillaman@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/block-core.json | 3 +++
block/rbd.c | 44 +++++++++++++++++++++++++++++++-------------
2 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 48631218fa..9758fc48d2 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3544,6 +3544,8 @@
#
# @pool: Ceph pool name.
#
+# @namespace: Rados namespace name in the Ceph pool. (Since 5.0)
+#
# @image: Image name in the Ceph pool.
#
# @conf: path to Ceph configuration file. Values
@@ -3570,6 +3572,7 @@
##
{ 'struct': 'BlockdevOptionsRbd',
'data': { 'pool': 'str',
+ '*namespace': 'str',
'image': 'str',
'*conf': 'str',
'*snapshot': 'str',
diff --git a/block/rbd.c b/block/rbd.c
index 027cbcc695..84115d34b4 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -104,6 +104,7 @@ typedef struct BDRVRBDState {
rbd_image_t image;
char *image_name;
char *snap;
+ char *namespace;
uint64_t image_size;
} BDRVRBDState;
@@ -152,7 +153,7 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
const char *start;
char *p, *buf;
QList *keypairs = NULL;
- char *found_str;
+ char *found_str, *image_name;
if (!strstart(filename, "rbd:", &start)) {
error_setg(errp, "File name must start with 'rbd:'");
@@ -171,18 +172,24 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
qdict_put_str(options, "pool", found_str);
if (strchr(p, '@')) {
- found_str = qemu_rbd_next_tok(p, '@', &p);
- qemu_rbd_unescape(found_str);
- qdict_put_str(options, "image", found_str);
+ image_name = qemu_rbd_next_tok(p, '@', &p);
found_str = qemu_rbd_next_tok(p, ':', &p);
qemu_rbd_unescape(found_str);
qdict_put_str(options, "snapshot", found_str);
} else {
- found_str = qemu_rbd_next_tok(p, ':', &p);
+ image_name = qemu_rbd_next_tok(p, ':', &p);
+ }
+ /* Check for namespace in the image_name */
+ if (strchr(image_name, '/')) {
+ found_str = qemu_rbd_next_tok(image_name, '/', &image_name);
qemu_rbd_unescape(found_str);
- qdict_put_str(options, "image", found_str);
+ qdict_put_str(options, "namespace", found_str);
+ } else {
+ qdict_put_str(options, "namespace", "");
}
+ qemu_rbd_unescape(image_name);
+ qdict_put_str(options, "image", image_name);
if (!p) {
goto done;
}
@@ -343,6 +350,11 @@ static QemuOptsList runtime_opts = {
.type = QEMU_OPT_STRING,
.help = "Rados pool name",
},
+ {
+ .name = "namespace",
+ .type = QEMU_OPT_STRING,
+ .help = "Rados namespace name in the pool",
+ },
{
.name = "image",
.type = QEMU_OPT_STRING,
@@ -467,13 +479,14 @@ static int coroutine_fn qemu_rbd_co_create_opts(const char *filename,
* schema, but when they come from -drive, they're all QString.
*/
loc = rbd_opts->location;
- loc->pool = g_strdup(qdict_get_try_str(options, "pool"));
- loc->conf = g_strdup(qdict_get_try_str(options, "conf"));
- loc->has_conf = !!loc->conf;
- loc->user = g_strdup(qdict_get_try_str(options, "user"));
- loc->has_user = !!loc->user;
- loc->image = g_strdup(qdict_get_try_str(options, "image"));
- keypairs = qdict_get_try_str(options, "=keyvalue-pairs");
+ loc->pool = g_strdup(qdict_get_try_str(options, "pool"));
+ loc->conf = g_strdup(qdict_get_try_str(options, "conf"));
+ loc->has_conf = !!loc->conf;
+ loc->user = g_strdup(qdict_get_try_str(options, "user"));
+ loc->has_user = !!loc->user;
+ loc->q_namespace = g_strdup(qdict_get_try_str(options, "namespace"));
+ loc->image = g_strdup(qdict_get_try_str(options, "image"));
+ keypairs = qdict_get_try_str(options, "=keyvalue-pairs");
ret = qemu_rbd_do_create(create_options, keypairs, password_secret, errp);
if (ret < 0) {
@@ -648,6 +661,11 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
error_setg_errno(errp, -r, "error opening pool %s", opts->pool);
goto failed_shutdown;
}
+ /*
+ * Set the namespace after opening the io context on the pool,
+ * if nspace == NULL or if nspace == "", it is just as we did nothing
+ */
+ rados_ioctx_set_namespace(*io_ctx, opts->q_namespace);
return 0;
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 28/29] iotests: Refactor blockdev-reopen test for iothreads
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (26 preceding siblings ...)
2020-03-06 17:14 ` [PULL 27/29] block/rbd: Add support for ceph namespaces Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 17:14 ` [PULL 29/29] block: bdrv_reopen() with backing file in different AioContext Kevin Wolf
` (2 subsequent siblings)
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
We'll want to test more than one successful case in the future, so
prepare the test for that by a refactoring that runs each scenario in a
separate VM.
test_iothreads_switch_{backing,overlay} currently produce errors, but
these are cases that should actually work, by switching either the
backing file node or the overlay node to the AioContext of the other
node.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Message-Id: <20200306141413.30705-2-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
tests/qemu-iotests/245 | 47 ++++++++++++++++++++++++++++++--------
tests/qemu-iotests/245.out | 4 ++--
2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
index 489bf78bd0..7d9eb6285c 100755
--- a/tests/qemu-iotests/245
+++ b/tests/qemu-iotests/245
@@ -970,8 +970,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.assertEqual(self.get_node('hd1'), None)
self.assert_qmp(self.get_node('hd2'), 'ro', True)
- # We don't allow setting a backing file that uses a different AioContext
- def test_iothreads(self):
+ def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None):
opts = hd_opts(0)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
@@ -986,20 +985,48 @@ class TestBlockdevReopen(iotests.QMPTestCase):
result = self.vm.qmp('object-add', qom_type='iothread', id='iothread1')
self.assert_qmp(result, 'return', {})
- result = self.vm.qmp('x-blockdev-set-iothread', node_name='hd0', iothread='iothread0')
+ result = self.vm.qmp('device_add', driver='virtio-scsi', id='scsi0',
+ iothread=iothread_a)
self.assert_qmp(result, 'return', {})
- self.reopen(opts, {'backing': 'hd2'}, "Cannot use a new backing file with a different AioContext")
-
- result = self.vm.qmp('x-blockdev-set-iothread', node_name='hd2', iothread='iothread1')
+ result = self.vm.qmp('device_add', driver='virtio-scsi', id='scsi1',
+ iothread=iothread_b)
self.assert_qmp(result, 'return', {})
- self.reopen(opts, {'backing': 'hd2'}, "Cannot use a new backing file with a different AioContext")
+ if iothread_a:
+ result = self.vm.qmp('device_add', driver='scsi-hd', drive='hd0',
+ share_rw=True, bus="scsi0.0")
+ self.assert_qmp(result, 'return', {})
- result = self.vm.qmp('x-blockdev-set-iothread', node_name='hd2', iothread='iothread0')
- self.assert_qmp(result, 'return', {})
+ if iothread_b:
+ result = self.vm.qmp('device_add', driver='scsi-hd', drive='hd2',
+ share_rw=True, bus="scsi1.0")
+ self.assert_qmp(result, 'return', {})
- self.reopen(opts, {'backing': 'hd2'})
+ # Attaching the backing file may or may not work
+ self.reopen(opts, {'backing': 'hd2'}, errmsg)
+
+ # But removing the backing file should always work
+ self.reopen(opts, {'backing': None})
+
+ self.vm.shutdown()
+
+ # We don't allow setting a backing file that uses a different AioContext if
+ # neither of them can switch to the other AioContext
+ def test_iothreads_error(self):
+ self.run_test_iothreads('iothread0', 'iothread1',
+ "Cannot use a new backing file with a different AioContext")
+
+ def test_iothreads_compatible_users(self):
+ self.run_test_iothreads('iothread0', 'iothread0')
+
+ def test_iothreads_switch_backing(self):
+ self.run_test_iothreads('iothread0', None,
+ "Cannot use a new backing file with a different AioContext")
+
+ def test_iothreads_switch_overlay(self):
+ self.run_test_iothreads(None, 'iothread0',
+ "Cannot use a new backing file with a different AioContext")
if __name__ == '__main__':
iotests.main(supported_fmts=["qcow2"],
diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out
index a19de5214d..682b93394d 100644
--- a/tests/qemu-iotests/245.out
+++ b/tests/qemu-iotests/245.out
@@ -1,6 +1,6 @@
-..................
+.....................
----------------------------------------------------------------------
-Ran 18 tests
+Ran 21 tests
OK
{"execute": "job-finalize", "arguments": {"id": "commit0"}}
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PULL 29/29] block: bdrv_reopen() with backing file in different AioContext
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (27 preceding siblings ...)
2020-03-06 17:14 ` [PULL 28/29] iotests: Refactor blockdev-reopen test for iothreads Kevin Wolf
@ 2020-03-06 17:14 ` Kevin Wolf
2020-03-06 19:16 ` [PULL 00/29] Block layer patches no-reply
2020-03-06 19:26 ` Peter Maydell
30 siblings, 0 replies; 41+ messages in thread
From: Kevin Wolf @ 2020-03-06 17:14 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
This patch allows bdrv_reopen() (and therefore the x-blockdev-reopen QMP
command) to attach a node as the new backing file even if the node is in
a different AioContext than the parent if one of both nodes can be moved
to the AioContext of the other node.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Message-Id: <20200306141413.30705-3-kwolf@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 32 ++++++++++++++++++++++++++------
tests/qemu-iotests/245 | 8 +++-----
2 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/block.c b/block.c
index aaa387504e..957630b1c5 100644
--- a/block.c
+++ b/block.c
@@ -3787,6 +3787,29 @@ static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs,
*shared = cumulative_shared_perms;
}
+static bool bdrv_reopen_can_attach(BlockDriverState *parent,
+ BdrvChild *child,
+ BlockDriverState *new_child,
+ Error **errp)
+{
+ AioContext *parent_ctx = bdrv_get_aio_context(parent);
+ AioContext *child_ctx = bdrv_get_aio_context(new_child);
+ GSList *ignore;
+ bool ret;
+
+ ignore = g_slist_prepend(NULL, child);
+ ret = bdrv_can_set_aio_context(new_child, parent_ctx, &ignore, NULL);
+ g_slist_free(ignore);
+ if (ret) {
+ return ret;
+ }
+
+ ignore = g_slist_prepend(NULL, child);
+ ret = bdrv_can_set_aio_context(parent, child_ctx, &ignore, errp);
+ g_slist_free(ignore);
+ return ret;
+}
+
/*
* Take a BDRVReopenState and check if the value of 'backing' in the
* reopen_state->options QDict is valid or not.
@@ -3838,14 +3861,11 @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state,
}
/*
- * TODO: before removing the x- prefix from x-blockdev-reopen we
- * should move the new backing file into the right AioContext
- * instead of returning an error.
+ * Check AioContext compatibility so that the bdrv_set_backing_hd() call in
+ * bdrv_reopen_commit() won't fail.
*/
if (new_backing_bs) {
- if (bdrv_get_aio_context(new_backing_bs) != bdrv_get_aio_context(bs)) {
- error_setg(errp, "Cannot use a new backing file "
- "with a different AioContext");
+ if (!bdrv_reopen_can_attach(bs, bs->backing, new_backing_bs, errp)) {
return -EINVAL;
}
}
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
index 7d9eb6285c..1001275a44 100755
--- a/tests/qemu-iotests/245
+++ b/tests/qemu-iotests/245
@@ -1015,18 +1015,16 @@ class TestBlockdevReopen(iotests.QMPTestCase):
# neither of them can switch to the other AioContext
def test_iothreads_error(self):
self.run_test_iothreads('iothread0', 'iothread1',
- "Cannot use a new backing file with a different AioContext")
+ "Cannot change iothread of active block backend")
def test_iothreads_compatible_users(self):
self.run_test_iothreads('iothread0', 'iothread0')
def test_iothreads_switch_backing(self):
- self.run_test_iothreads('iothread0', None,
- "Cannot use a new backing file with a different AioContext")
+ self.run_test_iothreads('iothread0', None)
def test_iothreads_switch_overlay(self):
- self.run_test_iothreads(None, 'iothread0',
- "Cannot use a new backing file with a different AioContext")
+ self.run_test_iothreads(None, 'iothread0')
if __name__ == '__main__':
iotests.main(supported_fmts=["qcow2"],
--
2.20.1
^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PULL 00/29] Block layer patches
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (28 preceding siblings ...)
2020-03-06 17:14 ` [PULL 29/29] block: bdrv_reopen() with backing file in different AioContext Kevin Wolf
@ 2020-03-06 19:16 ` no-reply
2020-03-06 19:26 ` Peter Maydell
30 siblings, 0 replies; 41+ messages in thread
From: no-reply @ 2020-03-06 19:16 UTC (permalink / raw)
To: kwolf; +Cc: kwolf, peter.maydell, qemu-devel, qemu-block
Patchew URL: https://patchew.org/QEMU/20200306171458.1848-1-kwolf@redhat.com/
Hi,
This series seems to have some coding style problems. See output below for
more information:
Subject: [PULL 00/29] Block layer patches
Message-id: 20200306171458.1848-1-kwolf@redhat.com
Type: series
=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
- [tag update] patchew/20200226155304.60219-1-david@redhat.com -> patchew/20200226155304.60219-1-david@redhat.com
Switched to a new branch 'test'
32121e1 block: bdrv_reopen() with backing file in different AioContext
b4fc54d iotests: Refactor blockdev-reopen test for iothreads
2d8f428 block/rbd: Add support for ceph namespaces
b316a0b qemu-storage-daemon: Add --monitor option
caf92c2 monitor: Add allow_hmp parameter to monitor_init()
73480ad hmp: Fail gracefully if chardev is already in use
1a7c874 qmp: Fail gracefully if chardev is already in use
f7fbb53 monitor: Create QAPIfied monitor_init()
85141e5 qapi: Create 'pragma' module
5012797 stubs: Update monitor stubs for qemu-storage-daemon
a32e4ac qemu-storage-daemon: Add --chardev option
2a264c4 qemu-storage-daemon: Add main loop
0f2bb9d qemu-storage-daemon: Add --export option
95f79fa blockdev-nbd: Boxed argument type for nbd-server-add
c3e93ca qemu-storage-daemon: Add --nbd-server option
2a54241 qemu-storage-daemon: Add --object option
b3767de qapi: Flatten object-add
40c88aa qemu-storage-daemon: Add --blockdev option
f52856a block: Move sysemu QMP commands to QAPI block module
280af2e block: Move common QMP commands to block-core QAPI module
223169a block: Move system emulator QMP commands to block/qapi-sysemu.c
c687d45 stubs: Add arch_type
1ca4df6 qemu-storage-daemon: Add barebone tool
e148d2c block/qcow2: Move bitmap reopen into bdrv_reopen_commit_post
90ceeb8 block: Introduce 'bdrv_reopen_commit_post' step
f82447c block: Fix leak in bdrv_create_file_fallback()
6c79b95 iotests/026: Test EIO on allocation in a data-file
ce45c2f iotests/026: Test EIO on preallocated zero cluster
6fe3d12 qcow2: Fix alloc_cluster_abort() for pre-existing clusters
=== OUTPUT BEGIN ===
1/29 Checking commit 6fe3d1204d78 (qcow2: Fix alloc_cluster_abort() for pre-existing clusters)
2/29 Checking commit ce45c2f906d8 (iotests/026: Test EIO on preallocated zero cluster)
3/29 Checking commit 6c79b9543536 (iotests/026: Test EIO on allocation in a data-file)
4/29 Checking commit f82447c66adc (block: Fix leak in bdrv_create_file_fallback())
5/29 Checking commit 90ceeb8bb6dc (block: Introduce 'bdrv_reopen_commit_post' step)
6/29 Checking commit e148d2cd2ef4 (block/qcow2: Move bitmap reopen into bdrv_reopen_commit_post)
7/29 Checking commit 1ca4df6e0c59 (qemu-storage-daemon: Add barebone tool)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#49:
new file mode 100644
total: 0 errors, 1 warnings, 142 lines checked
Patch 7/29 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
8/29 Checking commit c687d45eee38 (stubs: Add arch_type)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#40:
new file mode 100644
total: 0 errors, 1 warnings, 16 lines checked
Patch 8/29 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
9/29 Checking commit 223169a6a829 (block: Move system emulator QMP commands to block/qapi-sysemu.c)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#32:
new file mode 100644
WARNING: Block comments use a leading /* on a separate line
#258: FILE: block/qapi-sysemu.c:222:
+ /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
WARNING: Block comments use a trailing */ on a separate line
#261: FILE: block/qapi-sysemu.c:225:
+ * value passed here (i.e. false). */
WARNING: Block comments use a leading /* on a separate line
#305: FILE: block/qapi-sysemu.c:269:
+ /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
WARNING: Block comments use a trailing */ on a separate line
#309: FILE: block/qapi-sysemu.c:273:
+ * value passed here (i.e. true). */
WARNING: Block comments use a leading /* on a separate line
#442: FILE: block/qapi-sysemu.c:406:
+ /* If the medium has been inserted, the device has its own reference, so
WARNING: Block comments use a trailing */ on a separate line
#444: FILE: block/qapi-sysemu.c:408:
+ * the reference must be relinquished anyway */
WARNING: Block comments use a leading /* on a separate line
#551: FILE: block/qapi-sysemu.c:515:
+ /* Enable I/O limits if they're not enabled yet, otherwise
WARNING: Block comments use a trailing */ on a separate line
#552: FILE: block/qapi-sysemu.c:516:
+ * just update the throttling group. */
total: 0 errors, 9 warnings, 1187 lines checked
Patch 9/29 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
10/29 Checking commit 280af2e20a90 (block: Move common QMP commands to block-core QAPI module)
11/29 Checking commit f52856a99bc9 (block: Move sysemu QMP commands to QAPI block module)
12/29 Checking commit 40c88aa15edf (qemu-storage-daemon: Add --blockdev option)
13/29 Checking commit b3767de968be (qapi: Flatten object-add)
14/29 Checking commit 2a5424175819 (qemu-storage-daemon: Add --object option)
WARNING: Block comments use a leading /* on a separate line
#103: FILE: qemu-storage-daemon.c:155:
+ /* FIXME The keyval parser rejects 'help' arguments, so we must
WARNING: Block comments use a trailing */ on a separate line
#104: FILE: qemu-storage-daemon.c:156:
+ * unconditionall try QemuOpts first. */
total: 0 errors, 2 warnings, 98 lines checked
Patch 14/29 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
15/29 Checking commit c3e93ca278e4 (qemu-storage-daemon: Add --nbd-server option)
16/29 Checking commit 95f79fa744ce (blockdev-nbd: Boxed argument type for nbd-server-add)
17/29 Checking commit 0f2bb9d607ae (qemu-storage-daemon: Add --export option)
18/29 Checking commit 2a264c475078 (qemu-storage-daemon: Add main loop)
ERROR: do not initialise statics to 0 or NULL
#46: FILE: qemu-storage-daemon.c:56:
+static volatile bool exit_requested = false;
ERROR: Use of volatile is usually wrong, please add a comment
#46: FILE: qemu-storage-daemon.c:56:
+static volatile bool exit_requested = false;
total: 2 errors, 0 warnings, 40 lines checked
Patch 18/29 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
19/29 Checking commit a32e4ac9537a (qemu-storage-daemon: Add --chardev option)
ERROR: externs should be avoided in .c files
#66: FILE: qemu-storage-daemon.c:117:
+extern QemuOptsList qemu_chardev_opts;
total: 1 errors, 0 warnings, 67 lines checked
Patch 19/29 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
20/29 Checking commit 501279700888 (stubs: Update monitor stubs for qemu-storage-daemon)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#34:
new file mode 100644
total: 0 errors, 1 warnings, 58 lines checked
Patch 20/29 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
21/29 Checking commit 85141e527412 (qapi: Create 'pragma' module)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#31:
new file mode 100644
total: 0 errors, 1 warnings, 63 lines checked
Patch 21/29 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
22/29 Checking commit f7fbb5311767 (monitor: Create QAPIfied monitor_init())
23/29 Checking commit 1a7c87440187 (qmp: Fail gracefully if chardev is already in use)
24/29 Checking commit 73480ad8a7e9 (hmp: Fail gracefully if chardev is already in use)
25/29 Checking commit caf92c214b2a (monitor: Add allow_hmp parameter to monitor_init())
26/29 Checking commit b316a0bef865 (qemu-storage-daemon: Add --monitor option)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#269:
new file mode 100644
total: 0 errors, 1 warnings, 228 lines checked
Patch 26/29 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
27/29 Checking commit 2d8f428e905e (block/rbd: Add support for ceph namespaces)
28/29 Checking commit b4fc54d15f7a (iotests: Refactor blockdev-reopen test for iothreads)
29/29 Checking commit 32121e1b2fa3 (block: bdrv_reopen() with backing file in different AioContext)
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at
http://patchew.org/logs/20200306171458.1848-1-kwolf@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PULL 00/29] Block layer patches
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
` (29 preceding siblings ...)
2020-03-06 19:16 ` [PULL 00/29] Block layer patches no-reply
@ 2020-03-06 19:26 ` Peter Maydell
30 siblings, 0 replies; 41+ messages in thread
From: Peter Maydell @ 2020-03-06 19:26 UTC (permalink / raw)
To: Kevin Wolf; +Cc: QEMU Developers, Qemu-block
On Fri, 6 Mar 2020 at 17:15, Kevin Wolf <kwolf@redhat.com> wrote:
>
> The following changes since commit f4c4357fbfca0fb14e477bf661ae7384b4b9b283:
>
> Merge remote-tracking branch 'remotes/pmaydell/tags/pull-docs-20200306' into staging (2020-03-06 11:11:54 +0000)
>
> are available in the Git repository at:
>
> git://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to 1de6b45fb5c1489b450df7d1a4c692bba9678ce6:
>
> block: bdrv_reopen() with backing file in different AioContext (2020-03-06 17:34:09 +0100)
>
> ----------------------------------------------------------------
> Block layer patches:
>
> - Add qemu-storage-daemon (still experimental)
> - rbd: Add support for ceph namespaces
> - Fix bdrv_reopen() with backing file in different AioContext
> - qcow2: Fix read-write reopen with persistent dirty bitmaps
> - qcow2: Fix alloc_cluster_abort() for pre-existing clusters
>
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/5.0
for any user-visible changes.
-- PMM
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PULL 13/29] qapi: Flatten object-add
2020-03-06 17:14 ` [PULL 13/29] qapi: Flatten object-add Kevin Wolf
@ 2020-07-08 15:48 ` Paolo Bonzini
2020-07-08 16:05 ` Kevin Wolf
0 siblings, 1 reply; 41+ messages in thread
From: Paolo Bonzini @ 2020-07-08 15:48 UTC (permalink / raw)
To: Kevin Wolf, Markus Armbruster; +Cc: peter.maydell, qemu-devel
On 06/03/20 18:14, Kevin Wolf wrote:
> Mapping object-add to the command line as is doesn't result in nice
> syntax because of the nesting introduced with 'props'. This becomes
> nicer and more consistent with device_add and netdev_add when we accept
> properties for the object on the top level instead.
>
> 'props' is still accepted after this patch, but marked as deprecated.
>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> Message-Id: <20200224143008.13362-8-kwolf@redhat.com>
> Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Hi Kevin and Markus,
I just noticed this patch. In my opinion "nice syntax" is not a good
argument for having a "gen: false" command that is even less
introspectable than the "props" argument.
As an aside, it would have been nice to run this through Markus and me,
though in all fairness I'm not sure I would have been responsive back in
February.
I would like to un-deprecate this for 5.1, and revert it in either 5.1
or 5.2. (Also I will be away next week, so the decision would have to
be taken quickly).
Paolo
> ---
> qapi/qom.json | 12 +++++++---
> docs/system/deprecated.rst | 5 ++++
> include/qom/object_interfaces.h | 7 ++++++
> hw/block/xen-block.c | 11 ++++++++-
> monitor/misc.c | 2 ++
> qom/qom-qmp-cmds.c | 42 +++++++++++++++++++++++++++------
> 6 files changed, 68 insertions(+), 11 deletions(-)
>
> diff --git a/qapi/qom.json b/qapi/qom.json
> index ecc60c4401..8abe998962 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -210,7 +210,12 @@
> #
> # @id: the name of the new object
> #
> -# @props: a dictionary of properties to be passed to the backend
> +# @props: a dictionary of properties to be passed to the backend. Deprecated
> +# since 5.0, specify the properties on the top level instead. It is an
> +# error to specify the same option both on the top level and in @props.
> +#
> +# Additional arguments depend on qom-type and are passed to the backend
> +# unchanged.
> #
> # Returns: Nothing on success
> # Error if @qom-type is not a valid class name
> @@ -221,12 +226,13 @@
> #
> # -> { "execute": "object-add",
> # "arguments": { "qom-type": "rng-random", "id": "rng1",
> -# "props": { "filename": "/dev/hwrng" } } }
> +# "filename": "/dev/hwrng" } }
> # <- { "return": {} }
> #
> ##
> { 'command': 'object-add',
> - 'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'} }
> + 'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'},
> + 'gen': false } # so we can get the additional arguments
>
> ##
> # @object-del:
> diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
> index 1eaa559079..6c1d9034d9 100644
> --- a/docs/system/deprecated.rst
> +++ b/docs/system/deprecated.rst
> @@ -190,6 +190,11 @@ Use ``migrate-set-parameters`` instead.
>
> Use ``migrate-set-parameters`` and ``query-migrate-parameters`` instead.
>
> +``object-add`` option ``props`` (since 5.0)
> +'''''''''''''''''''''''''''''''''''''''''''
> +
> +Specify the properties for the object as top-level arguments instead.
> +
> ``query-block`` result field ``dirty-bitmaps[i].status`` (since 4.0)
> ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
>
> diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
> index 3e4e1d928b..6f92f3cebb 100644
> --- a/include/qom/object_interfaces.h
> +++ b/include/qom/object_interfaces.h
> @@ -162,4 +162,11 @@ void user_creatable_del(const char *id, Error **errp);
> */
> void user_creatable_cleanup(void);
>
> +/**
> + * qmp_object_add:
> + *
> + * QMP command handler for object-add. See the QAPI schema for documentation.
> + */
> +void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp);
> +
> #endif
> diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
> index 686bbc3f0d..3885464513 100644
> --- a/hw/block/xen-block.c
> +++ b/hw/block/xen-block.c
> @@ -18,6 +18,7 @@
> #include "qapi/visitor.h"
> #include "qapi/qmp/qdict.h"
> #include "qapi/qmp/qstring.h"
> +#include "qom/object_interfaces.h"
> #include "hw/xen/xen_common.h"
> #include "hw/block/xen_blkif.h"
> #include "hw/qdev-properties.h"
> @@ -858,10 +859,18 @@ static XenBlockIOThread *xen_block_iothread_create(const char *id,
> {
> XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1);
> Error *local_err = NULL;
> + QDict *opts;
> + QObject *ret_data;
>
> iothread->id = g_strdup(id);
>
> - qmp_object_add(TYPE_IOTHREAD, id, false, NULL, &local_err);
> + opts = qdict_new();
> + qdict_put_str(opts, "qom-type", TYPE_IOTHREAD);
> + qdict_put_str(opts, "id", id);
> + qmp_object_add(opts, &ret_data, &local_err);
> + qobject_unref(opts);
> + qobject_unref(ret_data);
> +
> if (local_err) {
> error_propagate(errp, local_err);
>
> diff --git a/monitor/misc.c b/monitor/misc.c
> index 6c41293102..1748ab3911 100644
> --- a/monitor/misc.c
> +++ b/monitor/misc.c
> @@ -248,6 +248,8 @@ static void monitor_init_qmp_commands(void)
> QCO_NO_OPTIONS);
> qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
> QCO_NO_OPTIONS);
> + qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
> + QCO_NO_OPTIONS);
>
> QTAILQ_INIT(&qmp_cap_negotiation_commands);
> qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
> diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
> index 6136efec16..49db926fcc 100644
> --- a/qom/qom-qmp-cmds.c
> +++ b/qom/qom-qmp-cmds.c
> @@ -14,6 +14,7 @@
> */
>
> #include "qemu/osdep.h"
> +#include "block/qdict.h"
> #include "hw/qdev-core.h"
> #include "qapi/error.h"
> #include "qapi/qapi-commands-qdev.h"
> @@ -240,13 +241,34 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
> return prop_list;
> }
>
> -void qmp_object_add(const char *type, const char *id,
> - bool has_props, QObject *props, Error **errp)
> +void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
> {
> + QObject *props;
> QDict *pdict;
> Visitor *v;
> Object *obj;
> + const char *type;
> + const char *id;
>
> + type = qdict_get_try_str(qdict, "qom-type");
> + if (!type) {
> + error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
> + return;
> + } else {
> + type = g_strdup(type);
> + qdict_del(qdict, "qom-type");
> + }
> +
> + id = qdict_get_try_str(qdict, "id");
> + if (!id) {
> + error_setg(errp, QERR_MISSING_PARAMETER, "id");
> + return;
> + } else {
> + id = g_strdup(id);
> + qdict_del(qdict, "id");
> + }
> +
> + props = qdict_get(qdict, "props");
> if (props) {
> pdict = qobject_to(QDict, props);
> if (!pdict) {
> @@ -254,17 +276,23 @@ void qmp_object_add(const char *type, const char *id,
> return;
> }
> qobject_ref(pdict);
> - } else {
> - pdict = qdict_new();
> + qdict_del(qdict, "props");
> + qdict_join(qdict, pdict, false);
> + if (qdict_size(pdict) != 0) {
> + error_setg(errp, "Option in 'props' conflicts with top level");
> + qobject_unref(pdict);
> + return;
> + }
> + qobject_unref(pdict);
> }
>
> - v = qobject_input_visitor_new(QOBJECT(pdict));
> - obj = user_creatable_add_type(type, id, pdict, v, errp);
> + v = qobject_input_visitor_new(QOBJECT(qdict));
> + obj = user_creatable_add_type(type, id, qdict, v, errp);
> visit_free(v);
> if (obj) {
> object_unref(obj);
> }
> - qobject_unref(pdict);
> + *ret_data = QOBJECT(qdict_new());
> }
>
> void qmp_object_del(const char *id, Error **errp)
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PULL 13/29] qapi: Flatten object-add
2020-07-08 15:48 ` Paolo Bonzini
@ 2020-07-08 16:05 ` Kevin Wolf
2020-07-08 16:12 ` Paolo Bonzini
0 siblings, 1 reply; 41+ messages in thread
From: Kevin Wolf @ 2020-07-08 16:05 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: peter.maydell, Markus Armbruster, qemu-devel
Am 08.07.2020 um 17:48 hat Paolo Bonzini geschrieben:
> On 06/03/20 18:14, Kevin Wolf wrote:
> > Mapping object-add to the command line as is doesn't result in nice
> > syntax because of the nesting introduced with 'props'. This becomes
> > nicer and more consistent with device_add and netdev_add when we accept
> > properties for the object on the top level instead.
> >
> > 'props' is still accepted after this patch, but marked as deprecated.
> >
> > Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> > Message-Id: <20200224143008.13362-8-kwolf@redhat.com>
> > Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
> > Signed-off-by: Kevin Wolf <kwolf@redhat.com>
>
> Hi Kevin and Markus,
>
> I just noticed this patch. In my opinion "nice syntax" is not a good
> argument for having a "gen: false" command that is even less
> introspectable than the "props" argument.
Markus was going to introduce new QAPI schema syntax that would allow to
specify a few options explicitly and then one option for "the rest" that
would just be mapped to a QDict like "any" or "gen": false, and that
wouldn't require any nesting.
I'm not sure if any progress was made there, but making things
consistent between device_add, netdev_add and object_add was a step in
this direction anyway.
> As an aside, it would have been nice to run this through Markus and me,
> though in all fairness I'm not sure I would have been responsive back
> in February.
It went through my tree because of the other patches in the series, but
I wrote this patch specifically at Markus's request.
> I would like to un-deprecate this for 5.1, and revert it in either 5.1
> or 5.2. (Also I will be away next week, so the decision would have to
> be taken quickly).
Please discuss it with Markus then.
Kevin
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PULL 13/29] qapi: Flatten object-add
2020-07-08 16:05 ` Kevin Wolf
@ 2020-07-08 16:12 ` Paolo Bonzini
2020-07-09 10:26 ` Markus Armbruster
0 siblings, 1 reply; 41+ messages in thread
From: Paolo Bonzini @ 2020-07-08 16:12 UTC (permalink / raw)
To: Kevin Wolf; +Cc: peter.maydell, Markus Armbruster, qemu-devel
On 08/07/20 18:05, Kevin Wolf wrote:
> Markus was going to introduce new QAPI schema syntax that would allow to
> specify a few options explicitly and then one option for "the rest" that
> would just be mapped to a QDict like "any" or "gen": false, and that
> wouldn't require any nesting.
Oh, I wasn't aware of that. That would be something like 'properties':
'remainder' I guess. That would be fine too.
Paolo
> I'm not sure if any progress was made there, but making things
> consistent between device_add, netdev_add and object_add was a step in
> this direction anyway.
>
>> As an aside, it would have been nice to run this through Markus and me,
>> though in all fairness I'm not sure I would have been responsive back
>> in February.
> It went through my tree because of the other patches in the series, but
> I wrote this patch specifically at Markus's request.
>
>> I would like to un-deprecate this for 5.1, and revert it in either 5.1
>> or 5.2. (Also I will be away next week, so the decision would have to
>> be taken quickly).
> Please discuss it with Markus then.
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PULL 13/29] qapi: Flatten object-add
2020-07-08 16:12 ` Paolo Bonzini
@ 2020-07-09 10:26 ` Markus Armbruster
0 siblings, 0 replies; 41+ messages in thread
From: Markus Armbruster @ 2020-07-09 10:26 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Kevin Wolf, peter.maydell, qemu-devel
Paolo Bonzini <pbonzini@redhat.com> writes:
> On 08/07/20 18:05, Kevin Wolf wrote:
>> Markus was going to introduce new QAPI schema syntax that would allow to
>> specify a few options explicitly and then one option for "the rest" that
>> would just be mapped to a QDict like "any" or "gen": false, and that
>> wouldn't require any nesting.
>
> Oh, I wasn't aware of that. That would be something like 'properties':
> 'remainder' I guess. That would be fine too.
Glad I'm spared a design argument ;)
>> I'm not sure if any progress was made there, but making things
Not yet; error handling ate me whole, and spit me out only the day
before yesterday or so.
>> consistent between device_add, netdev_add and object_add was a step in
>> this direction anyway.
Yes.
Permit me to digress.
We ran into the "and also arbitray properties" need repeatedly, and
tried several solutions over time. QAPI/QMP is big, and the left hand
often wasn't too interested in what the right hand had been doing.
If memory and my git archaeology skills serve, the first instance was
device_add:
3418bd25e1 "qdev hotplug: infrastructure and monitor commands."
2009-10-05
Simple adaption of the QemuOpts-based -device for HMP. Since QemuOpts
is flat, so is device_add. QAPI didn't exist, yet. A QMP version
followed:
8bc27249f0 "monitor: convert do_device_add() to QObject"
2010-03-16
Just as flat.
Next was netdev_add:
ae82d3242d "monitor: New commands netdev_add, netdev_del"
2010-04-18
Flat for the same reason.
When QAPI came along in
ebffe2afce "Merge remote-tracking branch 'qmp/queue/qmp' into
staging"
2011-10-10
these two commands were left unQAPIfied, as the schema language could
not express "and also arbitrary properties". Soon "solved" with a cop
out:
5dbee474f3 "qapi: allow a 'gen' key to suppress code generation"
2011-12-15
A half-hearted QAPIfication of netdev_add followed:
928059a37b "qapi: convert netdev_add"
2012-06-04
QAPI schema:
{ 'command': 'netdev_add',
'data': {'type': 'str', 'id': 'str', '*props': '**'},
'gen': 'no' }
Note the bogus type '**', which only works because 'gen': 'no' also
bypasses type checking (which you wouldn't guess from the commit
message, documentation, or even the schema). In fact, the whole 'props'
thing is a lie: there is no such parameter, the command is as flat as it
ever was. Fixed in
b8a98326d5 "qapi-schema: Fix up misleading specification of
netdev_add"
2015-09-21
{ 'command': 'netdev_add',
'data': {'type': 'str', 'id': 'str'},
'gen': false }
but by then it had already spread to object-add, with an equally bogus
type 'dict':
cff8b2c6fc "monitor: add object-add (QMP) and object_add (HMP)
command"
2014-01-06
{ 'command': 'object-add',
'data': {'qom-type': 'str', 'id': 'str', '*props': 'dict'},
'gen': 'no' }
Only 'props' was real this time: you really had to wrap the properties
in "props": { ... }. Non-flat. Meh.
Eventually, even device_add made it into the schema:
94cfd07f26 "qapi-schema: add 'device_add'"
2016-09-19
{ 'command': 'device_add',
'data': {'driver': 'str', 'id': 'str'},
'gen': false } # so we can get the additional arguments
And netdev_add was finally done right:
db2a380c84 "net: Complete qapi-fication of netdev_add"
2020-03-17
{ 'command': 'netdev_add', 'data': 'Netdev', 'boxed': true }
Doing device_add and object-add right is harder (impractical?), because
their schema would be a union with one branch per device / object type.
End of digression.
>>> As an aside, it would have been nice to run this through Markus and me,
>>> though in all fairness I'm not sure I would have been responsive back
>>> in February.
>> It went through my tree because of the other patches in the series, but
>> I wrote this patch specifically at Markus's request.
Yes. We discussed how to best satisfy Kevin's immediate needs without
making other problems harder. Perhaps we should have posted a summary
to the list.
>>> I would like to un-deprecate this for 5.1, and revert it in either 5.1
>>> or 5.2. (Also I will be away next week, so the decision would have to
>>> be taken quickly).
>> Please discuss it with Markus then.
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PULL 00/29] Block layer patches
@ 2023-02-23 18:51 Kevin Wolf
2023-02-24 18:50 ` Peter Maydell
0 siblings, 1 reply; 41+ messages in thread
From: Kevin Wolf @ 2023-02-23 18:51 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, peter.maydell, qemu-devel
The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:
Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into staging (2023-02-21 11:28:31 +0000)
are available in the Git repository at:
https://repo.or.cz/qemu/kevin.git tags/for-upstream
for you to fetch changes up to 0f385a2420d2c3f8ae7ed65fbe2712027664059e:
block/rbd: Add support for layered encryption (2023-02-23 19:49:35 +0100)
----------------------------------------------------------------
Block layer patches
- Lock the graph, part 2 (BlockDriver callbacks)
- virtio-scsi: fix SCSIDevice hot unplug with IOThread
- rbd: Add support for layered encryption
----------------------------------------------------------------
Emanuele Giuseppe Esposito (5):
block/qed: add missing graph rdlock in qed_need_check_timer_entry
block: Mark bdrv_co_flush() and callers GRAPH_RDLOCK
block: Mark bdrv_co_pdiscard() and callers GRAPH_RDLOCK
block: Mark bdrv_co_copy_range() GRAPH_RDLOCK
block: Mark bdrv_co_is_inserted() and callers GRAPH_RDLOCK
Kevin Wolf (18):
block: Make bdrv_can_set_read_only() static
mirror: Fix access of uninitialised fields during start
block: Mark bdrv_co_truncate() and callers GRAPH_RDLOCK
block: Mark bdrv_co_block_status() and callers GRAPH_RDLOCK
block: Mark bdrv_co_ioctl() and callers GRAPH_RDLOCK
block: Mark bdrv_co_pwrite_zeroes() and callers GRAPH_RDLOCK
block: Mark read/write in block/io.c GRAPH_RDLOCK
block: Mark public read/write functions GRAPH_RDLOCK
block: Mark bdrv_co_pwrite_sync() and callers GRAPH_RDLOCK
block: Mark bdrv_co_do_pwrite_zeroes() GRAPH_RDLOCK
block: Mark preadv_snapshot/snapshot_block_status GRAPH_RDLOCK
block: Mark bdrv_co_create() and callers GRAPH_RDLOCK
block: Mark bdrv_co_io_(un)plug() and callers GRAPH_RDLOCK
block: Mark bdrv_co_eject/lock_medium() and callers GRAPH_RDLOCK
block: Mark bdrv_(un)register_buf() GRAPH_RDLOCK
block: Mark bdrv_co_delete_file() and callers GRAPH_RDLOCK
block: Mark bdrv_*_dirty_bitmap() and callers GRAPH_RDLOCK
block: Mark bdrv_co_refresh_total_sectors() and callers GRAPH_RDLOCK
Or Ozeri (3):
block/rbd: Remove redundant stack variable passphrase_len
block/rbd: Add luks-any encryption opening option
block/rbd: Add support for layered encryption
Stefan Hajnoczi (3):
scsi: protect req->aiocb with AioContext lock
dma-helpers: prevent dma_blk_cb() vs dma_aio_cancel() race
virtio-scsi: reset SCSI devices from main loop thread
qapi/block-core.json | 27 +++++-
block/coroutines.h | 2 +-
block/qcow2.h | 27 ++++--
block/qed.h | 45 +++++----
include/block/block-copy.h | 6 +-
include/block/block-global-state.h | 14 +--
include/block/block-io.h | 110 ++++++++++++----------
include/block/block_int-common.h | 173 ++++++++++++++++++----------------
include/block/block_int-io.h | 53 ++++++-----
include/block/dirty-bitmap.h | 12 +--
include/hw/virtio/virtio-scsi.h | 11 ++-
include/sysemu/block-backend-io.h | 7 +-
block.c | 12 ++-
block/backup.c | 3 +
block/blkdebug.c | 19 ++--
block/blklogwrites.c | 35 ++++---
block/blkreplay.c | 24 +++--
block/blkverify.c | 5 +-
block/block-backend.c | 39 +++++---
block/block-copy.c | 32 ++++---
block/bochs.c | 2 +-
block/commit.c | 5 +-
block/copy-before-write.c | 33 ++++---
block/copy-on-read.c | 44 +++++----
block/create.c | 9 +-
block/crypto.c | 16 ++--
block/dirty-bitmap.c | 2 +
block/file-posix.c | 27 +++---
block/file-win32.c | 7 +-
block/filter-compress.c | 36 ++++---
block/io.c | 108 +++++++++++++--------
block/iscsi.c | 28 +++---
block/mirror.c | 59 ++++++++----
block/parallels.c | 33 +++----
block/preallocate.c | 38 ++++----
block/qcow.c | 46 +++++----
block/qcow2-cluster.c | 17 ++--
block/qcow2.c | 136 +++++++++++++++------------
block/qed-check.c | 3 +-
block/qed-table.c | 10 +-
block/qed.c | 101 ++++++++++----------
block/quorum.c | 62 +++++++-----
block/raw-format.c | 76 ++++++++-------
block/rbd.c | 188 ++++++++++++++++++++++++++++++++++---
block/replication.c | 18 ++--
block/snapshot-access.c | 8 +-
block/stream.c | 40 ++++----
block/throttle.c | 36 ++++---
block/vdi.c | 11 +--
block/vhdx.c | 18 ++--
block/vmdk.c | 132 ++++++++++++--------------
block/vpc.c | 11 +--
hw/scsi/scsi-disk.c | 23 +++--
hw/scsi/scsi-generic.c | 11 ++-
hw/scsi/virtio-scsi.c | 169 ++++++++++++++++++++++++++-------
qemu-img.c | 8 +-
softmmu/dma-helpers.c | 12 ++-
tests/unit/test-bdrv-drain.c | 20 ++--
tests/unit/test-block-iothread.c | 3 +-
59 files changed, 1355 insertions(+), 907 deletions(-)
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PULL 00/29] Block layer patches
2023-02-23 18:51 Kevin Wolf
@ 2023-02-24 18:50 ` Peter Maydell
2023-02-24 21:35 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 41+ messages in thread
From: Peter Maydell @ 2023-02-24 18:50 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-block, qemu-devel
On Thu, 23 Feb 2023 at 18:51, Kevin Wolf <kwolf@redhat.com> wrote:
>
> The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:
>
> Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into staging (2023-02-21 11:28:31 +0000)
>
> are available in the Git repository at:
>
> https://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to 0f385a2420d2c3f8ae7ed65fbe2712027664059e:
>
> block/rbd: Add support for layered encryption (2023-02-23 19:49:35 +0100)
>
> ----------------------------------------------------------------
> Block layer patches
>
> - Lock the graph, part 2 (BlockDriver callbacks)
> - virtio-scsi: fix SCSIDevice hot unplug with IOThread
> - rbd: Add support for layered encryption
>
> ----------------------------------------------------------------
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/8.0
for any user-visible changes.
-- PMM
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PULL 00/29] Block layer patches
2023-02-24 18:50 ` Peter Maydell
@ 2023-02-24 21:35 ` Philippe Mathieu-Daudé
2023-02-27 9:12 ` Thomas Huth
0 siblings, 1 reply; 41+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-02-24 21:35 UTC (permalink / raw)
To: Peter Maydell, Kevin Wolf
Cc: qemu-block, qemu-devel, Emanuele Giuseppe Esposito
Hi,
On 24/2/23 19:50, Peter Maydell wrote:
> On Thu, 23 Feb 2023 at 18:51, Kevin Wolf <kwolf@redhat.com> wrote:
>>
>> The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:
>>
>> Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into staging (2023-02-21 11:28:31 +0000)
>>
>> are available in the Git repository at:
>>
>> https://repo.or.cz/qemu/kevin.git tags/for-upstream
>>
>> for you to fetch changes up to 0f385a2420d2c3f8ae7ed65fbe2712027664059e:
>>
>> block/rbd: Add support for layered encryption (2023-02-23 19:49:35 +0100)
>>
>> ----------------------------------------------------------------
>> Block layer patches
>>
>> - Lock the graph, part 2 (BlockDriver callbacks)
>> - virtio-scsi: fix SCSIDevice hot unplug with IOThread
>> - rbd: Add support for layered encryption
>>
>> ----------------------------------------------------------------
>
>
> Applied, thanks.
Configuring with --extra-cflags=-ggdb, on
C compiler for the host machine: clang (clang 14.0.0 "Apple clang
version 14.0.0 (clang-1400.0.29.202)")
C linker for the host machine: clang ld64 820.1
Host machine cpu family: aarch64
Host machine cpu: aarch64
...
CFLAGS : -ggdb -g -O2
I'm getting:
../../block/io.c:182:38: warning: reading variable 'bdrv_aio_preadv'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
drv->bdrv_aio_preadv ||
^
../../block/io.c:997:14: warning: reading variable 'bdrv_aio_preadv'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
if (drv->bdrv_aio_preadv) {
^
../../block/io.c:1003:20: warning: reading variable 'bdrv_aio_preadv'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
acb = drv->bdrv_aio_preadv(bs, offset, bytes, qiov, flags,
^
../../block/io.c:1076:14: warning: reading variable 'bdrv_aio_pwritev'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
if (drv->bdrv_aio_pwritev) {
^
../../block/io.c:1082:20: warning: reading variable 'bdrv_aio_pwritev'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
acb = drv->bdrv_aio_pwritev(bs, offset, bytes, qiov, flags,
^
../../block/io.c:2899:25: warning: reading variable 'bdrv_aio_flush'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
} else if (bs->drv->bdrv_aio_flush) {
^
../../block/io.c:2905:24: warning: reading variable 'bdrv_aio_flush'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
^
../../block/io.c:2991:49: warning: reading variable 'bdrv_aio_pdiscard'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
if (!bs->drv->bdrv_co_pdiscard && !bs->drv->bdrv_aio_pdiscard) {
^
../../block/io.c:3058:28: warning: reading variable 'bdrv_aio_pdiscard'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
acb = bs->drv->bdrv_aio_pdiscard(bs, offset, num,
^
../../block/io.c:3094:24: warning: reading variable 'bdrv_aio_ioctl'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
^
../../block/io.c:3102:20: warning: reading variable 'bdrv_aio_ioctl'
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete,
&co);
^
11 warnings generated.
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PULL 00/29] Block layer patches
2023-02-24 21:35 ` Philippe Mathieu-Daudé
@ 2023-02-27 9:12 ` Thomas Huth
2023-02-27 11:22 ` Peter Maydell
0 siblings, 1 reply; 41+ messages in thread
From: Thomas Huth @ 2023-02-27 9:12 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, Peter Maydell, Kevin Wolf
Cc: qemu-block, qemu-devel, Emanuele Giuseppe Esposito
On 24/02/2023 22.35, Philippe Mathieu-Daudé wrote:
> Hi,
>
> On 24/2/23 19:50, Peter Maydell wrote:
>> On Thu, 23 Feb 2023 at 18:51, Kevin Wolf <kwolf@redhat.com> wrote:
>>>
>>> The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:
>>>
>>> Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into
>>> staging (2023-02-21 11:28:31 +0000)
>>>
>>> are available in the Git repository at:
>>>
>>> https://repo.or.cz/qemu/kevin.git tags/for-upstream
>>>
>>> for you to fetch changes up to 0f385a2420d2c3f8ae7ed65fbe2712027664059e:
>>>
>>> block/rbd: Add support for layered encryption (2023-02-23 19:49:35 +0100)
>>>
>>> ----------------------------------------------------------------
>>> Block layer patches
>>>
>>> - Lock the graph, part 2 (BlockDriver callbacks)
>>> - virtio-scsi: fix SCSIDevice hot unplug with IOThread
>>> - rbd: Add support for layered encryption
>>>
>>> ----------------------------------------------------------------
>>
>>
>> Applied, thanks.
>
> Configuring with --extra-cflags=-ggdb, on
>
> C compiler for the host machine: clang (clang 14.0.0 "Apple clang version
> 14.0.0 (clang-1400.0.29.202)")
> C linker for the host machine: clang ld64 820.1
> Host machine cpu family: aarch64
> Host machine cpu: aarch64
> ...
> CFLAGS : -ggdb -g -O2
>
> I'm getting:
>
> ../../block/io.c:182:38: warning: reading variable 'bdrv_aio_preadv'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> drv->bdrv_aio_preadv ||
> ^
> ../../block/io.c:997:14: warning: reading variable 'bdrv_aio_preadv'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> if (drv->bdrv_aio_preadv) {
> ^
> ../../block/io.c:1003:20: warning: reading variable 'bdrv_aio_preadv'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> acb = drv->bdrv_aio_preadv(bs, offset, bytes, qiov, flags,
> ^
> ../../block/io.c:1076:14: warning: reading variable 'bdrv_aio_pwritev'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> if (drv->bdrv_aio_pwritev) {
> ^
> ../../block/io.c:1082:20: warning: reading variable 'bdrv_aio_pwritev'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> acb = drv->bdrv_aio_pwritev(bs, offset, bytes, qiov, flags,
> ^
> ../../block/io.c:2899:25: warning: reading variable 'bdrv_aio_flush'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> } else if (bs->drv->bdrv_aio_flush) {
> ^
> ../../block/io.c:2905:24: warning: reading variable 'bdrv_aio_flush'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
> ^
> ../../block/io.c:2991:49: warning: reading variable 'bdrv_aio_pdiscard'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> if (!bs->drv->bdrv_co_pdiscard && !bs->drv->bdrv_aio_pdiscard) {
> ^
> ../../block/io.c:3058:28: warning: reading variable 'bdrv_aio_pdiscard'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> acb = bs->drv->bdrv_aio_pdiscard(bs, offset, num,
> ^
> ../../block/io.c:3094:24: warning: reading variable 'bdrv_aio_ioctl'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
> ^
> ../../block/io.c:3102:20: warning: reading variable 'bdrv_aio_ioctl'
> requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
> acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete, &co);
> ^
> 11 warnings generated.
This can also reproduced in the gitlab-ci:
https://gitlab.com/thuth/qemu/-/jobs/3837884040#L2862
Peter, in case you also have a github account, could you maybe enable the
Cirrus-CI for your gitlab repo like it is explained here:
.gitlab-ci.d/cirrus/README.rst
?
Thanks,
Thomas
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PULL 00/29] Block layer patches
2023-02-27 9:12 ` Thomas Huth
@ 2023-02-27 11:22 ` Peter Maydell
0 siblings, 0 replies; 41+ messages in thread
From: Peter Maydell @ 2023-02-27 11:22 UTC (permalink / raw)
To: Thomas Huth
Cc: Philippe Mathieu-Daudé, Kevin Wolf, qemu-block, qemu-devel,
Emanuele Giuseppe Esposito
On Mon, 27 Feb 2023 at 09:12, Thomas Huth <thuth@redhat.com> wrote:
> Peter, in case you also have a github account, could you maybe enable the
> Cirrus-CI for your gitlab repo like it is explained here:
>
> .gitlab-ci.d/cirrus/README.rst
Sorry, no. The Cirrus-CI signup wants more permissions on
my github account than I am willing to give it.
thanks
-- PMM
^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2023-02-27 11:23 UTC | newest]
Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-03-06 17:14 [PULL 00/29] Block layer patches Kevin Wolf
2020-03-06 17:14 ` [PULL 01/29] qcow2: Fix alloc_cluster_abort() for pre-existing clusters Kevin Wolf
2020-03-06 17:14 ` [PULL 02/29] iotests/026: Test EIO on preallocated zero cluster Kevin Wolf
2020-03-06 17:14 ` [PULL 03/29] iotests/026: Test EIO on allocation in a data-file Kevin Wolf
2020-03-06 17:14 ` [PULL 04/29] block: Fix leak in bdrv_create_file_fallback() Kevin Wolf
2020-03-06 17:14 ` [PULL 05/29] block: Introduce 'bdrv_reopen_commit_post' step Kevin Wolf
2020-03-06 17:14 ` [PULL 06/29] block/qcow2: Move bitmap reopen into bdrv_reopen_commit_post Kevin Wolf
2020-03-06 17:14 ` [PULL 07/29] qemu-storage-daemon: Add barebone tool Kevin Wolf
2020-03-06 17:14 ` [PULL 08/29] stubs: Add arch_type Kevin Wolf
2020-03-06 17:14 ` [PULL 09/29] block: Move system emulator QMP commands to block/qapi-sysemu.c Kevin Wolf
2020-03-06 17:14 ` [PULL 10/29] block: Move common QMP commands to block-core QAPI module Kevin Wolf
2020-03-06 17:14 ` [PULL 11/29] block: Move sysemu QMP commands to QAPI block module Kevin Wolf
2020-03-06 17:14 ` [PULL 12/29] qemu-storage-daemon: Add --blockdev option Kevin Wolf
2020-03-06 17:14 ` [PULL 13/29] qapi: Flatten object-add Kevin Wolf
2020-07-08 15:48 ` Paolo Bonzini
2020-07-08 16:05 ` Kevin Wolf
2020-07-08 16:12 ` Paolo Bonzini
2020-07-09 10:26 ` Markus Armbruster
2020-03-06 17:14 ` [PULL 14/29] qemu-storage-daemon: Add --object option Kevin Wolf
2020-03-06 17:14 ` [PULL 15/29] qemu-storage-daemon: Add --nbd-server option Kevin Wolf
2020-03-06 17:14 ` [PULL 16/29] blockdev-nbd: Boxed argument type for nbd-server-add Kevin Wolf
2020-03-06 17:14 ` [PULL 17/29] qemu-storage-daemon: Add --export option Kevin Wolf
2020-03-06 17:14 ` [PULL 18/29] qemu-storage-daemon: Add main loop Kevin Wolf
2020-03-06 17:14 ` [PULL 19/29] qemu-storage-daemon: Add --chardev option Kevin Wolf
2020-03-06 17:14 ` [PULL 20/29] stubs: Update monitor stubs for qemu-storage-daemon Kevin Wolf
2020-03-06 17:14 ` [PULL 21/29] qapi: Create 'pragma' module Kevin Wolf
2020-03-06 17:14 ` [PULL 22/29] monitor: Create QAPIfied monitor_init() Kevin Wolf
2020-03-06 17:14 ` [PULL 23/29] qmp: Fail gracefully if chardev is already in use Kevin Wolf
2020-03-06 17:14 ` [PULL 24/29] hmp: " Kevin Wolf
2020-03-06 17:14 ` [PULL 25/29] monitor: Add allow_hmp parameter to monitor_init() Kevin Wolf
2020-03-06 17:14 ` [PULL 26/29] qemu-storage-daemon: Add --monitor option Kevin Wolf
2020-03-06 17:14 ` [PULL 27/29] block/rbd: Add support for ceph namespaces Kevin Wolf
2020-03-06 17:14 ` [PULL 28/29] iotests: Refactor blockdev-reopen test for iothreads Kevin Wolf
2020-03-06 17:14 ` [PULL 29/29] block: bdrv_reopen() with backing file in different AioContext Kevin Wolf
2020-03-06 19:16 ` [PULL 00/29] Block layer patches no-reply
2020-03-06 19:26 ` Peter Maydell
-- strict thread matches above, loose matches on Subject: below --
2023-02-23 18:51 Kevin Wolf
2023-02-24 18:50 ` Peter Maydell
2023-02-24 21:35 ` Philippe Mathieu-Daudé
2023-02-27 9:12 ` Thomas Huth
2023-02-27 11:22 ` Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).