1
The following changes since commit 527266f324def9f7f392fe3b0dd940cb8dc699d9:
1
The following changes since commit 7bc8f9734213b76e76631a483be13d6737c2adbc:
2
2
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-pflash-2019-03-26' into staging (2019-03-26 09:57:07 +0000)
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20191025' into staging (2019-10-25 13:12:16 +0100)
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
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to c6e3f520c802c5cb2de80576aba7f9f1fe985d8b:
9
for you to fetch changes up to 5e9785505210e2477e590e61b1ab100d0ec22b01:
10
10
11
qemu-io: Add write -n for BDRV_REQ_NO_FALLBACK (2019-03-26 11:37:51 +0100)
11
qcow2: Fix corruption bug in qcow2_detect_metadata_preallocation() (2019-10-25 15:18:55 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- Fix slow pre-zeroing in qemu-img convert
16
- qcow2: Fix data corruption bug that is triggered in partial cluster
17
- Test case for block job pausing on I/O errors
17
allocation with default options
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
18
22
19
----------------------------------------------------------------
23
----------------------------------------------------------------
20
Kevin Wolf (6):
24
Kevin Wolf (5):
21
block: Remove error messages in bdrv_make_zero()
25
iotests: Skip read-only cases in 118 when run as root
22
block: Add BDRV_REQ_NO_FALLBACK
26
blockdev: Use error_report() in hmp_commit()
23
block: Advertise BDRV_REQ_NO_FALLBACK in filter drivers
27
doc: Describe missing generic -blockdev options
24
file-posix: Support BDRV_REQ_NO_FALLBACK for zero writes
28
coroutine: Add qemu_co_mutex_assert_locked()
25
qemu-img: Use BDRV_REQ_NO_FALLBACK for pre-zeroing
29
qcow2: Fix corruption bug in qcow2_detect_metadata_preallocation()
26
qemu-io: Add write -n for BDRV_REQ_NO_FALLBACK
30
31
Pavel Dovgaluk (1):
32
qapi: add support for blkreplay driver
27
33
28
Vladimir Sementsov-Ogievskiy (1):
34
Vladimir Sementsov-Ogievskiy (1):
29
iotests: add 248: test resume mirror after auto pause on ENOSPC
35
block/backup: drop dead code from backup_job_create
30
36
31
include/block/block.h | 7 ++++-
37
qapi/block-core.json | 18 ++++++++++++++++--
32
include/block/raw-aio.h | 1 +
38
include/qemu/coroutine.h | 15 +++++++++++++++
33
block/blkdebug.c | 2 +-
39
block/backup.c | 5 +----
34
block/copy-on-read.c | 7 ++---
40
block/qcow2-refcount.c | 2 ++
35
block/file-posix.c | 24 ++++++++++------
41
block/qcow2.c | 3 ++-
36
block/io.c | 16 +++++++----
42
blockdev.c | 7 +++----
37
block/mirror.c | 3 +-
43
qemu-options.hx | 22 +++++++++++++++++++++-
38
block/raw-format.c | 2 +-
44
tests/qemu-iotests/118 | 3 +++
39
qemu-img.c | 2 +-
45
tests/qemu-iotests/iotests.py | 10 ++++++++++
40
qemu-io-cmds.c | 13 +++++++--
46
9 files changed, 73 insertions(+), 12 deletions(-)
41
tests/qemu-iotests/248 | 71 ++++++++++++++++++++++++++++++++++++++++++++++
42
tests/qemu-iotests/248.out | 8 ++++++
43
tests/qemu-iotests/group | 1 +
44
13 files changed, 133 insertions(+), 24 deletions(-)
45
create mode 100755 tests/qemu-iotests/248
46
create mode 100644 tests/qemu-iotests/248.out
47
47
48
diff view generated by jsdifflib
1
We know that the kernel implements a slow fallback code path for
1
From: Pavel Dovgalyuk <pavel.dovgaluk@gmail.com>
2
BLKZEROOUT, so if BDRV_REQ_NO_FALLBACK is given, we shouldn't call it.
3
The other operations we call in the context of .bdrv_co_pwrite_zeroes
4
should usually be quick, so no modification should be needed for them.
5
If we ever notice that there are additional problematic cases, we can
6
still make these conditional as well.
7
2
3
This patch adds support for blkreplay driver to the blockdev options.
4
Now blkreplay can be used with -blockdev command line option
5
in the following format:
6
-blockdev driver=blkreplay,image=file-node-name,node-name=replay-node-name
7
8
This option makes possible implementation of the better command
9
line support for record/replay invocations.
10
11
Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Acked-by: Eric Blake <eblake@redhat.com>
10
---
13
---
11
include/block/raw-aio.h | 1 +
14
qapi/block-core.json | 18 ++++++++++++++++--
12
block/file-posix.c | 24 ++++++++++++++++--------
15
1 file changed, 16 insertions(+), 2 deletions(-)
13
2 files changed, 17 insertions(+), 8 deletions(-)
14
16
15
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
17
diff --git a/qapi/block-core.json b/qapi/block-core.json
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/include/block/raw-aio.h
19
--- a/qapi/block-core.json
18
+++ b/include/block/raw-aio.h
20
+++ b/qapi/block-core.json
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
20
/* AIO flags */
22
# @nvme: Since 2.12
21
#define QEMU_AIO_MISALIGNED 0x1000
23
# @copy-on-read: Since 3.0
22
#define QEMU_AIO_BLKDEV 0x2000
24
# @blklogwrites: Since 3.0
23
+#define QEMU_AIO_NO_FALLBACK 0x4000
25
+# @blkreplay: Since 4.2
24
26
#
25
27
# Since: 2.9
26
/* linux-aio.c - Linux native implementation */
28
##
27
diff --git a/block/file-posix.c b/block/file-posix.c
29
{ 'enum': 'BlockdevDriver',
28
index XXXXXXX..XXXXXXX 100644
30
- 'data': [ 'blkdebug', 'blklogwrites', 'blkverify', 'bochs', 'cloop',
29
--- a/block/file-posix.c
31
- 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps', 'gluster',
30
+++ b/block/file-posix.c
32
+ 'data': [ 'blkdebug', 'blklogwrites', 'blkreplay', 'blkverify', 'bochs',
31
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
33
+ 'cloop', 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps', 'gluster',
32
}
34
'host_cdrom', 'host_device', 'http', 'https', 'iscsi', 'luks',
33
#endif
35
'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels', 'qcow',
34
36
'qcow2', 'qed', 'quorum', 'raw', 'rbd',
35
- bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP;
37
@@ -XXX,XX +XXX,XX @@
36
+ bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
38
'data': { 'test': 'BlockdevRef',
37
ret = 0;
39
'raw': 'BlockdevRef' } }
38
fail:
40
39
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
41
+##
40
@@ -XXX,XX +XXX,XX @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
42
+# @BlockdevOptionsBlkreplay:
41
}
43
+#
42
44
+# Driver specific block device options for blkreplay.
43
#ifdef BLKZEROOUT
45
+#
44
- do {
46
+# @image: disk image which should be controlled with blkreplay
45
- uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
47
+#
46
- if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
48
+# Since: 4.2
47
- return 0;
49
+##
48
- }
50
+{ 'struct': 'BlockdevOptionsBlkreplay',
49
- } while (errno == EINTR);
51
+ 'data': { 'image': 'BlockdevRef' } }
50
+ /* The BLKZEROOUT implementation in the kernel doesn't set
52
+
51
+ * BLKDEV_ZERO_NOFALLBACK, so we can't call this if we have to avoid slow
53
##
52
+ * fallbacks. */
54
# @QuorumReadPattern:
53
+ if (!(aiocb->aio_type & QEMU_AIO_NO_FALLBACK)) {
55
#
54
+ do {
56
@@ -XXX,XX +XXX,XX @@
55
+ uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
57
'blkdebug': 'BlockdevOptionsBlkdebug',
56
+ if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
58
'blklogwrites':'BlockdevOptionsBlklogwrites',
57
+ return 0;
59
'blkverify': 'BlockdevOptionsBlkverify',
58
+ }
60
+ 'blkreplay': 'BlockdevOptionsBlkreplay',
59
+ } while (errno == EINTR);
61
'bochs': 'BlockdevOptionsGenericFormat',
60
62
'cloop': 'BlockdevOptionsGenericFormat',
61
- ret = translate_err(-errno);
63
'copy-on-read':'BlockdevOptionsGenericFormat',
62
+ ret = translate_err(-errno);
63
+ }
64
#endif
65
66
if (ret == -ENOTSUP) {
67
@@ -XXX,XX +XXX,XX @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
68
if (blkdev) {
69
acb.aio_type |= QEMU_AIO_BLKDEV;
70
}
71
+ if (flags & BDRV_REQ_NO_FALLBACK) {
72
+ acb.aio_type |= QEMU_AIO_NO_FALLBACK;
73
+ }
74
75
if (flags & BDRV_REQ_MAY_UNMAP) {
76
acb.aio_type |= QEMU_AIO_DISCARD;
77
--
64
--
78
2.20.1
65
2.20.1
79
66
80
67
diff view generated by jsdifflib
1
This makes the new BDRV_REQ_NO_FALLBACK flag available in the qemu-io
1
Some tests in 118 use chmod to remove write permissions from the file
2
write command.
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
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.
3
9
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Acked-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
---
12
---
7
qemu-io-cmds.c | 13 +++++++++++--
13
tests/qemu-iotests/118 | 3 +++
8
1 file changed, 11 insertions(+), 2 deletions(-)
14
tests/qemu-iotests/iotests.py | 10 ++++++++++
15
2 files changed, 13 insertions(+)
9
16
10
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
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
11
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
12
--- a/qemu-io-cmds.c
47
--- a/tests/qemu-iotests/iotests.py
13
+++ b/qemu-io-cmds.c
48
+++ b/tests/qemu-iotests/iotests.py
14
@@ -XXX,XX +XXX,XX @@ static void write_help(void)
49
@@ -XXX,XX +XXX,XX @@ def skip_if_unsupported(required_formats=[], read_only=False):
15
" -b, -- write to the VM state rather than the virtual disk\n"
50
return func_wrapper
16
" -c, -- write compressed data with blk_write_compressed\n"
51
return skip_test_decorator
17
" -f, -- use Force Unit Access semantics\n"
52
18
+" -n, -- with -z, don't allow slow fallback\n"
53
+def skip_if_user_is_root(func):
19
" -p, -- ignored for backwards compatibility\n"
54
+ '''Skip Test Decorator
20
" -P, -- use different pattern to fill file\n"
55
+ Runs the test only without root permissions'''
21
" -C, -- report statistics in a machine parsable format\n"
56
+ def func_wrapper(*args, **kwargs):
22
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t write_cmd = {
57
+ if os.getuid() == 0:
23
.perm = BLK_PERM_WRITE,
58
+ case_notrun('{}: cannot be run as root'.format(args[0]))
24
.argmin = 2,
59
+ else:
25
.argmax = -1,
60
+ return func(*args, **kwargs)
26
- .args = "[-bcCfquz] [-P pattern] off len",
61
+ return func_wrapper
27
+ .args = "[-bcCfnquz] [-P pattern] off len",
28
.oneline = "writes a number of bytes at a specified offset",
29
.help = write_help,
30
};
31
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
32
int64_t total = 0;
33
int pattern = 0xcd;
34
35
- while ((c = getopt(argc, argv, "bcCfpP:quz")) != -1) {
36
+ while ((c = getopt(argc, argv, "bcCfnpP:quz")) != -1) {
37
switch (c) {
38
case 'b':
39
bflag = true;
40
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
41
case 'f':
42
flags |= BDRV_REQ_FUA;
43
break;
44
+ case 'n':
45
+ flags |= BDRV_REQ_NO_FALLBACK;
46
+ break;
47
case 'p':
48
/* Ignored for backwards compatibility */
49
break;
50
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
51
return -EINVAL;
52
}
53
54
+ if ((flags & BDRV_REQ_NO_FALLBACK) && !zflag) {
55
+ printf("-n requires -z to be specified\n");
56
+ return -EINVAL;
57
+ }
58
+
62
+
59
if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
63
def execute_unittest(output, verbosity, debug):
60
printf("-u requires -z to be specified\n");
64
runner = unittest.TextTestRunner(stream=output, descriptions=True,
61
return -EINVAL;
65
verbosity=verbosity)
62
--
66
--
63
2.20.1
67
2.20.1
64
68
65
69
diff view generated by jsdifflib
1
If qemu-img convert sees that the target image isn't zero-initialised
1
Instead of using monitor_printf() to report errors, hmp_commit() should
2
yet, it tries to do an efficient zero write for the whole image first
2
use error_report() like other places do.
3
to save the overhead of repeated explicit zero writes during the
4
conversion. Obviously, this provides only an advantage if the
5
pre-zeroing is actually efficient. Otherwise, we can end up writing
6
zeroes slowly while zeroing out the whole image, and then overwrite the
7
same blocks again with real data, potentially doubling the written data.
8
9
Pass BDRV_REQ_NO_FALLBACK to blk_make_zero() to avoid this case. If we
10
can't efficiently zero out, we'll instead write explicit zeroes only if
11
there is no data to be written to a block.
12
3
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Acked-by: Eric Blake <eblake@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
---
7
---
16
qemu-img.c | 2 +-
8
blockdev.c | 7 +++----
17
1 file changed, 1 insertion(+), 1 deletion(-)
9
1 file changed, 3 insertions(+), 4 deletions(-)
18
10
19
diff --git a/qemu-img.c b/qemu-img.c
11
diff --git a/blockdev.c b/blockdev.c
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/qemu-img.c
13
--- a/blockdev.c
22
+++ b/qemu-img.c
14
+++ b/blockdev.c
23
@@ -XXX,XX +XXX,XX @@ static int convert_do_copy(ImgConvertState *s)
15
@@ -XXX,XX +XXX,XX @@ void hmp_commit(Monitor *mon, const QDict *qdict)
24
if (!s->has_zero_init && !s->target_has_backing &&
16
25
bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)))
17
blk = blk_by_name(device);
26
{
18
if (!blk) {
27
- ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP);
19
- monitor_printf(mon, "Device '%s' not found\n", device);
28
+ ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK);
20
+ error_report("Device '%s' not found", device);
29
if (ret == 0) {
21
return;
30
s->has_zero_init = true;
31
}
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
}
32
if (ret < 0) {
33
- monitor_printf(mon, "'commit' error for '%s': %s\n", device,
34
- strerror(-ret));
35
+ error_report("'commit' error for '%s': %s", device, strerror(-ret));
36
}
37
}
38
32
--
39
--
33
2.20.1
40
2.20.1
34
41
35
42
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Test that mirror job actually resume on resume command after being
3
After commit 00e30f05de1d195, there is no more "goto error" points
4
automatically paused on ENOSPC error.
4
after job creation, so after "error:" @job is always NULL and we don't
5
need roll-back job creation.
5
6
6
It's a follow-up test for 8d9648cbf3e
7
Reported-by: Coverity (CID 1406402)
7
"blockjob: fix user pause in block_job_error_action"
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Tested-by: John Snow <jsnow@redhat.com>
9
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
11
---
14
tests/qemu-iotests/248 | 71 ++++++++++++++++++++++++++++++++++++++
12
block/backup.c | 5 +----
15
tests/qemu-iotests/248.out | 8 +++++
13
1 file changed, 1 insertion(+), 4 deletions(-)
16
tests/qemu-iotests/group | 1 +
17
3 files changed, 80 insertions(+)
18
create mode 100755 tests/qemu-iotests/248
19
create mode 100644 tests/qemu-iotests/248.out
20
14
21
diff --git a/tests/qemu-iotests/248 b/tests/qemu-iotests/248
15
diff --git a/block/backup.c b/block/backup.c
22
new file mode 100755
23
index XXXXXXX..XXXXXXX
24
--- /dev/null
25
+++ b/tests/qemu-iotests/248
26
@@ -XXX,XX +XXX,XX @@
27
+#!/usr/bin/env python
28
+#
29
+# Test resume mirror after auto pause on ENOSPC
30
+#
31
+# Copyright (c) 2019 Virtuozzo International GmbH. All rights reserved.
32
+#
33
+# This program is free software; you can redistribute it and/or modify
34
+# it under the terms of the GNU General Public License as published by
35
+# the Free Software Foundation; either version 2 of the License, or
36
+# (at your option) any later version.
37
+#
38
+# This program is distributed in the hope that it will be useful,
39
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
40
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41
+# GNU General Public License for more details.
42
+#
43
+# You should have received a copy of the GNU General Public License
44
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
45
+#
46
+
47
+import iotests
48
+from iotests import qemu_img_create, qemu_io, file_path, filter_qmp_testfiles
49
+
50
+iotests.verify_image_format(supported_fmts=['qcow2'])
51
+
52
+source, target = file_path('source', 'target')
53
+size = 5 * 1024 * 1024
54
+limit = 2 * 1024 * 1024
55
+
56
+qemu_img_create('-f', iotests.imgfmt, source, str(size))
57
+qemu_img_create('-f', iotests.imgfmt, target, str(size))
58
+qemu_io('-c', 'write 0 {}'.format(size), source)
59
+
60
+# raw format don't like empty files
61
+qemu_io('-c', 'write 0 {}'.format(size), target)
62
+
63
+vm = iotests.VM().add_drive(source)
64
+vm.launch()
65
+
66
+blockdev_opts = {
67
+ 'driver': iotests.imgfmt,
68
+ 'node-name': 'target',
69
+ 'file': {
70
+ 'driver': 'raw',
71
+ 'size': limit,
72
+ 'file': {
73
+ 'driver': 'file',
74
+ 'filename': target
75
+ }
76
+ }
77
+}
78
+vm.qmp_log('blockdev-add', filters=[filter_qmp_testfiles], **blockdev_opts)
79
+
80
+vm.qmp_log('blockdev-mirror', device='drive0', sync='full', target='target',
81
+ on_target_error='enospc')
82
+
83
+vm.event_wait('JOB_STATUS_CHANGE', timeout=3.0,
84
+ match={'data': {'status': 'paused'}})
85
+
86
+# drop other cached events, to not interfere with further wait for 'running'
87
+vm.get_qmp_events()
88
+
89
+del blockdev_opts['file']['size']
90
+vm.qmp_log('x-blockdev-reopen', filters=[filter_qmp_testfiles],
91
+ **blockdev_opts)
92
+
93
+vm.qmp_log('block-job-resume', device='drive0')
94
+vm.event_wait('JOB_STATUS_CHANGE', timeout=1.0,
95
+ match={'data': {'status': 'running'}})
96
+
97
+vm.shutdown()
98
diff --git a/tests/qemu-iotests/248.out b/tests/qemu-iotests/248.out
99
new file mode 100644
100
index XXXXXXX..XXXXXXX
101
--- /dev/null
102
+++ b/tests/qemu-iotests/248.out
103
@@ -XXX,XX +XXX,XX @@
104
+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "raw", "file": {"driver": "file", "filename": "TEST_DIR/PID-target"}, "size": 2097152}, "node-name": "target"}}
105
+{"return": {}}
106
+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "on-target-error": "enospc", "sync": "full", "target": "target"}}
107
+{"return": {}}
108
+{"execute": "x-blockdev-reopen", "arguments": {"driver": "qcow2", "file": {"driver": "raw", "file": {"driver": "file", "filename": "TEST_DIR/PID-target"}}, "node-name": "target"}}
109
+{"return": {}}
110
+{"execute": "block-job-resume", "arguments": {"device": "drive0"}}
111
+{"return": {}}
112
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
113
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
114
--- a/tests/qemu-iotests/group
17
--- a/block/backup.c
115
+++ b/tests/qemu-iotests/group
18
+++ b/block/backup.c
116
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
117
245 rw auto
20
if (sync_bitmap) {
118
246 rw auto quick
21
bdrv_reclaim_dirty_bitmap(sync_bitmap, NULL);
119
247 rw auto quick
22
}
120
+248 rw auto quick
23
- if (job) {
24
- backup_clean(&job->common.job);
25
- job_early_fail(&job->common.job);
26
- } else if (backup_top) {
27
+ if (backup_top) {
28
bdrv_backup_top_drop(backup_top);
29
}
30
121
--
31
--
122
2.20.1
32
2.20.1
123
33
124
34
diff view generated by jsdifflib
1
Filter drivers that support .bdrv_co_pwrite_zeroes can safely advertise
1
We added more generic options after introducing -blockdev and forgot to
2
BDRV_REQ_NO_FALLBACK because they just forward the request flags to
2
update the documentation (man page and --help output) accordingly. Do
3
their child node.
3
that now.
4
4
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Acked-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
block/blkdebug.c | 2 +-
8
qemu-options.hx | 22 +++++++++++++++++++++-
9
block/copy-on-read.c | 7 +++----
9
1 file changed, 21 insertions(+), 1 deletion(-)
10
block/mirror.c | 3 ++-
11
block/raw-format.c | 2 +-
12
4 files changed, 7 insertions(+), 7 deletions(-)
13
10
14
diff --git a/block/blkdebug.c b/block/blkdebug.c
11
diff --git a/qemu-options.hx b/qemu-options.hx
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/block/blkdebug.c
13
--- a/qemu-options.hx
17
+++ b/block/blkdebug.c
14
+++ b/qemu-options.hx
18
@@ -XXX,XX +XXX,XX @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
15
@@ -XXX,XX +XXX,XX @@ ETEXI
19
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
16
DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,
20
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
17
"-blockdev [driver=]driver[,node-name=N][,discard=ignore|unmap]\n"
21
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
18
" [,cache.direct=on|off][,cache.no-flush=on|off]\n"
22
- ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
19
- " [,read-only=on|off][,detect-zeroes=on|off|unmap]\n"
23
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
20
+ " [,read-only=on|off][,auto-read-only=on|off]\n"
24
bs->file->bs->supported_zero_flags);
21
+ " [,force-share=on|off][,detect-zeroes=on|off|unmap]\n"
25
ret = -EINVAL;
22
" [,driver specific parameters...]\n"
26
23
" configure a block backend\n", QEMU_ARCH_ALL)
27
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
24
STEXI
28
index XXXXXXX..XXXXXXX 100644
25
@@ -XXX,XX +XXX,XX @@ name is not intended to be predictable and changes between QEMU invocations.
29
--- a/block/copy-on-read.c
26
For the top level, an explicit node name must be specified.
30
+++ b/block/copy-on-read.c
27
@item read-only
31
@@ -XXX,XX +XXX,XX @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
28
Open the node read-only. Guest write attempts will fail.
32
}
29
+
33
30
+Note that some block drivers support only read-only access, either generally or
34
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
31
+in certain configurations. In this case, the default value
35
- (BDRV_REQ_FUA &
32
+@option{read-only=off} does not work and the option must be specified
36
- bs->file->bs->supported_write_flags);
33
+explicitly.
37
+ (BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
34
+@item auto-read-only
38
35
+If @option{auto-read-only=on} is set, QEMU may fall back to read-only usage
39
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
36
+even when @option{read-only=off} is requested, or even switch between modes as
40
- ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
37
+needed, e.g. depending on whether the image file is writable or whether a
41
- bs->file->bs->supported_zero_flags);
38
+writing user is attached to the node.
42
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
39
+@item force-share
43
+ bs->file->bs->supported_zero_flags);
40
+Override the image locking system of QEMU by forcing the node to utilize
44
41
+weaker shared access for permissions where it would normally request exclusive
45
return 0;
42
+access. When there is the potential for multiple instances to have the same
46
}
43
+file open (whether this invocation of QEMU is the first or the second
47
diff --git a/block/mirror.c b/block/mirror.c
44
+instance), both instances must permit shared access for the second instance to
48
index XXXXXXX..XXXXXXX 100644
45
+succeed at opening the file.
49
--- a/block/mirror.c
46
+
50
+++ b/block/mirror.c
47
+Enabling @option{force-share=on} requires @option{read-only=on}.
51
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
48
@item cache.direct
52
}
49
The host page cache can be avoided with @option{cache.direct=on}. This will
53
mirror_top_bs->total_sectors = bs->total_sectors;
50
attempt to do disk IO directly to the guest's memory. QEMU may still perform an
54
mirror_top_bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED;
55
- mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED;
56
+ mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
57
+ BDRV_REQ_NO_FALLBACK;
58
bs_opaque = g_new0(MirrorBDSOpaque, 1);
59
mirror_top_bs->opaque = bs_opaque;
60
bdrv_set_aio_context(mirror_top_bs, bdrv_get_aio_context(bs));
61
diff --git a/block/raw-format.c b/block/raw-format.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/block/raw-format.c
64
+++ b/block/raw-format.c
65
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
66
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
67
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
68
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
69
- ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
70
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
71
bs->file->bs->supported_zero_flags);
72
73
if (bs->probed && !bdrv_is_read_only(bs)) {
74
--
51
--
75
2.20.1
52
2.20.1
76
53
77
54
diff view generated by jsdifflib
1
There is only a single caller of bdrv_make_zero(), which is qemu-img
1
Some functions require that the caller holds a certain CoMutex for them
2
convert. If the function fails, we just fall back to a different method
2
to operate correctly. Add a function so that they can assert the lock is
3
of zeroing out blocks on the target image. There is no good reason to
3
really held.
4
print error messages on stderr when the higher level operation will
5
actually succeed.
6
4
5
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Acked-by: Eric Blake <eblake@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>
9
---
12
---
10
block/io.c | 4 ----
13
include/qemu/coroutine.h | 15 +++++++++++++++
11
1 file changed, 4 deletions(-)
14
1 file changed, 15 insertions(+)
12
15
13
diff --git a/block/io.c b/block/io.c
16
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/block/io.c
18
--- a/include/qemu/coroutine.h
16
+++ b/block/io.c
19
+++ b/include/qemu/coroutine.h
17
@@ -XXX,XX +XXX,XX @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
20
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
18
}
21
*/
19
ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL);
22
void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
20
if (ret < 0) {
23
21
- error_report("error getting block status at offset %" PRId64 ": %s",
24
+/**
22
- offset, strerror(-ret));
25
+ * Assert that the current coroutine holds @mutex.
23
return ret;
26
+ */
24
}
27
+static inline coroutine_fn void qemu_co_mutex_assert_locked(CoMutex *mutex)
25
if (ret & BDRV_BLOCK_ZERO) {
28
+{
26
@@ -XXX,XX +XXX,XX @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
29
+ /*
27
}
30
+ * mutex->holder doesn't need any synchronisation if the assertion holds
28
ret = bdrv_pwrite_zeroes(child, offset, bytes, flags);
31
+ * true because the mutex protects it. If it doesn't hold true, we still
29
if (ret < 0) {
32
+ * don't mind if another thread takes or releases mutex behind our back,
30
- error_report("error writing zeroes at offset %" PRId64 ": %s",
33
+ * because the condition will be false no matter whether we read NULL or
31
- offset, strerror(-ret));
34
+ * the pointer for any other coroutine.
32
return ret;
35
+ */
33
}
36
+ assert(atomic_read(&mutex->locked) &&
34
offset += bytes;
37
+ mutex->holder == qemu_coroutine_self());
38
+}
39
40
/**
41
* CoQueues are a mechanism to queue coroutines in order to continue executing
35
--
42
--
36
2.20.1
43
2.20.1
37
44
38
45
diff view generated by jsdifflib
1
For qemu-img convert, we want an operation that zeroes out the whole
1
qcow2_detect_metadata_preallocation() calls qcow2_get_refcount() which
2
image if this can be done efficiently, but that returns an error
2
requires s->lock to be taken to protect its accesses to the refcount
3
otherwise so we don't write explicit zeroes and immediately overwrite
3
table and refcount blocks. However, nothing in this code path actually
4
them with the real data, potentially doubling the amount of data to be
4
took the lock. This could cause the same cache entry to be used by two
5
written.
5
requests at the same time, for different tables at different offsets,
6
resulting in image corruption.
6
7
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>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Acked-by: Eric Blake <eblake@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>
9
---
23
---
10
include/block/block.h | 7 ++++++-
24
block/qcow2-refcount.c | 2 ++
11
block/io.c | 12 +++++++++++-
25
block/qcow2.c | 3 ++-
12
2 files changed, 17 insertions(+), 2 deletions(-)
26
2 files changed, 4 insertions(+), 1 deletion(-)
13
27
14
diff --git a/include/block/block.h b/include/block/block.h
28
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
15
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/block.h
30
--- a/block/qcow2-refcount.c
17
+++ b/include/block/block.h
31
+++ b/block/qcow2-refcount.c
18
@@ -XXX,XX +XXX,XX @@ typedef enum {
32
@@ -XXX,XX +XXX,XX @@ int qcow2_detect_metadata_preallocation(BlockDriverState *bs)
19
*/
33
int64_t i, end_cluster, cluster_count = 0, threshold;
20
BDRV_REQ_SERIALISING = 0x80,
34
int64_t file_length, real_allocation, real_clusters;
21
35
22
+ /* Execute the request only if the operation can be offloaded or otherwise
36
+ qemu_co_mutex_assert_locked(&s->lock);
23
+ * be executed efficiently, but return an error instead of using a slow
24
+ * fallback. */
25
+ BDRV_REQ_NO_FALLBACK = 0x100,
26
+
37
+
27
/* Mask of valid flags */
38
file_length = bdrv_getlength(bs->file->bs);
28
- BDRV_REQ_MASK = 0xff,
39
if (file_length < 0) {
29
+ BDRV_REQ_MASK = 0x1ff,
40
return file_length;
30
} BdrvRequestFlags;
41
diff --git a/block/qcow2.c b/block/qcow2.c
31
32
typedef struct BlockSizes {
33
diff --git a/block/io.c b/block/io.c
34
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
35
--- a/block/io.c
43
--- a/block/qcow2.c
36
+++ b/block/io.c
44
+++ b/block/qcow2.c
37
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
45
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
38
unsigned int nb_sectors;
46
unsigned int bytes;
39
47
int status = 0;
40
assert(!(flags & ~BDRV_REQ_MASK));
48
41
+ assert(!(flags & BDRV_REQ_NO_FALLBACK));
49
+ qemu_co_mutex_lock(&s->lock);
42
50
+
43
if (!drv) {
51
if (!s->metadata_preallocation_checked) {
44
return -ENOMEDIUM;
52
ret = qcow2_detect_metadata_preallocation(bs);
45
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
53
s->metadata_preallocation = (ret == 1);
46
int ret;
54
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
47
48
assert(!(flags & ~BDRV_REQ_MASK));
49
+ assert(!(flags & BDRV_REQ_NO_FALLBACK));
50
51
if (!drv) {
52
return -ENOMEDIUM;
53
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
54
return -ENOMEDIUM;
55
}
55
}
56
56
57
+ if ((flags & ~bs->supported_zero_flags) & BDRV_REQ_NO_FALLBACK) {
57
bytes = MIN(INT_MAX, count);
58
+ return -ENOTSUP;
58
- qemu_co_mutex_lock(&s->lock);
59
+ }
59
ret = qcow2_get_cluster_offset(bs, offset, &bytes, &cluster_offset);
60
+
60
qemu_co_mutex_unlock(&s->lock);
61
assert(alignment % bs->bl.request_alignment == 0);
61
if (ret < 0) {
62
head = offset % alignment;
63
tail = (offset + bytes) % alignment;
64
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
65
assert(!bs->supported_zero_flags);
66
}
67
68
- if (ret == -ENOTSUP) {
69
+ if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) {
70
/* Fall back to bounce buffer if write zeroes is unsupported */
71
BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
72
73
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
74
BdrvTrackedRequest req;
75
int ret;
76
77
+ /* TODO We can support BDRV_REQ_NO_FALLBACK here */
78
+ assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
79
+ assert(!(write_flags & BDRV_REQ_NO_FALLBACK));
80
+
81
if (!dst || !dst->bs) {
82
return -ENOMEDIUM;
83
}
84
--
62
--
85
2.20.1
63
2.20.1
86
64
87
65
diff view generated by jsdifflib