1
The following changes since commit 7bc8f9734213b76e76631a483be13d6737c2adbc:
1
The following changes since commit e3acc2c1961cbe22ca474cd5da4163b7bbf7cea3:
2
2
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20191025' into staging (2019-10-25 13:12:16 +0100)
3
tests/docker/dockerfiles: Bump fedora-i386-cross to fedora 34 (2021-10-05 16:40:39 -0700)
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 5e9785505210e2477e590e61b1ab100d0ec22b01:
9
for you to fetch changes up to 3765315d4c84f9c0799744f43a314169baaccc05:
10
10
11
qcow2: Fix corruption bug in qcow2_detect_metadata_preallocation() (2019-10-25 15:18:55 +0200)
11
iotests: Update for pylint 2.11.1 (2021-10-06 10:25:55 +0200)
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
- Fix I/O errors because of incorrectly detected max_iov
17
allocation with default options
17
- Fix not white-listed copy-before-write
18
- qapi: add support for blkreplay driver
18
- qemu-storage-daemon: Only display FUSE help when FUSE is built-in
19
- doc: Describe missing generic -blockdev options
19
- iotests: update environment and linting configuration
20
- iotests: Fix 118 when run as root
21
- Minor code cleanups
22
20
23
----------------------------------------------------------------
21
----------------------------------------------------------------
24
Kevin Wolf (5):
22
Emanuele Giuseppe Esposito (1):
25
iotests: Skip read-only cases in 118 when run as root
23
include/block.h: remove outdated comment
26
blockdev: Use error_report() in hmp_commit()
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
24
31
Pavel Dovgaluk (1):
25
John Snow (5):
32
qapi: add support for blkreplay driver
26
iotests: add 'qemu' package location to PYTHONPATH in testenv
27
iotests/linters: check mypy files all at once
28
iotests/mirror-top-perms: Adjust imports
29
iotests/migrate-bitmaps-test: delint
30
iotests: Update for pylint 2.11.1
33
31
34
Vladimir Sementsov-Ogievskiy (1):
32
Paolo Bonzini (1):
35
block/backup: drop dead code from backup_job_create
33
block: introduce max_hw_iov for use in scsi-generic
36
34
37
qapi/block-core.json | 18 ++++++++++++++++--
35
Philippe Mathieu-Daudé (1):
38
include/qemu/coroutine.h | 15 +++++++++++++++
36
qemu-storage-daemon: Only display FUSE help when FUSE is built-in
39
block/backup.c | 5 +----
37
40
block/qcow2-refcount.c | 2 ++
38
Vladimir Sementsov-Ogievskiy (5):
41
block/qcow2.c | 3 ++-
39
block: implement bdrv_new_open_driver_opts()
42
blockdev.c | 7 +++----
40
block: bdrv_insert_node(): fix and improve error handling
43
qemu-options.hx | 22 +++++++++++++++++++++-
41
block: bdrv_insert_node(): doc and style
44
tests/qemu-iotests/118 | 3 +++
42
block: bdrv_insert_node(): don't use bdrv_open()
45
tests/qemu-iotests/iotests.py | 10 ++++++++++
43
iotests/image-fleecing: declare requirement of copy-before-write
46
9 files changed, 73 insertions(+), 12 deletions(-)
44
45
include/block/block.h | 8 ++-
46
include/block/block_int.h | 7 +++
47
include/sysemu/block-backend.h | 1 +
48
block.c | 79 ++++++++++++++++++++++-----
49
block/block-backend.c | 6 ++
50
block/file-posix.c | 2 +-
51
block/io.c | 1 +
52
hw/scsi/scsi-generic.c | 2 +-
53
storage-daemon/qemu-storage-daemon.c | 2 +
54
tests/qemu-iotests/iotests.py | 2 -
55
tests/qemu-iotests/testenv.py | 15 +++--
56
tests/qemu-iotests/testrunner.py | 7 ++-
57
tests/qemu-iotests/235 | 2 -
58
tests/qemu-iotests/297 | 52 +++++++-----------
59
tests/qemu-iotests/300 | 5 +-
60
tests/qemu-iotests/pylintrc | 6 +-
61
tests/qemu-iotests/tests/image-fleecing | 1 +
62
tests/qemu-iotests/tests/migrate-bitmaps-test | 50 +++++++++--------
63
tests/qemu-iotests/tests/mirror-top-perms | 12 ++--
64
19 files changed, 164 insertions(+), 96 deletions(-)
47
65
48
66
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
There are a couple of errors in bdrv_drained_begin header comment:
4
- block_job_pause does not exist anymore, it has been replaced
5
with job_pause in b15de82867
6
- job_pause is automatically invoked as a .drained_begin callback
7
(child_job_drained_begin) by the child_job BdrvChildClass struct
8
in blockjob.c. So no additional pause should be required.
9
10
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
11
Message-Id: <20210903113800.59970-1-eesposit@redhat.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
include/block/block.h | 4 +---
16
1 file changed, 1 insertion(+), 3 deletions(-)
17
18
diff --git a/include/block/block.h b/include/block/block.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/block/block.h
21
+++ b/include/block/block.h
22
@@ -XXX,XX +XXX,XX @@ bool bdrv_drain_poll(BlockDriverState *bs, bool recursive,
23
* bdrv_drained_begin:
24
*
25
* Begin a quiesced section for exclusive access to the BDS, by disabling
26
- * external request sources including NBD server and device model. Note that
27
- * this doesn't block timers or coroutines from submitting more requests, which
28
- * means block_job_pause is still necessary.
29
+ * external request sources including NBD server, block jobs, and device model.
30
*
31
* This function can be recursive.
32
*/
33
--
34
2.31.1
35
36
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
When configuring QEMU with --disable-fuse, the qemu-storage-daemon
4
still reports FUSE command line options in its help:
5
6
$ qemu-storage-daemon -h
7
Usage: qemu-storage-daemon [options]
8
QEMU storage daemon
9
10
--export [type=]fuse,id=<id>,node-name=<node-name>,mountpoint=<file>
11
[,growable=on|off][,writable=on|off]
12
export the specified block node over FUSE
13
14
Remove this help message when FUSE is disabled, to avoid:
15
16
$ qemu-storage-daemon --export fuse
17
qemu-storage-daemon: --export fuse: Invalid parameter 'fuse'
18
19
Reported-by: Qing Wang <qinwang@redhat.com>
20
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Message-Id: <20210816180442.2000642-1-philmd@redhat.com>
22
Reviewed-by: Eric Blake <eblake@redhat.com>
23
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
---
26
storage-daemon/qemu-storage-daemon.c | 2 ++
27
1 file changed, 2 insertions(+)
28
29
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/storage-daemon/qemu-storage-daemon.c
32
+++ b/storage-daemon/qemu-storage-daemon.c
33
@@ -XXX,XX +XXX,XX @@ static void help(void)
34
" export the specified block node over NBD\n"
35
" (requires --nbd-server)\n"
36
"\n"
37
+#ifdef CONFIG_FUSE
38
" --export [type=]fuse,id=<id>,node-name=<node-name>,mountpoint=<file>\n"
39
" [,growable=on|off][,writable=on|off]\n"
40
" export the specified block node over FUSE\n"
41
"\n"
42
+#endif /* CONFIG_FUSE */
43
" --monitor [chardev=]name[,mode=control][,pretty[=on|off]]\n"
44
" configure a QMP monitor\n"
45
"\n"
46
--
47
2.31.1
48
49
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Add version of bdrv_new_open_driver() that supports QDict options.
4
We'll use it in further commit.
5
6
Simply add one more argument to bdrv_new_open_driver() is worse, as
7
there are too many invocations of bdrv_new_open_driver() to update
8
then.
9
10
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Suggested-by: Kevin Wolf <kwolf@redhat.com>
12
Message-Id: <20210920115538.264372-2-vsementsov@virtuozzo.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
include/block/block.h | 4 ++++
16
block.c | 25 +++++++++++++++++++++----
17
2 files changed, 25 insertions(+), 4 deletions(-)
18
19
diff --git a/include/block/block.h b/include/block/block.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/block/block.h
22
+++ b/include/block/block.h
23
@@ -XXX,XX +XXX,XX @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
24
const char *bdref_key, Error **errp);
25
BlockDriverState *bdrv_open(const char *filename, const char *reference,
26
QDict *options, int flags, Error **errp);
27
+BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
28
+ const char *node_name,
29
+ QDict *options, int flags,
30
+ Error **errp);
31
BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
32
int flags, Error **errp);
33
BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
34
diff --git a/block.c b/block.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block.c
37
+++ b/block.c
38
@@ -XXX,XX +XXX,XX @@ open_failed:
39
return ret;
40
}
41
42
-BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
43
- int flags, Error **errp)
44
+/*
45
+ * Create and open a block node.
46
+ *
47
+ * @options is a QDict of options to pass to the block drivers, or NULL for an
48
+ * empty set of options. The reference to the QDict belongs to the block layer
49
+ * after the call (even on failure), so if the caller intends to reuse the
50
+ * dictionary, it needs to use qobject_ref() before calling bdrv_open.
51
+ */
52
+BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
53
+ const char *node_name,
54
+ QDict *options, int flags,
55
+ Error **errp)
56
{
57
BlockDriverState *bs;
58
int ret;
59
60
bs = bdrv_new();
61
bs->open_flags = flags;
62
- bs->explicit_options = qdict_new();
63
- bs->options = qdict_new();
64
+ bs->options = options ?: qdict_new();
65
+ bs->explicit_options = qdict_clone_shallow(bs->options);
66
bs->opaque = NULL;
67
68
update_options_from_flags(bs->options, flags);
69
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
70
return bs;
71
}
72
73
+/* Create and open a block node. */
74
+BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
75
+ int flags, Error **errp)
76
+{
77
+ return bdrv_new_open_driver_opts(drv, node_name, NULL, flags, errp);
78
+}
79
+
80
QemuOptsList bdrv_runtime_opts = {
81
.name = "bdrv_common",
82
.head = QTAILQ_HEAD_INITIALIZER(bdrv_runtime_opts.head),
83
--
84
2.31.1
85
86
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
After commit 00e30f05de1d195, there is no more "goto error" points
3
- use ERRP_GUARD(): function calls error_prepend(), so it must use
4
after job creation, so after "error:" @job is always NULL and we don't
4
ERRP_GUARD(), otherwise error_prepend() would not be called when
5
need roll-back job creation.
5
passed errp is error_fatal
6
6
7
Reported-by: Coverity (CID 1406402)
7
- drop error propagation, handle return code instead
8
9
- for symmetry, do error_prepend() for the second failure
10
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
12
Message-Id: <20210920115538.264372-3-vsementsov@virtuozzo.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
14
---
12
block/backup.c | 5 +----
15
block.c | 9 +++++----
13
1 file changed, 1 insertion(+), 4 deletions(-)
16
1 file changed, 5 insertions(+), 4 deletions(-)
14
17
15
diff --git a/block/backup.c b/block/backup.c
18
diff --git a/block.c b/block.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/block/backup.c
20
--- a/block.c
18
+++ b/block/backup.c
21
+++ b/block.c
19
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
22
@@ -XXX,XX +XXX,XX @@ static void bdrv_delete(BlockDriverState *bs)
20
if (sync_bitmap) {
23
BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
21
bdrv_reclaim_dirty_bitmap(sync_bitmap, NULL);
24
int flags, Error **errp)
25
{
26
+ ERRP_GUARD();
27
+ int ret;
28
BlockDriverState *new_node_bs;
29
- Error *local_err = NULL;
30
31
new_node_bs = bdrv_open(NULL, NULL, node_options, flags, errp);
32
if (new_node_bs == NULL) {
33
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
22
}
34
}
23
- if (job) {
35
24
- backup_clean(&job->common.job);
36
bdrv_drained_begin(bs);
25
- job_early_fail(&job->common.job);
37
- bdrv_replace_node(bs, new_node_bs, &local_err);
26
- } else if (backup_top) {
38
+ ret = bdrv_replace_node(bs, new_node_bs, errp);
27
+ if (backup_top) {
39
bdrv_drained_end(bs);
28
bdrv_backup_top_drop(backup_top);
40
41
- if (local_err) {
42
+ if (ret < 0) {
43
+ error_prepend(errp, "Could not replace node: ");
44
bdrv_unref(new_node_bs);
45
- error_propagate(errp, local_err);
46
return NULL;
29
}
47
}
30
48
31
--
49
--
32
2.20.1
50
2.31.1
33
51
34
52
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
- options & flags is common pair for open-like functions, let's use it
4
- add a comment that specifies use of @options
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-Id: <20210920115538.264372-4-vsementsov@virtuozzo.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
block.c | 13 +++++++++++--
11
1 file changed, 11 insertions(+), 2 deletions(-)
12
13
diff --git a/block.c b/block.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block.c
16
+++ b/block.c
17
@@ -XXX,XX +XXX,XX @@ static void bdrv_delete(BlockDriverState *bs)
18
g_free(bs);
19
}
20
21
-BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
22
+
23
+/*
24
+ * Replace @bs by newly created block node.
25
+ *
26
+ * @options is a QDict of options to pass to the block drivers, or NULL for an
27
+ * empty set of options. The reference to the QDict belongs to the block layer
28
+ * after the call (even on failure), so if the caller intends to reuse the
29
+ * dictionary, it needs to use qobject_ref() before calling bdrv_open.
30
+ */
31
+BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options,
32
int flags, Error **errp)
33
{
34
ERRP_GUARD();
35
int ret;
36
BlockDriverState *new_node_bs;
37
38
- new_node_bs = bdrv_open(NULL, NULL, node_options, flags, errp);
39
+ new_node_bs = bdrv_open(NULL, NULL, options, flags, errp);
40
if (new_node_bs == NULL) {
41
error_prepend(errp, "Could not create node: ");
42
return NULL;
43
--
44
2.31.1
45
46
diff view generated by jsdifflib
1
qcow2_detect_metadata_preallocation() calls qcow2_get_refcount() which
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
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
2
8
As it would be preferable to base the detection on consistent data (even
3
Use bdrv_new_open_driver_opts() instead of complicated bdrv_open().
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
4
12
This patch takes the lock in qcow2_co_block_status() earlier and asserts
5
Among other extra things bdrv_open() also check for white-listed
13
in qcow2_detect_metadata_preallocation() that we hold the lock.
6
formats, which we don't want for internal node creation: currently
7
backup doesn't work when copy-before-write filter is not white-listed.
8
As well block-stream doesn't work when copy-on-read is not
9
white-listed.
14
10
15
Fixes: 69f47505ee66afaa513305de0c1895a224e52c45
11
Fixes: 751cec7a261adaf1145dc7adf6de7c9c084e5a0b
16
Cc: qemu-stable@nongnu.org
12
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2004812
17
Reported-by: Michael Weiser <michael.weiser@gmx.de>
13
Reported-by: Yanan Fu
14
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
15
Message-Id: <20210920115538.264372-5-vsementsov@virtuozzo.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
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
---
17
---
24
block/qcow2-refcount.c | 2 ++
18
block.c | 34 ++++++++++++++++++++++++++++------
25
block/qcow2.c | 3 ++-
19
1 file changed, 28 insertions(+), 6 deletions(-)
26
2 files changed, 4 insertions(+), 1 deletion(-)
27
20
28
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
21
diff --git a/block.c b/block.c
29
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
30
--- a/block/qcow2-refcount.c
23
--- a/block.c
31
+++ b/block/qcow2-refcount.c
24
+++ b/block.c
32
@@ -XXX,XX +XXX,XX @@ int qcow2_detect_metadata_preallocation(BlockDriverState *bs)
25
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options,
33
int64_t i, end_cluster, cluster_count = 0, threshold;
26
{
34
int64_t file_length, real_allocation, real_clusters;
27
ERRP_GUARD();
35
28
int ret;
36
+ qemu_co_mutex_assert_locked(&s->lock);
29
- BlockDriverState *new_node_bs;
30
+ BlockDriverState *new_node_bs = NULL;
31
+ const char *drvname, *node_name;
32
+ BlockDriver *drv;
37
+
33
+
38
file_length = bdrv_getlength(bs->file->bs);
34
+ drvname = qdict_get_try_str(options, "driver");
39
if (file_length < 0) {
35
+ if (!drvname) {
40
return file_length;
36
+ error_setg(errp, "driver is not specified");
41
diff --git a/block/qcow2.c b/block/qcow2.c
37
+ goto fail;
42
index XXXXXXX..XXXXXXX 100644
38
+ }
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
+
39
+
51
if (!s->metadata_preallocation_checked) {
40
+ drv = bdrv_find_format(drvname);
52
ret = qcow2_detect_metadata_preallocation(bs);
41
+ if (!drv) {
53
s->metadata_preallocation = (ret == 1);
42
+ error_setg(errp, "Unknown driver: '%s'", drvname);
54
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
43
+ goto fail;
44
+ }
45
46
- new_node_bs = bdrv_open(NULL, NULL, options, flags, errp);
47
- if (new_node_bs == NULL) {
48
+ node_name = qdict_get_try_str(options, "node-name");
49
+
50
+ new_node_bs = bdrv_new_open_driver_opts(drv, node_name, options, flags,
51
+ errp);
52
+ options = NULL; /* bdrv_new_open_driver() eats options */
53
+ if (!new_node_bs) {
54
error_prepend(errp, "Could not create node: ");
55
- return NULL;
56
+ goto fail;
55
}
57
}
56
58
57
bytes = MIN(INT_MAX, count);
59
bdrv_drained_begin(bs);
58
- qemu_co_mutex_lock(&s->lock);
60
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options,
59
ret = qcow2_get_cluster_offset(bs, offset, &bytes, &cluster_offset);
61
60
qemu_co_mutex_unlock(&s->lock);
61
if (ret < 0) {
62
if (ret < 0) {
63
error_prepend(errp, "Could not replace node: ");
64
- bdrv_unref(new_node_bs);
65
- return NULL;
66
+ goto fail;
67
}
68
69
return new_node_bs;
70
+
71
+fail:
72
+ qobject_unref(options);
73
+ bdrv_unref(new_node_bs);
74
+ return NULL;
75
}
76
77
/*
62
--
78
--
63
2.20.1
79
2.31.1
64
80
65
81
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Now test fails if copy-before-write is not white-listed.
4
Let's skip test instead.
5
6
Fixes: c0605985696a19ef034fa25d04f53f3b3b383896
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-Id: <20210920115538.264372-6-vsementsov@virtuozzo.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
tests/qemu-iotests/tests/image-fleecing | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/tests/qemu-iotests/tests/image-fleecing b/tests/qemu-iotests/tests/image-fleecing
15
index XXXXXXX..XXXXXXX 100755
16
--- a/tests/qemu-iotests/tests/image-fleecing
17
+++ b/tests/qemu-iotests/tests/image-fleecing
18
@@ -XXX,XX +XXX,XX @@ from iotests import log, qemu_img, qemu_io, qemu_io_silent
19
iotests.script_initialize(
20
supported_fmts=['qcow2', 'qcow', 'qed', 'vmdk', 'vhdx', 'raw'],
21
supported_platforms=['linux'],
22
+ required_fmts=['copy-before-write'],
23
)
24
25
patterns = [('0x5d', '0', '64k'),
26
--
27
2.31.1
28
29
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
Linux limits the size of iovecs to 1024 (UIO_MAXIOV in the kernel
4
sources, IOV_MAX in POSIX). Because of this, on some host adapters
5
requests with many iovecs are rejected with -EINVAL by the
6
io_submit() or readv()/writev() system calls.
7
8
In fact, the same limit applies to SG_IO as well. To fix both the
9
EINVAL and the possible performance issues from using fewer iovecs
10
than allowed by Linux (some HBAs have max_segments as low as 128),
11
introduce a separate entry in BlockLimits to hold the max_segments
12
value from sysfs. This new limit is used only for SG_IO and clamped
13
to bs->bl.max_iov anyway, just like max_hw_transfer is clamped to
14
bs->bl.max_transfer.
15
16
Reported-by: Halil Pasic <pasic@linux.ibm.com>
17
Cc: Hanna Reitz <hreitz@redhat.com>
18
Cc: Kevin Wolf <kwolf@redhat.com>
19
Cc: qemu-block@nongnu.org
20
Cc: qemu-stable@nongnu.org
21
Fixes: 18473467d5 ("file-posix: try BLKSECTGET on block devices too, do not round to power of 2", 2021-06-25)
22
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
23
Message-Id: <20210923130436.1187591-1-pbonzini@redhat.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
---
26
include/block/block_int.h | 7 +++++++
27
include/sysemu/block-backend.h | 1 +
28
block/block-backend.c | 6 ++++++
29
block/file-posix.c | 2 +-
30
block/io.c | 1 +
31
hw/scsi/scsi-generic.c | 2 +-
32
6 files changed, 17 insertions(+), 2 deletions(-)
33
34
diff --git a/include/block/block_int.h b/include/block/block_int.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/block/block_int.h
37
+++ b/include/block/block_int.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct BlockLimits {
39
*/
40
uint64_t max_hw_transfer;
41
42
+ /* Maximal number of scatter/gather elements allowed by the hardware.
43
+ * Applies whenever transfers to the device bypass the kernel I/O
44
+ * scheduler, for example with SG_IO. If larger than max_iov
45
+ * or if zero, blk_get_max_hw_iov will fall back to max_iov.
46
+ */
47
+ int max_hw_iov;
48
+
49
/* memory alignment, in bytes so that no bounce buffer is needed */
50
size_t min_mem_alignment;
51
52
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/include/sysemu/block-backend.h
55
+++ b/include/sysemu/block-backend.h
56
@@ -XXX,XX +XXX,XX @@ uint32_t blk_get_request_alignment(BlockBackend *blk);
57
uint32_t blk_get_max_transfer(BlockBackend *blk);
58
uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
59
int blk_get_max_iov(BlockBackend *blk);
60
+int blk_get_max_hw_iov(BlockBackend *blk);
61
void blk_set_guest_block_size(BlockBackend *blk, int align);
62
void *blk_try_blockalign(BlockBackend *blk, size_t size);
63
void *blk_blockalign(BlockBackend *blk, size_t size);
64
diff --git a/block/block-backend.c b/block/block-backend.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/block/block-backend.c
67
+++ b/block/block-backend.c
68
@@ -XXX,XX +XXX,XX @@ uint32_t blk_get_max_transfer(BlockBackend *blk)
69
return ROUND_DOWN(max, blk_get_request_alignment(blk));
70
}
71
72
+int blk_get_max_hw_iov(BlockBackend *blk)
73
+{
74
+ return MIN_NON_ZERO(blk->root->bs->bl.max_hw_iov,
75
+ blk->root->bs->bl.max_iov);
76
+}
77
+
78
int blk_get_max_iov(BlockBackend *blk)
79
{
80
return blk->root->bs->bl.max_iov;
81
diff --git a/block/file-posix.c b/block/file-posix.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/block/file-posix.c
84
+++ b/block/file-posix.c
85
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
86
87
ret = hdev_get_max_segments(s->fd, &st);
88
if (ret > 0) {
89
- bs->bl.max_iov = ret;
90
+ bs->bl.max_hw_iov = ret;
91
}
92
}
93
}
94
diff --git a/block/io.c b/block/io.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/block/io.c
97
+++ b/block/io.c
98
@@ -XXX,XX +XXX,XX @@ static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
99
dst->min_mem_alignment = MAX(dst->min_mem_alignment,
100
src->min_mem_alignment);
101
dst->max_iov = MIN_NON_ZERO(dst->max_iov, src->max_iov);
102
+ dst->max_hw_iov = MIN_NON_ZERO(dst->max_hw_iov, src->max_hw_iov);
103
}
104
105
typedef struct BdrvRefreshLimitsState {
106
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/scsi/scsi-generic.c
109
+++ b/hw/scsi/scsi-generic.c
110
@@ -XXX,XX +XXX,XX @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
111
page = r->req.cmd.buf[2];
112
if (page == 0xb0) {
113
uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk);
114
- uint32_t max_iov = blk_get_max_iov(s->conf.blk);
115
+ uint32_t max_iov = blk_get_max_hw_iov(s->conf.blk);
116
117
assert(max_transfer);
118
max_transfer = MIN_NON_ZERO(max_transfer, max_iov * qemu_real_host_page_size)
119
--
120
2.31.1
121
122
diff view generated by jsdifflib
1
Some tests in 118 use chmod to remove write permissions from the file
1
From: John Snow <jsnow@redhat.com>
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
2
7
Introduce a @skip_if_root decorator and use it in 118 to skip the tests
3
We can drop the sys.path hacking in various places by doing
8
in question when the script is run as root.
4
this. Additionally, by doing it in one place right up top, we can print
5
interesting warnings in case the environment does not look correct. (See
6
next commit.)
9
7
8
If we ever decide to change how the environment is crafted, all of the
9
"help me find my python packages" goop is all in one place, right in one
10
function.
11
12
Signed-off-by: John Snow <jsnow@redhat.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
15
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
16
Message-Id: <20210923180715.4168522-2-jsnow@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
---
18
---
13
tests/qemu-iotests/118 | 3 +++
19
tests/qemu-iotests/iotests.py | 2 --
14
tests/qemu-iotests/iotests.py | 10 ++++++++++
20
tests/qemu-iotests/testenv.py | 15 +++++++++------
15
2 files changed, 13 insertions(+)
21
tests/qemu-iotests/235 | 2 --
22
tests/qemu-iotests/297 | 6 ------
23
tests/qemu-iotests/300 | 5 ++---
24
tests/qemu-iotests/tests/mirror-top-perms | 7 +++----
25
6 files changed, 14 insertions(+), 23 deletions(-)
16
26
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
27
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
46
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
47
--- a/tests/qemu-iotests/iotests.py
29
--- a/tests/qemu-iotests/iotests.py
48
+++ b/tests/qemu-iotests/iotests.py
30
+++ b/tests/qemu-iotests/iotests.py
49
@@ -XXX,XX +XXX,XX @@ def skip_if_unsupported(required_formats=[], read_only=False):
31
@@ -XXX,XX +XXX,XX @@
50
return func_wrapper
32
51
return skip_test_decorator
33
from contextlib import contextmanager
52
34
53
+def skip_if_user_is_root(func):
35
-# pylint: disable=import-error, wrong-import-position
54
+ '''Skip Test Decorator
36
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
55
+ Runs the test only without root permissions'''
37
from qemu.machine import qtest
56
+ def func_wrapper(*args, **kwargs):
38
from qemu.qmp import QMPMessage
57
+ if os.getuid() == 0:
39
58
+ case_notrun('{}: cannot be run as root'.format(args[0]))
40
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
59
+ else:
41
index XXXXXXX..XXXXXXX 100644
60
+ return func(*args, **kwargs)
42
--- a/tests/qemu-iotests/testenv.py
61
+ return func_wrapper
43
+++ b/tests/qemu-iotests/testenv.py
44
@@ -XXX,XX +XXX,XX @@ def init_directories(self) -> None:
45
SAMPLE_IMG_DIR
46
OUTPUT_DIR
47
"""
48
- self.pythonpath = os.getenv('PYTHONPATH')
49
- if self.pythonpath:
50
- self.pythonpath = self.source_iotests + os.pathsep + \
51
- self.pythonpath
52
- else:
53
- self.pythonpath = self.source_iotests
62
+
54
+
63
def execute_unittest(output, verbosity, debug):
55
+ # Path where qemu goodies live in this source tree.
64
runner = unittest.TextTestRunner(stream=output, descriptions=True,
56
+ qemu_srctree_path = Path(__file__, '../../../python').resolve()
65
verbosity=verbosity)
57
+
58
+ self.pythonpath = os.pathsep.join(filter(None, (
59
+ self.source_iotests,
60
+ str(qemu_srctree_path),
61
+ os.getenv('PYTHONPATH'),
62
+ )))
63
64
self.test_dir = os.getenv('TEST_DIR',
65
os.path.join(os.getcwd(), 'scratch'))
66
diff --git a/tests/qemu-iotests/235 b/tests/qemu-iotests/235
67
index XXXXXXX..XXXXXXX 100755
68
--- a/tests/qemu-iotests/235
69
+++ b/tests/qemu-iotests/235
70
@@ -XXX,XX +XXX,XX @@ import os
71
import iotests
72
from iotests import qemu_img_create, qemu_io, file_path, log
73
74
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
75
-
76
from qemu.machine import QEMUMachine
77
78
iotests.script_initialize(supported_fmts=['qcow2'])
79
diff --git a/tests/qemu-iotests/297 b/tests/qemu-iotests/297
80
index XXXXXXX..XXXXXXX 100755
81
--- a/tests/qemu-iotests/297
82
+++ b/tests/qemu-iotests/297
83
@@ -XXX,XX +XXX,XX @@ def run_linters():
84
# Todo notes are fine, but fixme's or xxx's should probably just be
85
# fixed (in tests, at least)
86
env = os.environ.copy()
87
- qemu_module_path = os.path.join(os.path.dirname(__file__),
88
- '..', '..', 'python')
89
- try:
90
- env['PYTHONPATH'] += os.pathsep + qemu_module_path
91
- except KeyError:
92
- env['PYTHONPATH'] = qemu_module_path
93
subprocess.run(('pylint-3', '--score=n', '--notes=FIXME,XXX', *files),
94
env=env, check=False)
95
96
diff --git a/tests/qemu-iotests/300 b/tests/qemu-iotests/300
97
index XXXXXXX..XXXXXXX 100755
98
--- a/tests/qemu-iotests/300
99
+++ b/tests/qemu-iotests/300
100
@@ -XXX,XX +XXX,XX @@ import random
101
import re
102
from typing import Dict, List, Optional
103
104
+from qemu.machine import machine
105
+
106
import iotests
107
108
-# Import qemu after iotests.py has amended sys.path
109
-# pylint: disable=wrong-import-order
110
-from qemu.machine import machine
111
112
BlockBitmapMapping = List[Dict[str, object]]
113
114
diff --git a/tests/qemu-iotests/tests/mirror-top-perms b/tests/qemu-iotests/tests/mirror-top-perms
115
index XXXXXXX..XXXXXXX 100755
116
--- a/tests/qemu-iotests/tests/mirror-top-perms
117
+++ b/tests/qemu-iotests/tests/mirror-top-perms
118
@@ -XXX,XX +XXX,XX @@
119
#
120
121
import os
122
-import iotests
123
-from iotests import qemu_img
124
125
-# Import qemu after iotests.py has amended sys.path
126
-# pylint: disable=wrong-import-order
127
import qemu
128
129
+import iotests
130
+from iotests import qemu_img
131
+
132
133
image_size = 1 * 1024 * 1024
134
source = os.path.join(iotests.test_dir, 'source.img')
66
--
135
--
67
2.20.1
136
2.31.1
68
137
69
138
diff view generated by jsdifflib
1
Some functions require that the caller holds a certain CoMutex for them
1
From: John Snow <jsnow@redhat.com>
2
to operate correctly. Add a function so that they can assert the lock is
3
really held.
4
2
5
Cc: qemu-stable@nongnu.org
3
We can circumvent the '__main__' redefinition problem by passing
4
--scripts-are-modules. Take mypy out of the loop per-filename and check
5
everything in one go: it's quite a bit faster.
6
7
Signed-off-by: John Snow <jsnow@redhat.com>
8
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Message-Id: <20210923180715.4168522-4-jsnow@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
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
---
14
---
13
include/qemu/coroutine.h | 15 +++++++++++++++
15
tests/qemu-iotests/297 | 46 +++++++++++++++++++-----------------------
14
1 file changed, 15 insertions(+)
16
1 file changed, 21 insertions(+), 25 deletions(-)
15
17
16
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
18
diff --git a/tests/qemu-iotests/297 b/tests/qemu-iotests/297
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100755
18
--- a/include/qemu/coroutine.h
20
--- a/tests/qemu-iotests/297
19
+++ b/include/qemu/coroutine.h
21
+++ b/tests/qemu-iotests/297
20
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
22
@@ -XXX,XX +XXX,XX @@ def run_linters():
21
*/
23
print('=== mypy ===')
22
void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
24
sys.stdout.flush()
23
25
24
+/**
26
- # We have to call mypy separately for each file. Otherwise, it
25
+ * Assert that the current coroutine holds @mutex.
27
- # will interpret all given files as belonging together (i.e., they
26
+ */
28
- # may not both define the same classes, etc.; most notably, they
27
+static inline coroutine_fn void qemu_co_mutex_assert_locked(CoMutex *mutex)
29
- # must not both define the __main__ module).
28
+{
30
env['MYPYPATH'] = env['PYTHONPATH']
29
+ /*
31
- for filename in files:
30
+ * mutex->holder doesn't need any synchronisation if the assertion holds
32
- p = subprocess.run(('mypy',
31
+ * true because the mutex protects it. If it doesn't hold true, we still
33
- '--warn-unused-configs',
32
+ * don't mind if another thread takes or releases mutex behind our back,
34
- '--disallow-subclassing-any',
33
+ * because the condition will be false no matter whether we read NULL or
35
- '--disallow-any-generics',
34
+ * the pointer for any other coroutine.
36
- '--disallow-incomplete-defs',
35
+ */
37
- '--disallow-untyped-decorators',
36
+ assert(atomic_read(&mutex->locked) &&
38
- '--no-implicit-optional',
37
+ mutex->holder == qemu_coroutine_self());
39
- '--warn-redundant-casts',
38
+}
40
- '--warn-unused-ignores',
39
41
- '--no-implicit-reexport',
40
/**
42
- '--namespace-packages',
41
* CoQueues are a mechanism to queue coroutines in order to continue executing
43
- filename),
44
- env=env,
45
- check=False,
46
- stdout=subprocess.PIPE,
47
- stderr=subprocess.STDOUT,
48
- universal_newlines=True)
49
-
50
- if p.returncode != 0:
51
- print(p.stdout)
52
+ p = subprocess.run(('mypy',
53
+ '--warn-unused-configs',
54
+ '--disallow-subclassing-any',
55
+ '--disallow-any-generics',
56
+ '--disallow-incomplete-defs',
57
+ '--disallow-untyped-decorators',
58
+ '--no-implicit-optional',
59
+ '--warn-redundant-casts',
60
+ '--warn-unused-ignores',
61
+ '--no-implicit-reexport',
62
+ '--namespace-packages',
63
+ '--scripts-are-modules',
64
+ *files),
65
+ env=env,
66
+ check=False,
67
+ stdout=subprocess.PIPE,
68
+ stderr=subprocess.STDOUT,
69
+ universal_newlines=True)
70
+
71
+ if p.returncode != 0:
72
+ print(p.stdout)
73
74
75
for linter in ('pylint-3', 'mypy'):
42
--
76
--
43
2.20.1
77
2.31.1
44
78
45
79
diff view generated by jsdifflib
1
We added more generic options after introducing -blockdev and forgot to
1
From: John Snow <jsnow@redhat.com>
2
update the documentation (man page and --help output) accordingly. Do
3
that now.
4
2
3
We need to import subpackages from the qemu namespace package; importing
4
the namespace package alone doesn't bring the subpackages with it --
5
unless someone else (like iotests.py) imports them too.
6
7
Adjust the imports.
8
9
Signed-off-by: John Snow <jsnow@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
Message-Id: <20210923180715.4168522-5-jsnow@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
---
16
---
8
qemu-options.hx | 22 +++++++++++++++++++++-
17
tests/qemu-iotests/tests/mirror-top-perms | 7 ++++---
9
1 file changed, 21 insertions(+), 1 deletion(-)
18
1 file changed, 4 insertions(+), 3 deletions(-)
10
19
11
diff --git a/qemu-options.hx b/qemu-options.hx
20
diff --git a/tests/qemu-iotests/tests/mirror-top-perms b/tests/qemu-iotests/tests/mirror-top-perms
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100755
13
--- a/qemu-options.hx
22
--- a/tests/qemu-iotests/tests/mirror-top-perms
14
+++ b/qemu-options.hx
23
+++ b/tests/qemu-iotests/tests/mirror-top-perms
15
@@ -XXX,XX +XXX,XX @@ ETEXI
24
@@ -XXX,XX +XXX,XX @@
16
DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,
25
17
"-blockdev [driver=]driver[,node-name=N][,discard=ignore|unmap]\n"
26
import os
18
" [,cache.direct=on|off][,cache.no-flush=on|off]\n"
27
19
- " [,read-only=on|off][,detect-zeroes=on|off|unmap]\n"
28
-import qemu
20
+ " [,read-only=on|off][,auto-read-only=on|off]\n"
29
+from qemu import qmp
21
+ " [,force-share=on|off][,detect-zeroes=on|off|unmap]\n"
30
+from qemu.machine import machine
22
" [,driver specific parameters...]\n"
31
23
" configure a block backend\n", QEMU_ARCH_ALL)
32
import iotests
24
STEXI
33
from iotests import qemu_img
25
@@ -XXX,XX +XXX,XX @@ name is not intended to be predictable and changes between QEMU invocations.
34
@@ -XXX,XX +XXX,XX @@ class TestMirrorTopPerms(iotests.QMPTestCase):
26
For the top level, an explicit node name must be specified.
35
def tearDown(self):
27
@item read-only
36
try:
28
Open the node read-only. Guest write attempts will fail.
37
self.vm.shutdown()
29
+
38
- except qemu.machine.machine.AbnormalShutdown:
30
+Note that some block drivers support only read-only access, either generally or
39
+ except machine.AbnormalShutdown:
31
+in certain configurations. In this case, the default value
40
pass
32
+@option{read-only=off} does not work and the option must be specified
41
33
+explicitly.
42
if self.vm_b is not None:
34
+@item auto-read-only
43
@@ -XXX,XX +XXX,XX @@ class TestMirrorTopPerms(iotests.QMPTestCase):
35
+If @option{auto-read-only=on} is set, QEMU may fall back to read-only usage
44
self.vm_b.launch()
36
+even when @option{read-only=off} is requested, or even switch between modes as
45
print('ERROR: VM B launched successfully, this should not have '
37
+needed, e.g. depending on whether the image file is writable or whether a
46
'happened')
38
+writing user is attached to the node.
47
- except qemu.qmp.QMPConnectError:
39
+@item force-share
48
+ except qmp.QMPConnectError:
40
+Override the image locking system of QEMU by forcing the node to utilize
49
assert 'Is another process using the image' in self.vm_b.get_log()
41
+weaker shared access for permissions where it would normally request exclusive
50
42
+access. When there is the potential for multiple instances to have the same
51
result = self.vm.qmp('block-job-cancel',
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
--
52
2.20.1
53
2.31.1
53
54
54
55
diff view generated by jsdifflib
1
From: Pavel Dovgalyuk <pavel.dovgaluk@gmail.com>
1
From: John Snow <jsnow@redhat.com>
2
2
3
This patch adds support for blkreplay driver to the blockdev options.
3
Mostly uninteresting stuff. Move the test injections under a function
4
Now blkreplay can be used with -blockdev command line option
4
named main() so that the variables used during that process aren't in
5
in the following format:
5
the global scope.
6
-blockdev driver=blkreplay,image=file-node-name,node-name=replay-node-name
7
6
8
This option makes possible implementation of the better command
7
Signed-off-by: John Snow <jsnow@redhat.com>
9
line support for record/replay invocations.
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
9
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
11
Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Message-Id: <20210923180715.4168522-6-jsnow@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
---
14
qapi/block-core.json | 18 ++++++++++++++++--
15
tests/qemu-iotests/tests/migrate-bitmaps-test | 50 +++++++++++--------
15
1 file changed, 16 insertions(+), 2 deletions(-)
16
1 file changed, 28 insertions(+), 22 deletions(-)
16
17
17
diff --git a/qapi/block-core.json b/qapi/block-core.json
18
diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-test b/tests/qemu-iotests/tests/migrate-bitmaps-test
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100755
19
--- a/qapi/block-core.json
20
--- a/tests/qemu-iotests/tests/migrate-bitmaps-test
20
+++ b/qapi/block-core.json
21
+++ b/tests/qemu-iotests/tests/migrate-bitmaps-test
21
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
22
# @nvme: Since 2.12
23
# along with this program. If not, see <http://www.gnu.org/licenses/>.
23
# @copy-on-read: Since 3.0
24
# @blklogwrites: Since 3.0
25
+# @blkreplay: Since 4.2
26
#
24
#
27
# Since: 2.9
25
28
##
26
-import os
29
{ 'enum': 'BlockdevDriver',
27
import itertools
30
- 'data': [ 'blkdebug', 'blklogwrites', 'blkverify', 'bochs', 'cloop',
28
import operator
31
- 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps', 'gluster',
29
+import os
32
+ 'data': [ 'blkdebug', 'blklogwrites', 'blkreplay', 'blkverify', 'bochs',
30
import re
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
+
31
+
53
##
32
import iotests
54
# @QuorumReadPattern:
33
from iotests import qemu_img, qemu_img_create, Timeout
55
#
34
56
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@ def inject_test_case(klass, suffix, method, *args, **kwargs):
57
'blkdebug': 'BlockdevOptionsBlkdebug',
36
setattr(klass, 'test_' + method + suffix, lambda self: mc(self))
58
'blklogwrites':'BlockdevOptionsBlklogwrites',
37
59
'blkverify': 'BlockdevOptionsBlkverify',
38
60
+ 'blkreplay': 'BlockdevOptionsBlkreplay',
39
-for cmb in list(itertools.product((True, False), repeat=5)):
61
'bochs': 'BlockdevOptionsGenericFormat',
40
- name = ('_' if cmb[0] else '_not_') + 'persistent_'
62
'cloop': 'BlockdevOptionsGenericFormat',
41
- name += ('_' if cmb[1] else '_not_') + 'migbitmap_'
63
'copy-on-read':'BlockdevOptionsGenericFormat',
42
- name += '_online' if cmb[2] else '_offline'
43
- name += '_shared' if cmb[3] else '_nonshared'
44
- if cmb[4]:
45
- name += '__pre_shutdown'
46
-
47
- inject_test_case(TestDirtyBitmapMigration, name, 'do_test_migration',
48
- *list(cmb))
49
-
50
-for cmb in list(itertools.product((True, False), repeat=2)):
51
- name = ('_' if cmb[0] else '_not_') + 'persistent_'
52
- name += ('_' if cmb[1] else '_not_') + 'migbitmap'
53
-
54
- inject_test_case(TestDirtyBitmapMigration, name,
55
- 'do_test_migration_resume_source', *list(cmb))
56
-
57
-
58
class TestDirtyBitmapBackingMigration(iotests.QMPTestCase):
59
def setUp(self):
60
qemu_img_create('-f', iotests.imgfmt, base_a, size)
61
@@ -XXX,XX +XXX,XX @@ class TestDirtyBitmapBackingMigration(iotests.QMPTestCase):
62
self.assert_qmp(result, 'return', {})
63
64
65
+def main() -> None:
66
+ for cmb in list(itertools.product((True, False), repeat=5)):
67
+ name = ('_' if cmb[0] else '_not_') + 'persistent_'
68
+ name += ('_' if cmb[1] else '_not_') + 'migbitmap_'
69
+ name += '_online' if cmb[2] else '_offline'
70
+ name += '_shared' if cmb[3] else '_nonshared'
71
+ if cmb[4]:
72
+ name += '__pre_shutdown'
73
+
74
+ inject_test_case(TestDirtyBitmapMigration, name, 'do_test_migration',
75
+ *list(cmb))
76
+
77
+ for cmb in list(itertools.product((True, False), repeat=2)):
78
+ name = ('_' if cmb[0] else '_not_') + 'persistent_'
79
+ name += ('_' if cmb[1] else '_not_') + 'migbitmap'
80
+
81
+ inject_test_case(TestDirtyBitmapMigration, name,
82
+ 'do_test_migration_resume_source', *list(cmb))
83
+
84
+ iotests.main(
85
+ supported_fmts=['qcow2'],
86
+ supported_protocols=['file']
87
+ )
88
+
89
+
90
if __name__ == '__main__':
91
- iotests.main(supported_fmts=['qcow2'],
92
- supported_protocols=['file'])
93
+ main()
64
--
94
--
65
2.20.1
95
2.31.1
66
96
67
97
diff view generated by jsdifflib
1
Instead of using monitor_printf() to report errors, hmp_commit() should
1
From: John Snow <jsnow@redhat.com>
2
use error_report() like other places do.
3
2
3
1. Ignore the new f-strings warning, we're not interested in doing a
4
full conversion at this time.
5
6
2. Just mute the unbalanced-tuple-unpacking warning, it's not a real
7
error in this case and muting the dozens of callsites is just not
8
worth it.
9
10
3. Add encodings to read_text().
11
12
Signed-off-by: John Snow <jsnow@redhat.com>
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
15
Message-Id: <20210923180715.4168522-7-jsnow@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
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
---
17
---
8
blockdev.c | 7 +++----
18
tests/qemu-iotests/testrunner.py | 7 ++++---
9
1 file changed, 3 insertions(+), 4 deletions(-)
19
tests/qemu-iotests/pylintrc | 6 +++++-
20
2 files changed, 9 insertions(+), 4 deletions(-)
10
21
11
diff --git a/blockdev.c b/blockdev.c
22
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
12
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
13
--- a/blockdev.c
24
--- a/tests/qemu-iotests/testrunner.py
14
+++ b/blockdev.c
25
+++ b/tests/qemu-iotests/testrunner.py
15
@@ -XXX,XX +XXX,XX @@ void hmp_commit(Monitor *mon, const QDict *qdict)
26
@@ -XXX,XX +XXX,XX @@ def do_run_test(self, test: str) -> TestResult:
16
27
diff=file_diff(str(f_reference), str(f_bad)))
17
blk = blk_by_name(device);
28
18
if (!blk) {
29
if f_notrun.exists():
19
- monitor_printf(mon, "Device '%s' not found\n", device);
30
- return TestResult(status='not run',
20
+ error_report("Device '%s' not found", device);
31
- description=f_notrun.read_text().strip())
21
return;
32
+ return TestResult(
22
}
33
+ status='not run',
23
if (!blk_is_available(blk)) {
34
+ description=f_notrun.read_text(encoding='utf-8').strip())
24
- monitor_printf(mon, "Device '%s' has no medium\n", device);
35
25
+ error_report("Device '%s' has no medium", device);
36
casenotrun = ''
26
return;
37
if f_casenotrun.exists():
27
}
38
- casenotrun = f_casenotrun.read_text()
28
39
+ casenotrun = f_casenotrun.read_text(encoding='utf-8')
29
@@ -XXX,XX +XXX,XX @@ void hmp_commit(Monitor *mon, const QDict *qdict)
40
30
aio_context_release(aio_context);
41
diff = file_diff(str(f_reference), str(f_bad))
31
}
42
if diff:
32
if (ret < 0) {
43
diff --git a/tests/qemu-iotests/pylintrc b/tests/qemu-iotests/pylintrc
33
- monitor_printf(mon, "'commit' error for '%s': %s\n", device,
44
index XXXXXXX..XXXXXXX 100644
34
- strerror(-ret));
45
--- a/tests/qemu-iotests/pylintrc
35
+ error_report("'commit' error for '%s': %s", device, strerror(-ret));
46
+++ b/tests/qemu-iotests/pylintrc
36
}
47
@@ -XXX,XX +XXX,XX @@ disable=invalid-name,
37
}
48
too-many-public-methods,
49
# pylint warns about Optional[] etc. as unsubscriptable in 3.9
50
unsubscriptable-object,
51
+ # pylint's static analysis causes false positivies for file_path();
52
+ # If we really care to make it statically knowable, we'll use mypy.
53
+ unbalanced-tuple-unpacking,
54
# Sometimes we need to disable a newly introduced pylint warning.
55
# Doing so should not produce a warning in older versions of pylint.
56
bad-option-value,
57
# These are temporary, and should be removed:
58
missing-docstring,
59
too-many-return-statements,
60
- too-many-statements
61
+ too-many-statements,
62
+ consider-using-f-string,
63
64
[FORMAT]
38
65
39
--
66
--
40
2.20.1
67
2.31.1
41
68
42
69
diff view generated by jsdifflib