qemu/block
Vladimir Sementsov-Ogievskiy 78632a3d16 monitor: hmp_qemu_io: acquire aio contex, fix crash
Max reported the following bug:

$ ./qemu-img create -f raw src.img 1G
$ ./qemu-img create -f raw dst.img 1G

$ (echo '
   {"execute":"qmp_capabilities"}
   {"execute":"blockdev-mirror",
    "arguments":{"job-id":"mirror",
                 "device":"source",
                 "target":"target",
                 "sync":"full",
                 "filter-node-name":"mirror-top"}}
'; sleep 3; echo '
   {"execute":"human-monitor-command",
    "arguments":{"command-line":
                 "qemu-io mirror-top \"write 0 1G\""}}') \
| x86_64-softmmu/qemu-system-x86_64 \
   -qmp stdio \
   -blockdev file,node-name=source,filename=src.img \
   -blockdev file,node-name=target,filename=dst.img \
   -object iothread,id=iothr0 \
   -device virtio-blk,drive=source,iothread=iothr0

crashes:

0  raise () at /usr/lib/libc.so.6
1  abort () at /usr/lib/libc.so.6
2  error_exit
   (err=<optimized out>,
   msg=msg@entry=0x55fbb1634790 <__func__.27> "qemu_mutex_unlock_impl")
   at ../util/qemu-thread-posix.c:37
3  qemu_mutex_unlock_impl
   (mutex=mutex@entry=0x55fbb25ab6e0,
   file=file@entry=0x55fbb1636957 "../util/async.c",
   line=line@entry=650)
   at ../util/qemu-thread-posix.c:109
4  aio_context_release (ctx=ctx@entry=0x55fbb25ab680) at ../util/async.c:650
5  bdrv_do_drained_begin
   (bs=bs@entry=0x55fbb3a87000, recursive=recursive@entry=false,
   parent=parent@entry=0x0,
   ignore_bds_parents=ignore_bds_parents@entry=false,
   poll=poll@entry=true) at ../block/io.c:441
6  bdrv_do_drained_begin
   (poll=true, ignore_bds_parents=false, parent=0x0, recursive=false,
   bs=0x55fbb3a87000) at ../block/io.c:448
7  blk_drain (blk=0x55fbb26c5a00) at ../block/block-backend.c:1718
8  blk_unref (blk=0x55fbb26c5a00) at ../block/block-backend.c:498
9  blk_unref (blk=0x55fbb26c5a00) at ../block/block-backend.c:491
10 hmp_qemu_io (mon=0x7fffaf3fc7d0, qdict=<optimized out>)
   at ../block/monitor/block-hmp-cmds.c:628

man pthread_mutex_unlock
...
    EPERM  The  mutex type is PTHREAD_MUTEX_ERRORCHECK or
    PTHREAD_MUTEX_RECURSIVE, or the mutex is a robust mutex, and the
    current thread does not own the mutex.

So, thread doesn't own the mutex. And we have iothread here.

Next, note that AIO_WAIT_WHILE() documents that ctx must be acquired
exactly once by caller. But where is it acquired in the call stack?
Seems nowhere.

qemuio_command do acquire aio context.. But we need context acquired
around blk_unref() as well and actually around blk_insert_bs() too.

Let's refactor qemuio_command so that it doesn't acquire aio context
but callers do that instead. This way we can cleanly acquire aio
context in hmp_qemu_io() around all three calls.

Reported-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20210423134233.51495-1-vsementsov@virtuozzo.com>
[mreitz: Fixed comment]
Signed-off-by: Max Reitz <mreitz@redhat.com>
2021-05-14 16:14:10 +02:00
..
export block/export: disable VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD for now 2021-03-19 10:15:06 +01:00
monitor monitor: hmp_qemu_io: acquire aio contex, fix crash 2021-05-14 16:14:10 +02:00
accounting.c block/accounting: Use lock guard macros 2020-12-11 17:52:39 +01:00
aio_task.c block: introduce aio task pool 2019-10-10 10:56:17 +02:00
amend.c block/amend: Check whether the node exists 2020-07-27 12:37:25 +02:00
backup-top.c block/backup-top: drop .active 2021-04-30 12:27:48 +02:00
backup-top.h qapi: backup: add perf.use-copy-range parameter 2021-01-26 14:36:37 +01:00
backup.c backup: Remove nodes from job in .clean() 2021-03-08 14:55:18 +01:00
blkdebug.c block: check return value of bdrv_open_child and drop error propagation 2021-03-08 15:07:09 -06:00
blklogwrites.c block: check return value of bdrv_open_child and drop error propagation 2021-03-08 15:07:09 -06:00
blkreplay.c block: check return value of bdrv_open_child and drop error propagation 2021-03-08 15:07:09 -06:00
blkverify.c block: check return value of bdrv_open_child and drop error propagation 2021-03-08 15:07:09 -06:00
block-backend.c Do not include sysemu/sysemu.h if it's not really necessary 2021-05-02 17:24:50 +02:00
block-copy.c ratelimit: protect with a mutex 2021-05-04 14:15:35 +02:00
block-gen.h scripts: add block-coroutine-wrapper.py 2020-10-05 10:59:06 +01:00
bochs.c block: Use bdrv_default_perms() 2020-05-18 19:05:25 +02:00
cloop.c block: Use bdrv_default_perms() 2020-05-18 19:05:25 +02:00
commit.c block: bdrv_append(): don't consume reference 2021-04-30 12:27:47 +02:00
copy-on-read.c copy-on-read: skip non-guest reads if no copy needed 2021-01-26 14:36:37 +01:00
copy-on-read.h copy-on-read: add filter drop function 2021-01-26 11:26:54 +01:00
coroutines.h block: Return depth level during bdrv_is_allocated_above 2020-10-30 15:21:23 -05:00
create.c block/create: Do not abort if a block driver is not available 2019-09-13 12:18:37 +02:00
crypto.c block: add bdrv_co_delete_file_noerr 2021-02-15 15:10:14 +01:00
crypto.h nomaintainer: Fix Lesser GPL version number 2020-11-15 17:04:40 +01:00
curl.c curl: Disconnect sockets from CURLState 2021-03-19 10:15:06 +01:00
dirty-bitmap.c block: remove dirty bitmaps 'status' field 2021-03-18 09:22:55 +00:00
dmg-bz2.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
dmg-lzfse.c block: Remove unused include 2020-11-09 15:44:21 +01:00
dmg.c block: Fix some code style problems, "foo* bar" should be "foo *bar" 2020-11-09 18:42:47 +01:00
dmg.h Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
file-posix.c block: bdrv_reopen_multiple: refresh permissions on updated graph 2021-04-30 12:27:48 +02:00
file-win32.c block/file: switch to use qemu_open/qemu_create for improved errors 2020-09-16 10:33:48 +01:00
filter-compress.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
gluster.c qapi: More complex uses of QAPI_LIST_APPEND 2021-01-28 08:08:45 +01:00
io_uring.c io_uring: do not use pointer after free 2020-11-17 12:26:48 +01:00
io.c block: make bdrv_refresh_limits() to be a transaction action 2021-04-30 12:27:48 +02:00
iscsi-opts.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
iscsi.c Remove superfluous timer_del() calls 2021-01-08 15:13:38 +00:00
linux-aio.c misc: Replace zero-length arrays with flexible array member (automatic) 2020-03-16 22:07:42 +01:00
meson.build block: Drop the sheepdog block driver 2021-05-12 17:42:23 +02:00
mirror.c block: bdrv_append(): don't consume reference 2021-04-30 12:27:47 +02:00
nbd.c block/nbd: fix possible use after free of s->connect_thread 2021-04-13 15:35:12 +02:00
nfs.c Do not include sysemu/sysemu.h if it's not really necessary 2021-05-02 17:24:50 +02:00
null.c block/null: Implement bdrv_get_allocated_file_size 2020-09-07 12:31:31 +02:00
nvme.c block/nvme: Trace NVMe spec version supported by the controller 2021-02-02 17:05:38 +01:00
parallels-ext.c parallels: support bitmap extension for read-only mode 2021-03-08 14:56:55 +01:00
parallels.c parallels: support bitmap extension for read-only mode 2021-03-08 14:56:55 +01:00
parallels.h parallels: support bitmap extension for read-only mode 2021-03-08 14:56:55 +01:00
preallocate.c block: introduce preallocate filter 2020-12-18 12:35:55 +01:00
qapi-sysemu.c block: Move system emulator QMP commands to block/qapi-sysemu.c 2020-03-06 17:15:38 +01:00
qapi.c block: remove 'dirty-bitmaps' field from 'BlockInfo' struct 2021-03-18 09:22:55 +00:00
qcow2-bitmap.c nbd patches for 2021-03-09 2021-03-11 13:57:08 +00:00
qcow2-cache.c core: replace getpagesize() with qemu_real_host_page_size 2019-10-26 15:38:06 +02:00
qcow2-cluster.c qcow2: Fix corruption on write_zeroes with MAY_UNMAP 2020-11-24 11:29:41 +01:00
qcow2-refcount.c qcow2: Make qcow2_free_any_clusters() free only one cluster 2020-09-15 11:05:13 +02:00
qcow2-snapshot.c migration: introduce icount field for snapshots 2020-10-06 08:34:49 +02:00
qcow2-threads.c qcow2: add zstd cluster compression 2020-05-13 14:20:31 +02:00
qcow2.c qcow2: Force preallocation with data-file-raw 2021-03-30 13:02:10 +02:00
qcow2.h block/qcow2-bitmap: return status from qcow2_store_persistent_dirty_bitmaps 2021-03-08 16:03:21 -06:00
qcow.c block/qcow: remove runtime opts 2020-09-15 11:05:13 +02:00
qed-check.c block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
qed-cluster.c
qed-l2-cache.c
qed-table.c block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
qed.c block/qed: bdrv_qed_do_open: deal with errp 2021-03-08 16:03:32 -06:00
qed.h qed: Simplify backing reads 2020-07-06 10:34:14 +02:00
quorum.c block: check return value of bdrv_open_child and drop error propagation 2021-03-08 15:07:09 -06:00
raw-format.c block/raw-format: implement .bdrv_cancel_in_flight handler 2021-02-12 09:45:18 -06:00
rbd.c block/rbd: Add an escape-aware strchr helper 2021-05-14 16:14:10 +02:00
replication.c qapi: backup: add max-chunk and max-workers to x-perf struct 2021-01-26 14:36:37 +01:00
snapshot.c block: rename and alter bdrv_all_find_snapshot semantics 2021-02-08 11:19:51 +00:00
ssh.c qapi: Smooth another visitor error checking pattern 2020-07-10 15:18:08 +02:00
stream.c stream: Don't crash when node permission is denied 2021-03-19 10:15:06 +01:00
throttle-groups.c block/throttle-groups: throttle_group_co_io_limits_intercept(): 64bit bytes 2021-02-03 08:14:00 -06:00
throttle.c qemu/atomic.h: rename atomic_ to qatomic_ 2020-09-23 16:07:44 +01:00
trace-events block: Drop the sheepdog block driver 2021-05-12 17:42:23 +02:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
vdi.c block/vdi: Don't assume that blocks are larger than VdiHeader 2021-03-31 10:44:21 +01:00
vhdx-endian.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
vhdx-log.c block: Add flags to bdrv(_co)_truncate() 2020-04-30 17:51:07 +02:00
vhdx.c block/vhdx: Support vhdx image only with 512 bytes logical sector size 2020-09-15 11:05:13 +02:00
vhdx.h block/vhdx: Use IEC binary prefixes for size constants 2019-04-30 15:29:00 +02:00
vmdk.c qapi: Use QAPI_LIST_APPEND in trivial cases 2021-01-28 08:08:45 +01:00
vpc.c block/vpc: Use sizeof() instead of HEADER_SIZE for footer size 2020-12-18 12:43:30 +01:00
vvfat.c block/vvfat: Fix bad printf format specifiers 2020-11-03 16:24:56 +01:00
win32-aio.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
write-threshold.c qapi: Drop qapi_event_send_FOO()'s Error ** argument 2018-08-28 18:21:38 +02:00