1 | The following changes since commit 7bc8f9734213b76e76631a483be13d6737c2adbc: | 1 | The following changes since commit ee59483267de29056b5b2ee2421ef3844e5c9932: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20191025' into staging (2019-10-25 13:12:16 +0100) | 3 | Merge tag 'qemu-openbios-20230307' of https://github.com/mcayland/qemu into staging (2023-03-09 16:55:03 +0000) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | git://repo.or.cz/qemu/kevin.git tags/for-upstream | 7 | https://repo.or.cz/qemu/kevin.git tags/for-upstream |
8 | 8 | ||
9 | for you to fetch changes up to 5e9785505210e2477e590e61b1ab100d0ec22b01: | 9 | for you to fetch changes up to ecf8191314798391b1df80bcb829c0ead4f8acc9: |
10 | 10 | ||
11 | qcow2: Fix corruption bug in qcow2_detect_metadata_preallocation() (2019-10-25 15:18:55 +0200) | 11 | qed: remove spurious BDRV_POLL_WHILE() (2023-03-10 15:14:46 +0100) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block layer patches: | 14 | Block layer patches |
15 | 15 | ||
16 | - qcow2: Fix data corruption bug that is triggered in partial cluster | 16 | - fuse: Fix fallocate(PUNCH_HOLE) to zero out the range |
17 | allocation with default options | 17 | - qed: remove spurious BDRV_POLL_WHILE() |
18 | - qapi: add support for blkreplay driver | ||
19 | - doc: Describe missing generic -blockdev options | ||
20 | - iotests: Fix 118 when run as root | ||
21 | - Minor code cleanups | ||
22 | 18 | ||
23 | ---------------------------------------------------------------- | 19 | ---------------------------------------------------------------- |
24 | Kevin Wolf (5): | 20 | Hanna Czenczek (2): |
25 | iotests: Skip read-only cases in 118 when run as root | 21 | block/fuse: Let PUNCH_HOLE write zeroes |
26 | blockdev: Use error_report() in hmp_commit() | 22 | iotests/308: Add test for 'write -zu' |
27 | doc: Describe missing generic -blockdev options | ||
28 | coroutine: Add qemu_co_mutex_assert_locked() | ||
29 | qcow2: Fix corruption bug in qcow2_detect_metadata_preallocation() | ||
30 | 23 | ||
31 | Pavel Dovgaluk (1): | 24 | Stefan Hajnoczi (1): |
32 | qapi: add support for blkreplay driver | 25 | qed: remove spurious BDRV_POLL_WHILE() |
33 | 26 | ||
34 | Vladimir Sementsov-Ogievskiy (1): | 27 | block/export/fuse.c | 11 ++++++++++- |
35 | block/backup: drop dead code from backup_job_create | 28 | block/qed.c | 1 - |
36 | 29 | tests/qemu-iotests/308 | 43 +++++++++++++++++++++++++++++++++++++++++++ | |
37 | qapi/block-core.json | 18 ++++++++++++++++-- | 30 | tests/qemu-iotests/308.out | 35 +++++++++++++++++++++++++++++++++++ |
38 | include/qemu/coroutine.h | 15 +++++++++++++++ | 31 | 4 files changed, 88 insertions(+), 2 deletions(-) |
39 | block/backup.c | 5 +---- | ||
40 | block/qcow2-refcount.c | 2 ++ | ||
41 | block/qcow2.c | 3 ++- | ||
42 | blockdev.c | 7 +++---- | ||
43 | qemu-options.hx | 22 +++++++++++++++++++++- | ||
44 | tests/qemu-iotests/118 | 3 +++ | ||
45 | tests/qemu-iotests/iotests.py | 10 ++++++++++ | ||
46 | 9 files changed, 73 insertions(+), 12 deletions(-) | ||
47 | |||
48 | diff view generated by jsdifflib |
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 1 | From: Hanna Czenczek <hreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | After commit 00e30f05de1d195, there is no more "goto error" points | 3 | fallocate(2) says about PUNCH_HOLE: "After a successful call, subsequent |
4 | after job creation, so after "error:" @job is always NULL and we don't | 4 | reads from this range will return zeros." As it is, PUNCH_HOLE is |
5 | need roll-back job creation. | 5 | implemented as a call to blk_pdiscard(), which does not guarantee this. |
6 | 6 | ||
7 | Reported-by: Coverity (CID 1406402) | 7 | We must call blk_pwrite_zeroes() instead. The difference to ZERO_RANGE |
8 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 8 | is that we pass the `BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK` flags to |
9 | Acked-by: Stefano Garzarella <sgarzare@redhat.com> | 9 | the call -- the storage is supposed to be unmapped, and a slow fallback |
10 | by actually writing zeroes as data is not allowed. | ||
11 | |||
12 | Closes: https://gitlab.com/qemu-project/qemu/-/issues/1507 | ||
13 | Signed-off-by: Hanna Czenczek <hreitz@redhat.com> | ||
14 | Message-Id: <20230227104725.33511-2-hreitz@redhat.com> | ||
15 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 16 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
11 | --- | 17 | --- |
12 | block/backup.c | 5 +---- | 18 | block/export/fuse.c | 11 ++++++++++- |
13 | 1 file changed, 1 insertion(+), 4 deletions(-) | 19 | 1 file changed, 10 insertions(+), 1 deletion(-) |
14 | 20 | ||
15 | diff --git a/block/backup.c b/block/backup.c | 21 | diff --git a/block/export/fuse.c b/block/export/fuse.c |
16 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/block/backup.c | 23 | --- a/block/export/fuse.c |
18 | +++ b/block/backup.c | 24 | +++ b/block/export/fuse.c |
19 | @@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, | 25 | @@ -XXX,XX +XXX,XX @@ static void fuse_fallocate(fuse_req_t req, fuse_ino_t inode, int mode, |
20 | if (sync_bitmap) { | 26 | do { |
21 | bdrv_reclaim_dirty_bitmap(sync_bitmap, NULL); | 27 | int size = MIN(length, BDRV_REQUEST_MAX_BYTES); |
22 | } | 28 | |
23 | - if (job) { | 29 | - ret = blk_pdiscard(exp->common.blk, offset, size); |
24 | - backup_clean(&job->common.job); | 30 | + ret = blk_pwrite_zeroes(exp->common.blk, offset, size, |
25 | - job_early_fail(&job->common.job); | 31 | + BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK); |
26 | - } else if (backup_top) { | 32 | + if (ret == -ENOTSUP) { |
27 | + if (backup_top) { | 33 | + /* |
28 | bdrv_backup_top_drop(backup_top); | 34 | + * fallocate() specifies to return EOPNOTSUPP for unsupported |
29 | } | 35 | + * operations |
30 | 36 | + */ | |
37 | + ret = -EOPNOTSUPP; | ||
38 | + } | ||
39 | + | ||
40 | offset += size; | ||
41 | length -= size; | ||
42 | } while (ret == 0 && length > 0); | ||
31 | -- | 43 | -- |
32 | 2.20.1 | 44 | 2.39.2 |
33 | |||
34 | diff view generated by jsdifflib |
1 | From: Pavel Dovgalyuk <pavel.dovgaluk@gmail.com> | 1 | From: Hanna Czenczek <hreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | This patch adds support for blkreplay driver to the blockdev options. | 3 | Try writing zeroes to a FUSE export while allowing the area to be |
4 | Now blkreplay can be used with -blockdev command line option | 4 | unmapped; block/file-posix.c generally implements writing zeroes with |
5 | in the following format: | 5 | BDRV_REQ_MAY_UNMAP ('write -zu') by calling fallocate(PUNCH_HOLE). This |
6 | -blockdev driver=blkreplay,image=file-node-name,node-name=replay-node-name | 6 | used to lead to a blk_pdiscard() in the FUSE export, which may or may |
7 | not lead to the area being zeroed. HEAD^ fixed this to use | ||
8 | blk_pwrite_zeroes() instead (again with BDRV_REQ_MAY_UNMAP), so verify | ||
9 | that running `qemu-io 'write -zu'` on a FUSE exports always results in | ||
10 | zeroes being written. | ||
7 | 11 | ||
8 | This option makes possible implementation of the better command | 12 | Signed-off-by: Hanna Czenczek <hreitz@redhat.com> |
9 | line support for record/replay invocations. | 13 | Message-Id: <20230227104725.33511-3-hreitz@redhat.com> |
10 | 14 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | |
11 | Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> | ||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
13 | --- | 16 | --- |
14 | qapi/block-core.json | 18 ++++++++++++++++-- | 17 | tests/qemu-iotests/308 | 43 ++++++++++++++++++++++++++++++++++++++ |
15 | 1 file changed, 16 insertions(+), 2 deletions(-) | 18 | tests/qemu-iotests/308.out | 35 +++++++++++++++++++++++++++++++ |
19 | 2 files changed, 78 insertions(+) | ||
16 | 20 | ||
17 | diff --git a/qapi/block-core.json b/qapi/block-core.json | 21 | diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308 |
22 | index XXXXXXX..XXXXXXX 100755 | ||
23 | --- a/tests/qemu-iotests/308 | ||
24 | +++ b/tests/qemu-iotests/308 | ||
25 | @@ -XXX,XX +XXX,XX @@ echo | ||
26 | echo '=== Compare copy with original ===' | ||
27 | |||
28 | $QEMU_IMG compare -f raw -F $IMGFMT "$COPIED_IMG" "$TEST_IMG" | ||
29 | +_cleanup_test_img | ||
30 | + | ||
31 | +echo | ||
32 | +echo '=== Writing zeroes while unmapping ===' | ||
33 | +# Regression test for https://gitlab.com/qemu-project/qemu/-/issues/1507 | ||
34 | +_make_test_img 64M | ||
35 | +$QEMU_IO -c 'write -s /dev/urandom 0 64M' "$TEST_IMG" | _filter_qemu_io | ||
36 | + | ||
37 | +_launch_qemu | ||
38 | +_send_qemu_cmd $QEMU_HANDLE \ | ||
39 | + "{'execute': 'qmp_capabilities'}" \ | ||
40 | + 'return' | ||
41 | + | ||
42 | +_send_qemu_cmd $QEMU_HANDLE \ | ||
43 | + "{'execute': 'blockdev-add', | ||
44 | + 'arguments': { | ||
45 | + 'driver': '$IMGFMT', | ||
46 | + 'node-name': 'node-format', | ||
47 | + 'file': { | ||
48 | + 'driver': 'file', | ||
49 | + 'filename': '$TEST_IMG' | ||
50 | + } | ||
51 | + } }" \ | ||
52 | + 'return' | ||
53 | + | ||
54 | +fuse_export_add 'export' "'mountpoint': '$EXT_MP', 'writable': true" | ||
55 | + | ||
56 | +# Try writing zeroes by unmapping | ||
57 | +$QEMU_IO -f raw -c 'write -zu 0 64M' "$EXT_MP" | _filter_qemu_io | ||
58 | + | ||
59 | +# Check the result | ||
60 | +$QEMU_IO -f raw -c 'read -P 0 0 64M' "$EXT_MP" | _filter_qemu_io | ||
61 | + | ||
62 | +_send_qemu_cmd $QEMU_HANDLE \ | ||
63 | + "{'execute': 'quit'}" \ | ||
64 | + 'return' | ||
65 | + | ||
66 | +wait=yes _cleanup_qemu | ||
67 | + | ||
68 | +# Check the original image | ||
69 | +$QEMU_IO -c 'read -P 0 0 64M' "$TEST_IMG" | _filter_qemu_io | ||
70 | + | ||
71 | +_cleanup_test_img | ||
72 | |||
73 | # success, all done | ||
74 | echo "*** done" | ||
75 | diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out | ||
18 | index XXXXXXX..XXXXXXX 100644 | 76 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/qapi/block-core.json | 77 | --- a/tests/qemu-iotests/308.out |
20 | +++ b/qapi/block-core.json | 78 | +++ b/tests/qemu-iotests/308.out |
21 | @@ -XXX,XX +XXX,XX @@ | 79 | @@ -XXX,XX +XXX,XX @@ OK: Post-truncate image size is as expected |
22 | # @nvme: Since 2.12 | 80 | |
23 | # @copy-on-read: Since 3.0 | 81 | === Compare copy with original === |
24 | # @blklogwrites: Since 3.0 | 82 | Images are identical. |
25 | +# @blkreplay: Since 4.2 | ||
26 | # | ||
27 | # Since: 2.9 | ||
28 | ## | ||
29 | { 'enum': 'BlockdevDriver', | ||
30 | - 'data': [ 'blkdebug', 'blklogwrites', 'blkverify', 'bochs', 'cloop', | ||
31 | - 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps', 'gluster', | ||
32 | + 'data': [ 'blkdebug', 'blklogwrites', 'blkreplay', 'blkverify', 'bochs', | ||
33 | + 'cloop', 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps', 'gluster', | ||
34 | 'host_cdrom', 'host_device', 'http', 'https', 'iscsi', 'luks', | ||
35 | 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels', 'qcow', | ||
36 | 'qcow2', 'qed', 'quorum', 'raw', 'rbd', | ||
37 | @@ -XXX,XX +XXX,XX @@ | ||
38 | 'data': { 'test': 'BlockdevRef', | ||
39 | 'raw': 'BlockdevRef' } } | ||
40 | |||
41 | +## | ||
42 | +# @BlockdevOptionsBlkreplay: | ||
43 | +# | ||
44 | +# Driver specific block device options for blkreplay. | ||
45 | +# | ||
46 | +# @image: disk image which should be controlled with blkreplay | ||
47 | +# | ||
48 | +# Since: 4.2 | ||
49 | +## | ||
50 | +{ 'struct': 'BlockdevOptionsBlkreplay', | ||
51 | + 'data': { 'image': 'BlockdevRef' } } | ||
52 | + | 83 | + |
53 | ## | 84 | +=== Writing zeroes while unmapping === |
54 | # @QuorumReadPattern: | 85 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 |
55 | # | 86 | +wrote 67108864/67108864 bytes at offset 0 |
56 | @@ -XXX,XX +XXX,XX @@ | 87 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
57 | 'blkdebug': 'BlockdevOptionsBlkdebug', | 88 | +{'execute': 'qmp_capabilities'} |
58 | 'blklogwrites':'BlockdevOptionsBlklogwrites', | 89 | +{"return": {}} |
59 | 'blkverify': 'BlockdevOptionsBlkverify', | 90 | +{'execute': 'blockdev-add', |
60 | + 'blkreplay': 'BlockdevOptionsBlkreplay', | 91 | + 'arguments': { |
61 | 'bochs': 'BlockdevOptionsGenericFormat', | 92 | + 'driver': 'IMGFMT', |
62 | 'cloop': 'BlockdevOptionsGenericFormat', | 93 | + 'node-name': 'node-format', |
63 | 'copy-on-read':'BlockdevOptionsGenericFormat', | 94 | + 'file': { |
95 | + 'driver': 'file', | ||
96 | + 'filename': 'TEST_DIR/t.IMGFMT' | ||
97 | + } | ||
98 | + } } | ||
99 | +{"return": {}} | ||
100 | +{'execute': 'block-export-add', | ||
101 | + 'arguments': { | ||
102 | + 'type': 'fuse', | ||
103 | + 'id': 'export', | ||
104 | + 'node-name': 'node-format', | ||
105 | + 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true | ||
106 | + } } | ||
107 | +{"return": {}} | ||
108 | +wrote 67108864/67108864 bytes at offset 0 | ||
109 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
110 | +read 67108864/67108864 bytes at offset 0 | ||
111 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
112 | +{'execute': 'quit'} | ||
113 | +{"return": {}} | ||
114 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} | ||
115 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export"}} | ||
116 | +read 67108864/67108864 bytes at offset 0 | ||
117 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
118 | *** done | ||
64 | -- | 119 | -- |
65 | 2.20.1 | 120 | 2.39.2 |
66 | |||
67 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Some tests in 118 use chmod to remove write permissions from the file | ||
2 | and assume that the image can indeed not be opened read-write | ||
3 | afterwards. This doesn't work when the test is run as root, because root | ||
4 | can still open the file as writable even when the permission bit isn't | ||
5 | set. | ||
6 | 1 | ||
7 | Introduce a @skip_if_root decorator and use it in 118 to skip the tests | ||
8 | in question when the script is run as root. | ||
9 | |||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
12 | --- | ||
13 | tests/qemu-iotests/118 | 3 +++ | ||
14 | tests/qemu-iotests/iotests.py | 10 ++++++++++ | ||
15 | 2 files changed, 13 insertions(+) | ||
16 | |||
17 | diff --git a/tests/qemu-iotests/118 b/tests/qemu-iotests/118 | ||
18 | index XXXXXXX..XXXXXXX 100755 | ||
19 | --- a/tests/qemu-iotests/118 | ||
20 | +++ b/tests/qemu-iotests/118 | ||
21 | @@ -XXX,XX +XXX,XX @@ class TestChangeReadOnly(ChangeBaseClass): | ||
22 | self.assert_qmp(result, 'return[0]/inserted/ro', True) | ||
23 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | ||
24 | |||
25 | + @iotests.skip_if_user_is_root | ||
26 | def test_rw_ro_retain(self): | ||
27 | os.chmod(new_img, 0o444) | ||
28 | self.vm.add_drive(old_img, 'media=disk', 'none') | ||
29 | @@ -XXX,XX +XXX,XX @@ class TestChangeReadOnly(ChangeBaseClass): | ||
30 | self.assert_qmp(result, 'return[0]/inserted/ro', True) | ||
31 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | ||
32 | |||
33 | + @iotests.skip_if_user_is_root | ||
34 | def test_make_ro_rw(self): | ||
35 | os.chmod(new_img, 0o444) | ||
36 | self.vm.add_drive(old_img, 'media=disk', 'none') | ||
37 | @@ -XXX,XX +XXX,XX @@ class TestChangeReadOnly(ChangeBaseClass): | ||
38 | self.assert_qmp(result, 'return[0]/inserted/ro', True) | ||
39 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | ||
40 | |||
41 | + @iotests.skip_if_user_is_root | ||
42 | def test_make_ro_rw_by_retain(self): | ||
43 | os.chmod(new_img, 0o444) | ||
44 | self.vm.add_drive(old_img, 'media=disk', 'none') | ||
45 | diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py | ||
46 | index XXXXXXX..XXXXXXX 100644 | ||
47 | --- a/tests/qemu-iotests/iotests.py | ||
48 | +++ b/tests/qemu-iotests/iotests.py | ||
49 | @@ -XXX,XX +XXX,XX @@ def skip_if_unsupported(required_formats=[], read_only=False): | ||
50 | return func_wrapper | ||
51 | return skip_test_decorator | ||
52 | |||
53 | +def skip_if_user_is_root(func): | ||
54 | + '''Skip Test Decorator | ||
55 | + Runs the test only without root permissions''' | ||
56 | + def func_wrapper(*args, **kwargs): | ||
57 | + if os.getuid() == 0: | ||
58 | + case_notrun('{}: cannot be run as root'.format(args[0])) | ||
59 | + else: | ||
60 | + return func(*args, **kwargs) | ||
61 | + return func_wrapper | ||
62 | + | ||
63 | def execute_unittest(output, verbosity, debug): | ||
64 | runner = unittest.TextTestRunner(stream=output, descriptions=True, | ||
65 | verbosity=verbosity) | ||
66 | -- | ||
67 | 2.20.1 | ||
68 | |||
69 | diff view generated by jsdifflib |
1 | Instead of using monitor_printf() to report errors, hmp_commit() should | 1 | From: Stefan Hajnoczi <stefanha@redhat.com> |
---|---|---|---|
2 | use error_report() like other places do. | ||
3 | 2 | ||
3 | This looks like a copy-paste or merge error. BDRV_POLL_WHILE() is | ||
4 | already called above. It's not needed in the qemu_in_coroutine() case. | ||
5 | |||
6 | Fixes: 9fb4dfc570ce ("qed: make bdrv_qed_do_open a coroutine_fn") | ||
7 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
8 | Message-Id: <20230309163134.398707-1-stefanha@redhat.com> | ||
9 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
5 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
6 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
7 | --- | 11 | --- |
8 | blockdev.c | 7 +++---- | 12 | block/qed.c | 1 - |
9 | 1 file changed, 3 insertions(+), 4 deletions(-) | 13 | 1 file changed, 1 deletion(-) |
10 | 14 | ||
11 | diff --git a/blockdev.c b/blockdev.c | 15 | diff --git a/block/qed.c b/block/qed.c |
12 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/blockdev.c | 17 | --- a/block/qed.c |
14 | +++ b/blockdev.c | 18 | +++ b/block/qed.c |
15 | @@ -XXX,XX +XXX,XX @@ void hmp_commit(Monitor *mon, const QDict *qdict) | 19 | @@ -XXX,XX +XXX,XX @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags, |
16 | 20 | qemu_coroutine_enter(qemu_coroutine_create(bdrv_qed_open_entry, &qoc)); | |
17 | blk = blk_by_name(device); | 21 | BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS); |
18 | if (!blk) { | ||
19 | - monitor_printf(mon, "Device '%s' not found\n", device); | ||
20 | + error_report("Device '%s' not found", device); | ||
21 | return; | ||
22 | } | ||
23 | if (!blk_is_available(blk)) { | ||
24 | - monitor_printf(mon, "Device '%s' has no medium\n", device); | ||
25 | + error_report("Device '%s' has no medium", device); | ||
26 | return; | ||
27 | } | ||
28 | |||
29 | @@ -XXX,XX +XXX,XX @@ void hmp_commit(Monitor *mon, const QDict *qdict) | ||
30 | aio_context_release(aio_context); | ||
31 | } | 22 | } |
32 | if (ret < 0) { | 23 | - BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS); |
33 | - monitor_printf(mon, "'commit' error for '%s': %s\n", device, | 24 | return qoc.ret; |
34 | - strerror(-ret)); | ||
35 | + error_report("'commit' error for '%s': %s", device, strerror(-ret)); | ||
36 | } | ||
37 | } | 25 | } |
38 | 26 | ||
39 | -- | 27 | -- |
40 | 2.20.1 | 28 | 2.39.2 |
41 | |||
42 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | We added more generic options after introducing -blockdev and forgot to | ||
2 | update the documentation (man page and --help output) accordingly. Do | ||
3 | that now. | ||
4 | 1 | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
7 | --- | ||
8 | qemu-options.hx | 22 +++++++++++++++++++++- | ||
9 | 1 file changed, 21 insertions(+), 1 deletion(-) | ||
10 | |||
11 | diff --git a/qemu-options.hx b/qemu-options.hx | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/qemu-options.hx | ||
14 | +++ b/qemu-options.hx | ||
15 | @@ -XXX,XX +XXX,XX @@ ETEXI | ||
16 | DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev, | ||
17 | "-blockdev [driver=]driver[,node-name=N][,discard=ignore|unmap]\n" | ||
18 | " [,cache.direct=on|off][,cache.no-flush=on|off]\n" | ||
19 | - " [,read-only=on|off][,detect-zeroes=on|off|unmap]\n" | ||
20 | + " [,read-only=on|off][,auto-read-only=on|off]\n" | ||
21 | + " [,force-share=on|off][,detect-zeroes=on|off|unmap]\n" | ||
22 | " [,driver specific parameters...]\n" | ||
23 | " configure a block backend\n", QEMU_ARCH_ALL) | ||
24 | STEXI | ||
25 | @@ -XXX,XX +XXX,XX @@ name is not intended to be predictable and changes between QEMU invocations. | ||
26 | For the top level, an explicit node name must be specified. | ||
27 | @item read-only | ||
28 | Open the node read-only. Guest write attempts will fail. | ||
29 | + | ||
30 | +Note that some block drivers support only read-only access, either generally or | ||
31 | +in certain configurations. In this case, the default value | ||
32 | +@option{read-only=off} does not work and the option must be specified | ||
33 | +explicitly. | ||
34 | +@item auto-read-only | ||
35 | +If @option{auto-read-only=on} is set, QEMU may fall back to read-only usage | ||
36 | +even when @option{read-only=off} is requested, or even switch between modes as | ||
37 | +needed, e.g. depending on whether the image file is writable or whether a | ||
38 | +writing user is attached to the node. | ||
39 | +@item force-share | ||
40 | +Override the image locking system of QEMU by forcing the node to utilize | ||
41 | +weaker shared access for permissions where it would normally request exclusive | ||
42 | +access. When there is the potential for multiple instances to have the same | ||
43 | +file open (whether this invocation of QEMU is the first or the second | ||
44 | +instance), both instances must permit shared access for the second instance to | ||
45 | +succeed at opening the file. | ||
46 | + | ||
47 | +Enabling @option{force-share=on} requires @option{read-only=on}. | ||
48 | @item cache.direct | ||
49 | The host page cache can be avoided with @option{cache.direct=on}. This will | ||
50 | attempt to do disk IO directly to the guest's memory. QEMU may still perform an | ||
51 | -- | ||
52 | 2.20.1 | ||
53 | |||
54 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Some functions require that the caller holds a certain CoMutex for them | ||
2 | to operate correctly. Add a function so that they can assert the lock is | ||
3 | really held. | ||
4 | 1 | ||
5 | Cc: qemu-stable@nongnu.org | ||
6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
7 | Tested-by: Michael Weiser <michael.weiser@gmx.de> | ||
8 | Reviewed-by: Michael Weiser <michael.weiser@gmx.de> | ||
9 | Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
10 | Reviewed-by: Denis V. Lunev <den@openvz.org> | ||
11 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | include/qemu/coroutine.h | 15 +++++++++++++++ | ||
14 | 1 file changed, 15 insertions(+) | ||
15 | |||
16 | diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/include/qemu/coroutine.h | ||
19 | +++ b/include/qemu/coroutine.h | ||
20 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex); | ||
21 | */ | ||
22 | void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex); | ||
23 | |||
24 | +/** | ||
25 | + * Assert that the current coroutine holds @mutex. | ||
26 | + */ | ||
27 | +static inline coroutine_fn void qemu_co_mutex_assert_locked(CoMutex *mutex) | ||
28 | +{ | ||
29 | + /* | ||
30 | + * mutex->holder doesn't need any synchronisation if the assertion holds | ||
31 | + * true because the mutex protects it. If it doesn't hold true, we still | ||
32 | + * don't mind if another thread takes or releases mutex behind our back, | ||
33 | + * because the condition will be false no matter whether we read NULL or | ||
34 | + * the pointer for any other coroutine. | ||
35 | + */ | ||
36 | + assert(atomic_read(&mutex->locked) && | ||
37 | + mutex->holder == qemu_coroutine_self()); | ||
38 | +} | ||
39 | |||
40 | /** | ||
41 | * CoQueues are a mechanism to queue coroutines in order to continue executing | ||
42 | -- | ||
43 | 2.20.1 | ||
44 | |||
45 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | qcow2_detect_metadata_preallocation() calls qcow2_get_refcount() which | ||
2 | requires s->lock to be taken to protect its accesses to the refcount | ||
3 | table and refcount blocks. However, nothing in this code path actually | ||
4 | took the lock. This could cause the same cache entry to be used by two | ||
5 | requests at the same time, for different tables at different offsets, | ||
6 | resulting in image corruption. | ||
7 | 1 | ||
8 | As it would be preferable to base the detection on consistent data (even | ||
9 | though it's just heuristics), let's take the lock not only around the | ||
10 | qcow2_get_refcount() calls, but around the whole function. | ||
11 | |||
12 | This patch takes the lock in qcow2_co_block_status() earlier and asserts | ||
13 | in qcow2_detect_metadata_preallocation() that we hold the lock. | ||
14 | |||
15 | Fixes: 69f47505ee66afaa513305de0c1895a224e52c45 | ||
16 | Cc: qemu-stable@nongnu.org | ||
17 | Reported-by: Michael Weiser <michael.weiser@gmx.de> | ||
18 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
19 | Tested-by: Michael Weiser <michael.weiser@gmx.de> | ||
20 | Reviewed-by: Michael Weiser <michael.weiser@gmx.de> | ||
21 | Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
22 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
23 | --- | ||
24 | block/qcow2-refcount.c | 2 ++ | ||
25 | block/qcow2.c | 3 ++- | ||
26 | 2 files changed, 4 insertions(+), 1 deletion(-) | ||
27 | |||
28 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/block/qcow2-refcount.c | ||
31 | +++ b/block/qcow2-refcount.c | ||
32 | @@ -XXX,XX +XXX,XX @@ int qcow2_detect_metadata_preallocation(BlockDriverState *bs) | ||
33 | int64_t i, end_cluster, cluster_count = 0, threshold; | ||
34 | int64_t file_length, real_allocation, real_clusters; | ||
35 | |||
36 | + qemu_co_mutex_assert_locked(&s->lock); | ||
37 | + | ||
38 | file_length = bdrv_getlength(bs->file->bs); | ||
39 | if (file_length < 0) { | ||
40 | return file_length; | ||
41 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/block/qcow2.c | ||
44 | +++ b/block/qcow2.c | ||
45 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs, | ||
46 | unsigned int bytes; | ||
47 | int status = 0; | ||
48 | |||
49 | + qemu_co_mutex_lock(&s->lock); | ||
50 | + | ||
51 | if (!s->metadata_preallocation_checked) { | ||
52 | ret = qcow2_detect_metadata_preallocation(bs); | ||
53 | s->metadata_preallocation = (ret == 1); | ||
54 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs, | ||
55 | } | ||
56 | |||
57 | bytes = MIN(INT_MAX, count); | ||
58 | - qemu_co_mutex_lock(&s->lock); | ||
59 | ret = qcow2_get_cluster_offset(bs, offset, &bytes, &cluster_offset); | ||
60 | qemu_co_mutex_unlock(&s->lock); | ||
61 | if (ret < 0) { | ||
62 | -- | ||
63 | 2.20.1 | ||
64 | |||
65 | diff view generated by jsdifflib |