1 | The following changes since commit b4fbe1f65a4769c09e6bf2d79fc84360f840f40e: | 1 | The following changes since commit 15ef89d2a1a7b93845a6b09c2ee8e1979f6eb30b: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190129' into staging (2019-01-29 12:00:19 +0000) | 3 | Update version for v7.0.0-rc1 release (2022-03-22 22:58:44 +0000) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | https://git.xanclic.moe/XanClic/qemu.git tags/pull-block-2019-01-31 | 7 | https://gitlab.com/stefanha/qemu.git tags/block-pull-request |
8 | 8 | ||
9 | for you to fetch changes up to 908b30164bbffad7430d551b2a03a8fbcaa631ef: | 9 | for you to fetch changes up to 2539eade4f689eda7e9fe45486f18334bfbafaf0: |
10 | 10 | ||
11 | iotests: Allow 147 to be run concurrently (2019-01-31 00:44:55 +0100) | 11 | hw: Fix misleading hexadecimal format (2022-03-24 10:38:42 +0000) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block patches: | 14 | Pull request |
15 | - New debugging QMP command to explore block graphs | 15 | |
16 | - Converted DPRINTF()s to trace events | 16 | Philippe found cases where the 0x%d format string was used, leading to |
17 | - Fixed qemu-io's use of getopt() for systems with optreset | 17 | misleading output. The patches look harmless and could save people time, so I |
18 | - Minor NVMe emulation fixes | 18 | think it's worth including them in 7.0. |
19 | - An iotest fix | ||
20 | 19 | ||
21 | ---------------------------------------------------------------- | 20 | ---------------------------------------------------------------- |
22 | Laurent Vivier (4): | ||
23 | block/ssh: Convert from DPRINTF() macro to trace events | ||
24 | block/curl: Convert from DPRINTF() macro to trace events | ||
25 | block/file-posix: Convert from DPRINTF() macro to trace events | ||
26 | block/sheepdog: Convert from DPRINTF() macro to trace events | ||
27 | 21 | ||
28 | Li Qiang (3): | 22 | Philippe Mathieu-Daudé (2): |
29 | nvme: use TYPE_NVME instead of constant string | 23 | block: Fix misleading hexadecimal format |
30 | nvme: ensure the num_queues is not zero | 24 | hw: Fix misleading hexadecimal format |
31 | nvme: use pci_dev directly in nvme_realize | ||
32 | 25 | ||
33 | Max Reitz (3): | 26 | block/parallels-ext.c | 2 +- |
34 | iotests.py: Add qemu_nbd_pipe() | 27 | hw/i386/sgx.c | 2 +- |
35 | iotests: Bind qemu-nbd to localhost in 147 | 28 | hw/i386/trace-events | 6 +++--- |
36 | iotests: Allow 147 to be run concurrently | 29 | hw/misc/trace-events | 4 ++-- |
37 | 30 | hw/scsi/trace-events | 4 ++-- | |
38 | Richard W.M. Jones (1): | 31 | 5 files changed, 9 insertions(+), 9 deletions(-) |
39 | qemu-io: Add generic function for reinitializing optind. | ||
40 | |||
41 | Vladimir Sementsov-Ogievskiy (2): | ||
42 | qapi: add x-debug-query-block-graph | ||
43 | scripts: add render_block_graph function for QEMUMachine | ||
44 | |||
45 | configure | 14 ++++ | ||
46 | qapi/block-core.json | 108 ++++++++++++++++++++++++ | ||
47 | include/block/block.h | 1 + | ||
48 | include/qemu/osdep.h | 16 ++++ | ||
49 | include/sysemu/block-backend.h | 2 + | ||
50 | block.c | 148 +++++++++++++++++++++++++++++++++ | ||
51 | block/block-backend.c | 5 ++ | ||
52 | block/curl.c | 29 ++----- | ||
53 | block/file-posix.c | 25 ++---- | ||
54 | block/sheepdog.c | 47 ++++------- | ||
55 | block/ssh.c | 46 ++++------ | ||
56 | blockdev.c | 5 ++ | ||
57 | hw/block/nvme.c | 15 ++-- | ||
58 | qemu-img.c | 2 +- | ||
59 | qemu-io-cmds.c | 2 +- | ||
60 | block/trace-events | 47 +++++++++++ | ||
61 | scripts/render_block_graph.py | 120 ++++++++++++++++++++++++++ | ||
62 | tests/qemu-iotests/147 | 98 +++++++++++++++------- | ||
63 | tests/qemu-iotests/iotests.py | 14 ++++ | ||
64 | 19 files changed, 608 insertions(+), 136 deletions(-) | ||
65 | create mode 100755 scripts/render_block_graph.py | ||
66 | 32 | ||
67 | -- | 33 | -- |
68 | 2.20.1 | 34 | 2.35.1 |
69 | 35 | ||
70 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Add a new command, returning block nodes (and their users) graph. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Message-id: 20181221170909.25584-2-vsementsov@virtuozzo.com | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | --- | ||
9 | qapi/block-core.json | 108 ++++++++++++++++++++++++ | ||
10 | include/block/block.h | 1 + | ||
11 | include/sysemu/block-backend.h | 2 + | ||
12 | block.c | 148 +++++++++++++++++++++++++++++++++ | ||
13 | block/block-backend.c | 5 ++ | ||
14 | blockdev.c | 5 ++ | ||
15 | 6 files changed, 269 insertions(+) | ||
16 | |||
17 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/qapi/block-core.json | ||
20 | +++ b/qapi/block-core.json | ||
21 | @@ -XXX,XX +XXX,XX @@ | ||
22 | ## | ||
23 | { 'command': 'query-named-block-nodes', 'returns': [ 'BlockDeviceInfo' ] } | ||
24 | |||
25 | +## | ||
26 | +# @XDbgBlockGraphNodeType: | ||
27 | +# | ||
28 | +# @block-backend: corresponds to BlockBackend | ||
29 | +# | ||
30 | +# @block-job: corresonds to BlockJob | ||
31 | +# | ||
32 | +# @block-driver: corresponds to BlockDriverState | ||
33 | +# | ||
34 | +# Since: 4.0 | ||
35 | +## | ||
36 | +{ 'enum': 'XDbgBlockGraphNodeType', | ||
37 | + 'data': [ 'block-backend', 'block-job', 'block-driver' ] } | ||
38 | + | ||
39 | +## | ||
40 | +# @XDbgBlockGraphNode: | ||
41 | +# | ||
42 | +# @id: Block graph node identifier. This @id is generated only for | ||
43 | +# x-debug-query-block-graph and does not relate to any other identifiers in | ||
44 | +# Qemu. | ||
45 | +# | ||
46 | +# @type: Type of graph node. Can be one of block-backend, block-job or | ||
47 | +# block-driver-state. | ||
48 | +# | ||
49 | +# @name: Human readable name of the node. Corresponds to node-name for | ||
50 | +# block-driver-state nodes; is not guaranteed to be unique in the whole | ||
51 | +# graph (with block-jobs and block-backends). | ||
52 | +# | ||
53 | +# Since: 4.0 | ||
54 | +## | ||
55 | +{ 'struct': 'XDbgBlockGraphNode', | ||
56 | + 'data': { 'id': 'uint64', 'type': 'XDbgBlockGraphNodeType', 'name': 'str' } } | ||
57 | + | ||
58 | +## | ||
59 | +# @BlockPermission: | ||
60 | +# | ||
61 | +# Enum of base block permissions. | ||
62 | +# | ||
63 | +# @consistent-read: A user that has the "permission" of consistent reads is | ||
64 | +# guaranteed that their view of the contents of the block | ||
65 | +# device is complete and self-consistent, representing the | ||
66 | +# contents of a disk at a specific point. | ||
67 | +# For most block devices (including their backing files) this | ||
68 | +# is true, but the property cannot be maintained in a few | ||
69 | +# situations like for intermediate nodes of a commit block | ||
70 | +# job. | ||
71 | +# | ||
72 | +# @write: This permission is required to change the visible disk contents. | ||
73 | +# | ||
74 | +# @write-unchanged: This permission (which is weaker than BLK_PERM_WRITE) is | ||
75 | +# both enough and required for writes to the block node when | ||
76 | +# the caller promises that the visible disk content doesn't | ||
77 | +# change. | ||
78 | +# As the BLK_PERM_WRITE permission is strictly stronger, | ||
79 | +# either is sufficient to perform an unchanging write. | ||
80 | +# | ||
81 | +# @resize: This permission is required to change the size of a block node. | ||
82 | +# | ||
83 | +# @graph-mod: This permission is required to change the node that this | ||
84 | +# BdrvChild points to. | ||
85 | +# | ||
86 | +# Since: 4.0 | ||
87 | +## | ||
88 | + { 'enum': 'BlockPermission', | ||
89 | + 'data': [ 'consistent-read', 'write', 'write-unchanged', 'resize', | ||
90 | + 'graph-mod' ] } | ||
91 | +## | ||
92 | +# @XDbgBlockGraphEdge: | ||
93 | +# | ||
94 | +# Block Graph edge description for x-debug-query-block-graph. | ||
95 | +# | ||
96 | +# @parent: parent id | ||
97 | +# | ||
98 | +# @child: child id | ||
99 | +# | ||
100 | +# @name: name of the relation (examples are 'file' and 'backing') | ||
101 | +# | ||
102 | +# @perm: granted permissions for the parent operating on the child | ||
103 | +# | ||
104 | +# @shared-perm: permissions that can still be granted to other users of the | ||
105 | +# child while it is still attached to this parent | ||
106 | +# | ||
107 | +# Since: 4.0 | ||
108 | +## | ||
109 | +{ 'struct': 'XDbgBlockGraphEdge', | ||
110 | + 'data': { 'parent': 'uint64', 'child': 'uint64', | ||
111 | + 'name': 'str', 'perm': [ 'BlockPermission' ], | ||
112 | + 'shared-perm': [ 'BlockPermission' ] } } | ||
113 | + | ||
114 | +## | ||
115 | +# @XDbgBlockGraph: | ||
116 | +# | ||
117 | +# Block Graph - list of nodes and list of edges. | ||
118 | +# | ||
119 | +# Since: 4.0 | ||
120 | +## | ||
121 | +{ 'struct': 'XDbgBlockGraph', | ||
122 | + 'data': { 'nodes': ['XDbgBlockGraphNode'], 'edges': ['XDbgBlockGraphEdge'] } } | ||
123 | + | ||
124 | +## | ||
125 | +# @x-debug-query-block-graph: | ||
126 | +# | ||
127 | +# Get the block graph. | ||
128 | +# | ||
129 | +# Since: 4.0 | ||
130 | +## | ||
131 | +{ 'command': 'x-debug-query-block-graph', 'returns': 'XDbgBlockGraph' } | ||
132 | + | ||
133 | ## | ||
134 | # @drive-mirror: | ||
135 | # | ||
136 | diff --git a/include/block/block.h b/include/block/block.h | ||
137 | index XXXXXXX..XXXXXXX 100644 | ||
138 | --- a/include/block/block.h | ||
139 | +++ b/include/block/block.h | ||
140 | @@ -XXX,XX +XXX,XX @@ void bdrv_eject(BlockDriverState *bs, bool eject_flag); | ||
141 | const char *bdrv_get_format_name(BlockDriverState *bs); | ||
142 | BlockDriverState *bdrv_find_node(const char *node_name); | ||
143 | BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp); | ||
144 | +XDbgBlockGraph *bdrv_get_xdbg_block_graph(Error **errp); | ||
145 | BlockDriverState *bdrv_lookup_bs(const char *device, | ||
146 | const char *node_name, | ||
147 | Error **errp); | ||
148 | diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h | ||
149 | index XXXXXXX..XXXXXXX 100644 | ||
150 | --- a/include/sysemu/block-backend.h | ||
151 | +++ b/include/sysemu/block-backend.h | ||
152 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in, | ||
153 | int bytes, BdrvRequestFlags read_flags, | ||
154 | BdrvRequestFlags write_flags); | ||
155 | |||
156 | +const BdrvChild *blk_root(BlockBackend *blk); | ||
157 | + | ||
158 | #endif | ||
159 | diff --git a/block.c b/block.c | ||
160 | index XXXXXXX..XXXXXXX 100644 | ||
161 | --- a/block.c | ||
162 | +++ b/block.c | ||
163 | @@ -XXX,XX +XXX,XX @@ BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp) | ||
164 | return list; | ||
165 | } | ||
166 | |||
167 | +#define QAPI_LIST_ADD(list, element) do { \ | ||
168 | + typeof(list) _tmp = g_new(typeof(*(list)), 1); \ | ||
169 | + _tmp->value = (element); \ | ||
170 | + _tmp->next = (list); \ | ||
171 | + (list) = _tmp; \ | ||
172 | +} while (0) | ||
173 | + | ||
174 | +typedef struct XDbgBlockGraphConstructor { | ||
175 | + XDbgBlockGraph *graph; | ||
176 | + GHashTable *graph_nodes; | ||
177 | +} XDbgBlockGraphConstructor; | ||
178 | + | ||
179 | +static XDbgBlockGraphConstructor *xdbg_graph_new(void) | ||
180 | +{ | ||
181 | + XDbgBlockGraphConstructor *gr = g_new(XDbgBlockGraphConstructor, 1); | ||
182 | + | ||
183 | + gr->graph = g_new0(XDbgBlockGraph, 1); | ||
184 | + gr->graph_nodes = g_hash_table_new(NULL, NULL); | ||
185 | + | ||
186 | + return gr; | ||
187 | +} | ||
188 | + | ||
189 | +static XDbgBlockGraph *xdbg_graph_finalize(XDbgBlockGraphConstructor *gr) | ||
190 | +{ | ||
191 | + XDbgBlockGraph *graph = gr->graph; | ||
192 | + | ||
193 | + g_hash_table_destroy(gr->graph_nodes); | ||
194 | + g_free(gr); | ||
195 | + | ||
196 | + return graph; | ||
197 | +} | ||
198 | + | ||
199 | +static uintptr_t xdbg_graph_node_num(XDbgBlockGraphConstructor *gr, void *node) | ||
200 | +{ | ||
201 | + uintptr_t ret = (uintptr_t)g_hash_table_lookup(gr->graph_nodes, node); | ||
202 | + | ||
203 | + if (ret != 0) { | ||
204 | + return ret; | ||
205 | + } | ||
206 | + | ||
207 | + /* | ||
208 | + * Start counting from 1, not 0, because 0 interferes with not-found (NULL) | ||
209 | + * answer of g_hash_table_lookup. | ||
210 | + */ | ||
211 | + ret = g_hash_table_size(gr->graph_nodes) + 1; | ||
212 | + g_hash_table_insert(gr->graph_nodes, node, (void *)ret); | ||
213 | + | ||
214 | + return ret; | ||
215 | +} | ||
216 | + | ||
217 | +static void xdbg_graph_add_node(XDbgBlockGraphConstructor *gr, void *node, | ||
218 | + XDbgBlockGraphNodeType type, const char *name) | ||
219 | +{ | ||
220 | + XDbgBlockGraphNode *n; | ||
221 | + | ||
222 | + n = g_new0(XDbgBlockGraphNode, 1); | ||
223 | + | ||
224 | + n->id = xdbg_graph_node_num(gr, node); | ||
225 | + n->type = type; | ||
226 | + n->name = g_strdup(name); | ||
227 | + | ||
228 | + QAPI_LIST_ADD(gr->graph->nodes, n); | ||
229 | +} | ||
230 | + | ||
231 | +static void xdbg_graph_add_edge(XDbgBlockGraphConstructor *gr, void *parent, | ||
232 | + const BdrvChild *child) | ||
233 | +{ | ||
234 | + typedef struct { | ||
235 | + unsigned int flag; | ||
236 | + BlockPermission num; | ||
237 | + } PermissionMap; | ||
238 | + | ||
239 | + static const PermissionMap permissions[] = { | ||
240 | + { BLK_PERM_CONSISTENT_READ, BLOCK_PERMISSION_CONSISTENT_READ }, | ||
241 | + { BLK_PERM_WRITE, BLOCK_PERMISSION_WRITE }, | ||
242 | + { BLK_PERM_WRITE_UNCHANGED, BLOCK_PERMISSION_WRITE_UNCHANGED }, | ||
243 | + { BLK_PERM_RESIZE, BLOCK_PERMISSION_RESIZE }, | ||
244 | + { BLK_PERM_GRAPH_MOD, BLOCK_PERMISSION_GRAPH_MOD }, | ||
245 | + { 0, 0 } | ||
246 | + }; | ||
247 | + const PermissionMap *p; | ||
248 | + XDbgBlockGraphEdge *edge; | ||
249 | + | ||
250 | + QEMU_BUILD_BUG_ON(1UL << (ARRAY_SIZE(permissions) - 1) != BLK_PERM_ALL + 1); | ||
251 | + | ||
252 | + edge = g_new0(XDbgBlockGraphEdge, 1); | ||
253 | + | ||
254 | + edge->parent = xdbg_graph_node_num(gr, parent); | ||
255 | + edge->child = xdbg_graph_node_num(gr, child->bs); | ||
256 | + edge->name = g_strdup(child->name); | ||
257 | + | ||
258 | + for (p = permissions; p->flag; p++) { | ||
259 | + if (p->flag & child->perm) { | ||
260 | + QAPI_LIST_ADD(edge->perm, p->num); | ||
261 | + } | ||
262 | + if (p->flag & child->shared_perm) { | ||
263 | + QAPI_LIST_ADD(edge->shared_perm, p->num); | ||
264 | + } | ||
265 | + } | ||
266 | + | ||
267 | + QAPI_LIST_ADD(gr->graph->edges, edge); | ||
268 | +} | ||
269 | + | ||
270 | + | ||
271 | +XDbgBlockGraph *bdrv_get_xdbg_block_graph(Error **errp) | ||
272 | +{ | ||
273 | + BlockBackend *blk; | ||
274 | + BlockJob *job; | ||
275 | + BlockDriverState *bs; | ||
276 | + BdrvChild *child; | ||
277 | + XDbgBlockGraphConstructor *gr = xdbg_graph_new(); | ||
278 | + | ||
279 | + for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) { | ||
280 | + char *allocated_name = NULL; | ||
281 | + const char *name = blk_name(blk); | ||
282 | + | ||
283 | + if (!*name) { | ||
284 | + name = allocated_name = blk_get_attached_dev_id(blk); | ||
285 | + } | ||
286 | + xdbg_graph_add_node(gr, blk, X_DBG_BLOCK_GRAPH_NODE_TYPE_BLOCK_BACKEND, | ||
287 | + name); | ||
288 | + g_free(allocated_name); | ||
289 | + if (blk_root(blk)) { | ||
290 | + xdbg_graph_add_edge(gr, blk, blk_root(blk)); | ||
291 | + } | ||
292 | + } | ||
293 | + | ||
294 | + for (job = block_job_next(NULL); job; job = block_job_next(job)) { | ||
295 | + GSList *el; | ||
296 | + | ||
297 | + xdbg_graph_add_node(gr, job, X_DBG_BLOCK_GRAPH_NODE_TYPE_BLOCK_JOB, | ||
298 | + job->job.id); | ||
299 | + for (el = job->nodes; el; el = el->next) { | ||
300 | + xdbg_graph_add_edge(gr, job, (BdrvChild *)el->data); | ||
301 | + } | ||
302 | + } | ||
303 | + | ||
304 | + QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) { | ||
305 | + xdbg_graph_add_node(gr, bs, X_DBG_BLOCK_GRAPH_NODE_TYPE_BLOCK_DRIVER, | ||
306 | + bs->node_name); | ||
307 | + QLIST_FOREACH(child, &bs->children, next) { | ||
308 | + xdbg_graph_add_edge(gr, bs, child); | ||
309 | + } | ||
310 | + } | ||
311 | + | ||
312 | + return xdbg_graph_finalize(gr); | ||
313 | +} | ||
314 | + | ||
315 | BlockDriverState *bdrv_lookup_bs(const char *device, | ||
316 | const char *node_name, | ||
317 | Error **errp) | ||
318 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
319 | index XXXXXXX..XXXXXXX 100644 | ||
320 | --- a/block/block-backend.c | ||
321 | +++ b/block/block-backend.c | ||
322 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in, | ||
323 | blk_out->root, off_out, | ||
324 | bytes, read_flags, write_flags); | ||
325 | } | ||
326 | + | ||
327 | +const BdrvChild *blk_root(BlockBackend *blk) | ||
328 | +{ | ||
329 | + return blk->root; | ||
330 | +} | ||
331 | diff --git a/blockdev.c b/blockdev.c | ||
332 | index XXXXXXX..XXXXXXX 100644 | ||
333 | --- a/blockdev.c | ||
334 | +++ b/blockdev.c | ||
335 | @@ -XXX,XX +XXX,XX @@ BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp) | ||
336 | return bdrv_named_nodes_list(errp); | ||
337 | } | ||
338 | |||
339 | +XDbgBlockGraph *qmp_x_debug_query_block_graph(Error **errp) | ||
340 | +{ | ||
341 | + return bdrv_get_xdbg_block_graph(errp); | ||
342 | +} | ||
343 | + | ||
344 | BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn, | ||
345 | Error **errp) | ||
346 | { | ||
347 | -- | ||
348 | 2.20.1 | ||
349 | |||
350 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Render block nodes graph with help of graphviz. This new function is | ||
4 | for debugging, so there is no sense to put it into qemu.py as a method | ||
5 | of QEMUMachine. Let's instead put it separately. | ||
6 | |||
7 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
8 | Acked-by: Eduardo Habkost <ehabkost@redhat.com> | ||
9 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
10 | Message-id: 20181221170909.25584-3-vsementsov@virtuozzo.com | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | scripts/render_block_graph.py | 120 ++++++++++++++++++++++++++++++++++ | ||
14 | 1 file changed, 120 insertions(+) | ||
15 | create mode 100755 scripts/render_block_graph.py | ||
16 | |||
17 | diff --git a/scripts/render_block_graph.py b/scripts/render_block_graph.py | ||
18 | new file mode 100755 | ||
19 | index XXXXXXX..XXXXXXX | ||
20 | --- /dev/null | ||
21 | +++ b/scripts/render_block_graph.py | ||
22 | @@ -XXX,XX +XXX,XX @@ | ||
23 | +#!/usr/bin/env python | ||
24 | +# | ||
25 | +# Render Qemu Block Graph | ||
26 | +# | ||
27 | +# Copyright (c) 2018 Virtuozzo International GmbH. All rights reserved. | ||
28 | +# | ||
29 | +# This program is free software; you can redistribute it and/or modify | ||
30 | +# it under the terms of the GNU General Public License as published by | ||
31 | +# the Free Software Foundation; either version 2 of the License, or | ||
32 | +# (at your option) any later version. | ||
33 | +# | ||
34 | +# This program is distributed in the hope that it will be useful, | ||
35 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
36 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
37 | +# GNU General Public License for more details. | ||
38 | +# | ||
39 | +# You should have received a copy of the GNU General Public License | ||
40 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
41 | +# | ||
42 | + | ||
43 | +import os | ||
44 | +import sys | ||
45 | +import subprocess | ||
46 | +import json | ||
47 | +from graphviz import Digraph | ||
48 | +from qemu import MonitorResponseError | ||
49 | + | ||
50 | + | ||
51 | +def perm(arr): | ||
52 | + s = 'w' if 'write' in arr else '_' | ||
53 | + s += 'r' if 'consistent-read' in arr else '_' | ||
54 | + s += 'u' if 'write-unchanged' in arr else '_' | ||
55 | + s += 'g' if 'graph-mod' in arr else '_' | ||
56 | + s += 's' if 'resize' in arr else '_' | ||
57 | + return s | ||
58 | + | ||
59 | + | ||
60 | +def render_block_graph(qmp, filename, format='png'): | ||
61 | + ''' | ||
62 | + Render graph in text (dot) representation into "@filename" and | ||
63 | + representation in @format into "@filename.@format" | ||
64 | + ''' | ||
65 | + | ||
66 | + bds_nodes = qmp.command('query-named-block-nodes') | ||
67 | + bds_nodes = {n['node-name']: n for n in bds_nodes} | ||
68 | + | ||
69 | + job_nodes = qmp.command('query-block-jobs') | ||
70 | + job_nodes = {n['device']: n for n in job_nodes} | ||
71 | + | ||
72 | + block_graph = qmp.command('x-debug-query-block-graph') | ||
73 | + | ||
74 | + graph = Digraph(comment='Block Nodes Graph') | ||
75 | + graph.format = format | ||
76 | + graph.node('permission symbols:\l' | ||
77 | + ' w - Write\l' | ||
78 | + ' r - consistent-Read\l' | ||
79 | + ' u - write - Unchanged\l' | ||
80 | + ' g - Graph-mod\l' | ||
81 | + ' s - reSize\l' | ||
82 | + 'edge label scheme:\l' | ||
83 | + ' <child type>\l' | ||
84 | + ' <perm>\l' | ||
85 | + ' <shared_perm>\l', shape='none') | ||
86 | + | ||
87 | + for n in block_graph['nodes']: | ||
88 | + if n['type'] == 'block-driver': | ||
89 | + info = bds_nodes[n['name']] | ||
90 | + label = n['name'] + ' [' + info['drv'] + ']' | ||
91 | + if info['drv'] == 'file': | ||
92 | + label += '\n' + os.path.basename(info['file']) | ||
93 | + shape = 'ellipse' | ||
94 | + elif n['type'] == 'block-job': | ||
95 | + info = job_nodes[n['name']] | ||
96 | + label = info['type'] + ' job (' + n['name'] + ')' | ||
97 | + shape = 'box' | ||
98 | + else: | ||
99 | + assert n['type'] == 'block-backend' | ||
100 | + label = n['name'] if n['name'] else 'unnamed blk' | ||
101 | + shape = 'box' | ||
102 | + | ||
103 | + graph.node(str(n['id']), label, shape=shape) | ||
104 | + | ||
105 | + for e in block_graph['edges']: | ||
106 | + label = '%s\l%s\l%s\l' % (e['name'], perm(e['perm']), | ||
107 | + perm(e['shared-perm'])) | ||
108 | + graph.edge(str(e['parent']), str(e['child']), label=label) | ||
109 | + | ||
110 | + graph.render(filename) | ||
111 | + | ||
112 | + | ||
113 | +class LibvirtGuest(): | ||
114 | + def __init__(self, name): | ||
115 | + self.name = name | ||
116 | + | ||
117 | + def command(self, cmd): | ||
118 | + # only supports qmp commands without parameters | ||
119 | + m = {'execute': cmd} | ||
120 | + ar = ['virsh', 'qemu-monitor-command', self.name, json.dumps(m)] | ||
121 | + | ||
122 | + reply = json.loads(subprocess.check_output(ar)) | ||
123 | + | ||
124 | + if 'error' in reply: | ||
125 | + raise MonitorResponseError(reply) | ||
126 | + | ||
127 | + return reply['return'] | ||
128 | + | ||
129 | + | ||
130 | +if __name__ == '__main__': | ||
131 | + obj = sys.argv[1] | ||
132 | + out = sys.argv[2] | ||
133 | + | ||
134 | + if os.path.exists(obj): | ||
135 | + # assume unix socket | ||
136 | + qmp = QEMUMonitorProtocol(obj) | ||
137 | + qmp.connect() | ||
138 | + else: | ||
139 | + # assume libvirt guest name | ||
140 | + qmp = LibvirtGuest(obj) | ||
141 | + | ||
142 | + render_block_graph(qmp, out) | ||
143 | -- | ||
144 | 2.20.1 | ||
145 | |||
146 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Laurent Vivier <lvivier@redhat.com> | ||
2 | 1 | ||
3 | Signed-off-by: Laurent Vivier <lvivier@redhat.com> | ||
4 | Reviewed-by: Richard W.M. Jones <rjones@redhat.com> | ||
5 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
6 | Message-id: 20181213162727.17438-2-lvivier@redhat.com | ||
7 | [mreitz: Fixed type of ssh_{read,write}_return's parameter to be ssize_t | ||
8 | instead of size_t] | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | block/ssh.c | 46 +++++++++++++++++----------------------------- | ||
12 | block/trace-events | 17 +++++++++++++++++ | ||
13 | 2 files changed, 34 insertions(+), 29 deletions(-) | ||
14 | |||
15 | diff --git a/block/ssh.c b/block/ssh.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/block/ssh.c | ||
18 | +++ b/block/ssh.c | ||
19 | @@ -XXX,XX +XXX,XX @@ | ||
20 | #include "qapi/qmp/qstring.h" | ||
21 | #include "qapi/qobject-input-visitor.h" | ||
22 | #include "qapi/qobject-output-visitor.h" | ||
23 | +#include "trace.h" | ||
24 | |||
25 | -/* DEBUG_SSH=1 enables the DPRINTF (debugging printf) statements in | ||
26 | - * this block driver code. | ||
27 | - * | ||
28 | +/* | ||
29 | * TRACE_LIBSSH2=<bitmask> enables tracing in libssh2 itself. Note | ||
30 | * that this requires that libssh2 was specially compiled with the | ||
31 | * `./configure --enable-debug' option, so most likely you will have | ||
32 | * to compile it yourself. The meaning of <bitmask> is described | ||
33 | * here: http://www.libssh2.org/libssh2_trace.html | ||
34 | */ | ||
35 | -#define DEBUG_SSH 0 | ||
36 | #define TRACE_LIBSSH2 0 /* or try: LIBSSH2_TRACE_SFTP */ | ||
37 | |||
38 | -#define DPRINTF(fmt, ...) \ | ||
39 | - do { \ | ||
40 | - if (DEBUG_SSH) { \ | ||
41 | - fprintf(stderr, "ssh: %-15s " fmt "\n", \ | ||
42 | - __func__, ##__VA_ARGS__); \ | ||
43 | - } \ | ||
44 | - } while (0) | ||
45 | - | ||
46 | typedef struct BDRVSSHState { | ||
47 | /* Coroutine. */ | ||
48 | CoMutex lock; | ||
49 | @@ -XXX,XX +XXX,XX @@ static int check_host_key_knownhosts(BDRVSSHState *s, | ||
50 | switch (r) { | ||
51 | case LIBSSH2_KNOWNHOST_CHECK_MATCH: | ||
52 | /* OK */ | ||
53 | - DPRINTF("host key OK: %s", found->key); | ||
54 | + trace_ssh_check_host_key_knownhosts(found->key); | ||
55 | break; | ||
56 | case LIBSSH2_KNOWNHOST_CHECK_MISMATCH: | ||
57 | ret = -EINVAL; | ||
58 | @@ -XXX,XX +XXX,XX @@ static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts, | ||
59 | } | ||
60 | |||
61 | /* Open the remote file. */ | ||
62 | - DPRINTF("opening file %s flags=0x%x creat_mode=0%o", | ||
63 | - opts->path, ssh_flags, creat_mode); | ||
64 | + trace_ssh_connect_to_ssh(opts->path, ssh_flags, creat_mode); | ||
65 | s->sftp_handle = libssh2_sftp_open(s->sftp, opts->path, ssh_flags, | ||
66 | creat_mode); | ||
67 | if (!s->sftp_handle) { | ||
68 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn ssh_co_create_opts(const char *filename, QemuOpts *opts, | ||
69 | /* Get desired file size. */ | ||
70 | ssh_opts->size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), | ||
71 | BDRV_SECTOR_SIZE); | ||
72 | - DPRINTF("total_size=%" PRIi64, ssh_opts->size); | ||
73 | + trace_ssh_co_create_opts(ssh_opts->size); | ||
74 | |||
75 | uri_options = qdict_new(); | ||
76 | ret = parse_uri(filename, uri_options, errp); | ||
77 | @@ -XXX,XX +XXX,XX @@ static void restart_coroutine(void *opaque) | ||
78 | BDRVSSHState *s = bs->opaque; | ||
79 | AioContext *ctx = bdrv_get_aio_context(bs); | ||
80 | |||
81 | - DPRINTF("co=%p", restart->co); | ||
82 | + trace_ssh_restart_coroutine(restart->co); | ||
83 | aio_set_fd_handler(ctx, s->sock, false, NULL, NULL, NULL, NULL); | ||
84 | |||
85 | aio_co_wake(restart->co); | ||
86 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn void co_yield(BDRVSSHState *s, BlockDriverState *bs) | ||
87 | wr_handler = restart_coroutine; | ||
88 | } | ||
89 | |||
90 | - DPRINTF("s->sock=%d rd_handler=%p wr_handler=%p", s->sock, | ||
91 | - rd_handler, wr_handler); | ||
92 | + trace_ssh_co_yield(s->sock, rd_handler, wr_handler); | ||
93 | |||
94 | aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock, | ||
95 | false, rd_handler, wr_handler, NULL, &restart); | ||
96 | qemu_coroutine_yield(); | ||
97 | - DPRINTF("s->sock=%d - back", s->sock); | ||
98 | + trace_ssh_co_yield_back(s->sock); | ||
99 | } | ||
100 | |||
101 | /* SFTP has a function `libssh2_sftp_seek64' which seeks to a position | ||
102 | @@ -XXX,XX +XXX,XX @@ static void ssh_seek(BDRVSSHState *s, int64_t offset, int flags) | ||
103 | bool force = (flags & SSH_SEEK_FORCE) != 0; | ||
104 | |||
105 | if (force || op_read != s->offset_op_read || offset != s->offset) { | ||
106 | - DPRINTF("seeking to offset=%" PRIi64, offset); | ||
107 | + trace_ssh_seek(offset); | ||
108 | libssh2_sftp_seek64(s->sftp_handle, offset); | ||
109 | s->offset = offset; | ||
110 | s->offset_op_read = op_read; | ||
111 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int ssh_read(BDRVSSHState *s, BlockDriverState *bs, | ||
112 | char *buf, *end_of_vec; | ||
113 | struct iovec *i; | ||
114 | |||
115 | - DPRINTF("offset=%" PRIi64 " size=%zu", offset, size); | ||
116 | + trace_ssh_read(offset, size); | ||
117 | |||
118 | ssh_seek(s, offset, SSH_SEEK_READ); | ||
119 | |||
120 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int ssh_read(BDRVSSHState *s, BlockDriverState *bs, | ||
121 | */ | ||
122 | for (got = 0; got < size; ) { | ||
123 | again: | ||
124 | - DPRINTF("sftp_read buf=%p size=%zu", buf, end_of_vec - buf); | ||
125 | + trace_ssh_read_buf(buf, end_of_vec - buf); | ||
126 | r = libssh2_sftp_read(s->sftp_handle, buf, end_of_vec - buf); | ||
127 | - DPRINTF("sftp_read returned %zd", r); | ||
128 | + trace_ssh_read_return(r); | ||
129 | |||
130 | if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) { | ||
131 | co_yield(s, bs); | ||
132 | @@ -XXX,XX +XXX,XX @@ static int ssh_write(BDRVSSHState *s, BlockDriverState *bs, | ||
133 | char *buf, *end_of_vec; | ||
134 | struct iovec *i; | ||
135 | |||
136 | - DPRINTF("offset=%" PRIi64 " size=%zu", offset, size); | ||
137 | + trace_ssh_write(offset, size); | ||
138 | |||
139 | ssh_seek(s, offset, SSH_SEEK_WRITE); | ||
140 | |||
141 | @@ -XXX,XX +XXX,XX @@ static int ssh_write(BDRVSSHState *s, BlockDriverState *bs, | ||
142 | |||
143 | for (written = 0; written < size; ) { | ||
144 | again: | ||
145 | - DPRINTF("sftp_write buf=%p size=%zu", buf, end_of_vec - buf); | ||
146 | + trace_ssh_write_buf(buf, end_of_vec - buf); | ||
147 | r = libssh2_sftp_write(s->sftp_handle, buf, end_of_vec - buf); | ||
148 | - DPRINTF("sftp_write returned %zd", r); | ||
149 | + trace_ssh_write_return(r); | ||
150 | |||
151 | if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) { | ||
152 | co_yield(s, bs); | ||
153 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int ssh_flush(BDRVSSHState *s, BlockDriverState *bs) | ||
154 | { | ||
155 | int r; | ||
156 | |||
157 | - DPRINTF("fsync"); | ||
158 | + trace_ssh_flush(); | ||
159 | again: | ||
160 | r = libssh2_sftp_fsync(s->sftp_handle); | ||
161 | if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) { | ||
162 | @@ -XXX,XX +XXX,XX @@ static int64_t ssh_getlength(BlockDriverState *bs) | ||
163 | |||
164 | /* Note we cannot make a libssh2 call here. */ | ||
165 | length = (int64_t) s->attrs.filesize; | ||
166 | - DPRINTF("length=%" PRIi64, length); | ||
167 | + trace_ssh_getlength(length); | ||
168 | |||
169 | return length; | ||
170 | } | ||
171 | diff --git a/block/trace-events b/block/trace-events | ||
172 | index XXXXXXX..XXXXXXX 100644 | ||
173 | --- a/block/trace-events | ||
174 | +++ b/block/trace-events | ||
175 | @@ -XXX,XX +XXX,XX @@ iscsi_xcopy(void *src_lun, uint64_t src_off, void *dst_lun, uint64_t dst_off, ui | ||
176 | # block/nbd-client.c | ||
177 | nbd_read_reply_entry_fail(int ret, const char *err) "ret = %d, err: %s" | ||
178 | nbd_co_request_fail(uint64_t from, uint32_t len, uint64_t handle, uint16_t flags, uint16_t type, const char *name, int ret, const char *err) "Request failed { .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64 ", .flags = 0x%" PRIx16 ", .type = %" PRIu16 " (%s) } ret = %d, err: %s" | ||
179 | + | ||
180 | +# block/ssh.c | ||
181 | +ssh_restart_coroutine(void *co) "co=%p" | ||
182 | +ssh_flush(void) "fsync" | ||
183 | +ssh_check_host_key_knownhosts(const char *key) "host key OK: %s" | ||
184 | +ssh_connect_to_ssh(char *path, int flags, int mode) "opening file %s flags=0x%x creat_mode=0%o" | ||
185 | +ssh_co_yield(int sock, void *rd_handler, void *wr_handler) "s->sock=%d rd_handler=%p wr_handler=%p" | ||
186 | +ssh_co_yield_back(int sock) "s->sock=%d - back" | ||
187 | +ssh_getlength(int64_t length) "length=%" PRIi64 | ||
188 | +ssh_co_create_opts(uint64_t size) "total_size=%" PRIu64 | ||
189 | +ssh_read(int64_t offset, size_t size) "offset=%" PRIi64 " size=%zu" | ||
190 | +ssh_read_buf(void *buf, size_t size) "sftp_read buf=%p size=%zu" | ||
191 | +ssh_read_return(ssize_t ret) "sftp_read returned %zd" | ||
192 | +ssh_write(int64_t offset, size_t size) "offset=%" PRIi64 " size=%zu" | ||
193 | +ssh_write_buf(void *buf, size_t size) "sftp_write buf=%p size=%zu" | ||
194 | +ssh_write_return(ssize_t ret) "sftp_write returned %zd" | ||
195 | +ssh_seek(int64_t offset) "seeking to offset=%" PRIi64 | ||
196 | -- | ||
197 | 2.20.1 | ||
198 | |||
199 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Laurent Vivier <lvivier@redhat.com> | ||
2 | 1 | ||
3 | Signed-off-by: Laurent Vivier <lvivier@redhat.com> | ||
4 | Reviewed-by: Richard W.M. Jones <rjones@redhat.com> | ||
5 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
6 | Message-id: 20181213162727.17438-3-lvivier@redhat.com | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | --- | ||
9 | block/curl.c | 29 ++++++++--------------------- | ||
10 | block/trace-events | 9 +++++++++ | ||
11 | 2 files changed, 17 insertions(+), 21 deletions(-) | ||
12 | |||
13 | diff --git a/block/curl.c b/block/curl.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/block/curl.c | ||
16 | +++ b/block/curl.c | ||
17 | @@ -XXX,XX +XXX,XX @@ | ||
18 | #include "crypto/secret.h" | ||
19 | #include <curl/curl.h> | ||
20 | #include "qemu/cutils.h" | ||
21 | +#include "trace.h" | ||
22 | |||
23 | -// #define DEBUG_CURL | ||
24 | // #define DEBUG_VERBOSE | ||
25 | |||
26 | -#ifdef DEBUG_CURL | ||
27 | -#define DEBUG_CURL_PRINT 1 | ||
28 | -#else | ||
29 | -#define DEBUG_CURL_PRINT 0 | ||
30 | -#endif | ||
31 | -#define DPRINTF(fmt, ...) \ | ||
32 | - do { \ | ||
33 | - if (DEBUG_CURL_PRINT) { \ | ||
34 | - fprintf(stderr, fmt, ## __VA_ARGS__); \ | ||
35 | - } \ | ||
36 | - } while (0) | ||
37 | - | ||
38 | #if LIBCURL_VERSION_NUM >= 0x071000 | ||
39 | /* The multi interface timer callback was introduced in 7.16.0 */ | ||
40 | #define NEED_CURL_TIMER_CALLBACK | ||
41 | @@ -XXX,XX +XXX,XX @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque) | ||
42 | { | ||
43 | BDRVCURLState *s = opaque; | ||
44 | |||
45 | - DPRINTF("CURL: timer callback timeout_ms %ld\n", timeout_ms); | ||
46 | + trace_curl_timer_cb(timeout_ms); | ||
47 | if (timeout_ms == -1) { | ||
48 | timer_del(&s->timer); | ||
49 | } else { | ||
50 | @@ -XXX,XX +XXX,XX @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action, | ||
51 | } | ||
52 | socket = NULL; | ||
53 | |||
54 | - DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, (int)fd); | ||
55 | + trace_curl_sock_cb(action, (int)fd); | ||
56 | switch (action) { | ||
57 | case CURL_POLL_IN: | ||
58 | aio_set_fd_handler(s->aio_context, fd, false, | ||
59 | @@ -XXX,XX +XXX,XX @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque) | ||
60 | size_t realsize = size * nmemb; | ||
61 | int i; | ||
62 | |||
63 | - DPRINTF("CURL: Just reading %zd bytes\n", realsize); | ||
64 | + trace_curl_read_cb(realsize); | ||
65 | |||
66 | if (!s || !s->orig_buf) { | ||
67 | goto read_end; | ||
68 | @@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags, | ||
69 | } | ||
70 | } | ||
71 | |||
72 | - DPRINTF("CURL: Opening %s\n", file); | ||
73 | + trace_curl_open(file); | ||
74 | qemu_co_queue_init(&s->free_state_waitq); | ||
75 | s->aio_context = bdrv_get_aio_context(bs); | ||
76 | s->url = g_strdup(file); | ||
77 | @@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags, | ||
78 | "Server does not support 'range' (byte ranges)."); | ||
79 | goto out; | ||
80 | } | ||
81 | - DPRINTF("CURL: Size = %" PRIu64 "\n", s->len); | ||
82 | + trace_curl_open_size(s->len); | ||
83 | |||
84 | qemu_mutex_lock(&s->mutex); | ||
85 | curl_clean_state(state); | ||
86 | @@ -XXX,XX +XXX,XX @@ static void curl_setup_preadv(BlockDriverState *bs, CURLAIOCB *acb) | ||
87 | state->acb[0] = acb; | ||
88 | |||
89 | snprintf(state->range, 127, "%" PRIu64 "-%" PRIu64, start, end); | ||
90 | - DPRINTF("CURL (AIO): Reading %" PRIu64 " at %" PRIu64 " (%s)\n", | ||
91 | - acb->bytes, start, state->range); | ||
92 | + trace_curl_setup_preadv(acb->bytes, start, state->range); | ||
93 | curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range); | ||
94 | |||
95 | curl_multi_add_handle(s->multi, state->curl); | ||
96 | @@ -XXX,XX +XXX,XX @@ static void curl_close(BlockDriverState *bs) | ||
97 | { | ||
98 | BDRVCURLState *s = bs->opaque; | ||
99 | |||
100 | - DPRINTF("CURL: Close\n"); | ||
101 | + trace_curl_close(); | ||
102 | curl_detach_aio_context(bs); | ||
103 | qemu_mutex_destroy(&s->mutex); | ||
104 | |||
105 | diff --git a/block/trace-events b/block/trace-events | ||
106 | index XXXXXXX..XXXXXXX 100644 | ||
107 | --- a/block/trace-events | ||
108 | +++ b/block/trace-events | ||
109 | @@ -XXX,XX +XXX,XX @@ ssh_write(int64_t offset, size_t size) "offset=%" PRIi64 " size=%zu" | ||
110 | ssh_write_buf(void *buf, size_t size) "sftp_write buf=%p size=%zu" | ||
111 | ssh_write_return(ssize_t ret) "sftp_write returned %zd" | ||
112 | ssh_seek(int64_t offset) "seeking to offset=%" PRIi64 | ||
113 | + | ||
114 | +# block/curl.c | ||
115 | +curl_timer_cb(long timeout_ms) "timer callback timeout_ms %ld" | ||
116 | +curl_sock_cb(int action, int fd) "sock action %d on fd %d" | ||
117 | +curl_read_cb(size_t realsize) "just reading %zu bytes" | ||
118 | +curl_open(const char *file) "opening %s" | ||
119 | +curl_open_size(uint64_t size) "size = %" PRIu64 | ||
120 | +curl_setup_preadv(uint64_t bytes, uint64_t start, const char *range) "reading %" PRIu64 " at %" PRIu64 " (%s)" | ||
121 | +curl_close(void) "close" | ||
122 | -- | ||
123 | 2.20.1 | ||
124 | |||
125 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Laurent Vivier <lvivier@redhat.com> | ||
2 | 1 | ||
3 | Signed-off-by: Laurent Vivier <lvivier@redhat.com> | ||
4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
5 | Message-id: 20181213162727.17438-4-lvivier@redhat.com | ||
6 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
7 | --- | ||
8 | block/file-posix.c | 25 ++++++------------------- | ||
9 | block/trace-events | 7 +++++++ | ||
10 | 2 files changed, 13 insertions(+), 19 deletions(-) | ||
11 | |||
12 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/block/file-posix.c | ||
15 | +++ b/block/file-posix.c | ||
16 | @@ -XXX,XX +XXX,XX @@ | ||
17 | #include <xfs/xfs.h> | ||
18 | #endif | ||
19 | |||
20 | -//#define DEBUG_BLOCK | ||
21 | - | ||
22 | -#ifdef DEBUG_BLOCK | ||
23 | -# define DEBUG_BLOCK_PRINT 1 | ||
24 | -#else | ||
25 | -# define DEBUG_BLOCK_PRINT 0 | ||
26 | -#endif | ||
27 | -#define DPRINTF(fmt, ...) \ | ||
28 | -do { \ | ||
29 | - if (DEBUG_BLOCK_PRINT) { \ | ||
30 | - printf(fmt, ## __VA_ARGS__); \ | ||
31 | - } \ | ||
32 | -} while (0) | ||
33 | +#include "trace.h" | ||
34 | |||
35 | /* OS X does not have O_DSYNC */ | ||
36 | #ifndef O_DSYNC | ||
37 | @@ -XXX,XX +XXX,XX @@ static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes) | ||
38 | |||
39 | if (xfsctl(NULL, s->fd, XFS_IOC_ZERO_RANGE, &fl) < 0) { | ||
40 | err = errno; | ||
41 | - DPRINTF("cannot write zero range (%s)\n", strerror(errno)); | ||
42 | + trace_file_xfs_write_zeroes(strerror(errno)); | ||
43 | return -err; | ||
44 | } | ||
45 | |||
46 | @@ -XXX,XX +XXX,XX @@ static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes) | ||
47 | |||
48 | if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) { | ||
49 | err = errno; | ||
50 | - DPRINTF("cannot punch hole (%s)\n", strerror(errno)); | ||
51 | + trace_file_xfs_discard(strerror(errno)); | ||
52 | return -err; | ||
53 | } | ||
54 | |||
55 | @@ -XXX,XX +XXX,XX @@ static char *FindEjectableOpticalMedia(io_iterator_t *mediaIterator) | ||
56 | |||
57 | /* If a match was found, leave the loop */ | ||
58 | if (*mediaIterator != 0) { | ||
59 | - DPRINTF("Matching using %s\n", matching_array[index]); | ||
60 | + trace_file_FindEjectableOpticalMedia(matching_array[index]); | ||
61 | mediaType = g_strdup(matching_array[index]); | ||
62 | break; | ||
63 | } | ||
64 | @@ -XXX,XX +XXX,XX @@ static bool setup_cdrom(char *bsd_path, Error **errp) | ||
65 | if (partition_found == false) { | ||
66 | error_setg(errp, "Failed to find a working partition on disc"); | ||
67 | } else { | ||
68 | - DPRINTF("Using %s as optical disc\n", test_partition); | ||
69 | + trace_file_setup_cdrom(test_partition); | ||
70 | pstrcpy(bsd_path, MAXPATHLEN, test_partition); | ||
71 | } | ||
72 | return partition_found; | ||
73 | @@ -XXX,XX +XXX,XX @@ static bool hdev_is_sg(BlockDriverState *bs) | ||
74 | |||
75 | ret = ioctl(s->fd, SG_GET_SCSI_ID, &scsiid); | ||
76 | if (ret >= 0) { | ||
77 | - DPRINTF("SG device found: type=%d, version=%d\n", | ||
78 | - scsiid.scsi_type, sg_version); | ||
79 | + trace_file_hdev_is_sg(scsiid.scsi_type, sg_version); | ||
80 | return true; | ||
81 | } | ||
82 | |||
83 | diff --git a/block/trace-events b/block/trace-events | ||
84 | index XXXXXXX..XXXXXXX 100644 | ||
85 | --- a/block/trace-events | ||
86 | +++ b/block/trace-events | ||
87 | @@ -XXX,XX +XXX,XX @@ curl_open(const char *file) "opening %s" | ||
88 | curl_open_size(uint64_t size) "size = %" PRIu64 | ||
89 | curl_setup_preadv(uint64_t bytes, uint64_t start, const char *range) "reading %" PRIu64 " at %" PRIu64 " (%s)" | ||
90 | curl_close(void) "close" | ||
91 | + | ||
92 | +# block/file-posix.c | ||
93 | +file_xfs_write_zeroes(const char *error) "cannot write zero range (%s)" | ||
94 | +file_xfs_discard(const char *error) "cannot punch hole (%s)" | ||
95 | +file_FindEjectableOpticalMedia(const char *media) "Matching using %s" | ||
96 | +file_setup_cdrom(const char *partition) "Using %s as optical disc" | ||
97 | +file_hdev_is_sg(int type, int version) "SG device found: type=%d, version=%d" | ||
98 | -- | ||
99 | 2.20.1 | ||
100 | |||
101 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Laurent Vivier <lvivier@redhat.com> | ||
2 | 1 | ||
3 | Signed-off-by: Laurent Vivier <lvivier@redhat.com> | ||
4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
5 | Message-id: 20181213162727.17438-5-lvivier@redhat.com | ||
6 | [mreitz: Fixed sheepdog_snapshot_create_inode's format string to use | ||
7 | PRIx32 for uint32_ts] | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | block/sheepdog.c | 47 +++++++++++++++++----------------------------- | ||
11 | block/trace-events | 14 ++++++++++++++ | ||
12 | 2 files changed, 31 insertions(+), 30 deletions(-) | ||
13 | |||
14 | diff --git a/block/sheepdog.c b/block/sheepdog.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/block/sheepdog.c | ||
17 | +++ b/block/sheepdog.c | ||
18 | @@ -XXX,XX +XXX,XX @@ | ||
19 | #include "sysemu/block-backend.h" | ||
20 | #include "qemu/bitops.h" | ||
21 | #include "qemu/cutils.h" | ||
22 | +#include "trace.h" | ||
23 | |||
24 | #define SD_PROTO_VER 0x01 | ||
25 | |||
26 | @@ -XXX,XX +XXX,XX @@ static inline size_t count_data_objs(const struct SheepdogInode *inode) | ||
27 | (1UL << inode->block_size_shift)); | ||
28 | } | ||
29 | |||
30 | -#undef DPRINTF | ||
31 | -#ifdef DEBUG_SDOG | ||
32 | -#define DEBUG_SDOG_PRINT 1 | ||
33 | -#else | ||
34 | -#define DEBUG_SDOG_PRINT 0 | ||
35 | -#endif | ||
36 | -#define DPRINTF(fmt, args...) \ | ||
37 | - do { \ | ||
38 | - if (DEBUG_SDOG_PRINT) { \ | ||
39 | - fprintf(stderr, "%s %d: " fmt, __func__, __LINE__, ##args); \ | ||
40 | - } \ | ||
41 | - } while (0) | ||
42 | - | ||
43 | typedef struct SheepdogAIOCB SheepdogAIOCB; | ||
44 | typedef struct BDRVSheepdogState BDRVSheepdogState; | ||
45 | |||
46 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn void reconnect_to_sdog(void *opaque) | ||
47 | Error *local_err = NULL; | ||
48 | s->fd = get_sheep_fd(s, &local_err); | ||
49 | if (s->fd < 0) { | ||
50 | - DPRINTF("Wait for connection to be established\n"); | ||
51 | + trace_sheepdog_reconnect_to_sdog(); | ||
52 | error_report_err(local_err); | ||
53 | qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000000ULL); | ||
54 | } | ||
55 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn aio_read_response(void *opaque) | ||
56 | break; | ||
57 | case AIOCB_FLUSH_CACHE: | ||
58 | if (rsp.result == SD_RES_INVALID_PARMS) { | ||
59 | - DPRINTF("disable cache since the server doesn't support it\n"); | ||
60 | + trace_sheepdog_aio_read_response(); | ||
61 | s->cache_flags = SD_FLAG_CMD_DIRECT; | ||
62 | rsp.result = SD_RES_SUCCESS; | ||
63 | } | ||
64 | @@ -XXX,XX +XXX,XX @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags, | ||
65 | s->discard_supported = true; | ||
66 | |||
67 | if (snap_id || tag[0]) { | ||
68 | - DPRINTF("%" PRIx32 " snapshot inode was open.\n", vid); | ||
69 | + trace_sheepdog_open(vid); | ||
70 | s->is_snapshot = true; | ||
71 | } | ||
72 | |||
73 | @@ -XXX,XX +XXX,XX @@ static void sd_close(BlockDriverState *bs) | ||
74 | unsigned int wlen, rlen = 0; | ||
75 | int fd, ret; | ||
76 | |||
77 | - DPRINTF("%s\n", s->name); | ||
78 | + trace_sheepdog_close(s->name); | ||
79 | |||
80 | fd = connect_to_sdog(s, &local_err); | ||
81 | if (fd < 0) { | ||
82 | @@ -XXX,XX +XXX,XX @@ static int sd_create_branch(BDRVSheepdogState *s) | ||
83 | char *buf; | ||
84 | bool deleted; | ||
85 | |||
86 | - DPRINTF("%" PRIx32 " is snapshot.\n", s->inode.vdi_id); | ||
87 | + trace_sheepdog_create_branch_snapshot(s->inode.vdi_id); | ||
88 | |||
89 | buf = g_malloc(SD_INODE_SIZE); | ||
90 | |||
91 | @@ -XXX,XX +XXX,XX @@ static int sd_create_branch(BDRVSheepdogState *s) | ||
92 | goto out; | ||
93 | } | ||
94 | |||
95 | - DPRINTF("%" PRIx32 " is created.\n", vid); | ||
96 | + trace_sheepdog_create_branch_created(vid); | ||
97 | |||
98 | fd = connect_to_sdog(s, &local_err); | ||
99 | if (fd < 0) { | ||
100 | @@ -XXX,XX +XXX,XX @@ static int sd_create_branch(BDRVSheepdogState *s) | ||
101 | |||
102 | s->is_snapshot = false; | ||
103 | ret = 0; | ||
104 | - DPRINTF("%" PRIx32 " was newly created.\n", s->inode.vdi_id); | ||
105 | + trace_sheepdog_create_branch_new(s->inode.vdi_id); | ||
106 | |||
107 | out: | ||
108 | g_free(buf); | ||
109 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn sd_co_rw_vector(SheepdogAIOCB *acb) | ||
110 | } | ||
111 | |||
112 | if (create) { | ||
113 | - DPRINTF("update ino (%" PRIu32 ") %" PRIu64 " %" PRIu64 " %ld\n", | ||
114 | - inode->vdi_id, oid, | ||
115 | - vid_to_data_oid(inode->data_vdi_id[idx], idx), idx); | ||
116 | + trace_sheepdog_co_rw_vector_update(inode->vdi_id, oid, | ||
117 | + vid_to_data_oid(inode->data_vdi_id[idx], idx), | ||
118 | + idx); | ||
119 | oid = vid_to_data_oid(inode->vdi_id, idx); | ||
120 | - DPRINTF("new oid %" PRIx64 "\n", oid); | ||
121 | + trace_sheepdog_co_rw_vector_new(oid); | ||
122 | } | ||
123 | |||
124 | aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, create, | ||
125 | @@ -XXX,XX +XXX,XX @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) | ||
126 | SheepdogInode *inode; | ||
127 | unsigned int datalen; | ||
128 | |||
129 | - DPRINTF("sn_info: name %s id_str %s s: name %s vm_state_size %" PRId64 " " | ||
130 | - "is_snapshot %d\n", sn_info->name, sn_info->id_str, | ||
131 | - s->name, sn_info->vm_state_size, s->is_snapshot); | ||
132 | + trace_sheepdog_snapshot_create_info(sn_info->name, sn_info->id_str, s->name, | ||
133 | + sn_info->vm_state_size, s->is_snapshot); | ||
134 | |||
135 | if (s->is_snapshot) { | ||
136 | error_report("You can't create a snapshot of a snapshot VDI, " | ||
137 | @@ -XXX,XX +XXX,XX @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) | ||
138 | return -EINVAL; | ||
139 | } | ||
140 | |||
141 | - DPRINTF("%s %s\n", sn_info->name, sn_info->id_str); | ||
142 | + trace_sheepdog_snapshot_create(sn_info->name, sn_info->id_str); | ||
143 | |||
144 | s->inode.vm_state_size = sn_info->vm_state_size; | ||
145 | s->inode.vm_clock_nsec = sn_info->vm_clock_nsec; | ||
146 | @@ -XXX,XX +XXX,XX @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) | ||
147 | } | ||
148 | |||
149 | memcpy(&s->inode, inode, datalen); | ||
150 | - DPRINTF("s->inode: name %s snap_id %x oid %x\n", | ||
151 | - s->inode.name, s->inode.snap_id, s->inode.vdi_id); | ||
152 | + trace_sheepdog_snapshot_create_inode(s->inode.name, s->inode.snap_id, | ||
153 | + s->inode.vdi_id); | ||
154 | |||
155 | cleanup: | ||
156 | g_free(inode); | ||
157 | diff --git a/block/trace-events b/block/trace-events | ||
158 | index XXXXXXX..XXXXXXX 100644 | ||
159 | --- a/block/trace-events | ||
160 | +++ b/block/trace-events | ||
161 | @@ -XXX,XX +XXX,XX @@ file_xfs_discard(const char *error) "cannot punch hole (%s)" | ||
162 | file_FindEjectableOpticalMedia(const char *media) "Matching using %s" | ||
163 | file_setup_cdrom(const char *partition) "Using %s as optical disc" | ||
164 | file_hdev_is_sg(int type, int version) "SG device found: type=%d, version=%d" | ||
165 | + | ||
166 | +# block/sheepdog.c | ||
167 | +sheepdog_reconnect_to_sdog(void) "Wait for connection to be established" | ||
168 | +sheepdog_aio_read_response(void) "disable cache since the server doesn't support it" | ||
169 | +sheepdog_open(uint32_t vid) "0x%" PRIx32 " snapshot inode was open" | ||
170 | +sheepdog_close(const char *name) "%s" | ||
171 | +sheepdog_create_branch_snapshot(uint32_t vdi) "0x%" PRIx32 " is snapshot" | ||
172 | +sheepdog_create_branch_created(uint32_t vdi) "0x%" PRIx32 " is created" | ||
173 | +sheepdog_create_branch_new(uint32_t vdi) "0x%" PRIx32 " was newly created" | ||
174 | +sheepdog_co_rw_vector_update(uint32_t vdi, uint64_t oid, uint64_t data, long idx) "update ino (%" PRIu32 ") %" PRIu64 " %" PRIu64 " %ld" | ||
175 | +sheepdog_co_rw_vector_new(uint64_t oid) "new oid 0x%" PRIx64 | ||
176 | +sheepdog_snapshot_create_info(const char *sn_name, const char *id, const char *name, int64_t size, int is_snapshot) "sn_info: name %s id_str %s s: name %s vm_state_size %" PRId64 " " "is_snapshot %d" | ||
177 | +sheepdog_snapshot_create(const char *sn_name, const char *id) "%s %s" | ||
178 | +sheepdog_snapshot_create_inode(const char *name, uint32_t snap, uint32_t vdi) "s->inode: name %s snap_id 0x%" PRIx32 " vdi 0x%" PRIx32 | ||
179 | -- | ||
180 | 2.20.1 | ||
181 | |||
182 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Richard W.M. Jones" <rjones@redhat.com> | ||
2 | 1 | ||
3 | On FreeBSD 11.2: | ||
4 | |||
5 | $ nbdkit memory size=1M --run './qemu-io -f raw -c "aio_write 0 512" $nbd' | ||
6 | Parsing error: non-numeric argument, or extraneous/unrecognized suffix -- aio_write | ||
7 | |||
8 | After main option parsing, we reinitialize optind so we can parse each | ||
9 | command. However reinitializing optind to 0 does not work on FreeBSD. | ||
10 | What happens when you do this is optind remains 0 after the option | ||
11 | parsing loop, and the result is we try to parse argv[optind] == | ||
12 | argv[0] == "aio_write" as if it was the first parameter. | ||
13 | |||
14 | The FreeBSD manual page says: | ||
15 | |||
16 | In order to use getopt() to evaluate multiple sets of arguments, or to | ||
17 | evaluate a single set of arguments multiple times, the variable optreset | ||
18 | must be set to 1 before the second and each additional set of calls to | ||
19 | getopt(), and the variable optind must be reinitialized. | ||
20 | |||
21 | (From the rest of the man page it is clear that optind must be | ||
22 | reinitialized to 1). | ||
23 | |||
24 | The glibc man page says: | ||
25 | |||
26 | A program that scans multiple argument vectors, or rescans the same | ||
27 | vector more than once, and wants to make use of GNU extensions such as | ||
28 | '+' and '-' at the start of optstring, or changes the value of | ||
29 | POSIXLY_CORRECT between scans, must reinitialize getopt() by resetting | ||
30 | optind to 0, rather than the traditional value of 1. (Resetting to 0 | ||
31 | forces the invocation of an internal initialization routine that | ||
32 | rechecks POSIXLY_CORRECT and checks for GNU extensions in optstring.) | ||
33 | |||
34 | This commit introduces an OS-portability function called | ||
35 | qemu_reset_optind which provides a way of resetting optind that works | ||
36 | on FreeBSD and platforms that use optreset, while keeping it the same | ||
37 | as now on other platforms. | ||
38 | |||
39 | Note that the qemu codebase sets optind in many other places, but in | ||
40 | those other places it's setting a local variable and not using getopt. | ||
41 | This change is only needed in places where we are using getopt and the | ||
42 | associated global variable optind. | ||
43 | |||
44 | Signed-off-by: Richard W.M. Jones <rjones@redhat.com> | ||
45 | Message-id: 20190118101114.11759-2-rjones@redhat.com | ||
46 | Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> | ||
47 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
48 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
49 | --- | ||
50 | configure | 14 ++++++++++++++ | ||
51 | include/qemu/osdep.h | 16 ++++++++++++++++ | ||
52 | qemu-img.c | 2 +- | ||
53 | qemu-io-cmds.c | 2 +- | ||
54 | 4 files changed, 32 insertions(+), 2 deletions(-) | ||
55 | |||
56 | diff --git a/configure b/configure | ||
57 | index XXXXXXX..XXXXXXX 100755 | ||
58 | --- a/configure | ||
59 | +++ b/configure | ||
60 | @@ -XXX,XX +XXX,XX @@ if compile_prog "" "" ; then | ||
61 | signalfd=yes | ||
62 | fi | ||
63 | |||
64 | +# check if optreset global is declared by <getopt.h> | ||
65 | +optreset="no" | ||
66 | +cat > $TMPC << EOF | ||
67 | +#include <getopt.h> | ||
68 | +int main(void) { return optreset; } | ||
69 | +EOF | ||
70 | + | ||
71 | +if compile_prog "" "" ; then | ||
72 | + optreset=yes | ||
73 | +fi | ||
74 | + | ||
75 | # check if eventfd is supported | ||
76 | eventfd=no | ||
77 | cat > $TMPC << EOF | ||
78 | @@ -XXX,XX +XXX,XX @@ fi | ||
79 | if test "$signalfd" = "yes" ; then | ||
80 | echo "CONFIG_SIGNALFD=y" >> $config_host_mak | ||
81 | fi | ||
82 | +if test "$optreset" = "yes" ; then | ||
83 | + echo "HAVE_OPTRESET=y" >> $config_host_mak | ||
84 | +fi | ||
85 | if test "$tcg" = "yes"; then | ||
86 | echo "CONFIG_TCG=y" >> $config_host_mak | ||
87 | if test "$tcg_interpreter" = "yes" ; then | ||
88 | diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h | ||
89 | index XXXXXXX..XXXXXXX 100644 | ||
90 | --- a/include/qemu/osdep.h | ||
91 | +++ b/include/qemu/osdep.h | ||
92 | @@ -XXX,XX +XXX,XX @@ extern int daemon(int, int); | ||
93 | #include <ctype.h> | ||
94 | #include <errno.h> | ||
95 | #include <fcntl.h> | ||
96 | +#include <getopt.h> | ||
97 | #include <sys/stat.h> | ||
98 | #include <sys/time.h> | ||
99 | #include <assert.h> | ||
100 | @@ -XXX,XX +XXX,XX @@ extern int qemu_icache_linesize_log; | ||
101 | extern int qemu_dcache_linesize; | ||
102 | extern int qemu_dcache_linesize_log; | ||
103 | |||
104 | +/* | ||
105 | + * After using getopt or getopt_long, if you need to parse another set | ||
106 | + * of options, then you must reset optind. Unfortunately the way to | ||
107 | + * do this varies between implementations of getopt. | ||
108 | + */ | ||
109 | +static inline void qemu_reset_optind(void) | ||
110 | +{ | ||
111 | +#ifdef HAVE_OPTRESET | ||
112 | + optind = 1; | ||
113 | + optreset = 1; | ||
114 | +#else | ||
115 | + optind = 0; | ||
116 | +#endif | ||
117 | +} | ||
118 | + | ||
119 | #endif | ||
120 | diff --git a/qemu-img.c b/qemu-img.c | ||
121 | index XXXXXXX..XXXXXXX 100644 | ||
122 | --- a/qemu-img.c | ||
123 | +++ b/qemu-img.c | ||
124 | @@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv) | ||
125 | return 0; | ||
126 | } | ||
127 | argv += optind; | ||
128 | - optind = 0; | ||
129 | + qemu_reset_optind(); | ||
130 | |||
131 | if (!trace_init_backends()) { | ||
132 | exit(1); | ||
133 | diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c | ||
134 | index XXXXXXX..XXXXXXX 100644 | ||
135 | --- a/qemu-io-cmds.c | ||
136 | +++ b/qemu-io-cmds.c | ||
137 | @@ -XXX,XX +XXX,XX @@ static int command(BlockBackend *blk, const cmdinfo_t *ct, int argc, | ||
138 | } | ||
139 | } | ||
140 | |||
141 | - optind = 0; | ||
142 | + qemu_reset_optind(); | ||
143 | return ct->cfunc(blk, argc, argv); | ||
144 | } | ||
145 | |||
146 | -- | ||
147 | 2.20.1 | ||
148 | |||
149 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Li Qiang <liq3ea@163.com> | ||
2 | 1 | ||
3 | Signed-off-by: Li Qiang <liq3ea@163.com> | ||
4 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
5 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
6 | Message-id: 20190120055558.32984-2-liq3ea@163.com | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | --- | ||
9 | hw/block/nvme.c | 2 +- | ||
10 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/hw/block/nvme.c b/hw/block/nvme.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/hw/block/nvme.c | ||
15 | +++ b/hw/block/nvme.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static void nvme_instance_init(Object *obj) | ||
17 | } | ||
18 | |||
19 | static const TypeInfo nvme_info = { | ||
20 | - .name = "nvme", | ||
21 | + .name = TYPE_NVME, | ||
22 | .parent = TYPE_PCI_DEVICE, | ||
23 | .instance_size = sizeof(NvmeCtrl), | ||
24 | .class_init = nvme_class_init, | ||
25 | -- | ||
26 | 2.20.1 | ||
27 | |||
28 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Li Qiang <liq3ea@163.com> | ||
2 | 1 | ||
3 | When it is zero, it causes segv. | ||
4 | Using following command: | ||
5 | |||
6 | "-drive file=//home/test/test1.img,if=none,id=id0 | ||
7 | -device nvme,drive=id0,serial=test,num_queues=0" | ||
8 | causes following Backtrack: | ||
9 | |||
10 | Thread 4 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. | ||
11 | [Switching to Thread 0x7fffe9735700 (LWP 30952)] | ||
12 | 0x0000555555a7a77c in nvme_start_ctrl (n=0x5555577473f0) at hw/block/nvme.c:825 | ||
13 | 825 if (unlikely(n->cq[0])) { | ||
14 | (gdb) bt | ||
15 | 0 0x0000555555a7a77c in nvme_start_ctrl (n=0x5555577473f0) | ||
16 | at hw/block/nvme.c:825 | ||
17 | 1 0x0000555555a7af7f in nvme_write_bar (n=0x5555577473f0, offset=20, | ||
18 | data=4587521, size=4) at hw/block/nvme.c:969 | ||
19 | 2 0x0000555555a7b81a in nvme_mmio_write (opaque=0x5555577473f0, addr=20, | ||
20 | data=4587521, size=4) at hw/block/nvme.c:1163 | ||
21 | 3 0x0000555555869236 in memory_region_write_accessor (mr=0x555557747cd0, | ||
22 | addr=20, value=0x7fffe97320f8, size=4, shift=0, mask=4294967295, attrs=...) | ||
23 | at /home/test/qemu1/qemu/memory.c:502 | ||
24 | 4 0x0000555555869446 in access_with_adjusted_size (addr=20, | ||
25 | value=0x7fffe97320f8, size=4, access_size_min=2, access_size_max=8, | ||
26 | access_fn=0x55555586914d <memory_region_write_accessor>, | ||
27 | mr=0x555557747cd0, attrs=...) at /home/test/qemu1/qemu/memory.c:568 | ||
28 | 5 0x000055555586c479 in memory_region_dispatch_write (mr=0x555557747cd0, | ||
29 | addr=20, data=4587521, size=4, attrs=...) | ||
30 | at /home/test/qemu1/qemu/memory.c:1499 | ||
31 | 6 0x00005555558030af in flatview_write_continue (fv=0x7fffe0061130, | ||
32 | addr=4273930260, attrs=..., buf=0x7ffff7ff0028 "\001", len=4, addr1=20, | ||
33 | l=4, mr=0x555557747cd0) at /home/test/qemu1/qemu/exec.c:3234 | ||
34 | 7 0x00005555558031f9 in flatview_write (fv=0x7fffe0061130, addr=4273930260, | ||
35 | attrs=..., buf=0x7ffff7ff0028 "\001", len=4) | ||
36 | at /home/test/qemu1/qemu/exec.c:3273 | ||
37 | 8 0x00005555558034ff in address_space_write ( | ||
38 | ---Type <return> to continue, or q <return> to quit--- | ||
39 | as=0x555556758480 <address_space_memory>, addr=4273930260, attrs=..., | ||
40 | buf=0x7ffff7ff0028 "\001", len=4) at /home/test/qemu1/qemu/exec.c:3363 | ||
41 | 9 0x0000555555803550 in address_space_rw ( | ||
42 | as=0x555556758480 <address_space_memory>, addr=4273930260, attrs=..., | ||
43 | buf=0x7ffff7ff0028 "\001", len=4, is_write=true) | ||
44 | at /home/test/qemu1/qemu/exec.c:3374 | ||
45 | 10 0x00005555558884a1 in kvm_cpu_exec (cpu=0x555556920e40) | ||
46 | at /home/test/qemu1/qemu/accel/kvm/kvm-all.c:2031 | ||
47 | 11 0x000055555584cd9d in qemu_kvm_cpu_thread_fn (arg=0x555556920e40) | ||
48 | at /home/test/qemu1/qemu/cpus.c:1281 | ||
49 | 12 0x0000555555dbaf6d in qemu_thread_start (args=0x5555569438a0) | ||
50 | at util/qemu-thread-posix.c:502 | ||
51 | 13 0x00007ffff5dc86db in start_thread (arg=0x7fffe9735700) | ||
52 | at pthread_create.c:463 | ||
53 | 14 0x00007ffff5af188f in clone () | ||
54 | at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 | ||
55 | |||
56 | Signed-off-by: Li Qiang <liq3ea@163.com> | ||
57 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
58 | Message-id: 20190120055558.32984-3-liq3ea@163.com | ||
59 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
60 | --- | ||
61 | hw/block/nvme.c | 5 +++++ | ||
62 | 1 file changed, 5 insertions(+) | ||
63 | |||
64 | diff --git a/hw/block/nvme.c b/hw/block/nvme.c | ||
65 | index XXXXXXX..XXXXXXX 100644 | ||
66 | --- a/hw/block/nvme.c | ||
67 | +++ b/hw/block/nvme.c | ||
68 | @@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp) | ||
69 | int64_t bs_size; | ||
70 | uint8_t *pci_conf; | ||
71 | |||
72 | + if (!n->num_queues) { | ||
73 | + error_setg(errp, "num_queues can't be zero"); | ||
74 | + return; | ||
75 | + } | ||
76 | + | ||
77 | if (!n->conf.blk) { | ||
78 | error_setg(errp, "drive property not set"); | ||
79 | return; | ||
80 | -- | ||
81 | 2.20.1 | ||
82 | |||
83 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Li Qiang <liq3ea@163.com> | ||
2 | 1 | ||
3 | There is no need to make another reference. | ||
4 | |||
5 | Signed-off-by: Li Qiang <liq3ea@163.com> | ||
6 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
7 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
8 | Message-id: 20190120055558.32984-4-liq3ea@163.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | hw/block/nvme.c | 8 ++++---- | ||
12 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
13 | |||
14 | diff --git a/hw/block/nvme.c b/hw/block/nvme.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/hw/block/nvme.c | ||
17 | +++ b/hw/block/nvme.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp) | ||
19 | pci_conf[PCI_INTERRUPT_PIN] = 1; | ||
20 | pci_config_set_prog_interface(pci_dev->config, 0x2); | ||
21 | pci_config_set_class(pci_dev->config, PCI_CLASS_STORAGE_EXPRESS); | ||
22 | - pcie_endpoint_cap_init(&n->parent_obj, 0x80); | ||
23 | + pcie_endpoint_cap_init(pci_dev, 0x80); | ||
24 | |||
25 | n->num_namespaces = 1; | ||
26 | n->reg_size = pow2ceil(0x1004 + 2 * (n->num_queues + 1) * 4); | ||
27 | @@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp) | ||
28 | |||
29 | memory_region_init_io(&n->iomem, OBJECT(n), &nvme_mmio_ops, n, | ||
30 | "nvme", n->reg_size); | ||
31 | - pci_register_bar(&n->parent_obj, 0, | ||
32 | + pci_register_bar(pci_dev, 0, | ||
33 | PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64, | ||
34 | &n->iomem); | ||
35 | - msix_init_exclusive_bar(&n->parent_obj, n->num_queues, 4, NULL); | ||
36 | + msix_init_exclusive_bar(pci_dev, n->num_queues, 4, NULL); | ||
37 | |||
38 | id->vid = cpu_to_le16(pci_get_word(pci_conf + PCI_VENDOR_ID)); | ||
39 | id->ssvid = cpu_to_le16(pci_get_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID)); | ||
40 | @@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp) | ||
41 | n->cmbuf = g_malloc0(NVME_CMBSZ_GETSIZE(n->bar.cmbsz)); | ||
42 | memory_region_init_io(&n->ctrl_mem, OBJECT(n), &nvme_cmb_ops, n, | ||
43 | "nvme-cmb", NVME_CMBSZ_GETSIZE(n->bar.cmbsz)); | ||
44 | - pci_register_bar(&n->parent_obj, NVME_CMBLOC_BIR(n->bar.cmbloc), | ||
45 | + pci_register_bar(pci_dev, NVME_CMBLOC_BIR(n->bar.cmbloc), | ||
46 | PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 | | ||
47 | PCI_BASE_ADDRESS_MEM_PREFETCH, &n->ctrl_mem); | ||
48 | |||
49 | -- | ||
50 | 2.20.1 | ||
51 | |||
52 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | In some cases, we may want to deal with qemu-nbd errors (e.g. by | ||
2 | launching it in a different configuration until it no longer throws | ||
3 | any). In that case, we do not want its output ending up in the test | ||
4 | output. | ||
5 | 1 | ||
6 | It may still be useful for handling the error, though, so add a new | ||
7 | function that works basically like qemu_nbd(), only that it returns the | ||
8 | qemu-nbd output instead of making it end up in the log. In contrast to | ||
9 | qemu_img_pipe(), it does still return the exit code as well, though, | ||
10 | because that is even more important for error handling. | ||
11 | |||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | Message-id: 20181221234750.23577-2-mreitz@redhat.com | ||
14 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
15 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
16 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
17 | --- | ||
18 | tests/qemu-iotests/iotests.py | 14 ++++++++++++++ | ||
19 | 1 file changed, 14 insertions(+) | ||
20 | |||
21 | diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/tests/qemu-iotests/iotests.py | ||
24 | +++ b/tests/qemu-iotests/iotests.py | ||
25 | @@ -XXX,XX +XXX,XX @@ def qemu_nbd(*args): | ||
26 | '''Run qemu-nbd in daemon mode and return the parent's exit code''' | ||
27 | return subprocess.call(qemu_nbd_args + ['--fork'] + list(args)) | ||
28 | |||
29 | +def qemu_nbd_pipe(*args): | ||
30 | + '''Run qemu-nbd in daemon mode and return both the parent's exit code | ||
31 | + and its output''' | ||
32 | + subp = subprocess.Popen(qemu_nbd_args + ['--fork'] + list(args), | ||
33 | + stdout=subprocess.PIPE, | ||
34 | + stderr=subprocess.STDOUT, | ||
35 | + universal_newlines=True) | ||
36 | + exitcode = subp.wait() | ||
37 | + if exitcode < 0: | ||
38 | + sys.stderr.write('qemu-nbd received signal %i: %s\n' % | ||
39 | + (-exitcode, | ||
40 | + ' '.join(qemu_nbd_args + ['--fork'] + list(args)))) | ||
41 | + return exitcode, subp.communicate()[0] | ||
42 | + | ||
43 | def compare_images(img1, img2, fmt1=imgfmt, fmt2=imgfmt): | ||
44 | '''Return True if two image files are identical''' | ||
45 | return qemu_img('compare', '-f', fmt1, | ||
46 | -- | ||
47 | 2.20.1 | ||
48 | |||
49 | diff view generated by jsdifflib |
1 | To do this, we need to allow creating the NBD server on various ports | 1 | From: Philippe Mathieu-Daudé <f4bug@amsat.org> |
---|---|---|---|
2 | instead of a single one (which may not even work if you run just one | ||
3 | instance, because something entirely else might be using that port). | ||
4 | 2 | ||
5 | So we just pick a random port in [32768, 32768 + 1024) and try to create | 3 | "0x%u" format is very misleading, replace by "0x%x". |
6 | a server there. If that fails, we just retry until something sticks. | ||
7 | 4 | ||
8 | For the IPv6 test, we need a different range, though (just above that | 5 | Found running: |
9 | one). This is because "localhost" resolves to both 127.0.0.1 and ::1. | ||
10 | This means that if you bind to it, it will bind to both, if possible, or | ||
11 | just one if the other is already in use. Therefore, if the IPv6 test | ||
12 | has already taken [::1]:some_port and we then try to take | ||
13 | localhost:some_port, that will work -- only the second server will be | ||
14 | bound to 127.0.0.1:some_port alone and not [::1]:some_port in addition. | ||
15 | So we have two different servers on the same port, one for IPv4 and one | ||
16 | for IPv6. | ||
17 | 6 | ||
18 | But when we then try to connect to the server through | 7 | $ git grep -E '0x%[0-9]*([lL]*|" ?PRI)[dDuU]' block/ |
19 | localhost:some_port, we will always end up at the IPv6 one (as long as | ||
20 | it is up), and this may not be the one we want. | ||
21 | 8 | ||
22 | Thus, we must make sure not to create an IPv6-only NBD server on the | 9 | Inspired-by: Richard Henderson <richard.henderson@linaro.org> |
23 | same port as a normal "dual-stack" NBD server -- which is done by using | 10 | Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> |
24 | distinct port ranges, as explained above. | 11 | Reviewed-by: Hanna Reitz <hreitz@redhat.com> |
12 | Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> | ||
13 | Reviewed-by: Denis V. Lunev <den@openvz.org> | ||
14 | Message-id: 20220323114718.58714-2-philippe.mathieu.daude@gmail.com | ||
15 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
16 | --- | ||
17 | block/parallels-ext.c | 2 +- | ||
18 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
25 | 19 | ||
26 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 20 | diff --git a/block/parallels-ext.c b/block/parallels-ext.c |
27 | Message-id: 20181221234750.23577-4-mreitz@redhat.com | 21 | index XXXXXXX..XXXXXXX 100644 |
28 | Reviewed-by: John Snow <jsnow@redhat.com> | 22 | --- a/block/parallels-ext.c |
29 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 23 | +++ b/block/parallels-ext.c |
30 | --- | 24 | @@ -XXX,XX +XXX,XX @@ static int parallels_parse_format_extension(BlockDriverState *bs, |
31 | tests/qemu-iotests/147 | 98 +++++++++++++++++++++++++++++------------- | 25 | break; |
32 | 1 file changed, 68 insertions(+), 30 deletions(-) | 26 | |
33 | 27 | default: | |
34 | diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147 | 28 | - error_setg(errp, "Unknown feature: 0x%" PRIu64, fh.magic); |
35 | index XXXXXXX..XXXXXXX 100755 | 29 | + error_setg(errp, "Unknown feature: 0x%" PRIx64, fh.magic); |
36 | --- a/tests/qemu-iotests/147 | 30 | goto fail; |
37 | +++ b/tests/qemu-iotests/147 | 31 | } |
38 | @@ -XXX,XX +XXX,XX @@ | ||
39 | # | ||
40 | |||
41 | import os | ||
42 | +import random | ||
43 | import socket | ||
44 | import stat | ||
45 | import time | ||
46 | import iotests | ||
47 | -from iotests import cachemode, imgfmt, qemu_img, qemu_nbd | ||
48 | +from iotests import cachemode, imgfmt, qemu_img, qemu_nbd, qemu_nbd_pipe | ||
49 | |||
50 | -NBD_PORT = 10811 | ||
51 | +NBD_PORT_START = 32768 | ||
52 | +NBD_PORT_END = NBD_PORT_START + 1024 | ||
53 | +NBD_IPV6_PORT_START = NBD_PORT_END | ||
54 | +NBD_IPV6_PORT_END = NBD_IPV6_PORT_START + 1024 | ||
55 | |||
56 | test_img = os.path.join(iotests.test_dir, 'test.img') | ||
57 | unix_socket = os.path.join(iotests.test_dir, 'nbd.socket') | ||
58 | @@ -XXX,XX +XXX,XX @@ class QemuNBD(NBDBlockdevAddBase): | ||
59 | except OSError: | ||
60 | pass | ||
61 | |||
62 | + def _try_server_up(self, *args): | ||
63 | + status, msg = qemu_nbd_pipe('-f', imgfmt, test_img, *args) | ||
64 | + if status == 0: | ||
65 | + return True | ||
66 | + if 'Address already in use' in msg: | ||
67 | + return False | ||
68 | + self.fail(msg) | ||
69 | + | ||
70 | def _server_up(self, *args): | ||
71 | - self.assertEqual(qemu_nbd('-f', imgfmt, test_img, *args), 0) | ||
72 | + self.assertTrue(self._try_server_up(*args)) | ||
73 | |||
74 | def test_inet(self): | ||
75 | - self._server_up('-b', 'localhost', '-p', str(NBD_PORT)) | ||
76 | + while True: | ||
77 | + nbd_port = random.randrange(NBD_PORT_START, NBD_PORT_END) | ||
78 | + if self._try_server_up('-b', 'localhost', '-p', str(nbd_port)): | ||
79 | + break | ||
80 | + | ||
81 | address = { 'type': 'inet', | ||
82 | 'data': { | ||
83 | 'host': 'localhost', | ||
84 | - 'port': str(NBD_PORT) | ||
85 | + 'port': str(nbd_port) | ||
86 | } } | ||
87 | - self.client_test('nbd://localhost:%i' % NBD_PORT, | ||
88 | + self.client_test('nbd://localhost:%i' % nbd_port, | ||
89 | flatten_sock_addr(address)) | ||
90 | |||
91 | def test_unix(self): | ||
92 | @@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase): | ||
93 | except OSError: | ||
94 | pass | ||
95 | |||
96 | - def _server_up(self, address, export_name=None, export_name2=None): | ||
97 | + # Returns False on EADDRINUSE; fails an assertion on other errors. | ||
98 | + # Returns True on success. | ||
99 | + def _try_server_up(self, address, export_name=None, export_name2=None): | ||
100 | result = self.server.qmp('nbd-server-start', addr=address) | ||
101 | + if 'error' in result and \ | ||
102 | + 'Address already in use' in result['error']['desc']: | ||
103 | + return False | ||
104 | self.assert_qmp(result, 'return', {}) | ||
105 | |||
106 | if export_name is None: | ||
107 | @@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase): | ||
108 | name=export_name2) | ||
109 | self.assert_qmp(result, 'return', {}) | ||
110 | |||
111 | + return True | ||
112 | + | ||
113 | + def _server_up(self, address, export_name=None, export_name2=None): | ||
114 | + self.assertTrue(self._try_server_up(address, export_name, export_name2)) | ||
115 | |||
116 | def _server_down(self): | ||
117 | result = self.server.qmp('nbd-server-stop') | ||
118 | self.assert_qmp(result, 'return', {}) | ||
119 | |||
120 | def do_test_inet(self, export_name=None): | ||
121 | - address = { 'type': 'inet', | ||
122 | - 'data': { | ||
123 | - 'host': 'localhost', | ||
124 | - 'port': str(NBD_PORT) | ||
125 | - } } | ||
126 | - self._server_up(address, export_name) | ||
127 | + while True: | ||
128 | + nbd_port = random.randrange(NBD_PORT_START, NBD_PORT_END) | ||
129 | + address = { 'type': 'inet', | ||
130 | + 'data': { | ||
131 | + 'host': 'localhost', | ||
132 | + 'port': str(nbd_port) | ||
133 | + } } | ||
134 | + if self._try_server_up(address, export_name): | ||
135 | + break | ||
136 | + | ||
137 | export_name = export_name or 'nbd-export' | ||
138 | - self.client_test('nbd://localhost:%i/%s' % (NBD_PORT, export_name), | ||
139 | + self.client_test('nbd://localhost:%i/%s' % (nbd_port, export_name), | ||
140 | flatten_sock_addr(address), export_name) | ||
141 | self._server_down() | ||
142 | |||
143 | @@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase): | ||
144 | self.do_test_inet('shadow') | ||
145 | |||
146 | def test_inet_two_exports(self): | ||
147 | - address = { 'type': 'inet', | ||
148 | - 'data': { | ||
149 | - 'host': 'localhost', | ||
150 | - 'port': str(NBD_PORT) | ||
151 | - } } | ||
152 | - self._server_up(address, 'exp1', 'exp2') | ||
153 | - self.client_test('nbd://localhost:%i/%s' % (NBD_PORT, 'exp1'), | ||
154 | + while True: | ||
155 | + nbd_port = random.randrange(NBD_PORT_START, NBD_PORT_END) | ||
156 | + address = { 'type': 'inet', | ||
157 | + 'data': { | ||
158 | + 'host': 'localhost', | ||
159 | + 'port': str(nbd_port) | ||
160 | + } } | ||
161 | + if self._try_server_up(address, 'exp1', 'exp2'): | ||
162 | + break | ||
163 | + | ||
164 | + self.client_test('nbd://localhost:%i/%s' % (nbd_port, 'exp1'), | ||
165 | flatten_sock_addr(address), 'exp1', 'node1', False) | ||
166 | - self.client_test('nbd://localhost:%i/%s' % (NBD_PORT, 'exp2'), | ||
167 | + self.client_test('nbd://localhost:%i/%s' % (nbd_port, 'exp2'), | ||
168 | flatten_sock_addr(address), 'exp2', 'node2', False) | ||
169 | result = self.vm.qmp('blockdev-del', node_name='node1') | ||
170 | self.assert_qmp(result, 'return', {}) | ||
171 | @@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase): | ||
172 | except socket.gaierror: | ||
173 | # IPv6 not available, skip | ||
174 | return | ||
175 | - address = { 'type': 'inet', | ||
176 | - 'data': { | ||
177 | - 'host': '::1', | ||
178 | - 'port': str(NBD_PORT), | ||
179 | - 'ipv4': False, | ||
180 | - 'ipv6': True | ||
181 | - } } | ||
182 | + | ||
183 | + while True: | ||
184 | + nbd_port = random.randrange(NBD_IPV6_PORT_START, NBD_IPV6_PORT_END) | ||
185 | + address = { 'type': 'inet', | ||
186 | + 'data': { | ||
187 | + 'host': '::1', | ||
188 | + 'port': str(nbd_port), | ||
189 | + 'ipv4': False, | ||
190 | + 'ipv6': True | ||
191 | + } } | ||
192 | + if self._try_server_up(address): | ||
193 | + break | ||
194 | + | ||
195 | filename = { 'driver': 'raw', | ||
196 | 'file': { | ||
197 | 'driver': 'nbd', | ||
198 | 'export': 'nbd-export', | ||
199 | 'server': flatten_sock_addr(address) | ||
200 | } } | ||
201 | - self._server_up(address) | ||
202 | self.client_test(filename, flatten_sock_addr(address), 'nbd-export') | ||
203 | self._server_down() | ||
204 | 32 | ||
205 | -- | 33 | -- |
206 | 2.20.1 | 34 | 2.35.1 |
207 | 35 | ||
208 | 36 | diff view generated by jsdifflib |
1 | By default, qemu-nbd binds to 0.0.0.0. However, we then proceed to | 1 | From: Philippe Mathieu-Daudé <f4bug@amsat.org> |
---|---|---|---|
2 | connect to "localhost". Usually, this works out fine; but if this test | ||
3 | is run concurrently, some other test function may have bound a different | ||
4 | server to ::1 (on the same port -- you can bind different serves to the | ||
5 | same port, as long as one is on IPv4 and the other on IPv6). | ||
6 | 2 | ||
7 | So running qemu-nbd works, it can bind to 0.0.0.0:NBD_PORT. But | 3 | "0x%u" format is very misleading, replace by "0x%x". |
8 | potentially a concurrent test has successfully taken [::1]:NBD_PORT. In | ||
9 | this case, trying to connect to "localhost" will lead us to the IPv6 | ||
10 | instance, where we do not want to end up. | ||
11 | 4 | ||
12 | Fix this by just binding to "localhost". This will make qemu-nbd error | 5 | Found running: |
13 | out immediately and not give us cryptic errors later. | ||
14 | 6 | ||
15 | (Also, it will allow us to just try a different port as of a future | 7 | $ git grep -E '0x%[0-9]*([lL]*|" ?PRI)[dDuU]' hw/ |
16 | patch.) | ||
17 | 8 | ||
18 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 9 | Inspired-by: Richard Henderson <richard.henderson@linaro.org> |
19 | Message-id: 20181221234750.23577-3-mreitz@redhat.com | 10 | Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> |
20 | Reviewed-by: John Snow <jsnow@redhat.com> | 11 | Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> |
21 | Reviewed-by: Eric Blake <eblake@redhat.com> | 12 | Message-id: 20220323114718.58714-3-philippe.mathieu.daude@gmail.com |
22 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 13 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
23 | --- | 14 | --- |
24 | tests/qemu-iotests/147 | 2 +- | 15 | hw/i386/sgx.c | 2 +- |
25 | 1 file changed, 1 insertion(+), 1 deletion(-) | 16 | hw/i386/trace-events | 6 +++--- |
17 | hw/misc/trace-events | 4 ++-- | ||
18 | hw/scsi/trace-events | 4 ++-- | ||
19 | 4 files changed, 8 insertions(+), 8 deletions(-) | ||
26 | 20 | ||
27 | diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147 | 21 | diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c |
28 | index XXXXXXX..XXXXXXX 100755 | 22 | index XXXXXXX..XXXXXXX 100644 |
29 | --- a/tests/qemu-iotests/147 | 23 | --- a/hw/i386/sgx.c |
30 | +++ b/tests/qemu-iotests/147 | 24 | +++ b/hw/i386/sgx.c |
31 | @@ -XXX,XX +XXX,XX @@ class QemuNBD(NBDBlockdevAddBase): | 25 | @@ -XXX,XX +XXX,XX @@ void pc_machine_init_sgx_epc(PCMachineState *pcms) |
32 | self.assertEqual(qemu_nbd('-f', imgfmt, test_img, *args), 0) | 26 | } |
33 | 27 | ||
34 | def test_inet(self): | 28 | if ((sgx_epc->base + sgx_epc->size) < sgx_epc->base) { |
35 | - self._server_up('-p', str(NBD_PORT)) | 29 | - error_report("Size of all 'sgx-epc' =0x%"PRIu64" causes EPC to wrap", |
36 | + self._server_up('-b', 'localhost', '-p', str(NBD_PORT)) | 30 | + error_report("Size of all 'sgx-epc' =0x%"PRIx64" causes EPC to wrap", |
37 | address = { 'type': 'inet', | 31 | sgx_epc->size); |
38 | 'data': { | 32 | exit(EXIT_FAILURE); |
39 | 'host': 'localhost', | 33 | } |
34 | diff --git a/hw/i386/trace-events b/hw/i386/trace-events | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/hw/i386/trace-events | ||
37 | +++ b/hw/i386/trace-events | ||
38 | @@ -XXX,XX +XXX,XX @@ vtd_fault_disabled(void) "Fault processing disabled for context entry" | ||
39 | vtd_replay_ce_valid(const char *mode, uint8_t bus, uint8_t dev, uint8_t fn, uint16_t domain, uint64_t hi, uint64_t lo) "%s: replay valid context device %02"PRIx8":%02"PRIx8".%02"PRIx8" domain 0x%"PRIx16" hi 0x%"PRIx64" lo 0x%"PRIx64 | ||
40 | vtd_replay_ce_invalid(uint8_t bus, uint8_t dev, uint8_t fn) "replay invalid context device %02"PRIx8":%02"PRIx8".%02"PRIx8 | ||
41 | vtd_page_walk_level(uint64_t addr, uint32_t level, uint64_t start, uint64_t end) "walk (base=0x%"PRIx64", level=%"PRIu32") iova range 0x%"PRIx64" - 0x%"PRIx64 | ||
42 | -vtd_page_walk_one(uint16_t domain, uint64_t iova, uint64_t gpa, uint64_t mask, int perm) "domain 0x%"PRIu16" iova 0x%"PRIx64" -> gpa 0x%"PRIx64" mask 0x%"PRIx64" perm %d" | ||
43 | +vtd_page_walk_one(uint16_t domain, uint64_t iova, uint64_t gpa, uint64_t mask, int perm) "domain 0x%"PRIx16" iova 0x%"PRIx64" -> gpa 0x%"PRIx64" mask 0x%"PRIx64" perm %d" | ||
44 | vtd_page_walk_one_skip_map(uint64_t iova, uint64_t mask, uint64_t translated) "iova 0x%"PRIx64" mask 0x%"PRIx64" translated 0x%"PRIx64 | ||
45 | vtd_page_walk_one_skip_unmap(uint64_t iova, uint64_t mask) "iova 0x%"PRIx64" mask 0x%"PRIx64 | ||
46 | vtd_page_walk_skip_read(uint64_t iova, uint64_t next) "Page walk skip iova 0x%"PRIx64" - 0x%"PRIx64" due to unable to read" | ||
47 | vtd_page_walk_skip_reserve(uint64_t iova, uint64_t next) "Page walk skip iova 0x%"PRIx64" - 0x%"PRIx64" due to rsrv set" | ||
48 | vtd_switch_address_space(uint8_t bus, uint8_t slot, uint8_t fn, bool on) "Device %02x:%02x.%x switching address space (iommu enabled=%d)" | ||
49 | vtd_as_unmap_whole(uint8_t bus, uint8_t slot, uint8_t fn, uint64_t iova, uint64_t size) "Device %02x:%02x.%x start 0x%"PRIx64" size 0x%"PRIx64 | ||
50 | -vtd_translate_pt(uint16_t sid, uint64_t addr) "source id 0x%"PRIu16", iova 0x%"PRIx64 | ||
51 | -vtd_pt_enable_fast_path(uint16_t sid, bool success) "sid 0x%"PRIu16" %d" | ||
52 | +vtd_translate_pt(uint16_t sid, uint64_t addr) "source id 0x%"PRIx16", iova 0x%"PRIx64 | ||
53 | +vtd_pt_enable_fast_path(uint16_t sid, bool success) "sid 0x%"PRIx16" %d" | ||
54 | vtd_irq_generate(uint64_t addr, uint64_t data) "addr 0x%"PRIx64" data 0x%"PRIx64 | ||
55 | vtd_reg_read(uint64_t addr, uint64_t size) "addr 0x%"PRIx64" size 0x%"PRIx64 | ||
56 | vtd_reg_write(uint64_t addr, uint64_t size, uint64_t val) "addr 0x%"PRIx64" size 0x%"PRIx64" value 0x%"PRIx64 | ||
57 | diff --git a/hw/misc/trace-events b/hw/misc/trace-events | ||
58 | index XXXXXXX..XXXXXXX 100644 | ||
59 | --- a/hw/misc/trace-events | ||
60 | +++ b/hw/misc/trace-events | ||
61 | @@ -XXX,XX +XXX,XX @@ | ||
62 | # See docs/devel/tracing.rst for syntax documentation. | ||
63 | |||
64 | # allwinner-cpucfg.c | ||
65 | -allwinner_cpucfg_cpu_reset(uint8_t cpu_id, uint32_t reset_addr) "id %u, reset_addr 0x%" PRIu32 | ||
66 | +allwinner_cpucfg_cpu_reset(uint8_t cpu_id, uint32_t reset_addr) "id %u, reset_addr 0x%" PRIx32 | ||
67 | allwinner_cpucfg_read(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %" PRIu32 | ||
68 | allwinner_cpucfg_write(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %" PRIu32 | ||
69 | |||
70 | @@ -XXX,XX +XXX,XX @@ imx7_gpr_write(uint64_t offset, uint64_t value) "addr 0x%08" PRIx64 "value 0x%08 | ||
71 | |||
72 | # mos6522.c | ||
73 | mos6522_set_counter(int index, unsigned int val) "T%d.counter=%d" | ||
74 | -mos6522_get_next_irq_time(uint16_t latch, int64_t d, int64_t delta) "latch=%d counter=0x%"PRId64 " delta_next=0x%"PRId64 | ||
75 | +mos6522_get_next_irq_time(uint16_t latch, int64_t d, int64_t delta) "latch=%d counter=0x%"PRIx64 " delta_next=0x%"PRIx64 | ||
76 | mos6522_set_sr_int(void) "set sr_int" | ||
77 | mos6522_write(uint64_t addr, const char *name, uint64_t val) "reg=0x%"PRIx64 " [%s] val=0x%"PRIx64 | ||
78 | mos6522_read(uint64_t addr, const char *name, unsigned val) "reg=0x%"PRIx64 " [%s] val=0x%x" | ||
79 | diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events | ||
80 | index XXXXXXX..XXXXXXX 100644 | ||
81 | --- a/hw/scsi/trace-events | ||
82 | +++ b/hw/scsi/trace-events | ||
83 | @@ -XXX,XX +XXX,XX @@ lsi_bad_phase_interrupt(void) "Phase mismatch interrupt" | ||
84 | lsi_bad_selection(uint32_t id) "Selected absent target %"PRIu32 | ||
85 | lsi_do_dma_unavailable(void) "DMA no data available" | ||
86 | lsi_do_dma(uint64_t addr, int len) "DMA addr=0x%"PRIx64" len=%d" | ||
87 | -lsi_queue_command(uint32_t tag) "Queueing tag=0x%"PRId32 | ||
88 | +lsi_queue_command(uint32_t tag) "Queueing tag=0x%"PRIx32 | ||
89 | lsi_add_msg_byte_error(void) "MSG IN data too long" | ||
90 | lsi_add_msg_byte(uint8_t data) "MSG IN 0x%02x" | ||
91 | lsi_reselect(int id) "Reselected target %d" | ||
92 | @@ -XXX,XX +XXX,XX @@ lsi_do_msgout_noop(void) "MSG: No Operation" | ||
93 | lsi_do_msgout_extended(uint8_t msg, uint8_t len) "Extended message 0x%x (len %d)" | ||
94 | lsi_do_msgout_ignored(const char *msg) "%s (ignored)" | ||
95 | lsi_do_msgout_simplequeue(uint8_t select_tag) "SIMPLE queue tag=0x%x" | ||
96 | -lsi_do_msgout_abort(uint32_t tag) "MSG: ABORT TAG tag=0x%"PRId32 | ||
97 | +lsi_do_msgout_abort(uint32_t tag) "MSG: ABORT TAG tag=0x%"PRIx32 | ||
98 | lsi_do_msgout_clearqueue(uint32_t tag) "MSG: CLEAR QUEUE tag=0x%"PRIx32 | ||
99 | lsi_do_msgout_busdevicereset(uint32_t tag) "MSG: BUS DEVICE RESET tag=0x%"PRIx32 | ||
100 | lsi_do_msgout_select(int id) "Select LUN %d" | ||
40 | -- | 101 | -- |
41 | 2.20.1 | 102 | 2.35.1 |
42 | 103 | ||
43 | 104 | diff view generated by jsdifflib |