Render block nodes graph with help of graphviz. This new function is for debugging, so there is no sense to put it into qemu.py as a method of QEMUMachine. Let's instead put it separately.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- scripts/render_block_graph.py | 78 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 scripts/render_block_graph.py diff --git a/scripts/render_block_graph.py b/scripts/render_block_graph.py new file mode 100644 index 0000000000..7048a0bac8 --- /dev/null +++ b/scripts/render_block_graph.py @@ -0,0 +1,78 @@ +# Render Qemu Block Graph +# +# Copyright (c) 2017 Parallels International GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import os +from graphviz import Digraph + +def perm(arr): + s = 'w' if 'write' in arr else '_' + s += 'r' if 'consistent-read' in arr else '_' + s += 'u' if 'write-unchanged' in arr else '_' + s += 'g' if 'graph-mod' in arr else '_' + s += 's' if 'resize' in arr else '_' + return s + +def render_block_graph(vm, filename, pointers=False, format='png'): + ''' + Render graph in text (dot) representation into "@filename" and + representation in @format into "@filename.@format" + ''' + + nodes = vm.command('query-named-block-nodes') + nodes_info = {n['node-name']: n for n in nodes} + + block_graph = vm.command('x-query-block-graph') + + graph = Digraph(comment='Block Nodes Graph') + graph.format = format + graph.node('permission symbols:\l' + ' w - Write\l' + ' r - consistent-Read\l' + ' u - write - Unchanged\l' + ' g - Graph-mod\l' + ' s - reSize\l' + 'edge label scheme:\l' + ' <child type>\l' + ' <perm>\l' + ' <shared_perm>\l', shape='none') + + + for n in block_graph['nodes']: + if n['type'] == 'block': + info = nodes_info[n['node-name']] + label = n['node-name'] + ' [' + info['drv'] + ']' + shape = 'ellipse' + else: + assert n['type'] == 'other' + label = n['description'] + shape = 'box' + + if pointers: + label += '\n0x%x' % n['id'] + + if n['type'] == 'block' and info['drv'] == 'file': + label += '\n' + os.path.basename(info['file']) + + graph.node(str(n['id']), label, shape=shape) + + for e in block_graph['edges']: + label = '%s\l%s\l%s\l' % (e['name'], perm(e['perm']), + perm(e['shared-perm'])) + graph.edge(str(e['parent']), str(e['child']), label=label) + + graph.render(filename) -- 2.11.1