1
The following changes since commit 95b31d709ba343ad237c3630047ee7438bac4065:
1
The following changes since commit 3521ade3510eb5cefb2e27a101667f25dad89935:
2
2
3
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20170331.0' into staging (2017-03-31 18:06:13 +0100)
3
Merge remote-tracking branch 'remotes/thuth-gitlab/tags/pull-request-2021-07-29' into staging (2021-07-29 13:17:20 +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://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to 34634ca28688652198f77d7001c0f1e204434663:
9
for you to fetch changes up to cc8eecd7f105a1dff5876adeb238a14696061a4a:
10
10
11
block/curl: Check protocol prefix (2017-03-31 15:53:22 -0400)
11
MAINTAINERS: Added myself as a reviewer for the NVMe Block Driver (2021-07-29 17:17:34 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches for -rc3
14
Pull request
15
16
The main fix here is for io_uring. Spurious -EAGAIN errors can happen and the
17
request needs to be resubmitted.
18
19
The MAINTAINERS changes carry no risk and we might as well include them in QEMU
20
6.1.
21
15
----------------------------------------------------------------
22
----------------------------------------------------------------
16
23
17
Eric Blake (1):
24
Fabian Ebner (1):
18
rbd: Fix regression in legacy key/values containing escaped :
25
block/io_uring: resubmit when result is -EAGAIN
19
26
20
Max Reitz (2):
27
Philippe Mathieu-Daudé (1):
21
qapi/curl: Extend and fix blockdev-add schema
28
MAINTAINERS: Added myself as a reviewer for the NVMe Block Driver
22
block/curl: Check protocol prefix
23
29
24
block/curl.c | 10 +++++
30
Stefano Garzarella (1):
25
block/rbd.c | 83 +++++++++++++++++++++--------------------
31
MAINTAINERS: add Stefano Garzarella as io_uring reviewer
26
qapi/block-core.json | 103 ++++++++++++++++++++++++++++++++++++++++++++++-----
32
27
3 files changed, 146 insertions(+), 50 deletions(-)
33
MAINTAINERS | 2 ++
34
block/io_uring.c | 16 +++++++++++++++-
35
2 files changed, 17 insertions(+), 1 deletion(-)
28
36
29
--
37
--
30
2.9.3
38
2.31.1
31
39
32
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
If the user has explicitly specified a block driver and thus a protocol,
3
I've been working with io_uring for a while so I'd like to help
4
we have to make sure the URL's protocol prefix matches. Otherwise the
4
with reviews.
5
latter will silently override the former which might catch some users by
6
surprise.
7
5
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-Id: <20210728131515.131045-1-sgarzare@redhat.com>
10
Reviewed-by: Jeff Cody <jcody@redhat.com>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Message-id: 20170331120431.1767-3-mreitz@redhat.com
13
Signed-off-by: Jeff Cody <jcody@redhat.com>
14
---
9
---
15
block/curl.c | 10 ++++++++++
10
MAINTAINERS | 1 +
16
1 file changed, 10 insertions(+)
11
1 file changed, 1 insertion(+)
17
12
18
diff --git a/block/curl.c b/block/curl.c
13
diff --git a/MAINTAINERS b/MAINTAINERS
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/block/curl.c
15
--- a/MAINTAINERS
21
+++ b/block/curl.c
16
+++ b/MAINTAINERS
22
@@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
17
@@ -XXX,XX +XXX,XX @@ Linux io_uring
23
const char *cookie;
18
M: Aarushi Mehta <mehta.aaru20@gmail.com>
24
double d;
19
M: Julia Suvorova <jusual@redhat.com>
25
const char *secretid;
20
M: Stefan Hajnoczi <stefanha@redhat.com>
26
+ const char *protocol_delimiter;
21
+R: Stefano Garzarella <sgarzare@redhat.com>
27
22
L: qemu-block@nongnu.org
28
static int inited = 0;
23
S: Maintained
29
24
F: block/io_uring.c
30
@@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
31
goto out_noclean;
32
}
33
34
+ if (!strstart(file, bs->drv->protocol_name, &protocol_delimiter) ||
35
+ !strstart(protocol_delimiter, "://", NULL))
36
+ {
37
+ error_setg(errp, "%s curl driver cannot handle the URL '%s' (does not "
38
+ "start with '%s://')", bs->drv->protocol_name, file,
39
+ bs->drv->protocol_name);
40
+ goto out_noclean;
41
+ }
42
+
43
s->username = g_strdup(qemu_opt_get(opts, CURL_BLOCK_OPT_USERNAME));
44
secretid = qemu_opt_get(opts, CURL_BLOCK_OPT_PASSWORD_SECRET);
45
46
--
25
--
47
2.9.3
26
2.31.1
48
27
49
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Fabian Ebner <f.ebner@proxmox.com>
2
2
3
The curl block driver accepts more options than just "filename"; also,
3
Linux SCSI can throw spurious -EAGAIN in some corner cases in its
4
the URL is actually expected to be passed through the "url" option
4
completion path, which will end up being the result in the completed
5
instead of "filename".
5
io_uring request.
6
6
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Resubmitting such requests should allow block jobs to complete, even
8
Reviewed-by: Jeff Cody <jcody@redhat.com>
8
if such spurious errors are encountered.
9
Reviewed-by: Eric Blake <eblake@redhat.com>
9
10
Message-id: 20170331120431.1767-2-mreitz@redhat.com
10
Co-authored-by: Stefan Hajnoczi <stefanha@gmail.com>
11
Signed-off-by: Jeff Cody <jcody@redhat.com>
11
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
12
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
13
Message-id: 20210729091029.65369-1-f.ebner@proxmox.com
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
15
---
13
qapi/block-core.json | 103 ++++++++++++++++++++++++++++++++++++++++++++++-----
16
block/io_uring.c | 16 +++++++++++++++-
14
1 file changed, 94 insertions(+), 9 deletions(-)
17
1 file changed, 15 insertions(+), 1 deletion(-)
15
18
16
diff --git a/qapi/block-core.json b/qapi/block-core.json
19
diff --git a/block/io_uring.c b/block/io_uring.c
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/qapi/block-core.json
21
--- a/block/io_uring.c
19
+++ b/qapi/block-core.json
22
+++ b/block/io_uring.c
20
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static void luring_process_completions(LuringState *s)
21
'*debug': 'int' } }
24
total_bytes = ret + luringcb->total_read;
22
25
23
##
26
if (ret < 0) {
24
-# @BlockdevOptionsCurl:
27
- if (ret == -EINTR) {
25
+# @BlockdevOptionsCurlBase:
28
+ /*
26
#
29
+ * Only writev/readv/fsync requests on regular files or host block
27
-# Driver specific block device options for the curl backend.
30
+ * devices are submitted. Therefore -EAGAIN is not expected but it's
28
+# Driver specific block device options shared by all protocols supported by the
31
+ * known to happen sometimes with Linux SCSI. Submit again and hope
29
+# curl backend.
32
+ * the request completes successfully.
30
#
33
+ *
31
-# @filename: path to the image file
34
+ * For more information, see:
32
+# @url: URL of the image file
35
+ * https://lore.kernel.org/io-uring/20210727165811.284510-3-axboe@kernel.dk/T/#u
33
+#
36
+ *
34
+# @readahead: Size of the read-ahead cache; must be a multiple of
37
+ * If the code is changed to submit other types of requests in the
35
+# 512 (defaults to 256 kB)
38
+ * future, then this workaround may need to be extended to deal with
36
+#
39
+ * genuine -EAGAIN results that should not be resubmitted
37
+# @timeout: Timeout for connections, in seconds (defaults to 5)
40
+ * immediately.
38
+#
41
+ */
39
+# @username: Username for authentication (defaults to none)
42
+ if (ret == -EINTR || ret == -EAGAIN) {
40
+#
43
luring_resubmit(s, luringcb);
41
+# @password-secret: ID of a QCryptoSecret object providing a password
44
continue;
42
+# for authentication (defaults to no password)
45
}
43
+#
44
+# @proxy-username: Username for proxy authentication (defaults to none)
45
+#
46
+# @proxy-password-secret: ID of a QCryptoSecret object providing a password
47
+# for proxy authentication (defaults to no password)
48
+#
49
+# Since: 2.9
50
+##
51
+{ 'struct': 'BlockdevOptionsCurlBase',
52
+ 'data': { 'url': 'str',
53
+ '*readahead': 'int',
54
+ '*timeout': 'int',
55
+ '*username': 'str',
56
+ '*password-secret': 'str',
57
+ '*proxy-username': 'str',
58
+ '*proxy-password-secret': 'str' } }
59
+
60
+##
61
+# @BlockdevOptionsCurlHttp:
62
+#
63
+# Driver specific block device options for HTTP connections over the curl
64
+# backend. URLs must start with "http://".
65
+#
66
+# @cookie: List of cookies to set; format is
67
+# "name1=content1; name2=content2;" as explained by
68
+# CURLOPT_COOKIE(3). Defaults to no cookies.
69
+#
70
+# Since: 2.9
71
+##
72
+{ 'struct': 'BlockdevOptionsCurlHttp',
73
+ 'base': 'BlockdevOptionsCurlBase',
74
+ 'data': { '*cookie': 'str' } }
75
+
76
+##
77
+# @BlockdevOptionsCurlHttps:
78
+#
79
+# Driver specific block device options for HTTPS connections over the curl
80
+# backend. URLs must start with "https://".
81
+#
82
+# @cookie: List of cookies to set; format is
83
+# "name1=content1; name2=content2;" as explained by
84
+# CURLOPT_COOKIE(3). Defaults to no cookies.
85
+#
86
+# @sslverify: Whether to verify the SSL certificate's validity (defaults to
87
+# true)
88
+#
89
+# Since: 2.9
90
+##
91
+{ 'struct': 'BlockdevOptionsCurlHttps',
92
+ 'base': 'BlockdevOptionsCurlBase',
93
+ 'data': { '*cookie': 'str',
94
+ '*sslverify': 'bool' } }
95
+
96
+##
97
+# @BlockdevOptionsCurlFtp:
98
+#
99
+# Driver specific block device options for FTP connections over the curl
100
+# backend. URLs must start with "ftp://".
101
+#
102
+# Since: 2.9
103
+##
104
+{ 'struct': 'BlockdevOptionsCurlFtp',
105
+ 'base': 'BlockdevOptionsCurlBase',
106
+ 'data': { } }
107
+
108
+##
109
+# @BlockdevOptionsCurlFtps:
110
+#
111
+# Driver specific block device options for FTPS connections over the curl
112
+# backend. URLs must start with "ftps://".
113
+#
114
+# @sslverify: Whether to verify the SSL certificate's validity (defaults to
115
+# true)
116
#
117
# Since: 2.9
118
##
119
-{ 'struct': 'BlockdevOptionsCurl',
120
- 'data': { 'filename': 'str' } }
121
+{ 'struct': 'BlockdevOptionsCurlFtps',
122
+ 'base': 'BlockdevOptionsCurlBase',
123
+ 'data': { '*sslverify': 'bool' } }
124
125
##
126
# @BlockdevOptionsNbd:
127
@@ -XXX,XX +XXX,XX @@
128
'cloop': 'BlockdevOptionsGenericFormat',
129
'dmg': 'BlockdevOptionsGenericFormat',
130
'file': 'BlockdevOptionsFile',
131
- 'ftp': 'BlockdevOptionsCurl',
132
- 'ftps': 'BlockdevOptionsCurl',
133
+ 'ftp': 'BlockdevOptionsCurlFtp',
134
+ 'ftps': 'BlockdevOptionsCurlFtps',
135
'gluster': 'BlockdevOptionsGluster',
136
'host_cdrom': 'BlockdevOptionsFile',
137
'host_device':'BlockdevOptionsFile',
138
- 'http': 'BlockdevOptionsCurl',
139
- 'https': 'BlockdevOptionsCurl',
140
+ 'http': 'BlockdevOptionsCurlHttp',
141
+ 'https': 'BlockdevOptionsCurlHttps',
142
'iscsi': 'BlockdevOptionsIscsi',
143
'luks': 'BlockdevOptionsLUKS',
144
'nbd': 'BlockdevOptionsNbd',
145
--
46
--
146
2.9.3
47
2.31.1
147
48
148
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Commit c7cacb3 accidentally broke legacy key-value parsing through
3
I'm interested in following the activity around the NVMe bdrv.
4
pseudo-filename parsing of -drive file=rbd://..., for any key that
5
contains an escaped ':'. Such a key is surprisingly common, thanks
6
to mon_host specifying a 'host:port' string. The break happens
7
because passing things from QDict through QemuOpts back to another
8
QDict requires that we pack our parsed key/value pairs into a string,
9
and then reparse that string, but the intermediate string that we
10
created ("key1=value1:key2=value2") lost the \: escaping that was
11
present in the original, so that we could no longer see which : were
12
used as separators vs. those used as part of the original input.
13
4
14
Fix it by collecting the key/value pairs through a QList, and
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
sending that list on a round trip through a JSON QString (as in
6
Message-id: 20210728183340.2018313-1-philmd@redhat.com
16
'["key1","value1","key2","value2"]') on its way through QemuOpts,
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
rather than hand-rolling our own string. Since the string is only
8
---
18
handled internally, this was faster than creating a full-blown
9
MAINTAINERS | 1 +
19
struct of '[{"key1":"value1"},{"key2":"value2"}]', and safer at
10
1 file changed, 1 insertion(+)
20
guaranteeing order compared to '{"key1":"value1","key2":"value2"}'.
21
11
22
It would be nicer if we didn't have to round-trip through QemuOpts
12
diff --git a/MAINTAINERS b/MAINTAINERS
23
in the first place, but that's a much bigger task for later.
13
index XXXXXXX..XXXXXXX 100644
14
--- a/MAINTAINERS
15
+++ b/MAINTAINERS
16
@@ -XXX,XX +XXX,XX @@ F: block/null.c
17
NVMe Block Driver
18
M: Stefan Hajnoczi <stefanha@redhat.com>
19
R: Fam Zheng <fam@euphon.net>
20
+R: Philippe Mathieu-Daudé <philmd@redhat.com>
21
L: qemu-block@nongnu.org
22
S: Supported
23
F: block/nvme*
24
--
25
2.31.1
24
26
25
Reproducer:
26
./x86_64-softmmu/qemu-system-x86_64 -nodefaults -nographic -qmp stdio \
27
-drive 'file=rbd:volumes/volume-ea141b5c-cdb3-4765-910d-e7008b209a70'\
28
':id=compute:key=AQAVkvxXAAAAABAA9ZxWFYdRmV+DSwKr7BKKXg=='\
29
':auth_supported=cephx\;none:mon_host=192.168.1.2\:6789'\
30
',format=raw,if=none,id=drive-virtio-disk0,'\
31
'serial=ea141b5c-cdb3-4765-910d-e7008b209a70,cache=writeback'
32
33
Even without an RBD setup, this serves a test of whether we get
34
the incorrect parser error of:
35
qemu-system-x86_64: -drive file=rbd:...cache=writeback: conf option 6789 has no value
36
or the correct behavior of hanging while trying to connect to
37
the requested mon_host of 192.168.1.2:6789.
38
39
Reported-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
40
Signed-off-by: Eric Blake <eblake@redhat.com>
41
Reviewed-by: Jeff Cody <jcody@redhat.com>
42
Reviewed-by: Max Reitz <mreitz@redhat.com>
43
Message-id: 20170331152730.12514-1-eblake@redhat.com
44
Signed-off-by: Jeff Cody <jcody@redhat.com>
45
---
46
block/rbd.c | 83 +++++++++++++++++++++++++++++++------------------------------
47
1 file changed, 42 insertions(+), 41 deletions(-)
48
49
diff --git a/block/rbd.c b/block/rbd.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/block/rbd.c
52
+++ b/block/rbd.c
53
@@ -XXX,XX +XXX,XX @@
54
#include "crypto/secret.h"
55
#include "qemu/cutils.h"
56
#include "qapi/qmp/qstring.h"
57
+#include "qapi/qmp/qjson.h"
58
59
/*
60
* When specifying the image filename use:
61
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
62
Error **errp)
63
{
64
const char *start;
65
- char *p, *buf, *keypairs;
66
+ char *p, *buf;
67
+ QList *keypairs = NULL;
68
char *found_str;
69
- size_t max_keypair_size;
70
71
if (!strstart(filename, "rbd:", &start)) {
72
error_setg(errp, "File name must start with 'rbd:'");
73
return;
74
}
75
76
- max_keypair_size = strlen(start) + 1;
77
buf = g_strdup(start);
78
- keypairs = g_malloc0(max_keypair_size);
79
p = buf;
80
81
found_str = qemu_rbd_next_tok(p, '/', &p);
82
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
83
} else if (!strcmp(name, "id")) {
84
qdict_put(options, "user" , qstring_from_str(value));
85
} else {
86
- /* FIXME: This is pretty ugly, and not the right way to do this.
87
- * These should be contained in a structure, and then
88
- * passed explicitly as individual key/value pairs to
89
- * rados. Consider this legacy code that needs to be
90
- * updated. */
91
- char *tmp = g_malloc0(max_keypair_size);
92
- /* only use a delimiter if it is not the first keypair found */
93
- /* These are sets of unknown key/value pairs we'll pass along
94
- * to ceph */
95
- if (keypairs[0]) {
96
- snprintf(tmp, max_keypair_size, ":%s=%s", name, value);
97
- pstrcat(keypairs, max_keypair_size, tmp);
98
- } else {
99
- snprintf(keypairs, max_keypair_size, "%s=%s", name, value);
100
+ /*
101
+ * We pass these internally to qemu_rbd_set_keypairs(), so
102
+ * we can get away with the simpler list of [ "key1",
103
+ * "value1", "key2", "value2" ] rather than a raw dict
104
+ * { "key1": "value1", "key2": "value2" } where we can't
105
+ * guarantee order, or even a more correct but complex
106
+ * [ { "key1": "value1" }, { "key2": "value2" } ]
107
+ */
108
+ if (!keypairs) {
109
+ keypairs = qlist_new();
110
}
111
- g_free(tmp);
112
+ qlist_append(keypairs, qstring_from_str(name));
113
+ qlist_append(keypairs, qstring_from_str(value));
114
}
115
}
116
117
- if (keypairs[0]) {
118
- qdict_put(options, "=keyvalue-pairs", qstring_from_str(keypairs));
119
+ if (keypairs) {
120
+ qdict_put(options, "=keyvalue-pairs",
121
+ qobject_to_json(QOBJECT(keypairs)));
122
}
123
124
-
125
done:
126
g_free(buf);
127
- g_free(keypairs);
128
+ QDECREF(keypairs);
129
return;
130
}
131
132
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_set_auth(rados_t cluster, const char *secretid,
133
return 0;
134
}
135
136
-static int qemu_rbd_set_keypairs(rados_t cluster, const char *keypairs,
137
+static int qemu_rbd_set_keypairs(rados_t cluster, const char *keypairs_json,
138
Error **errp)
139
{
140
- char *p, *buf;
141
- char *name;
142
- char *value;
143
+ QList *keypairs;
144
+ QString *name;
145
+ QString *value;
146
+ const char *key;
147
+ size_t remaining;
148
int ret = 0;
149
150
- buf = g_strdup(keypairs);
151
- p = buf;
152
+ if (!keypairs_json) {
153
+ return ret;
154
+ }
155
+ keypairs = qobject_to_qlist(qobject_from_json(keypairs_json,
156
+ &error_abort));
157
+ remaining = qlist_size(keypairs) / 2;
158
+ assert(remaining);
159
160
- while (p) {
161
- name = qemu_rbd_next_tok(p, '=', &p);
162
- if (!p) {
163
- error_setg(errp, "conf option %s has no value", name);
164
- ret = -EINVAL;
165
- break;
166
- }
167
+ while (remaining--) {
168
+ name = qobject_to_qstring(qlist_pop(keypairs));
169
+ value = qobject_to_qstring(qlist_pop(keypairs));
170
+ assert(name && value);
171
+ key = qstring_get_str(name);
172
173
- value = qemu_rbd_next_tok(p, ':', &p);
174
-
175
- ret = rados_conf_set(cluster, name, value);
176
+ ret = rados_conf_set(cluster, key, qstring_get_str(value));
177
+ QDECREF(name);
178
+ QDECREF(value);
179
if (ret < 0) {
180
- error_setg_errno(errp, -ret, "invalid conf option %s", name);
181
+ error_setg_errno(errp, -ret, "invalid conf option %s", key);
182
ret = -EINVAL;
183
break;
184
}
185
}
186
187
- g_free(buf);
188
+ QDECREF(keypairs);
189
return ret;
190
}
191
192
--
193
2.9.3
194
195
diff view generated by jsdifflib