1#! /usr/bin/env python
2#
3# btt blkno plotting interface
4#
5#  (C) Copyright 2008 Hewlett-Packard Development Company, L.P.
6#
7#  This program is free software; you can redistribute it and/or modify
8#  it under the terms of the GNU General Public License as published by
9#  the Free Software Foundation; either version 2 of the License, or
10#  (at your option) any later version.
11#
12#  This program is distributed in the hope that it will be useful,
13#  but WITHOUT ANY WARRANTY; without even the implied warranty of
14#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15#  GNU General Public License for more details.
16#
17#  You should have received a copy of the GNU General Public License
18#  along with this program; if not, write to the Free Software
19#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20#
21"""
22bno_plot.py
23	[ -h | --help       ]
24	[ -K | --keys-below ]
25	[ -v | --verbose    ]
26	[ <file...>         ]
27
28Utilizes gnuplot to generate a 3D plot of the block number output
29from btt.  If no <files> are specified, it will utilize all files
30generated after btt was run with -B blknos (meaning: all files of the
31form blknos*[rw].dat).
32
33The -K option forces bno_plot.py to put the keys below the graph,
34typically all keys for input files are put in the upper right corner
35of the graph. If the number of devices exceed 10, then bno_plot.py will
36automatically push the keys under the graph.
37
38To exit the plotter, enter 'quit' or ^D at the 'gnuplot> ' prompt.
39"""
40
41import getopt, glob, os, sys, tempfile
42
43verbose	= 0
44cmds	= """
45set title 'btt Generated Block Accesses'
46set xlabel 'Time (secs)'
47set ylabel 'Block Number'
48set zlabel '# Blocks per IO'
49set grid
50"""
51
52
53#-----------------------------------------------------------------------------
54def parse_args(in_args):
55	global verbose
56
57	keys_below = False
58	s_opts = 'hKv'
59	l_opts = [ 'help', 'keys-below', 'verbose' ]
60
61	try:
62		(opts, args) = getopt.getopt(in_args, s_opts, l_opts)
63	except getopt.error, msg:
64		print >>sys.stderr, msg
65		print >>sys.stderr, __doc__
66		sys.exit(1)
67
68	for (o, a) in opts:
69		if o in ('-h', '--help'):
70			print __doc__
71			sys.exit(0)
72		elif o in ('-v', '--verbose'):
73			verbose += 1
74		elif o in ('-K', '--keys-below'):
75			keys_below = True
76
77	if len(args) > 0:	bnos = args
78	else:			bnos = glob.glob('blknos*[rw].dat')
79
80	return (bnos, keys_below)
81
82#-----------------------------------------------------------------------------
83if __name__ == '__main__':
84	(bnos, keys_below) = parse_args(sys.argv[1:])
85
86	if verbose:
87		print 'Using files:',
88		for bno in bnos: print bno,
89		if keys_below:	print '\nKeys are to be placed below graph'
90		else:		print ''
91
92	tmpdir = tempfile.mktemp()
93	os.mkdir(tmpdir)
94
95	plot_cmd = None
96	for f in bnos:
97		t = '%s/%s' % (tmpdir, f)
98
99		fo = open(t, 'w')
100		for line in open(f, 'r'):
101			fld = line.split(None)
102			print >>fo, fld[0], fld[1], int(fld[2])-int(fld[1])
103		fo.close()
104
105		t = t[t.rfind('/')+1:]
106		if plot_cmd == None: plot_cmd = "splot '%s'" % t
107		else:                plot_cmd = "%s,'%s'" % (plot_cmd, t)
108
109	fo = open('%s/plot.cmds' % tmpdir, 'w')
110	print >>fo, cmds
111	if len(bnos) > 10 or keys_below: print >>fo, 'set key below'
112	print >>fo, plot_cmd
113	fo.close()
114
115	pid = os.fork()
116	if pid == 0:
117		cmd = '/usr/bin/gnuplot %s/plot.cmds -' % tmpdir
118
119		if verbose: print 'Executing %s' % cmd
120
121		cmd = cmd.split(None)
122		os.chdir(tmpdir)
123		os.execvp(cmd[0], cmd)
124		sys.exit(1)
125
126	os.waitpid(pid, 0)
127	os.system('/bin/rm -rf ' + tmpdir)
128