1
The following changes since commit bfec359afba088aaacc7d316f43302f28c6e642a:
1
The following changes since commit 96662996eda78c48aadddd4e76d8615c7eb72d80:
2
2
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qdev-2017-04-21' into staging (2017-04-21 11:42:03 +0100)
3
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20210513a' into staging (2021-05-14 12:03:47 +0100)
4
4
5
are available in the git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/codyprime/qemu-kvm-jtc.git tags/block-pull-request
7
https://github.com/XanClic/qemu.git tags/pull-block-2021-05-14
8
8
9
for you to fetch changes up to 1507631e438930bc07f776f303af127a9cdb4d41:
9
for you to fetch changes up to c61ebf362d0abf288ce266845519d5a550a1d89f:
10
10
11
qemu-iotests: _cleanup_qemu must be called on exit (2017-04-21 08:32:44 -0400)
11
write-threshold: deal with includes (2021-05-14 16:14:10 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
Block patches:
15
Block patches for 2.10
15
- drop block/io write notifiers
16
- qemu-iotests enhancements to make debugging easier
17
- rbd parsing fix
18
- HMP qemu-io fix (for iothreads)
19
- mirror job cancel relaxation (do not cancel in-flight requests when a
20
READY mirror job is canceled with force=false)
21
- document qcow2's data_file and data_file_raw features
22
- fix iotest 297 for pylint 2.8
23
- block/copy-on-read refactoring
16
24
17
----------------------------------------------------------------
25
----------------------------------------------------------------
26
Connor Kuehl (3):
27
iotests/231: Update expected deprecation message
28
block/rbd: Add an escape-aware strchr helper
29
Document qemu-img options data_file and data_file_raw
18
30
19
Ashish Mittal (2):
31
Emanuele Giuseppe Esposito (1):
20
block/vxhs.c: Add support for a new block device type called "vxhs"
32
qemu-iotests: fix pylint 2.8 consider-using-with error
21
block/vxhs.c: Add qemu-iotests for new block device type "vxhs"
22
33
23
Jeff Cody (10):
34
Paolo Bonzini (5):
24
qemu-iotests: exclude vxhs from image creation via protocol
35
qemu-iotests: do not buffer the test output
25
block: add bdrv_set_read_only() helper function
36
qemu-iotests: allow passing unittest.main arguments to the test
26
block: do not set BDS read_only if copy_on_read enabled
37
scripts
27
block: honor BDRV_O_ALLOW_RDWR when clearing bs->read_only
38
qemu-iotests: move command line and environment handling from
28
block: code movement
39
TestRunner to TestEnv
29
block: introduce bdrv_can_set_read_only()
40
qemu-iotests: let "check" spawn an arbitrary test command
30
block: use bdrv_can_set_read_only() during reopen
41
qemu-iotests: fix case of SOCK_DIR already in the environment
31
block/rbd - update variable names to more apt names
32
block/rbd: Add support for reopen()
33
qemu-iotests: _cleanup_qemu must be called on exit
34
42
35
block.c | 56 +++-
43
Vladimir Sementsov-Ogievskiy (10):
36
block/Makefile.objs | 2 +
44
monitor: hmp_qemu_io: acquire aio contex, fix crash
37
block/bochs.c | 5 +-
45
mirror: stop cancelling in-flight requests on non-force cancel in
38
block/cloop.c | 5 +-
46
READY
39
block/dmg.c | 6 +-
47
block/copy-on-read: use bdrv_drop_filter() and drop s->active
40
block/rbd.c | 65 +++--
48
block/write-threshold: don't use write notifiers
41
block/trace-events | 17 ++
49
block: drop write notifiers
42
block/vvfat.c | 19 +-
50
test-write-threshold: rewrite test_threshold_(not_)trigger tests
43
block/vxhs.c | 575 +++++++++++++++++++++++++++++++++++++++
51
block/write-threshold: drop extra APIs
44
configure | 39 +++
52
test-write-threshold: drop extra tests
45
include/block/block.h | 2 +
53
test-write-threshold: drop extra TestStruct structure
46
qapi/block-core.json | 23 +-
54
write-threshold: deal with includes
47
tests/qemu-iotests/017 | 1 +
55
48
tests/qemu-iotests/020 | 1 +
56
docs/tools/qemu-img.rst | 31 +++++++
49
tests/qemu-iotests/028 | 1 +
57
include/block/block_int.h | 15 +---
50
tests/qemu-iotests/029 | 1 +
58
include/block/write-threshold.h | 27 ++----
51
tests/qemu-iotests/073 | 1 +
59
include/qemu/job.h | 2 +-
52
tests/qemu-iotests/094 | 11 +-
60
block.c | 1 -
53
tests/qemu-iotests/102 | 5 +-
61
block/backup.c | 2 +-
54
tests/qemu-iotests/109 | 1 +
62
block/copy-on-read.c | 33 +------
55
tests/qemu-iotests/114 | 1 +
63
block/io.c | 11 +--
56
tests/qemu-iotests/117 | 1 +
64
block/mirror.c | 6 +-
57
tests/qemu-iotests/130 | 2 +
65
block/monitor/block-hmp-cmds.c | 31 ++++---
58
tests/qemu-iotests/134 | 1 +
66
block/rbd.c | 32 ++++---
59
tests/qemu-iotests/140 | 1 +
67
block/write-threshold.c | 91 ++++---------------
60
tests/qemu-iotests/141 | 1 +
68
job.c | 2 +-
61
tests/qemu-iotests/143 | 1 +
69
qemu-io-cmds.c | 8 +-
62
tests/qemu-iotests/156 | 2 +
70
qemu-io.c | 17 +++-
63
tests/qemu-iotests/158 | 1 +
71
tests/unit/test-write-threshold.c | 90 ++-----------------
64
tests/qemu-iotests/common | 6 +
72
tests/qemu-iotests/231 | 4 +
65
tests/qemu-iotests/common.config | 13 +
73
tests/qemu-iotests/231.out | 7 +-
66
tests/qemu-iotests/common.filter | 1 +
74
tests/qemu-iotests/240.out | 8 +-
67
tests/qemu-iotests/common.rc | 19 ++
75
tests/qemu-iotests/245.out | 8 +-
68
33 files changed, 844 insertions(+), 42 deletions(-)
76
tests/qemu-iotests/264 | 2 +-
69
create mode 100644 block/vxhs.c
77
tests/qemu-iotests/295.out | 6 +-
78
tests/qemu-iotests/296.out | 8 +-
79
tests/qemu-iotests/check | 19 +++-
80
tests/qemu-iotests/iotests.py | 145 +++++++++++++++++-------------
81
tests/qemu-iotests/pylintrc | 3 +
82
tests/qemu-iotests/testenv.py | 22 ++++-
83
tests/qemu-iotests/testrunner.py | 37 +++-----
84
28 files changed, 289 insertions(+), 379 deletions(-)
70
85
71
--
86
--
72
2.9.3
87
2.31.1
73
88
74
89
diff view generated by jsdifflib
New patch
1
From: Connor Kuehl <ckuehl@redhat.com>
1
2
3
The deprecation message in the expected output has technically been
4
wrong since the wrong version of a patch was applied to it. Because of
5
this, the test fails. Correct the expected output so that it passes.
6
7
Signed-off-by: Connor Kuehl <ckuehl@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-Id: <20210421212343.85524-2-ckuehl@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
13
tests/qemu-iotests/231.out | 4 +---
14
1 file changed, 1 insertion(+), 3 deletions(-)
15
16
diff --git a/tests/qemu-iotests/231.out b/tests/qemu-iotests/231.out
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qemu-iotests/231.out
19
+++ b/tests/qemu-iotests/231.out
20
@@ -XXX,XX +XXX,XX @@
21
QA output created by 231
22
-qemu-img: RBD options encoded in the filename as keyvalue pairs is deprecated. Future versions may cease to parse these options in the future.
23
+qemu-img: warning: RBD options encoded in the filename as keyvalue pairs is deprecated
24
unable to get monitor info from DNS SRV with service name: ceph-mon
25
-no monitors specified to connect to.
26
qemu-img: Could not open 'json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=BOGUS_CONF'}': error connecting: No such file or directory
27
unable to get monitor info from DNS SRV with service name: ceph-mon
28
-no monitors specified to connect to.
29
qemu-img: Could not open 'json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'BOGUS_CONF'}': error connecting: No such file or directory
30
*** done
31
--
32
2.31.1
33
34
diff view generated by jsdifflib
1
This adds support for reopen in rbd, for changing between r/w and r/o.
1
From: Connor Kuehl <ckuehl@redhat.com>
2
2
3
Note, that this is only a flag change, but we will block a change from
3
Sometimes the parser needs to further split a token it has collected
4
r/o to r/w if we are using an RBD internal snapshot.
4
from the token input stream. Right now, it does a cursory check to see
5
if the relevant characters appear in the token to determine if it should
6
break it down further.
5
7
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
However, qemu_rbd_next_tok() will escape characters as it removes tokens
7
Signed-off-by: Jeff Cody <jcody@redhat.com>
9
from the token stream and plain strchr() won't. This can make the
8
Reviewed-by: John Snow <jsnow@redhat.com>
10
initial strchr() check slightly misleading since it implies
9
Message-id: d4e87539167ec6527d44c97b164eabcccf96e4f3.1491597120.git.jcody@redhat.com
11
qemu_rbd_next_tok() will find the token and split on it, except the
12
reality is that qemu_rbd_next_tok() will pass over it if it is escaped.
13
14
Use a custom strchr to avoid mixing escaped and unescaped string
15
operations. Furthermore, this code is identical to how
16
qemu_rbd_next_tok() seeks its next token, so incorporate this custom
17
strchr into the body of that function to reduce duplication.
18
19
Reported-by: Han Han <hhan@redhat.com>
20
Fixes: https://bugzilla.redhat.com/1873913
21
Signed-off-by: Connor Kuehl <ckuehl@redhat.com>
22
Message-Id: <20210421212343.85524-3-ckuehl@redhat.com>
23
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
24
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
25
---
11
block/rbd.c | 21 +++++++++++++++++++++
26
block/rbd.c | 32 +++++++++++++++++++++-----------
12
1 file changed, 21 insertions(+)
27
tests/qemu-iotests/231 | 4 ++++
28
tests/qemu-iotests/231.out | 3 +++
29
3 files changed, 28 insertions(+), 11 deletions(-)
13
30
14
diff --git a/block/rbd.c b/block/rbd.c
31
diff --git a/block/rbd.c b/block/rbd.c
15
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
16
--- a/block/rbd.c
33
--- a/block/rbd.c
17
+++ b/block/rbd.c
34
+++ b/block/rbd.c
18
@@ -XXX,XX +XXX,XX @@ failed_opts:
35
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
19
return r;
36
const char *keypairs, const char *secretid,
20
}
37
Error **errp);
21
38
39
+static char *qemu_rbd_strchr(char *src, char delim)
40
+{
41
+ char *p;
22
+
42
+
23
+/* Since RBD is currently always opened R/W via the API,
43
+ for (p = src; *p; ++p) {
24
+ * we just need to check if we are using a snapshot or not, in
44
+ if (*p == delim) {
25
+ * order to determine if we will allow it to be R/W */
45
+ return p;
26
+static int qemu_rbd_reopen_prepare(BDRVReopenState *state,
46
+ }
27
+ BlockReopenQueue *queue, Error **errp)
47
+ if (*p == '\\' && p[1] != '\0') {
28
+{
48
+ ++p;
29
+ BDRVRBDState *s = state->bs->opaque;
49
+ }
30
+ int ret = 0;
31
+
32
+ if (s->snap && state->flags & BDRV_O_RDWR) {
33
+ error_setg(errp,
34
+ "Cannot change node '%s' to r/w when using RBD snapshot",
35
+ bdrv_get_device_or_node_name(state->bs));
36
+ ret = -EINVAL;
37
+ }
50
+ }
38
+
51
+
39
+ return ret;
52
+ return NULL;
40
+}
53
+}
41
+
54
+
42
static void qemu_rbd_close(BlockDriverState *bs)
55
+
56
static char *qemu_rbd_next_tok(char *src, char delim, char **p)
43
{
57
{
44
BDRVRBDState *s = bs->opaque;
58
char *end;
45
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_rbd = {
59
46
.bdrv_parse_filename = qemu_rbd_parse_filename,
60
*p = NULL;
47
.bdrv_file_open = qemu_rbd_open,
61
48
.bdrv_close = qemu_rbd_close,
62
- for (end = src; *end; ++end) {
49
+ .bdrv_reopen_prepare = qemu_rbd_reopen_prepare,
63
- if (*end == delim) {
50
.bdrv_create = qemu_rbd_create,
64
- break;
51
.bdrv_has_zero_init = bdrv_has_zero_init_1,
65
- }
52
.bdrv_get_info = qemu_rbd_getinfo,
66
- if (*end == '\\' && end[1] != '\0') {
67
- end++;
68
- }
69
- }
70
- if (*end == delim) {
71
+ end = qemu_rbd_strchr(src, delim);
72
+ if (end) {
73
*p = end + 1;
74
*end = '\0';
75
}
76
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
77
qemu_rbd_unescape(found_str);
78
qdict_put_str(options, "pool", found_str);
79
80
- if (strchr(p, '@')) {
81
+ if (qemu_rbd_strchr(p, '@')) {
82
image_name = qemu_rbd_next_tok(p, '@', &p);
83
84
found_str = qemu_rbd_next_tok(p, ':', &p);
85
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
86
image_name = qemu_rbd_next_tok(p, ':', &p);
87
}
88
/* Check for namespace in the image_name */
89
- if (strchr(image_name, '/')) {
90
+ if (qemu_rbd_strchr(image_name, '/')) {
91
found_str = qemu_rbd_next_tok(image_name, '/', &image_name);
92
qemu_rbd_unescape(found_str);
93
qdict_put_str(options, "namespace", found_str);
94
diff --git a/tests/qemu-iotests/231 b/tests/qemu-iotests/231
95
index XXXXXXX..XXXXXXX 100755
96
--- a/tests/qemu-iotests/231
97
+++ b/tests/qemu-iotests/231
98
@@ -XXX,XX +XXX,XX @@ _filter_conf()
99
$QEMU_IMG info "json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=${BOGUS_CONF}'}" 2>&1 | _filter_conf
100
$QEMU_IMG info "json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'${BOGUS_CONF}'}" 2>&1 | _filter_conf
101
102
+# Regression test: the qemu-img invocation is expected to fail, but it should
103
+# not seg fault the parser.
104
+$QEMU_IMG create "rbd:rbd/aa\/bb:conf=${BOGUS_CONF}" 1M 2>&1 | _filter_conf
105
+
106
# success, all done
107
echo "*** done"
108
rm -f $seq.full
109
diff --git a/tests/qemu-iotests/231.out b/tests/qemu-iotests/231.out
110
index XXXXXXX..XXXXXXX 100644
111
--- a/tests/qemu-iotests/231.out
112
+++ b/tests/qemu-iotests/231.out
113
@@ -XXX,XX +XXX,XX @@ unable to get monitor info from DNS SRV with service name: ceph-mon
114
qemu-img: Could not open 'json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=BOGUS_CONF'}': error connecting: No such file or directory
115
unable to get monitor info from DNS SRV with service name: ceph-mon
116
qemu-img: Could not open 'json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'BOGUS_CONF'}': error connecting: No such file or directory
117
+Formatting 'rbd:rbd/aa\/bb:conf=BOGUS_CONF', fmt=raw size=1048576
118
+unable to get monitor info from DNS SRV with service name: ceph-mon
119
+qemu-img: rbd:rbd/aa\/bb:conf=BOGUS_CONF: error connecting: No such file or directory
120
*** done
53
--
121
--
54
2.9.3
122
2.31.1
55
123
56
124
diff view generated by jsdifflib
1
From: Ashish Mittal <ashmit602@gmail.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Source code for the qnio library that this code loads can be downloaded from:
3
Max reported the following bug:
4
https://github.com/VeritasHyperScale/libqnio.git
4
5
5
$ ./qemu-img create -f raw src.img 1G
6
Sample command line using JSON syntax:
6
$ ./qemu-img create -f raw dst.img 1G
7
./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
7
8
-k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
8
$ (echo '
9
-msg timestamp=on
9
{"execute":"qmp_capabilities"}
10
'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
10
{"execute":"blockdev-mirror",
11
"server":{"host":"172.172.17.4","port":"9999"}}'
11
"arguments":{"job-id":"mirror",
12
12
"device":"source",
13
Sample command line using URI syntax:
13
"target":"target",
14
qemu-img convert -f raw -O raw -n
14
"sync":"full",
15
/var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
15
"filter-node-name":"mirror-top"}}
16
vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
16
'; sleep 3; echo '
17
17
{"execute":"human-monitor-command",
18
Sample command line using TLS credentials (run in secure mode):
18
"arguments":{"command-line":
19
./qemu-io --object
19
"qemu-io mirror-top \"write 0 1G\""}}') \
20
tls-creds-x509,id=tls0,dir=/etc/pki/qemu/vxhs,endpoint=client -c 'read
20
| x86_64-softmmu/qemu-system-x86_64 \
21
-v 66000 2.5k' 'json:{"server.host": "127.0.0.1", "server.port": "9999",
21
-qmp stdio \
22
"vdisk-id": "/test.raw", "driver": "vxhs", "tls-creds":"tls0"}'
22
-blockdev file,node-name=source,filename=src.img \
23
23
-blockdev file,node-name=target,filename=dst.img \
24
Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
24
-object iothread,id=iothr0 \
25
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
25
-device virtio-blk,drive=source,iothread=iothr0
26
Reviewed-by: Jeff Cody <jcody@redhat.com>
26
27
Signed-off-by: Jeff Cody <jcody@redhat.com>
27
crashes:
28
Message-id: 1491277689-24949-2-git-send-email-Ashish.Mittal@veritas.com
28
29
0 raise () at /usr/lib/libc.so.6
30
1 abort () at /usr/lib/libc.so.6
31
2 error_exit
32
(err=<optimized out>,
33
msg=msg@entry=0x55fbb1634790 <__func__.27> "qemu_mutex_unlock_impl")
34
at ../util/qemu-thread-posix.c:37
35
3 qemu_mutex_unlock_impl
36
(mutex=mutex@entry=0x55fbb25ab6e0,
37
file=file@entry=0x55fbb1636957 "../util/async.c",
38
line=line@entry=650)
39
at ../util/qemu-thread-posix.c:109
40
4 aio_context_release (ctx=ctx@entry=0x55fbb25ab680) at ../util/async.c:650
41
5 bdrv_do_drained_begin
42
(bs=bs@entry=0x55fbb3a87000, recursive=recursive@entry=false,
43
parent=parent@entry=0x0,
44
ignore_bds_parents=ignore_bds_parents@entry=false,
45
poll=poll@entry=true) at ../block/io.c:441
46
6 bdrv_do_drained_begin
47
(poll=true, ignore_bds_parents=false, parent=0x0, recursive=false,
48
bs=0x55fbb3a87000) at ../block/io.c:448
49
7 blk_drain (blk=0x55fbb26c5a00) at ../block/block-backend.c:1718
50
8 blk_unref (blk=0x55fbb26c5a00) at ../block/block-backend.c:498
51
9 blk_unref (blk=0x55fbb26c5a00) at ../block/block-backend.c:491
52
10 hmp_qemu_io (mon=0x7fffaf3fc7d0, qdict=<optimized out>)
53
at ../block/monitor/block-hmp-cmds.c:628
54
55
man pthread_mutex_unlock
56
...
57
EPERM The mutex type is PTHREAD_MUTEX_ERRORCHECK or
58
PTHREAD_MUTEX_RECURSIVE, or the mutex is a robust mutex, and the
59
current thread does not own the mutex.
60
61
So, thread doesn't own the mutex. And we have iothread here.
62
63
Next, note that AIO_WAIT_WHILE() documents that ctx must be acquired
64
exactly once by caller. But where is it acquired in the call stack?
65
Seems nowhere.
66
67
qemuio_command do acquire aio context.. But we need context acquired
68
around blk_unref() as well and actually around blk_insert_bs() too.
69
70
Let's refactor qemuio_command so that it doesn't acquire aio context
71
but callers do that instead. This way we can cleanly acquire aio
72
context in hmp_qemu_io() around all three calls.
73
74
Reported-by: Max Reitz <mreitz@redhat.com>
75
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
76
Message-Id: <20210423134233.51495-1-vsementsov@virtuozzo.com>
77
[mreitz: Fixed comment]
78
Signed-off-by: Max Reitz <mreitz@redhat.com>
29
---
79
---
30
block/Makefile.objs | 2 +
80
block/monitor/block-hmp-cmds.c | 31 +++++++++++++++++++++----------
31
block/trace-events | 17 ++
81
qemu-io-cmds.c | 8 ++++----
32
block/vxhs.c | 575 +++++++++++++++++++++++++++++++++++++++++++++++++++
82
qemu-io.c | 17 +++++++++++++++--
33
configure | 39 ++++
83
3 files changed, 40 insertions(+), 16 deletions(-)
34
qapi/block-core.json | 23 ++-
84
35
5 files changed, 654 insertions(+), 2 deletions(-)
85
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
36
create mode 100644 block/vxhs.c
37
38
diff --git a/block/Makefile.objs b/block/Makefile.objs
39
index XXXXXXX..XXXXXXX 100644
86
index XXXXXXX..XXXXXXX 100644
40
--- a/block/Makefile.objs
87
--- a/block/monitor/block-hmp-cmds.c
41
+++ b/block/Makefile.objs
88
+++ b/block/monitor/block-hmp-cmds.c
42
@@ -XXX,XX +XXX,XX @@ block-obj-$(CONFIG_LIBNFS) += nfs.o
89
@@ -XXX,XX +XXX,XX @@ void hmp_eject(Monitor *mon, const QDict *qdict)
43
block-obj-$(CONFIG_CURL) += curl.o
90
44
block-obj-$(CONFIG_RBD) += rbd.o
91
void hmp_qemu_io(Monitor *mon, const QDict *qdict)
45
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
92
{
46
+block-obj-$(CONFIG_VXHS) += vxhs.o
93
- BlockBackend *blk;
47
block-obj-$(CONFIG_LIBSSH2) += ssh.o
94
+ BlockBackend *blk = NULL;
48
block-obj-y += accounting.o dirty-bitmap.o
95
+ BlockDriverState *bs = NULL;
49
block-obj-y += write-threshold.o
96
BlockBackend *local_blk = NULL;
50
@@ -XXX,XX +XXX,XX @@ rbd.o-cflags := $(RBD_CFLAGS)
97
+ AioContext *ctx = NULL;
51
rbd.o-libs := $(RBD_LIBS)
98
bool qdev = qdict_get_try_bool(qdict, "qdev", false);
52
gluster.o-cflags := $(GLUSTERFS_CFLAGS)
99
const char *device = qdict_get_str(qdict, "device");
53
gluster.o-libs := $(GLUSTERFS_LIBS)
100
const char *command = qdict_get_str(qdict, "command");
54
+vxhs.o-libs := $(VXHS_LIBS)
101
@@ -XXX,XX +XXX,XX @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
55
ssh.o-cflags := $(LIBSSH2_CFLAGS)
102
} else {
56
ssh.o-libs := $(LIBSSH2_LIBS)
103
blk = blk_by_name(device);
57
block-obj-$(if $(CONFIG_BZIP2),m,n) += dmg-bz2.o
104
if (!blk) {
58
diff --git a/block/trace-events b/block/trace-events
105
- BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
106
- if (bs) {
107
- blk = local_blk = blk_new(bdrv_get_aio_context(bs),
108
- 0, BLK_PERM_ALL);
109
- ret = blk_insert_bs(blk, bs, &err);
110
- if (ret < 0) {
111
- goto fail;
112
- }
113
- } else {
114
+ bs = bdrv_lookup_bs(NULL, device, &err);
115
+ if (!bs) {
116
goto fail;
117
}
118
}
119
}
120
121
+ ctx = blk ? blk_get_aio_context(blk) : bdrv_get_aio_context(bs);
122
+ aio_context_acquire(ctx);
123
+
124
+ if (bs) {
125
+ blk = local_blk = blk_new(bdrv_get_aio_context(bs), 0, BLK_PERM_ALL);
126
+ ret = blk_insert_bs(blk, bs, &err);
127
+ if (ret < 0) {
128
+ goto fail;
129
+ }
130
+ }
131
+
132
/*
133
* Notably absent: Proper permission management. This is sad, but it seems
134
* almost impossible to achieve without changing the semantics and thereby
135
@@ -XXX,XX +XXX,XX @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
136
137
fail:
138
blk_unref(local_blk);
139
+
140
+ if (ctx) {
141
+ aio_context_release(ctx);
142
+ }
143
+
144
hmp_handle_error(mon, err);
145
}
146
147
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
59
index XXXXXXX..XXXXXXX 100644
148
index XXXXXXX..XXXXXXX 100644
60
--- a/block/trace-events
149
--- a/qemu-io-cmds.c
61
+++ b/block/trace-events
150
+++ b/qemu-io-cmds.c
62
@@ -XXX,XX +XXX,XX @@ qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s
151
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t help_cmd = {
63
qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
152
.oneline = "help for one or all commands",
64
qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
153
};
65
qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
154
66
+
67
+# block/vxhs.c
68
+vxhs_iio_callback(int error) "ctx is NULL: error %d"
69
+vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d"
70
+vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d"
71
+vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d"
72
+vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, void *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d size = %lu offset = %lu ACB = %p. Error = %d, errno = %d"
73
+vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d"
74
+vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %lu"
75
+vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %ld"
76
+vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s"
77
+vxhs_open_vdiskid(const char *vdisk_id) "Opening vdisk-id %s"
78
+vxhs_open_hostinfo(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState"
79
+vxhs_open_iio_open(const char *host) "Failed to connect to storage agent on host %s"
80
+vxhs_parse_uri_hostinfo(char *host, int port) "Host: IP %s, Port %d"
81
+vxhs_close(char *vdisk_guid) "Closing vdisk %s"
82
+vxhs_get_creds(const char *cacert, const char *client_key, const char *client_cert) "cacert %s, client_key %s, client_cert %s"
83
diff --git a/block/vxhs.c b/block/vxhs.c
84
new file mode 100644
85
index XXXXXXX..XXXXXXX
86
--- /dev/null
87
+++ b/block/vxhs.c
88
@@ -XXX,XX +XXX,XX @@
89
+/*
155
+/*
90
+ * QEMU Block driver for Veritas HyperScale (VxHS)
156
+ * Called with aio context of blk acquired. Or with qemu_get_aio_context()
91
+ *
157
+ * context acquired if blk is NULL.
92
+ * Copyright (c) 2017 Veritas Technologies LLC.
93
+ *
94
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
95
+ * See the COPYING file in the top-level directory.
96
+ *
97
+ */
158
+ */
98
+
159
int qemuio_command(BlockBackend *blk, const char *cmd)
99
+#include "qemu/osdep.h"
160
{
100
+#include <qnio/qnio_api.h>
161
- AioContext *ctx;
101
+#include <sys/param.h>
162
char *input;
102
+#include "block/block_int.h"
163
const cmdinfo_t *ct;
103
+#include "qapi/qmp/qerror.h"
164
char **v;
104
+#include "qapi/qmp/qdict.h"
165
@@ -XXX,XX +XXX,XX @@ int qemuio_command(BlockBackend *blk, const char *cmd)
105
+#include "qapi/qmp/qstring.h"
166
if (c) {
106
+#include "trace.h"
167
ct = find_command(v[0]);
107
+#include "qemu/uri.h"
168
if (ct) {
108
+#include "qapi/error.h"
169
- ctx = blk ? blk_get_aio_context(blk) : qemu_get_aio_context();
109
+#include "qemu/uuid.h"
170
- aio_context_acquire(ctx);
110
+#include "crypto/tlscredsx509.h"
171
ret = command(blk, ct, c, v);
111
+
172
- aio_context_release(ctx);
112
+#define VXHS_OPT_FILENAME "filename"
173
} else {
113
+#define VXHS_OPT_VDISK_ID "vdisk-id"
174
fprintf(stderr, "command \"%s\" not found\n", v[0]);
114
+#define VXHS_OPT_SERVER "server"
175
ret = -EINVAL;
115
+#define VXHS_OPT_HOST "host"
176
diff --git a/qemu-io.c b/qemu-io.c
116
+#define VXHS_OPT_PORT "port"
177
index XXXXXXX..XXXXXXX 100644
117
+
178
--- a/qemu-io.c
118
+/* Only accessed under QEMU global mutex */
179
+++ b/qemu-io.c
119
+static uint32_t vxhs_ref;
180
@@ -XXX,XX +XXX,XX @@ static void prep_fetchline(void *opaque)
120
+
181
*fetchable= 1;
121
+typedef enum {
182
}
122
+ VDISK_AIO_READ,
183
123
+ VDISK_AIO_WRITE,
184
+static int do_qemuio_command(const char *cmd)
124
+} VDISKAIOCmd;
125
+
126
+/*
127
+ * HyperScale AIO callbacks structure
128
+ */
129
+typedef struct VXHSAIOCB {
130
+ BlockAIOCB common;
131
+ int err;
132
+} VXHSAIOCB;
133
+
134
+typedef struct VXHSvDiskHostsInfo {
135
+ void *dev_handle; /* Device handle */
136
+ char *host; /* Host name or IP */
137
+ int port; /* Host's port number */
138
+} VXHSvDiskHostsInfo;
139
+
140
+/*
141
+ * Structure per vDisk maintained for state
142
+ */
143
+typedef struct BDRVVXHSState {
144
+ VXHSvDiskHostsInfo vdisk_hostinfo; /* Per host info */
145
+ char *vdisk_guid;
146
+ char *tlscredsid; /* tlscredsid */
147
+} BDRVVXHSState;
148
+
149
+static void vxhs_complete_aio_bh(void *opaque)
150
+{
185
+{
151
+ VXHSAIOCB *acb = opaque;
186
+ int ret;
152
+ BlockCompletionFunc *cb = acb->common.cb;
187
+ AioContext *ctx =
153
+ void *cb_opaque = acb->common.opaque;
188
+ qemuio_blk ? blk_get_aio_context(qemuio_blk) : qemu_get_aio_context();
154
+ int ret = 0;
189
+
155
+
190
+ aio_context_acquire(ctx);
156
+ if (acb->err != 0) {
191
+ ret = qemuio_command(qemuio_blk, cmd);
157
+ trace_vxhs_complete_aio(acb, acb->err);
192
+ aio_context_release(ctx);
158
+ ret = (-EIO);
159
+ }
160
+
161
+ qemu_aio_unref(acb);
162
+ cb(cb_opaque, ret);
163
+}
164
+
165
+/*
166
+ * Called from a libqnio thread
167
+ */
168
+static void vxhs_iio_callback(void *ctx, uint32_t opcode, uint32_t error)
169
+{
170
+ VXHSAIOCB *acb = NULL;
171
+
172
+ switch (opcode) {
173
+ case IRP_READ_REQUEST:
174
+ case IRP_WRITE_REQUEST:
175
+
176
+ /*
177
+ * ctx is VXHSAIOCB*
178
+ * ctx is NULL if error is QNIOERROR_CHANNEL_HUP
179
+ */
180
+ if (ctx) {
181
+ acb = ctx;
182
+ } else {
183
+ trace_vxhs_iio_callback(error);
184
+ goto out;
185
+ }
186
+
187
+ if (error) {
188
+ if (!acb->err) {
189
+ acb->err = error;
190
+ }
191
+ trace_vxhs_iio_callback(error);
192
+ }
193
+
194
+ aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
195
+ vxhs_complete_aio_bh, acb);
196
+ break;
197
+
198
+ default:
199
+ if (error == QNIOERROR_HUP) {
200
+ /*
201
+ * Channel failed, spontaneous notification,
202
+ * not in response to I/O
203
+ */
204
+ trace_vxhs_iio_callback_chnfail(error, errno);
205
+ } else {
206
+ trace_vxhs_iio_callback_unknwn(opcode, error);
207
+ }
208
+ break;
209
+ }
210
+out:
211
+ return;
212
+}
213
+
214
+static QemuOptsList runtime_opts = {
215
+ .name = "vxhs",
216
+ .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
217
+ .desc = {
218
+ {
219
+ .name = VXHS_OPT_FILENAME,
220
+ .type = QEMU_OPT_STRING,
221
+ .help = "URI to the Veritas HyperScale image",
222
+ },
223
+ {
224
+ .name = VXHS_OPT_VDISK_ID,
225
+ .type = QEMU_OPT_STRING,
226
+ .help = "UUID of the VxHS vdisk",
227
+ },
228
+ {
229
+ .name = "tls-creds",
230
+ .type = QEMU_OPT_STRING,
231
+ .help = "ID of the TLS/SSL credentials to use",
232
+ },
233
+ { /* end of list */ }
234
+ },
235
+};
236
+
237
+static QemuOptsList runtime_tcp_opts = {
238
+ .name = "vxhs_tcp",
239
+ .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head),
240
+ .desc = {
241
+ {
242
+ .name = VXHS_OPT_HOST,
243
+ .type = QEMU_OPT_STRING,
244
+ .help = "host address (ipv4 addresses)",
245
+ },
246
+ {
247
+ .name = VXHS_OPT_PORT,
248
+ .type = QEMU_OPT_NUMBER,
249
+ .help = "port number on which VxHSD is listening (default 9999)",
250
+ .def_value_str = "9999"
251
+ },
252
+ { /* end of list */ }
253
+ },
254
+};
255
+
256
+/*
257
+ * Parse incoming URI and populate *options with the host
258
+ * and device information
259
+ */
260
+static int vxhs_parse_uri(const char *filename, QDict *options)
261
+{
262
+ URI *uri = NULL;
263
+ char *port;
264
+ int ret = 0;
265
+
266
+ trace_vxhs_parse_uri_filename(filename);
267
+ uri = uri_parse(filename);
268
+ if (!uri || !uri->server || !uri->path) {
269
+ uri_free(uri);
270
+ return -EINVAL;
271
+ }
272
+
273
+ qdict_put(options, VXHS_OPT_SERVER".host", qstring_from_str(uri->server));
274
+
275
+ if (uri->port) {
276
+ port = g_strdup_printf("%d", uri->port);
277
+ qdict_put(options, VXHS_OPT_SERVER".port", qstring_from_str(port));
278
+ g_free(port);
279
+ }
280
+
281
+ qdict_put(options, "vdisk-id", qstring_from_str(uri->path));
282
+
283
+ trace_vxhs_parse_uri_hostinfo(uri->server, uri->port);
284
+ uri_free(uri);
285
+
193
+
286
+ return ret;
194
+ return ret;
287
+}
195
+}
288
+
196
+
289
+static void vxhs_parse_filename(const char *filename, QDict *options,
197
static int command_loop(void)
290
+ Error **errp)
198
{
291
+{
199
int i, fetchable = 0, prompted = 0;
292
+ if (qdict_haskey(options, "vdisk-id") || qdict_haskey(options, "server")) {
200
@@ -XXX,XX +XXX,XX @@ static int command_loop(void)
293
+ error_setg(errp, "vdisk-id/server and a file name may not be specified "
201
char *input;
294
+ "at the same time");
202
295
+ return;
203
for (i = 0; !quit_qemu_io && i < ncmdline; i++) {
296
+ }
204
- ret = qemuio_command(qemuio_blk, cmdline[i]);
297
+
205
+ ret = do_qemuio_command(cmdline[i]);
298
+ if (strstr(filename, "://")) {
206
if (ret < 0) {
299
+ int ret = vxhs_parse_uri(filename, options);
207
last_error = ret;
300
+ if (ret < 0) {
208
}
301
+ error_setg(errp, "Invalid URI. URI should be of the form "
209
@@ -XXX,XX +XXX,XX @@ static int command_loop(void)
302
+ " vxhs://<host_ip>:<port>/<vdisk-id>");
210
if (input == NULL) {
303
+ }
211
break;
304
+ }
212
}
305
+}
213
- ret = qemuio_command(qemuio_blk, input);
306
+
214
+ ret = do_qemuio_command(input);
307
+static int vxhs_init_and_ref(void)
215
g_free(input);
308
+{
216
309
+ if (vxhs_ref++ == 0) {
217
if (ret < 0) {
310
+ if (iio_init(QNIO_VERSION, vxhs_iio_callback)) {
311
+ return -ENODEV;
312
+ }
313
+ }
314
+ return 0;
315
+}
316
+
317
+static void vxhs_unref(void)
318
+{
319
+ if (--vxhs_ref == 0) {
320
+ iio_fini();
321
+ }
322
+}
323
+
324
+static void vxhs_get_tls_creds(const char *id, char **cacert,
325
+ char **key, char **cert, Error **errp)
326
+{
327
+ Object *obj;
328
+ QCryptoTLSCreds *creds;
329
+ QCryptoTLSCredsX509 *creds_x509;
330
+
331
+ obj = object_resolve_path_component(
332
+ object_get_objects_root(), id);
333
+
334
+ if (!obj) {
335
+ error_setg(errp, "No TLS credentials with id '%s'",
336
+ id);
337
+ return;
338
+ }
339
+
340
+ creds_x509 = (QCryptoTLSCredsX509 *)
341
+ object_dynamic_cast(obj, TYPE_QCRYPTO_TLS_CREDS_X509);
342
+
343
+ if (!creds_x509) {
344
+ error_setg(errp, "Object with id '%s' is not TLS credentials",
345
+ id);
346
+ return;
347
+ }
348
+
349
+ creds = &creds_x509->parent_obj;
350
+
351
+ if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
352
+ error_setg(errp,
353
+ "Expecting TLS credentials with a client endpoint");
354
+ return;
355
+ }
356
+
357
+ /*
358
+ * Get the cacert, client_cert and client_key file names.
359
+ */
360
+ if (!creds->dir) {
361
+ error_setg(errp, "TLS object missing 'dir' property value");
362
+ return;
363
+ }
364
+
365
+ *cacert = g_strdup_printf("%s/%s", creds->dir,
366
+ QCRYPTO_TLS_CREDS_X509_CA_CERT);
367
+ *cert = g_strdup_printf("%s/%s", creds->dir,
368
+ QCRYPTO_TLS_CREDS_X509_CLIENT_CERT);
369
+ *key = g_strdup_printf("%s/%s", creds->dir,
370
+ QCRYPTO_TLS_CREDS_X509_CLIENT_KEY);
371
+}
372
+
373
+static int vxhs_open(BlockDriverState *bs, QDict *options,
374
+ int bdrv_flags, Error **errp)
375
+{
376
+ BDRVVXHSState *s = bs->opaque;
377
+ void *dev_handlep;
378
+ QDict *backing_options = NULL;
379
+ QemuOpts *opts = NULL;
380
+ QemuOpts *tcp_opts = NULL;
381
+ char *of_vsa_addr = NULL;
382
+ Error *local_err = NULL;
383
+ const char *vdisk_id_opt;
384
+ const char *server_host_opt;
385
+ int ret = 0;
386
+ char *cacert = NULL;
387
+ char *client_key = NULL;
388
+ char *client_cert = NULL;
389
+
390
+ ret = vxhs_init_and_ref();
391
+ if (ret < 0) {
392
+ ret = -EINVAL;
393
+ goto out;
394
+ }
395
+
396
+ /* Create opts info from runtime_opts and runtime_tcp_opts list */
397
+ opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
398
+ tcp_opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort);
399
+
400
+ qemu_opts_absorb_qdict(opts, options, &local_err);
401
+ if (local_err) {
402
+ ret = -EINVAL;
403
+ goto out;
404
+ }
405
+
406
+ /* vdisk-id is the disk UUID */
407
+ vdisk_id_opt = qemu_opt_get(opts, VXHS_OPT_VDISK_ID);
408
+ if (!vdisk_id_opt) {
409
+ error_setg(&local_err, QERR_MISSING_PARAMETER, VXHS_OPT_VDISK_ID);
410
+ ret = -EINVAL;
411
+ goto out;
412
+ }
413
+
414
+ /* vdisk-id may contain a leading '/' */
415
+ if (strlen(vdisk_id_opt) > UUID_FMT_LEN + 1) {
416
+ error_setg(&local_err, "vdisk-id cannot be more than %d characters",
417
+ UUID_FMT_LEN);
418
+ ret = -EINVAL;
419
+ goto out;
420
+ }
421
+
422
+ s->vdisk_guid = g_strdup(vdisk_id_opt);
423
+ trace_vxhs_open_vdiskid(vdisk_id_opt);
424
+
425
+ /* get the 'server.' arguments */
426
+ qdict_extract_subqdict(options, &backing_options, VXHS_OPT_SERVER".");
427
+
428
+ qemu_opts_absorb_qdict(tcp_opts, backing_options, &local_err);
429
+ if (local_err != NULL) {
430
+ ret = -EINVAL;
431
+ goto out;
432
+ }
433
+
434
+ server_host_opt = qemu_opt_get(tcp_opts, VXHS_OPT_HOST);
435
+ if (!server_host_opt) {
436
+ error_setg(&local_err, QERR_MISSING_PARAMETER,
437
+ VXHS_OPT_SERVER"."VXHS_OPT_HOST);
438
+ ret = -EINVAL;
439
+ goto out;
440
+ }
441
+
442
+ if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
443
+ error_setg(&local_err, "server.host cannot be more than %d characters",
444
+ MAXHOSTNAMELEN);
445
+ ret = -EINVAL;
446
+ goto out;
447
+ }
448
+
449
+ /* check if we got tls-creds via the --object argument */
450
+ s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
451
+ if (s->tlscredsid) {
452
+ vxhs_get_tls_creds(s->tlscredsid, &cacert, &client_key,
453
+ &client_cert, &local_err);
454
+ if (local_err != NULL) {
455
+ ret = -EINVAL;
456
+ goto out;
457
+ }
458
+ trace_vxhs_get_creds(cacert, client_key, client_cert);
459
+ }
460
+
461
+ s->vdisk_hostinfo.host = g_strdup(server_host_opt);
462
+ s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
463
+ VXHS_OPT_PORT),
464
+ NULL, 0);
465
+
466
+ trace_vxhs_open_hostinfo(s->vdisk_hostinfo.host,
467
+ s->vdisk_hostinfo.port);
468
+
469
+ of_vsa_addr = g_strdup_printf("of://%s:%d",
470
+ s->vdisk_hostinfo.host,
471
+ s->vdisk_hostinfo.port);
472
+
473
+ /*
474
+ * Open qnio channel to storage agent if not opened before
475
+ */
476
+ dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0,
477
+ cacert, client_key, client_cert);
478
+ if (dev_handlep == NULL) {
479
+ trace_vxhs_open_iio_open(of_vsa_addr);
480
+ ret = -ENODEV;
481
+ goto out;
482
+ }
483
+ s->vdisk_hostinfo.dev_handle = dev_handlep;
484
+
485
+out:
486
+ g_free(of_vsa_addr);
487
+ QDECREF(backing_options);
488
+ qemu_opts_del(tcp_opts);
489
+ qemu_opts_del(opts);
490
+ g_free(cacert);
491
+ g_free(client_key);
492
+ g_free(client_cert);
493
+
494
+ if (ret < 0) {
495
+ vxhs_unref();
496
+ error_propagate(errp, local_err);
497
+ g_free(s->vdisk_hostinfo.host);
498
+ g_free(s->vdisk_guid);
499
+ g_free(s->tlscredsid);
500
+ s->vdisk_guid = NULL;
501
+ }
502
+
503
+ return ret;
504
+}
505
+
506
+static const AIOCBInfo vxhs_aiocb_info = {
507
+ .aiocb_size = sizeof(VXHSAIOCB)
508
+};
509
+
510
+/*
511
+ * This allocates QEMU-VXHS callback for each IO
512
+ * and is passed to QNIO. When QNIO completes the work,
513
+ * it will be passed back through the callback.
514
+ */
515
+static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, int64_t sector_num,
516
+ QEMUIOVector *qiov, int nb_sectors,
517
+ BlockCompletionFunc *cb, void *opaque,
518
+ VDISKAIOCmd iodir)
519
+{
520
+ VXHSAIOCB *acb = NULL;
521
+ BDRVVXHSState *s = bs->opaque;
522
+ size_t size;
523
+ uint64_t offset;
524
+ int iio_flags = 0;
525
+ int ret = 0;
526
+ void *dev_handle = s->vdisk_hostinfo.dev_handle;
527
+
528
+ offset = sector_num * BDRV_SECTOR_SIZE;
529
+ size = nb_sectors * BDRV_SECTOR_SIZE;
530
+ acb = qemu_aio_get(&vxhs_aiocb_info, bs, cb, opaque);
531
+
532
+ /*
533
+ * Initialize VXHSAIOCB.
534
+ */
535
+ acb->err = 0;
536
+
537
+ iio_flags = IIO_FLAG_ASYNC;
538
+
539
+ switch (iodir) {
540
+ case VDISK_AIO_WRITE:
541
+ ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
542
+ offset, (uint64_t)size, iio_flags);
543
+ break;
544
+ case VDISK_AIO_READ:
545
+ ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
546
+ offset, (uint64_t)size, iio_flags);
547
+ break;
548
+ default:
549
+ trace_vxhs_aio_rw_invalid(iodir);
550
+ goto errout;
551
+ }
552
+
553
+ if (ret != 0) {
554
+ trace_vxhs_aio_rw_ioerr(s->vdisk_guid, iodir, size, offset,
555
+ acb, ret, errno);
556
+ goto errout;
557
+ }
558
+ return &acb->common;
559
+
560
+errout:
561
+ qemu_aio_unref(acb);
562
+ return NULL;
563
+}
564
+
565
+static BlockAIOCB *vxhs_aio_readv(BlockDriverState *bs,
566
+ int64_t sector_num, QEMUIOVector *qiov,
567
+ int nb_sectors,
568
+ BlockCompletionFunc *cb, void *opaque)
569
+{
570
+ return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
571
+ opaque, VDISK_AIO_READ);
572
+}
573
+
574
+static BlockAIOCB *vxhs_aio_writev(BlockDriverState *bs,
575
+ int64_t sector_num, QEMUIOVector *qiov,
576
+ int nb_sectors,
577
+ BlockCompletionFunc *cb, void *opaque)
578
+{
579
+ return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors,
580
+ cb, opaque, VDISK_AIO_WRITE);
581
+}
582
+
583
+static void vxhs_close(BlockDriverState *bs)
584
+{
585
+ BDRVVXHSState *s = bs->opaque;
586
+
587
+ trace_vxhs_close(s->vdisk_guid);
588
+
589
+ g_free(s->vdisk_guid);
590
+ s->vdisk_guid = NULL;
591
+
592
+ /*
593
+ * Close vDisk device
594
+ */
595
+ if (s->vdisk_hostinfo.dev_handle) {
596
+ iio_close(s->vdisk_hostinfo.dev_handle);
597
+ s->vdisk_hostinfo.dev_handle = NULL;
598
+ }
599
+
600
+ vxhs_unref();
601
+
602
+ /*
603
+ * Free the dynamically allocated host string etc
604
+ */
605
+ g_free(s->vdisk_hostinfo.host);
606
+ g_free(s->tlscredsid);
607
+ s->tlscredsid = NULL;
608
+ s->vdisk_hostinfo.host = NULL;
609
+ s->vdisk_hostinfo.port = 0;
610
+}
611
+
612
+static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s)
613
+{
614
+ int64_t vdisk_size = -1;
615
+ int ret = 0;
616
+ void *dev_handle = s->vdisk_hostinfo.dev_handle;
617
+
618
+ ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
619
+ if (ret < 0) {
620
+ trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno);
621
+ return -EIO;
622
+ }
623
+
624
+ trace_vxhs_get_vdisk_stat(s->vdisk_guid, vdisk_size);
625
+ return vdisk_size;
626
+}
627
+
628
+/*
629
+ * Returns the size of vDisk in bytes. This is required
630
+ * by QEMU block upper block layer so that it is visible
631
+ * to guest.
632
+ */
633
+static int64_t vxhs_getlength(BlockDriverState *bs)
634
+{
635
+ BDRVVXHSState *s = bs->opaque;
636
+ int64_t vdisk_size;
637
+
638
+ vdisk_size = vxhs_get_vdisk_stat(s);
639
+ if (vdisk_size < 0) {
640
+ return -EIO;
641
+ }
642
+
643
+ return vdisk_size;
644
+}
645
+
646
+static BlockDriver bdrv_vxhs = {
647
+ .format_name = "vxhs",
648
+ .protocol_name = "vxhs",
649
+ .instance_size = sizeof(BDRVVXHSState),
650
+ .bdrv_file_open = vxhs_open,
651
+ .bdrv_parse_filename = vxhs_parse_filename,
652
+ .bdrv_close = vxhs_close,
653
+ .bdrv_getlength = vxhs_getlength,
654
+ .bdrv_aio_readv = vxhs_aio_readv,
655
+ .bdrv_aio_writev = vxhs_aio_writev,
656
+};
657
+
658
+static void bdrv_vxhs_init(void)
659
+{
660
+ bdrv_register(&bdrv_vxhs);
661
+}
662
+
663
+block_init(bdrv_vxhs_init);
664
diff --git a/configure b/configure
665
index XXXXXXX..XXXXXXX 100755
666
--- a/configure
667
+++ b/configure
668
@@ -XXX,XX +XXX,XX @@ numa=""
669
tcmalloc="no"
670
jemalloc="no"
671
replication="yes"
672
+vxhs=""
673
674
supported_cpu="no"
675
supported_os="no"
676
@@ -XXX,XX +XXX,XX @@ for opt do
677
;;
678
--enable-replication) replication="yes"
679
;;
680
+ --disable-vxhs) vxhs="no"
681
+ ;;
682
+ --enable-vxhs) vxhs="yes"
683
+ ;;
684
*)
685
echo "ERROR: unknown option $opt"
686
echo "Try '$0 --help' for more information"
687
@@ -XXX,XX +XXX,XX @@ disabled with --disable-FEATURE, default is enabled if available:
688
xfsctl xfsctl support
689
qom-cast-debug cast debugging support
690
tools build qemu-io, qemu-nbd and qemu-image tools
691
+ vxhs Veritas HyperScale vDisk backend support
692
693
NOTE: The object files are built at the place where configure is launched
694
EOF
695
@@ -XXX,XX +XXX,XX @@ if compile_prog "" "" ; then
696
fi
697
698
##########################################
699
+# Veritas HyperScale block driver VxHS
700
+# Check if libvxhs is installed
701
+
702
+if test "$vxhs" != "no" ; then
703
+ cat > $TMPC <<EOF
704
+#include <stdint.h>
705
+#include <qnio/qnio_api.h>
706
+
707
+void *vxhs_callback;
708
+
709
+int main(void) {
710
+ iio_init(QNIO_VERSION, vxhs_callback);
711
+ return 0;
712
+}
713
+EOF
714
+ vxhs_libs="-lvxhs -lssl"
715
+ if compile_prog "" "$vxhs_libs" ; then
716
+ vxhs=yes
717
+ else
718
+ if test "$vxhs" = "yes" ; then
719
+ feature_not_found "vxhs block device" "Install libvxhs See github"
720
+ fi
721
+ vxhs=no
722
+ fi
723
+fi
724
+
725
+##########################################
726
# End of CC checks
727
# After here, no more $cc or $ld runs
728
729
@@ -XXX,XX +XXX,XX @@ echo "tcmalloc support $tcmalloc"
730
echo "jemalloc support $jemalloc"
731
echo "avx2 optimization $avx2_opt"
732
echo "replication support $replication"
733
+echo "VxHS block device $vxhs"
734
735
if test "$sdl_too_old" = "yes"; then
736
echo "-> Your SDL version is too old - please upgrade to have SDL support"
737
@@ -XXX,XX +XXX,XX @@ if test "$pthread_setname_np" = "yes" ; then
738
echo "CONFIG_PTHREAD_SETNAME_NP=y" >> $config_host_mak
739
fi
740
741
+if test "$vxhs" = "yes" ; then
742
+ echo "CONFIG_VXHS=y" >> $config_host_mak
743
+ echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak
744
+fi
745
+
746
if test "$tcg_interpreter" = "yes"; then
747
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
748
elif test "$ARCH" = "sparc64" ; then
749
diff --git a/qapi/block-core.json b/qapi/block-core.json
750
index XXXXXXX..XXXXXXX 100644
751
--- a/qapi/block-core.json
752
+++ b/qapi/block-core.json
753
@@ -XXX,XX +XXX,XX @@
754
#
755
# Drivers that are supported in block device operations.
756
#
757
+# @vxhs: Since 2.10
758
+#
759
# Since: 2.9
760
##
761
{ 'enum': 'BlockdevDriver',
762
@@ -XXX,XX +XXX,XX @@
763
'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs',
764
'null-aio', 'null-co', 'parallels', 'qcow', 'qcow2', 'qed',
765
'quorum', 'raw', 'rbd', 'replication', 'sheepdog', 'ssh',
766
- 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
767
+ 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] }
768
769
##
770
# @BlockdevOptionsFile:
771
@@ -XXX,XX +XXX,XX @@
772
'data': { '*offset': 'int', '*size': 'int' } }
773
774
##
775
+# @BlockdevOptionsVxHS:
776
+#
777
+# Driver specific block device options for VxHS
778
+#
779
+# @vdisk-id: UUID of VxHS volume
780
+# @server: vxhs server IP, port
781
+# @tls-creds: TLS credentials ID
782
+#
783
+# Since: 2.10
784
+##
785
+{ 'struct': 'BlockdevOptionsVxHS',
786
+ 'data': { 'vdisk-id': 'str',
787
+ 'server': 'InetSocketAddressBase',
788
+ '*tls-creds': 'str' } }
789
+
790
+##
791
# @BlockdevOptions:
792
#
793
# Options for creating a block device. Many options are available for all
794
@@ -XXX,XX +XXX,XX @@
795
'vhdx': 'BlockdevOptionsGenericFormat',
796
'vmdk': 'BlockdevOptionsGenericCOWFormat',
797
'vpc': 'BlockdevOptionsGenericFormat',
798
- 'vvfat': 'BlockdevOptionsVVFAT'
799
+ 'vvfat': 'BlockdevOptionsVVFAT',
800
+ 'vxhs': 'BlockdevOptionsVxHS'
801
} }
802
803
##
804
--
218
--
805
2.9.3
219
2.31.1
806
220
807
221
diff view generated by jsdifflib
1
A few block drivers will set the BDS read_only flag from their
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
.bdrv_open() function. This means the bs->read_only flag could
3
be set after we enable copy_on_read, as the BDRV_O_COPY_ON_READ
4
flag check occurs prior to the call to bdrv->bdrv_open().
5
2
6
This adds an error return to bdrv_set_read_only(), and an error will be
3
If mirror is READY than cancel operation is not discarding the whole
7
return if we try to set the BDS to read_only while copy_on_read is
4
result of the operation, but instead it's a documented way get a
8
enabled.
5
point-in-time snapshot of source disk.
9
6
10
This patch also changes the behavior of vvfat. Before, vvfat could
7
So, we should not cancel any requests if mirror is READ and
11
override the drive 'readonly' flag with its own, internal 'rw' flag.
8
force=false. Let's fix that case.
12
9
13
For instance, this -drive parameter would result in a writable image:
10
Note, that bug that we have before this commit is not critical, as the
11
only .bdrv_cancel_in_flight implementation is nbd_cancel_in_flight()
12
and it cancels only requests waiting for reconnection, so it should be
13
rare case.
14
14
15
"-drive format=vvfat,dir=/tmp/vvfat,rw,if=virtio,readonly=on"
15
Fixes: 521ff8b779b11c394dbdc43f02e158dd99df308a
16
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
17
Message-Id: <20210421075858.40197-1-vsementsov@virtuozzo.com>
18
Signed-off-by: Max Reitz <mreitz@redhat.com>
19
---
20
include/block/block_int.h | 2 +-
21
include/qemu/job.h | 2 +-
22
block/backup.c | 2 +-
23
block/mirror.c | 6 ++++--
24
job.c | 2 +-
25
tests/qemu-iotests/264 | 2 +-
26
6 files changed, 9 insertions(+), 7 deletions(-)
16
27
17
This is not correct. Now, attempting to use the above -drive parameter
28
diff --git a/include/block/block_int.h b/include/block/block_int.h
18
will result in an error (i.e., 'rw' is incompatible with 'readonly=on').
19
20
Signed-off-by: Jeff Cody <jcody@redhat.com>
21
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Reviewed-by: John Snow <jsnow@redhat.com>
23
Message-id: 0c5b4c1cc2c651471b131f21376dfd5ea24d2196.1491597120.git.jcody@redhat.com
24
---
25
block.c | 10 +++++++++-
26
block/bochs.c | 5 ++++-
27
block/cloop.c | 5 ++++-
28
block/dmg.c | 6 +++++-
29
block/rbd.c | 11 ++++++++++-
30
block/vvfat.c | 19 +++++++++++++++----
31
include/block/block.h | 2 +-
32
7 files changed, 48 insertions(+), 10 deletions(-)
33
34
diff --git a/block.c b/block.c
35
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
36
--- a/block.c
30
--- a/include/block/block_int.h
37
+++ b/block.c
31
+++ b/include/block/block_int.h
38
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
32
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
33
* of in-flight requests, so don't waste the time if possible.
34
*
35
* One example usage is to avoid waiting for an nbd target node reconnect
36
- * timeout during job-cancel.
37
+ * timeout during job-cancel with force=true.
38
*/
39
void (*bdrv_cancel_in_flight)(BlockDriverState *bs);
40
41
diff --git a/include/qemu/job.h b/include/qemu/job.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/qemu/job.h
44
+++ b/include/qemu/job.h
45
@@ -XXX,XX +XXX,XX @@ struct JobDriver {
46
/**
47
* If the callback is not NULL, it will be invoked in job_cancel_async
48
*/
49
- void (*cancel)(Job *job);
50
+ void (*cancel)(Job *job, bool force);
51
52
53
/** Called when the job is freed */
54
diff --git a/block/backup.c b/block/backup.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/block/backup.c
57
+++ b/block/backup.c
58
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_set_speed(BlockJob *job, int64_t speed)
39
}
59
}
40
}
60
}
41
61
42
-void bdrv_set_read_only(BlockDriverState *bs, bool read_only)
62
-static void backup_cancel(Job *job)
43
+int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
63
+static void backup_cancel(Job *job, bool force)
44
{
64
{
45
+ /* Do not set read_only if copy_on_read is enabled */
65
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
46
+ if (bs->copy_on_read && read_only) {
66
47
+ error_setg(errp, "Can't set node '%s' to r/o with copy-on-read enabled",
67
diff --git a/block/mirror.c b/block/mirror.c
48
+ bdrv_get_device_or_node_name(bs));
68
index XXXXXXX..XXXXXXX 100644
49
+ return -EINVAL;
69
--- a/block/mirror.c
70
+++ b/block/mirror.c
71
@@ -XXX,XX +XXX,XX @@ static bool mirror_drained_poll(BlockJob *job)
72
return !!s->in_flight;
73
}
74
75
-static void mirror_cancel(Job *job)
76
+static void mirror_cancel(Job *job, bool force)
77
{
78
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
79
BlockDriverState *target = blk_bs(s->target);
80
81
- bdrv_cancel_in_flight(target);
82
+ if (force || !job_is_ready(job)) {
83
+ bdrv_cancel_in_flight(target);
50
+ }
84
+ }
51
+
52
bs->read_only = read_only;
53
+ return 0;
54
}
85
}
55
86
56
void bdrv_get_full_backing_filename_from_filename(const char *backed,
87
static const BlockJobDriver mirror_job_driver = {
57
diff --git a/block/bochs.c b/block/bochs.c
88
diff --git a/job.c b/job.c
58
index XXXXXXX..XXXXXXX 100644
89
index XXXXXXX..XXXXXXX 100644
59
--- a/block/bochs.c
90
--- a/job.c
60
+++ b/block/bochs.c
91
+++ b/job.c
61
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
92
@@ -XXX,XX +XXX,XX @@ static int job_finalize_single(Job *job)
62
return -EINVAL;
93
static void job_cancel_async(Job *job, bool force)
94
{
95
if (job->driver->cancel) {
96
- job->driver->cancel(job);
97
+ job->driver->cancel(job, force);
63
}
98
}
64
99
if (job->user_paused) {
65
- bdrv_set_read_only(bs, true); /* no write support yet */
100
/* Do not call job_enter here, the caller will handle it. */
66
+ ret = bdrv_set_read_only(bs, true, errp); /* no write support yet */
101
diff --git a/tests/qemu-iotests/264 b/tests/qemu-iotests/264
67
+ if (ret < 0) {
102
index XXXXXXX..XXXXXXX 100755
68
+ return ret;
103
--- a/tests/qemu-iotests/264
69
+ }
104
+++ b/tests/qemu-iotests/264
70
105
@@ -XXX,XX +XXX,XX @@ class TestNbdReconnect(iotests.QMPTestCase):
71
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
106
self.assert_qmp(result, 'return', {})
72
if (ret < 0) {
107
73
diff --git a/block/cloop.c b/block/cloop.c
108
def cancel_job(self):
74
index XXXXXXX..XXXXXXX 100644
109
- result = self.vm.qmp('block-job-cancel', device='drive0')
75
--- a/block/cloop.c
110
+ result = self.vm.qmp('block-job-cancel', device='drive0', force=True)
76
+++ b/block/cloop.c
111
self.assert_qmp(result, 'return', {})
77
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
112
78
return -EINVAL;
113
start_t = time.time()
79
}
80
81
- bdrv_set_read_only(bs, true);
82
+ ret = bdrv_set_read_only(bs, true, errp);
83
+ if (ret < 0) {
84
+ return ret;
85
+ }
86
87
/* read header */
88
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
89
diff --git a/block/dmg.c b/block/dmg.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/block/dmg.c
92
+++ b/block/dmg.c
93
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
94
return -EINVAL;
95
}
96
97
+ ret = bdrv_set_read_only(bs, true, errp);
98
+ if (ret < 0) {
99
+ return ret;
100
+ }
101
+
102
block_module_load_one("dmg-bz2");
103
- bdrv_set_read_only(bs, true);
104
105
s->n_chunks = 0;
106
s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
107
diff --git a/block/rbd.c b/block/rbd.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/block/rbd.c
110
+++ b/block/rbd.c
111
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
112
goto failed_shutdown;
113
}
114
115
+ /* rbd_open is always r/w */
116
r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);
117
if (r < 0) {
118
error_setg_errno(errp, -r, "error reading header from %s", s->name);
119
goto failed_open;
120
}
121
122
- bdrv_set_read_only(bs, (s->snap != NULL));
123
+ /* If we are using an rbd snapshot, we must be r/o, otherwise
124
+ * leave as-is */
125
+ if (s->snap != NULL) {
126
+ r = bdrv_set_read_only(bs, true, &local_err);
127
+ if (r < 0) {
128
+ error_propagate(errp, local_err);
129
+ goto failed_open;
130
+ }
131
+ }
132
133
qemu_opts_del(opts);
134
return 0;
135
diff --git a/block/vvfat.c b/block/vvfat.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/block/vvfat.c
138
+++ b/block/vvfat.c
139
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
140
141
s->current_cluster=0xffffffff;
142
143
- /* read only is the default for safety */
144
- bdrv_set_read_only(bs, true);
145
s->qcow = NULL;
146
s->qcow_filename = NULL;
147
s->fat2 = NULL;
148
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
149
s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
150
151
if (qemu_opt_get_bool(opts, "rw", false)) {
152
- ret = enable_write_target(bs, errp);
153
+ if (!bdrv_is_read_only(bs)) {
154
+ ret = enable_write_target(bs, errp);
155
+ if (ret < 0) {
156
+ goto fail;
157
+ }
158
+ } else {
159
+ ret = -EPERM;
160
+ error_setg(errp,
161
+ "Unable to set VVFAT to 'rw' when drive is read-only");
162
+ goto fail;
163
+ }
164
+ } else {
165
+ /* read only is the default for safety */
166
+ ret = bdrv_set_read_only(bs, true, &local_err);
167
if (ret < 0) {
168
+ error_propagate(errp, local_err);
169
goto fail;
170
}
171
- bdrv_set_read_only(bs, false);
172
}
173
174
bs->total_sectors = cyls * heads * secs;
175
diff --git a/include/block/block.h b/include/block/block.h
176
index XXXXXXX..XXXXXXX 100644
177
--- a/include/block/block.h
178
+++ b/include/block/block.h
179
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
180
int64_t sector_num, int nb_sectors, int *pnum);
181
182
bool bdrv_is_read_only(BlockDriverState *bs);
183
-void bdrv_set_read_only(BlockDriverState *bs, bool read_only);
184
+int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
185
bool bdrv_is_sg(BlockDriverState *bs);
186
bool bdrv_is_inserted(BlockDriverState *bs);
187
int bdrv_media_changed(BlockDriverState *bs);
188
--
114
--
189
2.9.3
115
2.31.1
190
116
191
117
diff view generated by jsdifflib
New patch
1
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
3
Instead of buffering the test output into a StringIO, patch it on
4
the fly by wrapping sys.stdout's write method. This can be
5
done unconditionally, even if using -d, which makes execute_unittest
6
a bit simpler.
7
8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Tested-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
11
Message-Id: <20210323181928.311862-2-pbonzini@redhat.com>
12
Message-Id: <20210503110110.476887-2-pbonzini@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
tests/qemu-iotests/240.out | 8 ++--
16
tests/qemu-iotests/245.out | 8 ++--
17
tests/qemu-iotests/295.out | 6 +--
18
tests/qemu-iotests/296.out | 8 ++--
19
tests/qemu-iotests/iotests.py | 70 ++++++++++++++++++++---------------
20
5 files changed, 56 insertions(+), 44 deletions(-)
21
22
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
23
index XXXXXXX..XXXXXXX 100644
24
--- a/tests/qemu-iotests/240.out
25
+++ b/tests/qemu-iotests/240.out
26
@@ -XXX,XX +XXX,XX @@
27
{"return": {}}
28
{"execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
29
{"return": {}}
30
-==Attach two SCSI disks using the same block device and the same iothread==
31
+.==Attach two SCSI disks using the same block device and the same iothread==
32
{"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true, "read-zeroes": true}}
33
{"return": {}}
34
{"execute": "object-add", "arguments": {"id": "iothread0", "qom-type": "iothread"}}
35
@@ -XXX,XX +XXX,XX @@
36
{"return": {}}
37
{"execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
38
{"return": {}}
39
-==Attach two SCSI disks using the same block device but different iothreads==
40
+.==Attach two SCSI disks using the same block device but different iothreads==
41
{"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true, "read-zeroes": true}}
42
{"return": {}}
43
{"execute": "object-add", "arguments": {"id": "iothread0", "qom-type": "iothread"}}
44
@@ -XXX,XX +XXX,XX @@
45
{"return": {}}
46
{"execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
47
{"return": {}}
48
-==Attach a SCSI disks using the same block device as a NBD server==
49
+.==Attach a SCSI disks using the same block device as a NBD server==
50
{"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true, "read-zeroes": true}}
51
{"return": {}}
52
{"execute": "nbd-server-start", "arguments": {"addr": {"data": {"path": "SOCK_DIR/PID-nbd.sock"}, "type": "unix"}}}
53
@@ -XXX,XX +XXX,XX @@
54
{"return": {}}
55
{"execute": "device_add", "arguments": {"drive": "hd0", "driver": "scsi-hd", "id": "scsi-hd0"}}
56
{"return": {}}
57
-....
58
+.
59
----------------------------------------------------------------------
60
Ran 4 tests
61
62
diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out
63
index XXXXXXX..XXXXXXX 100644
64
--- a/tests/qemu-iotests/245.out
65
+++ b/tests/qemu-iotests/245.out
66
@@ -XXX,XX +XXX,XX @@
67
-{"execute": "job-finalize", "arguments": {"id": "commit0"}}
68
+..{"execute": "job-finalize", "arguments": {"id": "commit0"}}
69
{"return": {}}
70
{"data": {"id": "commit0", "type": "commit"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
71
{"data": {"device": "commit0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
72
-{"execute": "job-finalize", "arguments": {"id": "stream0"}}
73
+...{"execute": "job-finalize", "arguments": {"id": "stream0"}}
74
{"return": {}}
75
{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
76
{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
77
-{"execute": "job-finalize", "arguments": {"id": "stream0"}}
78
+.{"execute": "job-finalize", "arguments": {"id": "stream0"}}
79
{"return": {}}
80
{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
81
{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
82
-.....................
83
+...............
84
----------------------------------------------------------------------
85
Ran 21 tests
86
87
diff --git a/tests/qemu-iotests/295.out b/tests/qemu-iotests/295.out
88
index XXXXXXX..XXXXXXX 100644
89
--- a/tests/qemu-iotests/295.out
90
+++ b/tests/qemu-iotests/295.out
91
@@ -XXX,XX +XXX,XX @@
92
{"return": {}}
93
{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
94
{"return": {}}
95
-{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
96
+.{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
97
{"return": {}}
98
{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
99
{"return": {}}
100
@@ -XXX,XX +XXX,XX @@ Job failed: Invalid password, cannot unlock any keyslot
101
{"return": {}}
102
{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
103
{"return": {}}
104
-{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
105
+.{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
106
{"return": {}}
107
{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
108
{"return": {}}
109
@@ -XXX,XX +XXX,XX @@ Job failed: All the active keyslots match the (old) password that was given and
110
{"return": {}}
111
{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
112
{"return": {}}
113
-...
114
+.
115
----------------------------------------------------------------------
116
Ran 3 tests
117
118
diff --git a/tests/qemu-iotests/296.out b/tests/qemu-iotests/296.out
119
index XXXXXXX..XXXXXXX 100644
120
--- a/tests/qemu-iotests/296.out
121
+++ b/tests/qemu-iotests/296.out
122
@@ -XXX,XX +XXX,XX @@ Job failed: Failed to get shared "consistent read" lock
123
qemu-img: Failed to get shared "consistent read" lock
124
Is another process using the image [TEST_DIR/test.img]?
125
126
-Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
127
+.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
128
129
Job failed: Block node is read-only
130
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
131
@@ -XXX,XX +XXX,XX @@ Job failed: Failed to get shared "consistent read" lock
132
{"return": {}}
133
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
134
{"return": {}}
135
-Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
136
+.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
137
138
{"return": {}}
139
{"error": {"class": "GenericError", "desc": "Failed to get \"write\" lock"}}
140
-Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
141
+.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
142
143
{"return": {}}
144
{"return": {}}
145
-....
146
+.
147
----------------------------------------------------------------------
148
Ran 4 tests
149
150
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
151
index XXXXXXX..XXXXXXX 100644
152
--- a/tests/qemu-iotests/iotests.py
153
+++ b/tests/qemu-iotests/iotests.py
154
@@ -XXX,XX +XXX,XX @@
155
import bz2
156
from collections import OrderedDict
157
import faulthandler
158
-import io
159
import json
160
import logging
161
import os
162
@@ -XXX,XX +XXX,XX @@
163
import sys
164
import time
165
from typing import (Any, Callable, Dict, Iterable,
166
- List, Optional, Sequence, Tuple, TypeVar)
167
+ List, Optional, Sequence, TextIO, Tuple, Type, TypeVar)
168
import unittest
169
170
from contextlib import contextmanager
171
@@ -XXX,XX +XXX,XX @@ def func_wrapper(*args, **kwargs):
172
return func(*args, **kwargs)
173
return func_wrapper
174
175
+# We need to filter out the time taken from the output so that
176
+# qemu-iotest can reliably diff the results against master output,
177
+# and hide skipped tests from the reference output.
178
+
179
+class ReproducibleTestResult(unittest.TextTestResult):
180
+ def addSkip(self, test, reason):
181
+ # Same as TextTestResult, but print dot instead of "s"
182
+ unittest.TestResult.addSkip(self, test, reason)
183
+ if self.showAll:
184
+ self.stream.writeln("skipped {0!r}".format(reason))
185
+ elif self.dots:
186
+ self.stream.write(".")
187
+ self.stream.flush()
188
+
189
+class ReproducibleStreamWrapper:
190
+ def __init__(self, stream: TextIO):
191
+ self.stream = stream
192
+
193
+ def __getattr__(self, attr):
194
+ if attr in ('stream', '__getstate__'):
195
+ raise AttributeError(attr)
196
+ return getattr(self.stream, attr)
197
+
198
+ def write(self, arg=None):
199
+ arg = re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 tests', arg)
200
+ arg = re.sub(r' \(skipped=\d+\)', r'', arg)
201
+ self.stream.write(arg)
202
+
203
+class ReproducibleTestRunner(unittest.TextTestRunner):
204
+ def __init__(self, stream: Optional[TextIO] = None,
205
+ resultclass: Type[unittest.TestResult] = ReproducibleTestResult,
206
+ **kwargs: Any) -> None:
207
+ rstream = ReproducibleStreamWrapper(stream or sys.stdout)
208
+ super().__init__(stream=rstream, # type: ignore
209
+ descriptions=True,
210
+ resultclass=resultclass,
211
+ **kwargs)
212
+
213
def execute_unittest(debug=False):
214
"""Executes unittests within the calling module."""
215
216
verbosity = 2 if debug else 1
217
-
218
- if debug:
219
- output = sys.stdout
220
- else:
221
- # We need to filter out the time taken from the output so that
222
- # qemu-iotest can reliably diff the results against master output.
223
- output = io.StringIO()
224
-
225
- runner = unittest.TextTestRunner(stream=output, descriptions=True,
226
- verbosity=verbosity)
227
- try:
228
- # unittest.main() will use sys.exit(); so expect a SystemExit
229
- # exception
230
- unittest.main(testRunner=runner)
231
- finally:
232
- # We need to filter out the time taken from the output so that
233
- # qemu-iotest can reliably diff the results against master output.
234
- if not debug:
235
- out = output.getvalue()
236
- out = re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 tests', out)
237
-
238
- # Hide skipped tests from the reference output
239
- out = re.sub(r'OK \(skipped=\d+\)', 'OK', out)
240
- out_first_line, out_rest = out.split('\n', 1)
241
- out = out_first_line.replace('s', '.') + '\n' + out_rest
242
-
243
- sys.stderr.write(out)
244
+ runner = ReproducibleTestRunner(verbosity=verbosity)
245
+ unittest.main(testRunner=runner)
246
247
def execute_setup_common(supported_fmts: Sequence[str] = (),
248
supported_platforms: Sequence[str] = (),
249
--
250
2.31.1
251
252
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
Python test scripts that use unittest consist of multiple tests.
4
unittest.main allows selecting which tests to run, but currently this
5
is not possible because the iotests wrapper ignores sys.argv.
6
7
unittest.main command line options also allow the user to pick the
8
desired options for verbosity, failfast mode, etc. While "-d" is
9
currently translated to "-v", it also enables extra debug output,
10
and other options are not available at all.
11
12
These command line options only work if the unittest.main testRunner
13
argument is a type, rather than a TestRunner instance. Therefore, pass
14
the class name and "verbosity" argument to unittest.main, and adjust for
15
the different default warnings between TextTestRunner and unittest.main.
16
17
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
18
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
19
Tested-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
20
Message-Id: <20210323181928.311862-3-pbonzini@redhat.com>
21
Message-Id: <20210503110110.476887-3-pbonzini@redhat.com>
22
Signed-off-by: Max Reitz <mreitz@redhat.com>
23
---
24
tests/qemu-iotests/iotests.py | 14 +++++++++-----
25
1 file changed, 9 insertions(+), 5 deletions(-)
26
27
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
28
index XXXXXXX..XXXXXXX 100644
29
--- a/tests/qemu-iotests/iotests.py
30
+++ b/tests/qemu-iotests/iotests.py
31
@@ -XXX,XX +XXX,XX @@ def __init__(self, stream: Optional[TextIO] = None,
32
resultclass=resultclass,
33
**kwargs)
34
35
-def execute_unittest(debug=False):
36
+def execute_unittest(argv: List[str], debug: bool = False) -> None:
37
"""Executes unittests within the calling module."""
38
39
- verbosity = 2 if debug else 1
40
- runner = ReproducibleTestRunner(verbosity=verbosity)
41
- unittest.main(testRunner=runner)
42
+ # Some tests have warnings, especially ResourceWarnings for unclosed
43
+ # files and sockets. Ignore them for now to ensure reproducibility of
44
+ # the test output.
45
+ unittest.main(argv=argv,
46
+ testRunner=ReproducibleTestRunner,
47
+ verbosity=2 if debug else 1,
48
+ warnings=None if sys.warnoptions else 'ignore')
49
50
def execute_setup_common(supported_fmts: Sequence[str] = (),
51
supported_platforms: Sequence[str] = (),
52
@@ -XXX,XX +XXX,XX @@ def execute_test(*args, test_function=None, **kwargs):
53
54
debug = execute_setup_common(*args, **kwargs)
55
if not test_function:
56
- execute_unittest(debug)
57
+ execute_unittest(sys.argv, debug)
58
else:
59
test_function()
60
61
--
62
2.31.1
63
64
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
In the next patch, "check" will learn how to execute a test script without
4
going through TestRunner. To enable this, keep only the text output
5
and subprocess handling in the TestRunner; move into TestEnv the logic
6
to prepare for running a subprocess.
7
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10
Tested-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
11
Message-Id: <20210323181928.311862-4-pbonzini@redhat.com>
12
Message-Id: <20210503110110.476887-4-pbonzini@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
tests/qemu-iotests/testenv.py | 17 ++++++++++++++++-
16
tests/qemu-iotests/testrunner.py | 14 +-------------
17
2 files changed, 17 insertions(+), 14 deletions(-)
18
19
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/qemu-iotests/testenv.py
22
+++ b/tests/qemu-iotests/testenv.py
23
@@ -XXX,XX +XXX,XX @@
24
import random
25
import subprocess
26
import glob
27
-from typing import Dict, Any, Optional, ContextManager
28
+from typing import List, Dict, Any, Optional, ContextManager
29
30
31
def isxfile(path: str) -> bool:
32
@@ -XXX,XX +XXX,XX @@ class TestEnv(ContextManager['TestEnv']):
33
'CACHEMODE_IS_DEFAULT', 'IMGFMT_GENERIC', 'IMGOPTSSYNTAX',
34
'IMGKEYSECRET', 'QEMU_DEFAULT_MACHINE', 'MALLOC_PERTURB_']
35
36
+ def prepare_subprocess(self, args: List[str]) -> Dict[str, str]:
37
+ if self.debug:
38
+ args.append('-d')
39
+
40
+ with open(args[0], encoding="utf-8") as f:
41
+ try:
42
+ if f.readline().rstrip() == '#!/usr/bin/env python3':
43
+ args.insert(0, self.python)
44
+ except UnicodeDecodeError: # binary test? for future.
45
+ pass
46
+
47
+ os_env = os.environ.copy()
48
+ os_env.update(self.get_env())
49
+ return os_env
50
+
51
def get_env(self) -> Dict[str, str]:
52
env = {}
53
for v in self.env_variables:
54
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
55
index XXXXXXX..XXXXXXX 100644
56
--- a/tests/qemu-iotests/testrunner.py
57
+++ b/tests/qemu-iotests/testrunner.py
58
@@ -XXX,XX +XXX,XX @@ class TestRunner(ContextManager['TestRunner']):
59
def __init__(self, env: TestEnv, makecheck: bool = False,
60
color: str = 'auto') -> None:
61
self.env = env
62
- self.test_run_env = self.env.get_env()
63
self.makecheck = makecheck
64
self.last_elapsed = LastElapsedTime('.last-elapsed-cache', env)
65
66
@@ -XXX,XX +XXX,XX @@ def do_run_test(self, test: str) -> TestResult:
67
silent_unlink(p)
68
69
args = [str(f_test.resolve())]
70
- if self.env.debug:
71
- args.append('-d')
72
-
73
- with f_test.open(encoding="utf-8") as f:
74
- try:
75
- if f.readline().rstrip() == '#!/usr/bin/env python3':
76
- args.insert(0, self.env.python)
77
- except UnicodeDecodeError: # binary test? for future.
78
- pass
79
-
80
- env = os.environ.copy()
81
- env.update(self.test_run_env)
82
+ env = self.env.prepare_subprocess(args)
83
84
t0 = time.time()
85
with f_bad.open('w', encoding="utf-8") as f:
86
--
87
2.31.1
88
89
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
Right now there is no easy way for "check" to print a reproducer command.
4
Because such a reproducer command line would be huge, we can instead teach
5
check to start a command of our choice. This can be for example a Python
6
unit test with arguments to only run a specific subtest.
7
8
Move the trailing empty line to print_env(), since it always looks better
9
and one caller was not adding it.
10
11
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Tested-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
14
Message-Id: <20210323181928.311862-5-pbonzini@redhat.com>
15
Message-Id: <20210503110110.476887-5-pbonzini@redhat.com>
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
17
---
18
tests/qemu-iotests/check | 19 ++++++++++++++++++-
19
tests/qemu-iotests/testenv.py | 3 ++-
20
tests/qemu-iotests/testrunner.py | 1 -
21
3 files changed, 20 insertions(+), 3 deletions(-)
22
23
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
24
index XXXXXXX..XXXXXXX 100755
25
--- a/tests/qemu-iotests/check
26
+++ b/tests/qemu-iotests/check
27
@@ -XXX,XX +XXX,XX @@
28
import os
29
import sys
30
import argparse
31
+import shutil
32
+from pathlib import Path
33
+
34
from findtests import TestFinder
35
from testenv import TestEnv
36
from testrunner import TestRunner
37
@@ -XXX,XX +XXX,XX @@ def make_argparser() -> argparse.ArgumentParser:
38
'rerun failed ./check command, starting from the '
39
'middle of the process.')
40
g_sel.add_argument('tests', metavar='TEST_FILES', nargs='*',
41
- help='tests to run')
42
+ help='tests to run, or "--" followed by a command')
43
44
return p
45
46
@@ -XXX,XX +XXX,XX @@ if __name__ == '__main__':
47
imgopts=args.imgopts, misalign=args.misalign,
48
debug=args.debug, valgrind=args.valgrind)
49
50
+ if len(sys.argv) > 1 and sys.argv[-len(args.tests)-1] == '--':
51
+ if not args.tests:
52
+ sys.exit("missing command after '--'")
53
+ cmd = args.tests
54
+ env.print_env()
55
+ exec_pathstr = shutil.which(cmd[0])
56
+ if exec_pathstr is None:
57
+ sys.exit('command not found: ' + cmd[0])
58
+ exec_path = Path(exec_pathstr).resolve()
59
+ cmd[0] = str(exec_path)
60
+ full_env = env.prepare_subprocess(cmd)
61
+ os.chdir(exec_path.parent)
62
+ os.execve(cmd[0], cmd, full_env)
63
+
64
testfinder = TestFinder(test_dir=env.source_iotests)
65
66
groups = args.groups.split(',') if args.groups else None
67
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
68
index XXXXXXX..XXXXXXX 100644
69
--- a/tests/qemu-iotests/testenv.py
70
+++ b/tests/qemu-iotests/testenv.py
71
@@ -XXX,XX +XXX,XX @@ def print_env(self) -> None:
72
PLATFORM -- {platform}
73
TEST_DIR -- {TEST_DIR}
74
SOCK_DIR -- {SOCK_DIR}
75
-SOCKET_SCM_HELPER -- {SOCKET_SCM_HELPER}"""
76
+SOCKET_SCM_HELPER -- {SOCKET_SCM_HELPER}
77
+"""
78
79
args = collections.defaultdict(str, self.get_env())
80
81
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
82
index XXXXXXX..XXXXXXX 100644
83
--- a/tests/qemu-iotests/testrunner.py
84
+++ b/tests/qemu-iotests/testrunner.py
85
@@ -XXX,XX +XXX,XX @@ def run_tests(self, tests: List[str]) -> bool:
86
87
if not self.makecheck:
88
self.env.print_env()
89
- print()
90
91
test_field_width = max(len(os.path.basename(t)) for t in tests) + 2
92
93
--
94
2.31.1
95
96
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
Due to a typo, in this case the SOCK_DIR was not being created.
4
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Tested-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
8
Message-Id: <20210323181928.311862-6-pbonzini@redhat.com>
9
Message-Id: <20210503110110.476887-6-pbonzini@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
tests/qemu-iotests/testenv.py | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
16
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qemu-iotests/testenv.py
18
+++ b/tests/qemu-iotests/testenv.py
19
@@ -XXX,XX +XXX,XX @@ def init_directories(self) -> None:
20
try:
21
self.sock_dir = os.environ['SOCK_DIR']
22
self.tmp_sock_dir = False
23
- Path(self.test_dir).mkdir(parents=True, exist_ok=True)
24
+ Path(self.sock_dir).mkdir(parents=True, exist_ok=True)
25
except KeyError:
26
self.sock_dir = tempfile.mkdtemp()
27
self.tmp_sock_dir = True
28
--
29
2.31.1
30
31
diff view generated by jsdifflib
New patch
1
From: Connor Kuehl <ckuehl@redhat.com>
1
2
3
The contents of this patch were initially developed and posted by Han
4
Han[1], however, it appears the original patch was not applied. Since
5
then, the relevant documentation has been moved and adapted to a new
6
format.
7
8
I've taken most of the original wording and tweaked it according to
9
some of the feedback from the original patch submission. I've also
10
adapted it to restructured text, which is the format the documentation
11
currently uses.
12
13
[1] https://lists.nongnu.org/archive/html/qemu-block/2019-10/msg01253.html
14
15
Fixes: https://bugzilla.redhat.com/1763105
16
Signed-off-by: Han Han <hhan@redhat.com>
17
Suggested-by: Max Reitz <mreitz@redhat.com>
18
[ Max: provided description of data_file_raw behavior ]
19
Signed-off-by: Connor Kuehl <ckuehl@redhat.com>
20
Message-Id: <20210505195512.391128-1-ckuehl@redhat.com>
21
Signed-off-by: Max Reitz <mreitz@redhat.com>
22
---
23
docs/tools/qemu-img.rst | 31 +++++++++++++++++++++++++++++++
24
1 file changed, 31 insertions(+)
25
26
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
27
index XXXXXXX..XXXXXXX 100644
28
--- a/docs/tools/qemu-img.rst
29
+++ b/docs/tools/qemu-img.rst
30
@@ -XXX,XX +XXX,XX @@ Supported image file formats:
31
issue ``lsattr filename`` to check if the NOCOW flag is set or not
32
(Capital 'C' is NOCOW flag).
33
34
+ ``data_file``
35
+ Filename where all guest data will be stored. If this option is used,
36
+ the qcow2 file will only contain the image's metadata.
37
+
38
+ Note: Data loss will occur if the given filename already exists when
39
+ using this option with ``qemu-img create`` since ``qemu-img`` will create
40
+ the data file anew, overwriting the file's original contents. To simply
41
+ update the reference to point to the given pre-existing file, use
42
+ ``qemu-img amend``.
43
+
44
+ ``data_file_raw``
45
+ If this option is set to ``on``, QEMU will always keep the external data
46
+ file consistent as a standalone read-only raw image.
47
+
48
+ It does this by forwarding all write accesses to the qcow2 file through to
49
+ the raw data file, including their offsets. Therefore, data that is visible
50
+ on the qcow2 node (i.e., to the guest) at some offset is visible at the same
51
+ offset in the raw data file. This results in a read-only raw image. Writes
52
+ that bypass the qcow2 metadata may corrupt the qcow2 metadata because the
53
+ out-of-band writes may result in the metadata falling out of sync with the
54
+ raw image.
55
+
56
+ If this option is ``off``, QEMU will use the data file to store data in an
57
+ arbitrary manner. The file’s content will not make sense without the
58
+ accompanying qcow2 metadata. Where data is written will have no relation to
59
+ its offset as seen by the guest, and some writes (specifically zero writes)
60
+ may not be forwarded to the data file at all, but will only be handled by
61
+ modifying qcow2 metadata.
62
+
63
+ This option can only be enabled if ``data_file`` is set.
64
+
65
``Other``
66
67
QEMU also supports various other image file formats for
68
--
69
2.31.1
70
71
diff view generated by jsdifflib
1
Update 'clientname' to be 'user', which tracks better with both
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
the QAPI and rados variable naming.
3
2
4
Update 'name' to be 'image_name', as it indicates the rbd image.
3
Now, after huge update of block graph permission update algorithm, we
5
Naming it 'image' would have been ideal, but we are using that for
4
don't need this workaround with active state of the filter. Drop it and
6
the rados_image_t value returned by rbd_open().
5
use new smart bdrv_drop_filter() function.
7
6
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Signed-off-by: Jeff Cody <jcody@redhat.com>
8
Message-Id: <20210506194143.394141-1-vsementsov@virtuozzo.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Message-id: b7ec1fb2e1cf36f9b6911631447a5b0422590b7d.1491597120.git.jcody@redhat.com
12
---
10
---
13
block/rbd.c | 33 +++++++++++++++++----------------
11
block/copy-on-read.c | 33 +--------------------------------
14
1 file changed, 17 insertions(+), 16 deletions(-)
12
1 file changed, 1 insertion(+), 32 deletions(-)
15
13
16
diff --git a/block/rbd.c b/block/rbd.c
14
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/block/rbd.c
16
--- a/block/copy-on-read.c
19
+++ b/block/rbd.c
17
+++ b/block/copy-on-read.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRBDState {
18
@@ -XXX,XX +XXX,XX @@
21
rados_t cluster;
19
22
rados_ioctx_t io_ctx;
20
23
rbd_image_t image;
21
typedef struct BDRVStateCOR {
24
- char *name;
22
- bool active;
25
+ char *image_name;
23
BlockDriverState *bottom_bs;
26
char *snap;
24
bool chain_frozen;
27
} BDRVRBDState;
25
} BDRVStateCOR;
28
26
@@ -XXX,XX +XXX,XX @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
29
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
27
*/
30
int64_t bytes = 0;
28
bdrv_ref(bottom_bs);
31
int64_t objsize;
32
int obj_order = 0;
33
- const char *pool, *name, *conf, *clientname, *keypairs;
34
+ const char *pool, *image_name, *conf, *user, *keypairs;
35
const char *secretid;
36
rados_t cluster;
37
rados_ioctx_t io_ctx;
38
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
39
*/
40
pool = qdict_get_try_str(options, "pool");
41
conf = qdict_get_try_str(options, "conf");
42
- clientname = qdict_get_try_str(options, "user");
43
- name = qdict_get_try_str(options, "image");
44
+ user = qdict_get_try_str(options, "user");
45
+ image_name = qdict_get_try_str(options, "image");
46
keypairs = qdict_get_try_str(options, "=keyvalue-pairs");
47
48
- ret = rados_create(&cluster, clientname);
49
+ ret = rados_create(&cluster, user);
50
if (ret < 0) {
51
error_setg_errno(errp, -ret, "error initializing");
52
goto exit;
53
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
54
goto shutdown;
55
}
29
}
56
30
- state->active = true;
57
- ret = rbd_create(io_ctx, name, bytes, &obj_order);
31
state->bottom_bs = bottom_bs;
58
+ ret = rbd_create(io_ctx, image_name, bytes, &obj_order);
32
59
if (ret < 0) {
33
/*
60
error_setg_errno(errp, -ret, "error rbd create");
34
@@ -XXX,XX +XXX,XX @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
35
uint64_t perm, uint64_t shared,
36
uint64_t *nperm, uint64_t *nshared)
37
{
38
- BDRVStateCOR *s = bs->opaque;
39
-
40
- if (!s->active) {
41
- /*
42
- * While the filter is being removed
43
- */
44
- *nperm = 0;
45
- *nshared = BLK_PERM_ALL;
46
- return;
47
- }
48
-
49
*nperm = perm & PERM_PASSTHROUGH;
50
*nshared = (shared & PERM_PASSTHROUGH) | PERM_UNCHANGED;
51
52
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_copy_on_read = {
53
54
void bdrv_cor_filter_drop(BlockDriverState *cor_filter_bs)
55
{
56
- BdrvChild *child;
57
- BlockDriverState *bs;
58
BDRVStateCOR *s = cor_filter_bs->opaque;
59
60
- child = bdrv_filter_child(cor_filter_bs);
61
- if (!child) {
62
- return;
63
- }
64
- bs = child->bs;
65
-
66
- /* Retain the BDS until we complete the graph change. */
67
- bdrv_ref(bs);
68
- /* Hold a guest back from writing while permissions are being reset. */
69
- bdrv_drained_begin(bs);
70
- /* Drop permissions before the graph change. */
71
- s->active = false;
72
/* unfreeze, as otherwise bdrv_replace_node() will fail */
73
if (s->chain_frozen) {
74
s->chain_frozen = false;
75
bdrv_unfreeze_backing_chain(cor_filter_bs, s->bottom_bs);
61
}
76
}
62
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
77
- bdrv_child_refresh_perms(cor_filter_bs, child, &error_abort);
63
Error **errp)
78
- bdrv_replace_node(cor_filter_bs, bs, &error_abort);
64
{
79
-
65
BDRVRBDState *s = bs->opaque;
80
- bdrv_drained_end(bs);
66
- const char *pool, *snap, *conf, *clientname, *name, *keypairs;
81
- bdrv_unref(bs);
67
+ const char *pool, *snap, *conf, *user, *image_name, *keypairs;
82
+ bdrv_drop_filter(cor_filter_bs, &error_abort);
68
const char *secretid;
83
bdrv_unref(cor_filter_bs);
69
QemuOpts *opts;
70
Error *local_err = NULL;
71
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
72
pool = qemu_opt_get(opts, "pool");
73
conf = qemu_opt_get(opts, "conf");
74
snap = qemu_opt_get(opts, "snapshot");
75
- clientname = qemu_opt_get(opts, "user");
76
- name = qemu_opt_get(opts, "image");
77
+ user = qemu_opt_get(opts, "user");
78
+ image_name = qemu_opt_get(opts, "image");
79
keypairs = qemu_opt_get(opts, "=keyvalue-pairs");
80
81
- if (!pool || !name) {
82
+ if (!pool || !image_name) {
83
error_setg(errp, "Parameters 'pool' and 'image' are required");
84
r = -EINVAL;
85
goto failed_opts;
86
}
87
88
- r = rados_create(&s->cluster, clientname);
89
+ r = rados_create(&s->cluster, user);
90
if (r < 0) {
91
error_setg_errno(errp, -r, "error initializing");
92
goto failed_opts;
93
}
94
95
s->snap = g_strdup(snap);
96
- s->name = g_strdup(name);
97
+ s->image_name = g_strdup(image_name);
98
99
/* try default location when conf=NULL, but ignore failure */
100
r = rados_conf_read_file(s->cluster, conf);
101
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
102
}
103
104
/* rbd_open is always r/w */
105
- r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);
106
+ r = rbd_open(s->io_ctx, s->image_name, &s->image, s->snap);
107
if (r < 0) {
108
- error_setg_errno(errp, -r, "error reading header from %s", s->name);
109
+ error_setg_errno(errp, -r, "error reading header from %s",
110
+ s->image_name);
111
goto failed_open;
112
}
113
114
@@ -XXX,XX +XXX,XX @@ failed_open:
115
failed_shutdown:
116
rados_shutdown(s->cluster);
117
g_free(s->snap);
118
- g_free(s->name);
119
+ g_free(s->image_name);
120
failed_opts:
121
qemu_opts_del(opts);
122
g_free(mon_host);
123
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_close(BlockDriverState *bs)
124
rbd_close(s->image);
125
rados_ioctx_destroy(s->io_ctx);
126
g_free(s->snap);
127
- g_free(s->name);
128
+ g_free(s->image_name);
129
rados_shutdown(s->cluster);
130
}
84
}
131
85
132
--
86
--
133
2.9.3
87
2.31.1
134
88
135
89
diff view generated by jsdifflib
1
Signed-off-by: Jeff Cody <jcody@redhat.com>
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
2
3
Reviewed-by: John Snow <jsnow@redhat.com>
3
pylint 2.8 introduces consider-using-with error, suggesting
4
Message-id: 00aed7ffdd7be4b9ed9ce1007d50028a72b34ebe.1491597120.git.jcody@redhat.com
4
to use the 'with' block statement when possible.
5
6
Modify all subprocess.Popen call to use the 'with' statement,
7
except the one in __init__ of QemuIoInteractive class, since
8
it is assigned to a class field and used in other methods.
9
10
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
11
Message-Id: <20210510190449.65948-1-eesposit@redhat.com>
12
[mreitz: Disable bad-option-value warning in the iotests' pylintrc, so
13
that disabling consider-using-with in QemuIoInteractive will
14
not produce a warning in pre-2.8 pylint versions]
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
---
16
---
6
block.c | 14 ++++++++------
17
tests/qemu-iotests/iotests.py | 65 ++++++++++++++++----------------
7
1 file changed, 8 insertions(+), 6 deletions(-)
18
tests/qemu-iotests/pylintrc | 3 ++
19
tests/qemu-iotests/testrunner.py | 22 +++++------
20
3 files changed, 47 insertions(+), 43 deletions(-)
8
21
9
diff --git a/block.c b/block.c
22
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
10
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
11
--- a/block.c
24
--- a/tests/qemu-iotests/iotests.py
12
+++ b/block.c
25
+++ b/tests/qemu-iotests/iotests.py
13
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
26
@@ -XXX,XX +XXX,XX @@ def qemu_tool_pipe_and_status(tool: str, args: Sequence[str],
14
BlockDriver *drv;
27
Run a tool and return both its output and its exit code
15
QemuOpts *opts;
28
"""
16
const char *value;
29
stderr = subprocess.STDOUT if connect_stderr else None
17
+ bool read_only;
30
- subp = subprocess.Popen(args,
18
31
- stdout=subprocess.PIPE,
19
assert(reopen_state != NULL);
32
- stderr=stderr,
20
assert(reopen_state->bs->drv != NULL);
33
- universal_newlines=True)
21
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
34
- output = subp.communicate()[0]
22
qdict_put(reopen_state->options, "driver", qstring_from_str(value));
35
- if subp.returncode < 0:
23
}
36
- cmd = ' '.join(args)
24
37
- sys.stderr.write(f'{tool} received signal {-subp.returncode}: {cmd}\n')
25
- /* if we are to stay read-only, do not allow permission change
38
- return (output, subp.returncode)
26
- * to r/w */
39
+ with subprocess.Popen(args, stdout=subprocess.PIPE,
27
- if (!(reopen_state->bs->open_flags & BDRV_O_ALLOW_RDWR) &&
40
+ stderr=stderr, universal_newlines=True) as subp:
28
- reopen_state->flags & BDRV_O_RDWR) {
41
+ output = subp.communicate()[0]
29
- error_setg(errp, "Node '%s' is read only",
42
+ if subp.returncode < 0:
30
- bdrv_get_device_or_node_name(reopen_state->bs));
43
+ cmd = ' '.join(args)
31
+ /* If we are to stay read-only, do not allow permission change
44
+ sys.stderr.write(f'{tool} received signal \
32
+ * to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is
45
+ {-subp.returncode}: {cmd}\n')
33
+ * not set, or if the BDS still has copy_on_read enabled */
46
+ return (output, subp.returncode)
34
+ read_only = !(reopen_state->flags & BDRV_O_RDWR);
47
35
+ ret = bdrv_can_set_read_only(reopen_state->bs, read_only, &local_err);
48
def qemu_img_pipe_and_status(*args: str) -> Tuple[str, int]:
36
+ if (local_err) {
49
"""
37
+ error_propagate(errp, local_err);
50
@@ -XXX,XX +XXX,XX @@ def qemu_io_silent_check(*args):
38
goto error;
51
class QemuIoInteractive:
39
}
52
def __init__(self, *args):
53
self.args = qemu_io_args_no_fmt + list(args)
54
+ # We need to keep the Popen objext around, and not
55
+ # close it immediately. Therefore, disable the pylint check:
56
+ # pylint: disable=consider-using-with
57
self._p = subprocess.Popen(self.args, stdin=subprocess.PIPE,
58
stdout=subprocess.PIPE,
59
stderr=subprocess.STDOUT,
60
@@ -XXX,XX +XXX,XX @@ def qemu_nbd_popen(*args):
61
cmd.extend(args)
62
63
log('Start NBD server')
64
- p = subprocess.Popen(cmd)
65
- try:
66
- while not os.path.exists(pid_file):
67
- if p.poll() is not None:
68
- raise RuntimeError(
69
- "qemu-nbd terminated with exit code {}: {}"
70
- .format(p.returncode, ' '.join(cmd)))
71
-
72
- time.sleep(0.01)
73
- yield
74
- finally:
75
- if os.path.exists(pid_file):
76
- os.remove(pid_file)
77
- log('Kill NBD server')
78
- p.kill()
79
- p.wait()
80
+ with subprocess.Popen(cmd) as p:
81
+ try:
82
+ while not os.path.exists(pid_file):
83
+ if p.poll() is not None:
84
+ raise RuntimeError(
85
+ "qemu-nbd terminated with exit code {}: {}"
86
+ .format(p.returncode, ' '.join(cmd)))
87
+
88
+ time.sleep(0.01)
89
+ yield
90
+ finally:
91
+ if os.path.exists(pid_file):
92
+ os.remove(pid_file)
93
+ log('Kill NBD server')
94
+ p.kill()
95
+ p.wait()
96
97
def compare_images(img1, img2, fmt1=imgfmt, fmt2=imgfmt):
98
'''Return True if two image files are identical'''
99
@@ -XXX,XX +XXX,XX @@ def compare_images(img1, img2, fmt1=imgfmt, fmt2=imgfmt):
100
101
def create_image(name, size):
102
'''Create a fully-allocated raw image with sector markers'''
103
- file = open(name, 'wb')
104
- i = 0
105
- while i < size:
106
- sector = struct.pack('>l504xl', i // 512, i // 512)
107
- file.write(sector)
108
- i = i + 512
109
- file.close()
110
+ with open(name, 'wb') as file:
111
+ i = 0
112
+ while i < size:
113
+ sector = struct.pack('>l504xl', i // 512, i // 512)
114
+ file.write(sector)
115
+ i = i + 512
116
117
def image_size(img):
118
'''Return image's virtual size'''
119
diff --git a/tests/qemu-iotests/pylintrc b/tests/qemu-iotests/pylintrc
120
index XXXXXXX..XXXXXXX 100644
121
--- a/tests/qemu-iotests/pylintrc
122
+++ b/tests/qemu-iotests/pylintrc
123
@@ -XXX,XX +XXX,XX @@ disable=invalid-name,
124
too-many-public-methods,
125
# pylint warns about Optional[] etc. as unsubscriptable in 3.9
126
unsubscriptable-object,
127
+ # Sometimes we need to disable a newly introduced pylint warning.
128
+ # Doing so should not produce a warning in older versions of pylint.
129
+ bad-option-value,
130
# These are temporary, and should be removed:
131
missing-docstring,
132
too-many-return-statements,
133
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
134
index XXXXXXX..XXXXXXX 100644
135
--- a/tests/qemu-iotests/testrunner.py
136
+++ b/tests/qemu-iotests/testrunner.py
137
@@ -XXX,XX +XXX,XX @@ def do_run_test(self, test: str) -> TestResult:
138
139
t0 = time.time()
140
with f_bad.open('w', encoding="utf-8") as f:
141
- proc = subprocess.Popen(args, cwd=str(f_test.parent), env=env,
142
- stdout=f, stderr=subprocess.STDOUT)
143
- try:
144
- proc.wait()
145
- except KeyboardInterrupt:
146
- proc.terminate()
147
- proc.wait()
148
- return TestResult(status='not run',
149
- description='Interrupted by user',
150
- interrupted=True)
151
- ret = proc.returncode
152
+ with subprocess.Popen(args, cwd=str(f_test.parent), env=env,
153
+ stdout=f, stderr=subprocess.STDOUT) as proc:
154
+ try:
155
+ proc.wait()
156
+ except KeyboardInterrupt:
157
+ proc.terminate()
158
+ proc.wait()
159
+ return TestResult(status='not run',
160
+ description='Interrupted by user',
161
+ interrupted=True)
162
+ ret = proc.returncode
163
164
elapsed = round(time.time() - t0, 1)
40
165
41
--
166
--
42
2.9.3
167
2.31.1
43
168
44
169
diff view generated by jsdifflib
1
Introduce check function for setting read_only flags. Will return < 0 on
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
error, with appropriate Error value set. Does not alter any flags.
3
2
4
Signed-off-by: Jeff Cody <jcody@redhat.com>
3
write-notifiers are used only for write-threshold. New code for such
4
purpose should create filters.
5
6
Let's better special-case write-threshold and drop write notifiers at
7
all. (Actually, write-threshold is special-cased anyway, as the only
8
user of write-notifiers)
9
10
So, create a new direct interface for bdrv_co_write_req_prepare() and
11
drop all write-notifier related logic from write-threshold.c.
12
13
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Reviewed-by: Max Reitz <mreitz@redhat.com>
15
Message-Id: <20210506090621.11848-2-vsementsov@virtuozzo.com>
16
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
18
[mreitz: Adjusted comment as per Eric's suggestion]
7
Message-id: e2bba34ac3bc76a0c42adc390413f358ae0566e8.1491597120.git.jcody@redhat.com
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
20
---
9
block.c | 14 +++++++++++++-
21
include/block/block_int.h | 1 -
10
include/block/block.h | 1 +
22
include/block/write-threshold.h | 9 +++++
11
2 files changed, 14 insertions(+), 1 deletion(-)
23
block/io.c | 5 ++-
24
block/write-threshold.c | 70 +++++++--------------------------
25
4 files changed, 27 insertions(+), 58 deletions(-)
12
26
13
diff --git a/block.c b/block.c
27
diff --git a/include/block/block_int.h b/include/block/block_int.h
14
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
15
--- a/block.c
29
--- a/include/block/block_int.h
16
+++ b/block.c
30
+++ b/include/block/block_int.h
17
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_read_only(BlockDriverState *bs)
31
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
18
return bs->read_only;
32
33
/* threshold limit for writes, in bytes. "High water mark". */
34
uint64_t write_threshold_offset;
35
- NotifierWithReturn write_threshold_notifier;
36
37
/* Writing to the list requires the BQL _and_ the dirty_bitmap_mutex.
38
* Reading from the list can be done with either the BQL or the
39
diff --git a/include/block/write-threshold.h b/include/block/write-threshold.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/block/write-threshold.h
42
+++ b/include/block/write-threshold.h
43
@@ -XXX,XX +XXX,XX @@ bool bdrv_write_threshold_is_set(const BlockDriverState *bs);
44
uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
45
const BdrvTrackedRequest *req);
46
47
+/*
48
+ * bdrv_write_threshold_check_write
49
+ *
50
+ * Check whether the specified request exceeds the write threshold.
51
+ * If so, send a corresponding event and disable write threshold checking.
52
+ */
53
+void bdrv_write_threshold_check_write(BlockDriverState *bs, int64_t offset,
54
+ int64_t bytes);
55
+
56
#endif
57
diff --git a/block/io.c b/block/io.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/io.c
60
+++ b/block/io.c
61
@@ -XXX,XX +XXX,XX @@
62
#include "block/blockjob_int.h"
63
#include "block/block_int.h"
64
#include "block/coroutines.h"
65
+#include "block/write-threshold.h"
66
#include "qemu/cutils.h"
67
#include "qapi/error.h"
68
#include "qemu/error-report.h"
69
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, int64_t bytes,
70
} else {
71
assert(child->perm & BLK_PERM_WRITE);
72
}
73
- return notifier_with_return_list_notify(&bs->before_write_notifiers,
74
- req);
75
+ bdrv_write_threshold_check_write(bs, offset, bytes);
76
+ return 0;
77
case BDRV_TRACKED_TRUNCATE:
78
assert(child->perm & BLK_PERM_RESIZE);
79
return 0;
80
diff --git a/block/write-threshold.c b/block/write-threshold.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/block/write-threshold.c
83
+++ b/block/write-threshold.c
84
@@ -XXX,XX +XXX,XX @@ bool bdrv_write_threshold_is_set(const BlockDriverState *bs)
85
return bs->write_threshold_offset > 0;
19
}
86
}
20
87
21
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
88
-static void write_threshold_disable(BlockDriverState *bs)
22
+int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
89
-{
90
- if (bdrv_write_threshold_is_set(bs)) {
91
- notifier_with_return_remove(&bs->write_threshold_notifier);
92
- bs->write_threshold_offset = 0;
93
- }
94
-}
95
-
96
uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
97
const BdrvTrackedRequest *req)
23
{
98
{
24
/* Do not set read_only if copy_on_read is enabled */
99
@@ -XXX,XX +XXX,XX @@ uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
25
if (bs->copy_on_read && read_only) {
26
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
27
return -EPERM;
28
}
29
30
+ return 0;
31
+}
32
+
33
+int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
34
+{
35
+ int ret = 0;
36
+
37
+ ret = bdrv_can_set_read_only(bs, read_only, errp);
38
+ if (ret < 0) {
39
+ return ret;
40
+ }
41
+
42
bs->read_only = read_only;
43
return 0;
100
return 0;
44
}
101
}
45
diff --git a/include/block/block.h b/include/block/block.h
102
46
index XXXXXXX..XXXXXXX 100644
103
-static int coroutine_fn before_write_notify(NotifierWithReturn *notifier,
47
--- a/include/block/block.h
104
- void *opaque)
48
+++ b/include/block/block.h
105
-{
49
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
106
- BdrvTrackedRequest *req = opaque;
50
int64_t sector_num, int nb_sectors, int *pnum);
107
- BlockDriverState *bs = req->bs;
51
108
- uint64_t amount = 0;
52
bool bdrv_is_read_only(BlockDriverState *bs);
109
-
53
+int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
110
- amount = bdrv_write_threshold_exceeded(bs, req);
54
int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
111
- if (amount > 0) {
55
bool bdrv_is_sg(BlockDriverState *bs);
112
- qapi_event_send_block_write_threshold(
56
bool bdrv_is_inserted(BlockDriverState *bs);
113
- bs->node_name,
114
- amount,
115
- bs->write_threshold_offset);
116
-
117
- /* autodisable to avoid flooding the monitor */
118
- write_threshold_disable(bs);
119
- }
120
-
121
- return 0; /* should always let other notifiers run */
122
-}
123
-
124
-static void write_threshold_register_notifier(BlockDriverState *bs)
125
-{
126
- bs->write_threshold_notifier.notify = before_write_notify;
127
- bdrv_add_before_write_notifier(bs, &bs->write_threshold_notifier);
128
-}
129
-
130
-static void write_threshold_update(BlockDriverState *bs,
131
- int64_t threshold_bytes)
132
-{
133
- bs->write_threshold_offset = threshold_bytes;
134
-}
135
-
136
void bdrv_write_threshold_set(BlockDriverState *bs, uint64_t threshold_bytes)
137
{
138
- if (bdrv_write_threshold_is_set(bs)) {
139
- if (threshold_bytes > 0) {
140
- write_threshold_update(bs, threshold_bytes);
141
- } else {
142
- write_threshold_disable(bs);
143
- }
144
- } else {
145
- if (threshold_bytes > 0) {
146
- /* avoid multiple registration */
147
- write_threshold_register_notifier(bs);
148
- write_threshold_update(bs, threshold_bytes);
149
- }
150
- /* discard bogus disable request */
151
- }
152
+ bs->write_threshold_offset = threshold_bytes;
153
}
154
155
void qmp_block_set_write_threshold(const char *node_name,
156
@@ -XXX,XX +XXX,XX @@ void qmp_block_set_write_threshold(const char *node_name,
157
158
aio_context_release(aio_context);
159
}
160
+
161
+void bdrv_write_threshold_check_write(BlockDriverState *bs, int64_t offset,
162
+ int64_t bytes)
163
+{
164
+ int64_t end = offset + bytes;
165
+ uint64_t wtr = bs->write_threshold_offset;
166
+
167
+ if (wtr > 0 && end > wtr) {
168
+ qapi_event_send_block_write_threshold(bs->node_name, end - wtr, wtr);
169
+
170
+ /* autodisable to avoid flooding the monitor */
171
+ bdrv_write_threshold_set(bs, 0);
172
+ }
173
+}
57
--
174
--
58
2.9.3
175
2.31.1
59
176
60
177
diff view generated by jsdifflib
1
Move bdrv_is_read_only() up with its friends.
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
They are unused now.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Message-Id: <20210506090621.11848-3-vsementsov@virtuozzo.com>
3
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
Reviewed-by: John Snow <jsnow@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Signed-off-by: Jeff Cody <jcody@redhat.com>
6
Message-id: 73b2399459760c32506f9407efb9dddb3a2789de.1491597120.git.jcody@redhat.com
7
---
10
---
8
block.c | 10 +++++-----
11
include/block/block_int.h | 12 ------------
9
1 file changed, 5 insertions(+), 5 deletions(-)
12
block.c | 1 -
13
block/io.c | 6 ------
14
3 files changed, 19 deletions(-)
10
15
16
diff --git a/include/block/block_int.h b/include/block/block_int.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/block/block_int.h
19
+++ b/include/block/block_int.h
20
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
21
*/
22
int64_t total_sectors;
23
24
- /* Callback before write request is processed */
25
- NotifierWithReturnList before_write_notifiers;
26
-
27
/* threshold limit for writes, in bytes. "High water mark". */
28
uint64_t write_threshold_offset;
29
30
@@ -XXX,XX +XXX,XX @@ void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
31
bool bdrv_backing_overridden(BlockDriverState *bs);
32
33
34
-/**
35
- * bdrv_add_before_write_notifier:
36
- *
37
- * Register a callback that is invoked before write requests are processed but
38
- * after any throttling or waiting for overlapping requests.
39
- */
40
-void bdrv_add_before_write_notifier(BlockDriverState *bs,
41
- NotifierWithReturn *notifier);
42
-
43
/**
44
* bdrv_add_aio_context_notifier:
45
*
11
diff --git a/block.c b/block.c
46
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
13
--- a/block.c
48
--- a/block.c
14
+++ b/block.c
49
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
50
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_new(void)
51
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
52
QLIST_INIT(&bs->op_blockers[i]);
16
}
53
}
54
- notifier_with_return_list_init(&bs->before_write_notifiers);
55
qemu_co_mutex_init(&bs->reqs_lock);
56
qemu_mutex_init(&bs->dirty_bitmap_mutex);
57
bs->refcnt = 1;
58
diff --git a/block/io.c b/block/io.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/block/io.c
61
+++ b/block/io.c
62
@@ -XXX,XX +XXX,XX @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
63
return true;
17
}
64
}
18
65
19
+bool bdrv_is_read_only(BlockDriverState *bs)
66
-void bdrv_add_before_write_notifier(BlockDriverState *bs,
20
+{
67
- NotifierWithReturn *notifier)
21
+ return bs->read_only;
22
+}
23
+
24
int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
25
{
26
/* Do not set read_only if copy_on_read is enabled */
27
@@ -XXX,XX +XXX,XX @@ void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
28
*nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;
29
}
30
31
-bool bdrv_is_read_only(BlockDriverState *bs)
32
-{
68
-{
33
- return bs->read_only;
69
- notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
34
-}
70
-}
35
-
71
-
36
bool bdrv_is_sg(BlockDriverState *bs)
72
void bdrv_io_plug(BlockDriverState *bs)
37
{
73
{
38
return bs->sg;
74
BdrvChild *child;
39
--
75
--
40
2.9.3
76
2.31.1
41
77
42
78
diff view generated by jsdifflib
1
From: Ashish Mittal <ashmit602@gmail.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
These changes use a vxhs test server that is a part of the following
3
These tests use bdrv_write_threshold_exceeded() API, which is used only
4
repository:
4
for test (since pre-previous commit). Better is testing real API, which
5
https://github.com/VeritasHyperScale/libqnio.git
5
is used in block.c as well.
6
6
7
Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
7
So, let's call bdrv_write_threshold_check_write(), and check is
8
bs->write_threshold_offset cleared or not (it's cleared iff threshold
9
triggered).
10
11
Also we get rid of BdrvTrackedRequest use here. Note, that paranoiac
12
bdrv_check_request() calls were added in 8b1170012b1 to protect
13
BdrvTrackedRequest. Drop them now.
14
15
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
16
Reviewed-by: Max Reitz <mreitz@redhat.com>
17
Message-Id: <20210506090621.11848-4-vsementsov@virtuozzo.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
18
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Jeff Cody <jcody@redhat.com>
11
Message-id: 1491277689-24949-3-git-send-email-Ashish.Mittal@veritas.com
12
---
20
---
13
tests/qemu-iotests/common | 6 ++++++
21
tests/unit/test-write-threshold.c | 22 ++++------------------
14
tests/qemu-iotests/common.config | 13 +++++++++++++
22
1 file changed, 4 insertions(+), 18 deletions(-)
15
tests/qemu-iotests/common.filter | 1 +
16
tests/qemu-iotests/common.rc | 19 +++++++++++++++++++
17
4 files changed, 39 insertions(+)
18
23
19
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
24
diff --git a/tests/unit/test-write-threshold.c b/tests/unit/test-write-threshold.c
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/qemu-iotests/common
26
--- a/tests/unit/test-write-threshold.c
22
+++ b/tests/qemu-iotests/common
27
+++ b/tests/unit/test-write-threshold.c
23
@@ -XXX,XX +XXX,XX @@ check options
28
@@ -XXX,XX +XXX,XX @@ static void test_threshold_multi_set_get(void)
24
-ssh test ssh
29
25
-nfs test nfs
30
static void test_threshold_not_trigger(void)
26
-luks test luks
27
+ -vxhs test vxhs
28
-xdiff graphical mode diff
29
-nocache use O_DIRECT on backing file
30
-misalign misalign memory allocations
31
@@ -XXX,XX +XXX,XX @@ testlist options
32
xpand=false
33
;;
34
35
+ -vxhs)
36
+ IMGPROTO=vxhs
37
+ xpand=false
38
+ ;;
39
+
40
-ssh)
41
IMGPROTO=ssh
42
xpand=false
43
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
44
index XXXXXXX..XXXXXXX 100644
45
--- a/tests/qemu-iotests/common.config
46
+++ b/tests/qemu-iotests/common.config
47
@@ -XXX,XX +XXX,XX @@ if [ -z "$QEMU_NBD_PROG" ]; then
48
export QEMU_NBD_PROG="`set_prog_path qemu-nbd`"
49
fi
50
51
+if [ -z "$QEMU_VXHS_PROG" ]; then
52
+ export QEMU_VXHS_PROG="`set_prog_path qnio_server`"
53
+fi
54
+
55
_qemu_wrapper()
56
{
31
{
57
(
32
- uint64_t amount = 0;
58
@@ -XXX,XX +XXX,XX @@ _qemu_nbd_wrapper()
33
uint64_t threshold = 4 * 1024 * 1024;
59
)
34
BlockDriverState bs;
35
- BdrvTrackedRequest req;
36
37
memset(&bs, 0, sizeof(bs));
38
- memset(&req, 0, sizeof(req));
39
- req.offset = 1024;
40
- req.bytes = 1024;
41
-
42
- bdrv_check_request(req.offset, req.bytes, &error_abort);
43
44
bdrv_write_threshold_set(&bs, threshold);
45
- amount = bdrv_write_threshold_exceeded(&bs, &req);
46
- g_assert_cmpuint(amount, ==, 0);
47
+ bdrv_write_threshold_check_write(&bs, 1024, 1024);
48
+ g_assert_cmpuint(bdrv_write_threshold_get(&bs), ==, threshold);
60
}
49
}
61
50
62
+_qemu_vxhs_wrapper()
51
63
+{
52
static void test_threshold_trigger(void)
64
+ (
53
{
65
+ echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
54
- uint64_t amount = 0;
66
+ exec "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
55
uint64_t threshold = 4 * 1024 * 1024;
67
+ )
56
BlockDriverState bs;
68
+}
57
- BdrvTrackedRequest req;
69
+
58
70
export QEMU=_qemu_wrapper
59
memset(&bs, 0, sizeof(bs));
71
export QEMU_IMG=_qemu_img_wrapper
60
- memset(&req, 0, sizeof(req));
72
export QEMU_IO=_qemu_io_wrapper
61
- req.offset = (4 * 1024 * 1024) - 1024;
73
export QEMU_NBD=_qemu_nbd_wrapper
62
- req.bytes = 2 * 1024;
74
+export QEMU_VXHS=_qemu_vxhs_wrapper
63
-
75
64
- bdrv_check_request(req.offset, req.bytes, &error_abort);
76
QEMU_IMG_EXTRA_ARGS=
65
77
if [ "$IMGOPTSSYNTAX" = "true" ]; then
66
bdrv_write_threshold_set(&bs, threshold);
78
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
67
- amount = bdrv_write_threshold_exceeded(&bs, &req);
79
index XXXXXXX..XXXXXXX 100644
68
- g_assert_cmpuint(amount, >=, 1024);
80
--- a/tests/qemu-iotests/common.filter
69
+ bdrv_write_threshold_check_write(&bs, threshold - 1024, 2 * 1024);
81
+++ b/tests/qemu-iotests/common.filter
70
+ g_assert_cmpuint(bdrv_write_threshold_get(&bs), ==, 0);
82
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
83
-e "s#$TEST_DIR#TEST_DIR#g" \
84
-e "s#$IMGFMT#IMGFMT#g" \
85
-e 's#nbd://127.0.0.1:10810$#TEST_DIR/t.IMGFMT#g' \
86
+ -e 's#json.*vdisk-id.*vxhs"}}#TEST_DIR/t.IMGFMT#' \
87
-e "/encrypted: yes/d" \
88
-e "/cluster_size: [0-9]\\+/d" \
89
-e "/table_size: [0-9]\\+/d" \
90
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
91
index XXXXXXX..XXXXXXX 100644
92
--- a/tests/qemu-iotests/common.rc
93
+++ b/tests/qemu-iotests/common.rc
94
@@ -XXX,XX +XXX,XX @@ else
95
elif [ "$IMGPROTO" = "nfs" ]; then
96
TEST_DIR="nfs://127.0.0.1/$TEST_DIR"
97
TEST_IMG=$TEST_DIR/t.$IMGFMT
98
+ elif [ "$IMGPROTO" = "vxhs" ]; then
99
+ TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
100
+ TEST_IMG="vxhs://127.0.0.1:9999/t.$IMGFMT"
101
else
102
TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
103
fi
104
@@ -XXX,XX +XXX,XX @@ _make_test_img()
105
eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT $TEST_IMG_FILE >/dev/null &"
106
sleep 1 # FIXME: qemu-nbd needs to be listening before we continue
107
fi
108
+
109
+ # Start QNIO server on image directory for vxhs protocol
110
+ if [ $IMGPROTO = "vxhs" ]; then
111
+ eval "$QEMU_VXHS -d $TEST_DIR > /dev/null &"
112
+ sleep 1 # Wait for server to come up.
113
+ fi
114
}
71
}
115
72
116
_rm_test_img()
73
typedef struct TestStruct {
117
@@ -XXX,XX +XXX,XX @@ _cleanup_test_img()
118
fi
119
rm -f "$TEST_IMG_FILE"
120
;;
121
+ vxhs)
122
+ if [ -f "${TEST_DIR}/qemu-vxhs.pid" ]; then
123
+ local QEMU_VXHS_PID
124
+ read QEMU_VXHS_PID < "${TEST_DIR}/qemu-vxhs.pid"
125
+ kill ${QEMU_VXHS_PID} >/dev/null 2>&1
126
+ rm -f "${TEST_DIR}/qemu-vxhs.pid"
127
+ fi
128
+ rm -f "$TEST_IMG_FILE"
129
+ ;;
130
+
131
file)
132
_rm_test_img "$TEST_DIR/t.$IMGFMT"
133
_rm_test_img "$TEST_DIR/t.$IMGFMT.orig"
134
--
74
--
135
2.9.3
75
2.31.1
136
76
137
77
diff view generated by jsdifflib
1
The BDRV_O_ALLOW_RDWR flag allows / prohibits the changing of
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
the BDS 'read_only' state, but there are a few places where it
3
is ignored. In the bdrv_set_read_only() helper, make sure to
4
honor the flag.
5
2
6
Signed-off-by: Jeff Cody <jcody@redhat.com>
3
bdrv_write_threshold_exceeded() is unused.
4
5
bdrv_write_threshold_is_set() is used only to double check the value of
6
bs->write_threshold_offset in tests. No real sense in it (both tests do
7
check real value with help of bdrv_write_threshold_get())
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Message-Id: <20210506090621.11848-5-vsementsov@virtuozzo.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
14
[mreitz: Adjusted commit message as per Eric's suggestion]
9
Message-id: be2e5fb2d285cbece2b6d06bed54a6f56520d251.1491597120.git.jcody@redhat.com
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
16
---
11
block.c | 7 +++++++
17
include/block/write-threshold.h | 24 ------------------------
12
1 file changed, 7 insertions(+)
18
block/write-threshold.c | 19 -------------------
19
tests/unit/test-write-threshold.c | 4 ----
20
3 files changed, 47 deletions(-)
13
21
14
diff --git a/block.c b/block.c
22
diff --git a/include/block/write-threshold.h b/include/block/write-threshold.h
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
24
--- a/include/block/write-threshold.h
17
+++ b/block.c
25
+++ b/include/block/write-threshold.h
18
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
26
@@ -XXX,XX +XXX,XX @@ void bdrv_write_threshold_set(BlockDriverState *bs, uint64_t threshold_bytes);
19
return -EINVAL;
27
*/
20
}
28
uint64_t bdrv_write_threshold_get(const BlockDriverState *bs);
21
29
22
+ /* Do not clear read_only if it is prohibited */
30
-/*
23
+ if (!read_only && !(bs->open_flags & BDRV_O_ALLOW_RDWR)) {
31
- * bdrv_write_threshold_is_set
24
+ error_setg(errp, "Node '%s' is read only",
32
- *
25
+ bdrv_get_device_or_node_name(bs));
33
- * Tell if a write threshold is set for a given BDS.
26
+ return -EPERM;
34
- */
27
+ }
35
-bool bdrv_write_threshold_is_set(const BlockDriverState *bs);
28
+
36
-
29
bs->read_only = read_only;
37
-/*
30
return 0;
38
- * bdrv_write_threshold_exceeded
39
- *
40
- * Return the extent of a write request that exceeded the threshold,
41
- * or zero if the request is below the threshold.
42
- * Return zero also if the threshold was not set.
43
- *
44
- * NOTE: here we assume the following holds for each request this code
45
- * deals with:
46
- *
47
- * assert((req->offset + req->bytes) <= UINT64_MAX)
48
- *
49
- * Please not there is *not* an actual C assert().
50
- */
51
-uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
52
- const BdrvTrackedRequest *req);
53
-
54
/*
55
* bdrv_write_threshold_check_write
56
*
57
diff --git a/block/write-threshold.c b/block/write-threshold.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/write-threshold.c
60
+++ b/block/write-threshold.c
61
@@ -XXX,XX +XXX,XX @@ uint64_t bdrv_write_threshold_get(const BlockDriverState *bs)
62
return bs->write_threshold_offset;
63
}
64
65
-bool bdrv_write_threshold_is_set(const BlockDriverState *bs)
66
-{
67
- return bs->write_threshold_offset > 0;
68
-}
69
-
70
-uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
71
- const BdrvTrackedRequest *req)
72
-{
73
- if (bdrv_write_threshold_is_set(bs)) {
74
- if (req->offset > bs->write_threshold_offset) {
75
- return (req->offset - bs->write_threshold_offset) + req->bytes;
76
- }
77
- if ((req->offset + req->bytes) > bs->write_threshold_offset) {
78
- return (req->offset + req->bytes) - bs->write_threshold_offset;
79
- }
80
- }
81
- return 0;
82
-}
83
-
84
void bdrv_write_threshold_set(BlockDriverState *bs, uint64_t threshold_bytes)
85
{
86
bs->write_threshold_offset = threshold_bytes;
87
diff --git a/tests/unit/test-write-threshold.c b/tests/unit/test-write-threshold.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/tests/unit/test-write-threshold.c
90
+++ b/tests/unit/test-write-threshold.c
91
@@ -XXX,XX +XXX,XX @@ static void test_threshold_not_set_on_init(void)
92
BlockDriverState bs;
93
memset(&bs, 0, sizeof(bs));
94
95
- g_assert(!bdrv_write_threshold_is_set(&bs));
96
-
97
res = bdrv_write_threshold_get(&bs);
98
g_assert_cmpint(res, ==, 0);
99
}
100
@@ -XXX,XX +XXX,XX @@ static void test_threshold_set_get(void)
101
102
bdrv_write_threshold_set(&bs, threshold);
103
104
- g_assert(bdrv_write_threshold_is_set(&bs));
105
-
106
res = bdrv_write_threshold_get(&bs);
107
g_assert_cmpint(res, ==, threshold);
31
}
108
}
32
--
109
--
33
2.9.3
110
2.31.1
34
111
35
112
diff view generated by jsdifflib
1
For the tests that use the common.qemu functions for running a QEMU
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
process, _cleanup_qemu must be called in the exit function.
3
2
4
If it is not, if the qemu process aborts, then not all of the droppings
3
Testing set/get of one 64bit variable doesn't seem necessary. We have a
5
are cleaned up (e.g. pidfile, fifos).
4
lot of such variables. Also remaining tests do test set/get anyway.
6
5
7
This updates those tests that did not have a cleanup in qemu-iotests.
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20210506090621.11848-7-vsementsov@virtuozzo.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
tests/unit/test-write-threshold.c | 43 -------------------------------
13
1 file changed, 43 deletions(-)
8
14
9
(I swapped spaces for tabs in test 102 as well)
15
diff --git a/tests/unit/test-write-threshold.c b/tests/unit/test-write-threshold.c
10
16
index XXXXXXX..XXXXXXX 100644
11
Reported-by: Eric Blake <eblake@redhat.com>
17
--- a/tests/unit/test-write-threshold.c
12
Reviewed-by: Eric Blake <eblake@redhat.com>
18
+++ b/tests/unit/test-write-threshold.c
13
Signed-off-by: Jeff Cody <jcody@redhat.com>
19
@@ -XXX,XX +XXX,XX @@
14
Message-id: d59c2f6ad6c1da8b9b3c7f357c94a7122ccfc55a.1492544096.git.jcody@redhat.com
20
#include "block/write-threshold.h"
15
---
21
16
tests/qemu-iotests/028 | 1 +
22
17
tests/qemu-iotests/094 | 11 ++++++++---
23
-static void test_threshold_not_set_on_init(void)
18
tests/qemu-iotests/102 | 5 +++--
24
-{
19
tests/qemu-iotests/109 | 1 +
25
- uint64_t res;
20
tests/qemu-iotests/117 | 1 +
26
- BlockDriverState bs;
21
tests/qemu-iotests/130 | 1 +
27
- memset(&bs, 0, sizeof(bs));
22
tests/qemu-iotests/140 | 1 +
28
-
23
tests/qemu-iotests/141 | 1 +
29
- res = bdrv_write_threshold_get(&bs);
24
tests/qemu-iotests/143 | 1 +
30
- g_assert_cmpint(res, ==, 0);
25
tests/qemu-iotests/156 | 1 +
31
-}
26
10 files changed, 19 insertions(+), 5 deletions(-)
32
-
27
33
-static void test_threshold_set_get(void)
28
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
34
-{
29
index XXXXXXX..XXXXXXX 100755
35
- uint64_t threshold = 4 * 1024 * 1024;
30
--- a/tests/qemu-iotests/028
36
- uint64_t res;
31
+++ b/tests/qemu-iotests/028
37
- BlockDriverState bs;
32
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
38
- memset(&bs, 0, sizeof(bs));
33
39
-
34
_cleanup()
40
- bdrv_write_threshold_set(&bs, threshold);
41
-
42
- res = bdrv_write_threshold_get(&bs);
43
- g_assert_cmpint(res, ==, threshold);
44
-}
45
-
46
-static void test_threshold_multi_set_get(void)
47
-{
48
- uint64_t threshold1 = 4 * 1024 * 1024;
49
- uint64_t threshold2 = 15 * 1024 * 1024;
50
- uint64_t res;
51
- BlockDriverState bs;
52
- memset(&bs, 0, sizeof(bs));
53
-
54
- bdrv_write_threshold_set(&bs, threshold1);
55
- bdrv_write_threshold_set(&bs, threshold2);
56
- res = bdrv_write_threshold_get(&bs);
57
- g_assert_cmpint(res, ==, threshold2);
58
-}
59
-
60
static void test_threshold_not_trigger(void)
35
{
61
{
36
+ _cleanup_qemu
62
uint64_t threshold = 4 * 1024 * 1024;
37
rm -f "${TEST_IMG}.copy"
63
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
38
_cleanup_test_img
39
}
40
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
41
index XXXXXXX..XXXXXXX 100755
42
--- a/tests/qemu-iotests/094
43
+++ b/tests/qemu-iotests/094
44
@@ -XXX,XX +XXX,XX @@ echo "QA output created by $seq"
45
here="$PWD"
46
status=1    # failure is the default!
47
48
-trap "exit \$status" 0 1 2 3 15
49
+_cleanup()
50
+{
51
+ _cleanup_qemu
52
+ _cleanup_test_img
53
+ rm -f "$TEST_DIR/source.$IMGFMT"
54
+}
55
+
56
+trap "_cleanup; exit \$status" 0 1 2 3 15
57
58
# get standard environment, filters and checks
59
. ./common.rc
60
@@ -XXX,XX +XXX,XX @@ _send_qemu_cmd $QEMU_HANDLE \
61
62
wait=1 _cleanup_qemu
63
64
-_cleanup_test_img
65
-rm -f "$TEST_DIR/source.$IMGFMT"
66
67
# success, all done
68
echo '*** done'
69
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
70
index XXXXXXX..XXXXXXX 100755
71
--- a/tests/qemu-iotests/102
72
+++ b/tests/qemu-iotests/102
73
@@ -XXX,XX +XXX,XX @@ seq=$(basename $0)
74
echo "QA output created by $seq"
75
76
here=$PWD
77
-status=1    # failure is the default!
78
+status=1 # failure is the default!
79
80
_cleanup()
81
{
64
{
82
-    _cleanup_test_img
65
size_t i;
83
+ _cleanup_qemu
66
TestStruct tests[] = {
84
+ _cleanup_test_img
67
- { "/write-threshold/not-set-on-init",
85
}
68
- test_threshold_not_set_on_init },
86
trap "_cleanup; exit \$status" 0 1 2 3 15
69
- { "/write-threshold/set-get",
87
70
- test_threshold_set_get },
88
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
71
- { "/write-threshold/multi-set-get",
89
index XXXXXXX..XXXXXXX 100755
72
- test_threshold_multi_set_get },
90
--- a/tests/qemu-iotests/109
73
{ "/write-threshold/not-trigger",
91
+++ b/tests/qemu-iotests/109
74
test_threshold_not_trigger },
92
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
75
{ "/write-threshold/trigger",
93
94
_cleanup()
95
{
96
+ _cleanup_qemu
97
rm -f $TEST_IMG.src
98
    _cleanup_test_img
99
}
100
diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117
101
index XXXXXXX..XXXXXXX 100755
102
--- a/tests/qemu-iotests/117
103
+++ b/tests/qemu-iotests/117
104
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
105
106
_cleanup()
107
{
108
+ _cleanup_qemu
109
    _cleanup_test_img
110
}
111
trap "_cleanup; exit \$status" 0 1 2 3 15
112
diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
113
index XXXXXXX..XXXXXXX 100755
114
--- a/tests/qemu-iotests/130
115
+++ b/tests/qemu-iotests/130
116
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
117
118
_cleanup()
119
{
120
+ _cleanup_qemu
121
_cleanup_test_img
122
}
123
trap "_cleanup; exit \$status" 0 1 2 3 15
124
diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140
125
index XXXXXXX..XXXXXXX 100755
126
--- a/tests/qemu-iotests/140
127
+++ b/tests/qemu-iotests/140
128
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
129
130
_cleanup()
131
{
132
+ _cleanup_qemu
133
_cleanup_test_img
134
rm -f "$TEST_DIR/nbd"
135
}
136
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
137
index XXXXXXX..XXXXXXX 100755
138
--- a/tests/qemu-iotests/141
139
+++ b/tests/qemu-iotests/141
140
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
141
142
_cleanup()
143
{
144
+ _cleanup_qemu
145
_cleanup_test_img
146
rm -f "$TEST_DIR/{b,m,o}.$IMGFMT"
147
}
148
diff --git a/tests/qemu-iotests/143 b/tests/qemu-iotests/143
149
index XXXXXXX..XXXXXXX 100755
150
--- a/tests/qemu-iotests/143
151
+++ b/tests/qemu-iotests/143
152
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
153
154
_cleanup()
155
{
156
+ _cleanup_qemu
157
rm -f "$TEST_DIR/nbd"
158
}
159
trap "_cleanup; exit \$status" 0 1 2 3 15
160
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
161
index XXXXXXX..XXXXXXX 100755
162
--- a/tests/qemu-iotests/156
163
+++ b/tests/qemu-iotests/156
164
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
165
166
_cleanup()
167
{
168
+ _cleanup_qemu
169
rm -f "$TEST_IMG{,.target}{,.backing,.overlay}"
170
}
171
trap "_cleanup; exit \$status" 0 1 2 3 15
172
--
76
--
173
2.9.3
77
2.31.1
174
78
175
79
diff view generated by jsdifflib
1
We have a helper wrapper for checking for the BDS read_only flag,
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
add a helper wrapper to set the read_only flag as well.
3
2
3
We don't need this extra logic: it doesn't make code simpler.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Message-Id: <20210506090621.11848-8-vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Signed-off-by: Jeff Cody <jcody@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
7
Message-id: 9b18972d05f5fa2ac16c014f0af98d680553048d.1491597120.git.jcody@redhat.com
8
---
10
---
9
block.c | 5 +++++
11
tests/unit/test-write-threshold.c | 20 +++-----------------
10
block/bochs.c | 2 +-
12
1 file changed, 3 insertions(+), 17 deletions(-)
11
block/cloop.c | 2 +-
12
block/dmg.c | 2 +-
13
block/rbd.c | 2 +-
14
block/vvfat.c | 4 ++--
15
include/block/block.h | 1 +
16
7 files changed, 12 insertions(+), 6 deletions(-)
17
13
18
diff --git a/block.c b/block.c
14
diff --git a/tests/unit/test-write-threshold.c b/tests/unit/test-write-threshold.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/block.c
16
--- a/tests/unit/test-write-threshold.c
21
+++ b/block.c
17
+++ b/tests/unit/test-write-threshold.c
22
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
18
@@ -XXX,XX +XXX,XX @@ static void test_threshold_trigger(void)
23
}
19
g_assert_cmpuint(bdrv_write_threshold_get(&bs), ==, 0);
24
}
20
}
25
21
26
+void bdrv_set_read_only(BlockDriverState *bs, bool read_only)
22
-typedef struct TestStruct {
27
+{
23
- const char *name;
28
+ bs->read_only = read_only;
24
- void (*func)(void);
29
+}
25
-} TestStruct;
26
-
27
28
int main(int argc, char **argv)
29
{
30
- size_t i;
31
- TestStruct tests[] = {
32
- { "/write-threshold/not-trigger",
33
- test_threshold_not_trigger },
34
- { "/write-threshold/trigger",
35
- test_threshold_trigger },
36
- { NULL, NULL }
37
- };
38
-
39
g_test_init(&argc, &argv, NULL);
40
- for (i = 0; tests[i].name != NULL; i++) {
41
- g_test_add_func(tests[i].name, tests[i].func);
42
- }
43
+ g_test_add_func("/write-threshold/not-trigger", test_threshold_not_trigger);
44
+ g_test_add_func("/write-threshold/trigger", test_threshold_trigger);
30
+
45
+
31
void bdrv_get_full_backing_filename_from_filename(const char *backed,
46
return g_test_run();
32
const char *backing,
47
}
33
char *dest, size_t sz,
34
diff --git a/block/bochs.c b/block/bochs.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block/bochs.c
37
+++ b/block/bochs.c
38
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
39
return -EINVAL;
40
}
41
42
- bs->read_only = true; /* no write support yet */
43
+ bdrv_set_read_only(bs, true); /* no write support yet */
44
45
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
46
if (ret < 0) {
47
diff --git a/block/cloop.c b/block/cloop.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/block/cloop.c
50
+++ b/block/cloop.c
51
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
52
return -EINVAL;
53
}
54
55
- bs->read_only = true;
56
+ bdrv_set_read_only(bs, true);
57
58
/* read header */
59
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
60
diff --git a/block/dmg.c b/block/dmg.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/block/dmg.c
63
+++ b/block/dmg.c
64
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
65
}
66
67
block_module_load_one("dmg-bz2");
68
- bs->read_only = true;
69
+ bdrv_set_read_only(bs, true);
70
71
s->n_chunks = 0;
72
s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
73
diff --git a/block/rbd.c b/block/rbd.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/block/rbd.c
76
+++ b/block/rbd.c
77
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
78
goto failed_open;
79
}
80
81
- bs->read_only = (s->snap != NULL);
82
+ bdrv_set_read_only(bs, (s->snap != NULL));
83
84
qemu_opts_del(opts);
85
return 0;
86
diff --git a/block/vvfat.c b/block/vvfat.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/block/vvfat.c
89
+++ b/block/vvfat.c
90
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
91
s->current_cluster=0xffffffff;
92
93
/* read only is the default for safety */
94
- bs->read_only = true;
95
+ bdrv_set_read_only(bs, true);
96
s->qcow = NULL;
97
s->qcow_filename = NULL;
98
s->fat2 = NULL;
99
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
100
if (ret < 0) {
101
goto fail;
102
}
103
- bs->read_only = false;
104
+ bdrv_set_read_only(bs, false);
105
}
106
107
bs->total_sectors = cyls * heads * secs;
108
diff --git a/include/block/block.h b/include/block/block.h
109
index XXXXXXX..XXXXXXX 100644
110
--- a/include/block/block.h
111
+++ b/include/block/block.h
112
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
113
int64_t sector_num, int nb_sectors, int *pnum);
114
115
bool bdrv_is_read_only(BlockDriverState *bs);
116
+void bdrv_set_read_only(BlockDriverState *bs, bool read_only);
117
bool bdrv_is_sg(BlockDriverState *bs);
118
bool bdrv_is_inserted(BlockDriverState *bs);
119
int bdrv_media_changed(BlockDriverState *bs);
120
--
48
--
121
2.9.3
49
2.31.1
122
50
123
51
diff view generated by jsdifflib
1
The protocol VXHS does not support image creation. Some tests expect
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
to be able to create images through the protocol. Exclude VXHS from
3
these tests.
4
2
5
Signed-off-by: Jeff Cody <jcody@redhat.com>
3
"qemu/typedefs.h" is enough for include/block/write-threshold.h header
4
with forward declaration of BlockDriverState. Also drop extra includes
5
from block/write-threshold.c and tests/unit/test-write-threshold.c
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-Id: <20210506090621.11848-9-vsementsov@virtuozzo.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
---
11
---
7
tests/qemu-iotests/017 | 1 +
12
include/block/write-threshold.h | 2 +-
8
tests/qemu-iotests/020 | 1 +
13
block/write-threshold.c | 2 --
9
tests/qemu-iotests/029 | 1 +
14
tests/unit/test-write-threshold.c | 1 -
10
tests/qemu-iotests/073 | 1 +
15
3 files changed, 1 insertion(+), 4 deletions(-)
11
tests/qemu-iotests/114 | 1 +
12
tests/qemu-iotests/130 | 1 +
13
tests/qemu-iotests/134 | 1 +
14
tests/qemu-iotests/156 | 1 +
15
tests/qemu-iotests/158 | 1 +
16
9 files changed, 9 insertions(+)
17
16
18
diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017
17
diff --git a/include/block/write-threshold.h b/include/block/write-threshold.h
19
index XXXXXXX..XXXXXXX 100755
18
index XXXXXXX..XXXXXXX 100644
20
--- a/tests/qemu-iotests/017
19
--- a/include/block/write-threshold.h
21
+++ b/tests/qemu-iotests/017
20
+++ b/include/block/write-threshold.h
22
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
21
@@ -XXX,XX +XXX,XX @@
23
# Any format supporting backing files
22
#ifndef BLOCK_WRITE_THRESHOLD_H
24
_supported_fmt qcow qcow2 vmdk qed
23
#define BLOCK_WRITE_THRESHOLD_H
25
_supported_proto generic
24
26
+_unsupported_proto vxhs
25
-#include "block/block_int.h"
27
_supported_os Linux
26
+#include "qemu/typedefs.h"
28
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
27
29
28
/*
30
diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020
29
* bdrv_write_threshold_set:
31
index XXXXXXX..XXXXXXX 100755
30
diff --git a/block/write-threshold.c b/block/write-threshold.c
32
--- a/tests/qemu-iotests/020
31
index XXXXXXX..XXXXXXX 100644
33
+++ b/tests/qemu-iotests/020
32
--- a/block/write-threshold.c
34
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
33
+++ b/block/write-threshold.c
35
# Any format supporting backing files
34
@@ -XXX,XX +XXX,XX @@
36
_supported_fmt qcow qcow2 vmdk qed
35
37
_supported_proto generic
36
#include "qemu/osdep.h"
38
+_unsupported_proto vxhs
37
#include "block/block_int.h"
39
_supported_os Linux
38
-#include "qemu/coroutine.h"
40
_unsupported_imgopts "subformat=monolithicFlat" \
39
#include "block/write-threshold.h"
41
"subformat=twoGbMaxExtentFlat" \
40
-#include "qemu/notify.h"
42
diff --git a/tests/qemu-iotests/029 b/tests/qemu-iotests/029
41
#include "qapi/error.h"
43
index XXXXXXX..XXXXXXX 100755
42
#include "qapi/qapi-commands-block-core.h"
44
--- a/tests/qemu-iotests/029
43
#include "qapi/qapi-events-block-core.h"
45
+++ b/tests/qemu-iotests/029
44
diff --git a/tests/unit/test-write-threshold.c b/tests/unit/test-write-threshold.c
46
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
45
index XXXXXXX..XXXXXXX 100644
47
# Any format supporting intenal snapshots
46
--- a/tests/unit/test-write-threshold.c
48
_supported_fmt qcow2
47
+++ b/tests/unit/test-write-threshold.c
49
_supported_proto generic
48
@@ -XXX,XX +XXX,XX @@
50
+_unsupported_proto vxhs
49
*/
51
_supported_os Linux
50
52
# Internal snapshots are (currently) impossible with refcount_bits=1
51
#include "qemu/osdep.h"
53
_unsupported_imgopts 'refcount_bits=1[^0-9]'
52
-#include "qapi/error.h"
54
diff --git a/tests/qemu-iotests/073 b/tests/qemu-iotests/073
53
#include "block/block_int.h"
55
index XXXXXXX..XXXXXXX 100755
54
#include "block/write-threshold.h"
56
--- a/tests/qemu-iotests/073
57
+++ b/tests/qemu-iotests/073
58
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
59
60
_supported_fmt qcow2
61
_supported_proto generic
62
+_unsupported_proto vxhs
63
_supported_os Linux
64
65
CLUSTER_SIZE=64k
66
diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114
67
index XXXXXXX..XXXXXXX 100755
68
--- a/tests/qemu-iotests/114
69
+++ b/tests/qemu-iotests/114
70
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
71
72
_supported_fmt qcow2
73
_supported_proto generic
74
+_unsupported_proto vxhs
75
_supported_os Linux
76
77
78
diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
79
index XXXXXXX..XXXXXXX 100755
80
--- a/tests/qemu-iotests/130
81
+++ b/tests/qemu-iotests/130
82
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
83
84
_supported_fmt qcow2
85
_supported_proto generic
86
+_unsupported_proto vxhs
87
_supported_os Linux
88
89
qemu_comm_method="monitor"
90
diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134
91
index XXXXXXX..XXXXXXX 100755
92
--- a/tests/qemu-iotests/134
93
+++ b/tests/qemu-iotests/134
94
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
95
96
_supported_fmt qcow2
97
_supported_proto generic
98
+_unsupported_proto vxhs
99
_supported_os Linux
100
101
102
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
103
index XXXXXXX..XXXXXXX 100755
104
--- a/tests/qemu-iotests/156
105
+++ b/tests/qemu-iotests/156
106
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
107
108
_supported_fmt qcow2 qed
109
_supported_proto generic
110
+_unsupported_proto vxhs
111
_supported_os Linux
112
113
# Create source disk
114
diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158
115
index XXXXXXX..XXXXXXX 100755
116
--- a/tests/qemu-iotests/158
117
+++ b/tests/qemu-iotests/158
118
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
119
120
_supported_fmt qcow2
121
_supported_proto generic
122
+_unsupported_proto vxhs
123
_supported_os Linux
124
125
55
126
--
56
--
127
2.9.3
57
2.31.1
128
58
129
59
diff view generated by jsdifflib