diff options
-rw-r--r-- | block/file-posix.c | 1 | ||||
-rw-r--r-- | block/io_uring.c | 2 | ||||
-rw-r--r-- | block/quorum.c | 5 | ||||
-rw-r--r-- | chardev/char-stdio.c | 4 | ||||
-rw-r--r-- | qapi/char.json | 3 | ||||
-rwxr-xr-x | tests/qemu-iotests/081 | 61 | ||||
-rw-r--r-- | tests/qemu-iotests/081.out | 27 |
7 files changed, 94 insertions, 9 deletions
diff --git a/block/file-posix.c b/block/file-posix.c index c63926d592..d5fd1dbcd2 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1698,6 +1698,7 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque) switch (ret) { case -ENOTSUP: case -EINVAL: + case -EBUSY: break; default: return ret; diff --git a/block/io_uring.c b/block/io_uring.c index 037af09471..00a3ee9fb8 100644 --- a/block/io_uring.c +++ b/block/io_uring.c @@ -425,6 +425,6 @@ LuringState *luring_init(Error **errp) void luring_cleanup(LuringState *s) { io_uring_queue_exit(&s->ring); - g_free(s); trace_luring_cleanup_state(s); + g_free(s); } diff --git a/block/quorum.c b/block/quorum.c index e846a7e892..b10fc2089e 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -1163,7 +1163,12 @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { + BDRVQuorumState *s = bs->opaque; + *nperm = perm & DEFAULT_PERM_PASSTHROUGH; + if (s->rewrite_corrupted) { + *nperm |= BLK_PERM_WRITE; + } /* * We cannot share RESIZE or WRITE, as this would make the diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c index 82eaebc1db..403da308c9 100644 --- a/chardev/char-stdio.c +++ b/chardev/char-stdio.c @@ -112,9 +112,7 @@ static void qemu_chr_open_stdio(Chardev *chr, qemu_chr_open_fd(chr, 0, 1); - if (opts->has_signal) { - stdio_allow_signal = opts->signal; - } + stdio_allow_signal = !opts->has_signal || opts->signal; qemu_chr_set_echo_stdio(chr, false); } #endif diff --git a/qapi/char.json b/qapi/char.json index b4d66ec90b..43486d1daa 100644 --- a/qapi/char.json +++ b/qapi/char.json @@ -321,8 +321,7 @@ # Configuration info for stdio chardevs. # # @signal: Allow signals (such as SIGINT triggered by ^C) -# be delivered to qemu. Default: true in -nographic mode, -# false otherwise. +# be delivered to qemu. Default: true. # # Since: 1.5 ## diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081 index 537d40dfd5..4e19972931 100755 --- a/tests/qemu-iotests/081 +++ b/tests/qemu-iotests/081 @@ -42,18 +42,20 @@ _supported_fmt raw _supported_proto file _supported_os Linux _require_drivers quorum +_require_devices virtio-scsi do_run_qemu() { - echo Testing: "$@" | _filter_imgfmt + echo Testing: "$@" $QEMU -nographic -qmp stdio -serial none "$@" echo } run_qemu() { - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp\ - | _filter_qemu_io | _filter_generated_node_ids + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_imgfmt | _filter_qemu \ + | _filter_qmp | _filter_qemu_io \ + | _filter_generated_node_ids } quorum="driver=raw,file.driver=quorum,file.vote-threshold=2" @@ -155,6 +157,59 @@ echo "== checking that quorum has corrected the corrupted file ==" $QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io echo +echo "== using quorum rewrite corrupted mode without WRITE permission ==" + +# The same as above, but this time, do it on a quorum node whose only +# parent will not take the WRITE permission + +echo '-- corrupting --' +# Only corrupt a portion: The guest device (scsi-hd on virtio-scsi) +# will read some data (looking for a partition table to guess the +# disk's geometry), which would trigger a quorum mismatch if the +# beginning of the image was corrupted. The subsequent +# QUORUM_REPORT_BAD event would be suppressed (because at that point, +# there cannot have been a qmp_capabilities on the monitor). Because +# that event is rate-limited, the next QUORUM_REPORT_BAD that happens +# thanks to our qemu-io read (which should trigger a mismatch) would +# then be delayed past the VM quit and not appear in the output. +# So we keep the first 1M intact to see a QUORUM_REPORT_BAD resulting +# from the qemu-io invocation. +$QEMU_IO -c "write -P 0x42 1M 1M" "$TEST_DIR/2.raw" | _filter_qemu_io + +# Fix the corruption (on a read-only quorum node, i.e. without taking +# the WRITE permission on it -- its child nodes need to be R/W OTOH, +# so that rewrite-corrupted works) +echo +echo '-- running quorum --' +run_qemu \ + -blockdev file,node-name=file1,filename="$TEST_DIR/1.raw" \ + -blockdev file,node-name=file2,filename="$TEST_DIR/2.raw" \ + -blockdev file,node-name=file3,filename="$TEST_DIR/3.raw" \ + -blockdev '{ + "driver": "quorum", + "node-name": "quorum", + "read-only": true, + "vote-threshold": 2, + "rewrite-corrupted": true, + "children": [ "file1", "file2", "file3" ] + }' \ + -device virtio-scsi,id=scsi \ + -device scsi-hd,id=quorum-drive,bus=scsi.0,drive=quorum \ + <<EOF +{ "execute": "qmp_capabilities" } +{ + "execute": "human-monitor-command", + "arguments": { + "command-line": 'qemu-io -d quorum-drive "read -P 0x32 0 $size"' + } +} +{ "execute": "quit" } +EOF + +echo '-- checking that the image has been corrected --' +$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io + +echo echo "== breaking quorum ==" $QEMU_IO -c "write -P 0x41 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out index 04091b64e5..1974262fac 100644 --- a/tests/qemu-iotests/081.out +++ b/tests/qemu-iotests/081.out @@ -47,6 +47,33 @@ read 10485760/10485760 bytes at offset 0 read 10485760/10485760 bytes at offset 0 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +== using quorum rewrite corrupted mode without WRITE permission == +-- corrupting -- +wrote 1048576/1048576 bytes at offset 1048576 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +-- running quorum -- +Testing: -blockdev file,node-name=file1,filename=TEST_DIR/1.IMGFMT -blockdev file,node-name=file2,filename=TEST_DIR/2.IMGFMT -blockdev file,node-name=file3,filename=TEST_DIR/3.IMGFMT -blockdev { + "driver": "quorum", + "node-name": "quorum", + "read-only": true, + "vote-threshold": 2, + "rewrite-corrupted": true, + "children": [ "file1", "file2", "file3" ] + } -device virtio-scsi,id=scsi -device scsi-hd,id=quorum-drive,bus=scsi.0,drive=quorum +QMP_VERSION +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "QUORUM_REPORT_BAD", "data": {"node-name": "file2", "sectors-count": 20480, "sector-num": 0, "type": "read"}} +read 10485760/10485760 bytes at offset 0 +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{"return": ""} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} + +-- checking that the image has been corrected -- +read 10485760/10485760 bytes at offset 0 +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + == breaking quorum == wrote 10485760/10485760 bytes at offset 0 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |