1
The following changes since commit 64175afc695c0672876fbbfc31b299c86d562cb4:
1
The following changes since commit b4fbe1f65a4769c09e6bf2d79fc84360f840f40e:
2
2
3
arm_gicv3: Fix ICC_BPR1 reset value when EL3 not implemented (2017-06-07 17:21:44 +0100)
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190129' into staging (2019-01-29 12:00:19 +0000)
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://git.xanclic.moe/XanClic/qemu.git tags/pull-block-2019-01-31
8
8
9
for you to fetch changes up to 56faeb9bb6872b3f926b3b3e0452a70beea10af2:
9
for you to fetch changes up to 908b30164bbffad7430d551b2a03a8fbcaa631ef:
10
10
11
block/gluster.c: Handle qdict_array_entries() failure (2017-06-09 08:41:29 -0400)
11
iotests: Allow 147 to be run concurrently (2019-01-31 00:44:55 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Gluster patch
14
Block patches:
15
- New debugging QMP command to explore block graphs
16
- Converted DPRINTF()s to trace events
17
- Fixed qemu-io's use of getopt() for systems with optreset
18
- Minor NVMe emulation fixes
19
- An iotest fix
20
15
----------------------------------------------------------------
21
----------------------------------------------------------------
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
16
27
17
Peter Maydell (1):
28
Li Qiang (3):
18
block/gluster.c: Handle qdict_array_entries() failure
29
nvme: use TYPE_NVME instead of constant string
30
nvme: ensure the num_queues is not zero
31
nvme: use pci_dev directly in nvme_realize
19
32
20
block/gluster.c | 3 +--
33
Max Reitz (3):
21
1 file changed, 1 insertion(+), 2 deletions(-)
34
iotests.py: Add qemu_nbd_pipe()
35
iotests: Bind qemu-nbd to localhost in 147
36
iotests: Allow 147 to be run concurrently
37
38
Richard W.M. Jones (1):
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
22
66
23
--
67
--
24
2.9.3
68
2.20.1
25
69
26
70
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
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
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
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
New patch
1
From: Laurent Vivier <lvivier@redhat.com>
1
2
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
New patch
1
From: Laurent Vivier <lvivier@redhat.com>
1
2
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
New patch
1
From: Laurent Vivier <lvivier@redhat.com>
1
2
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
New patch
1
From: Laurent Vivier <lvivier@redhat.com>
1
2
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
New patch
1
From: "Richard W.M. Jones" <rjones@redhat.com>
1
2
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
New patch
1
From: Li Qiang <liq3ea@163.com>
1
2
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
New patch
1
From: Li Qiang <liq3ea@163.com>
1
2
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
New patch
1
From: Li Qiang <liq3ea@163.com>
1
2
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
New 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.
1
5
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
From: Peter Maydell <peter.maydell@linaro.org>
1
By default, qemu-nbd binds to 0.0.0.0. However, we then proceed to
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).
2
6
3
In qemu_gluster_parse_json(), the call to qdict_array_entries()
7
So running qemu-nbd works, it can bind to 0.0.0.0:NBD_PORT. But
4
could return a negative error code, which we were ignoring
8
potentially a concurrent test has successfully taken [::1]:NBD_PORT. In
5
because we assigned the result to an unsigned variable.
9
this case, trying to connect to "localhost" will lead us to the IPv6
6
Fix this by using the 'int' type instead, which matches the
10
instance, where we do not want to end up.
7
return type of qdict_array_entries() and also the type
8
we use for the loop enumeration variable 'i'.
9
11
10
(Spotted by Coverity, CID 1360960.)
12
Fix this by just binding to "localhost". This will make qemu-nbd error
13
out immediately and not give us cryptic errors later.
11
14
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
(Also, it will allow us to just try a different port as of a future
16
patch.)
17
18
Signed-off-by: Max Reitz <mreitz@redhat.com>
19
Message-id: 20181221234750.23577-3-mreitz@redhat.com
20
Reviewed-by: John Snow <jsnow@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
21
Reviewed-by: Eric Blake <eblake@redhat.com>
14
Reviewed-by: Jeff Cody <jcody@redhat.com>
22
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Message-id: 1496682098-1540-1-git-send-email-peter.maydell@linaro.org
16
Signed-off-by: Jeff Cody <jcody@redhat.com>
17
---
23
---
18
block/gluster.c | 3 +--
24
tests/qemu-iotests/147 | 2 +-
19
1 file changed, 1 insertion(+), 2 deletions(-)
25
1 file changed, 1 insertion(+), 1 deletion(-)
20
26
21
diff --git a/block/gluster.c b/block/gluster.c
27
diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147
22
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100755
23
--- a/block/gluster.c
29
--- a/tests/qemu-iotests/147
24
+++ b/block/gluster.c
30
+++ b/tests/qemu-iotests/147
25
@@ -XXX,XX +XXX,XX @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
31
@@ -XXX,XX +XXX,XX @@ class QemuNBD(NBDBlockdevAddBase):
26
Error *local_err = NULL;
32
self.assertEqual(qemu_nbd('-f', imgfmt, test_img, *args), 0)
27
char *str = NULL;
33
28
const char *ptr;
34
def test_inet(self):
29
- size_t num_servers;
35
- self._server_up('-p', str(NBD_PORT))
30
- int i, type;
36
+ self._server_up('-b', 'localhost', '-p', str(NBD_PORT))
31
+ int i, type, num_servers;
37
address = { 'type': 'inet',
32
38
'data': {
33
/* create opts info from runtime_json_opts list */
39
'host': 'localhost',
34
opts = qemu_opts_create(&runtime_json_opts, NULL, 0, &error_abort);
35
--
40
--
36
2.9.3
41
2.20.1
37
42
38
43
diff view generated by jsdifflib
New patch
1
1
To do this, we need to allow creating the NBD server on various ports
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
5
So we just pick a random port in [32768, 32768 + 1024) and try to create
6
a server there. If that fails, we just retry until something sticks.
7
8
For the IPv6 test, we need a different range, though (just above that
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
18
But when we then try to connect to the server through
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
22
Thus, we must make sure not to create an IPv6-only NBD server on the
23
same port as a normal "dual-stack" NBD server -- which is done by using
24
distinct port ranges, as explained above.
25
26
Signed-off-by: Max Reitz <mreitz@redhat.com>
27
Message-id: 20181221234750.23577-4-mreitz@redhat.com
28
Reviewed-by: John Snow <jsnow@redhat.com>
29
Signed-off-by: Max Reitz <mreitz@redhat.com>
30
---
31
tests/qemu-iotests/147 | 98 +++++++++++++++++++++++++++++-------------
32
1 file changed, 68 insertions(+), 30 deletions(-)
33
34
diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147
35
index XXXXXXX..XXXXXXX 100755
36
--- a/tests/qemu-iotests/147
37
+++ b/tests/qemu-iotests/147
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
205
--
206
2.20.1
207
208
diff view generated by jsdifflib