1e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/*
2e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * blktrace output analysis: generate a timeline & gather statistics
3e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
4e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com>
5e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
6e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  This program is free software; you can redistribute it and/or modify
7e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  it under the terms of the GNU General Public License as published by
8e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  the Free Software Foundation; either version 2 of the License, or
9e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  (at your option) any later version.
10e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
11e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  This program is distributed in the hope that it will be useful,
12e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  GNU General Public License for more details.
15e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
16e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  You should have received a copy of the GNU General Public License
17e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  along with this program; if not, write to the Free Software
18e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
20e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */
21e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
22e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <stdio.h>
23e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <stdlib.h>
24e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <getopt.h>
25e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <sys/types.h>
26e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <sys/stat.h>
27e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <fcntl.h>
28e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include "globals.h"
29e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
30e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define SETBUFFER_SIZE	(64 * 1024)
31e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
32e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define S_OPTS	"aAB:d:D:e:hi:I:l:L:m:M:o:p:P:q:Q:rs:S:t:T:u:VvXz:"
33e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct option l_opts[] = {
34e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
35e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "seek-absolute",
36e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = no_argument,
37e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
38e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'a'
39e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
40e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
41e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "all-data",
42e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = no_argument,
43e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
44e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'A'
45e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
46e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
47e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "dump-blocknos",
48e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
49e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
50e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'B'
51e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
52e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
53e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "range-delta",
54e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
55e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
56e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'd'
57e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
58e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
59e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "devices",
60e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
61e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
62e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'D'
63e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
64e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
65e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "exes",
66e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
67e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
68e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'e'
69e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
70e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
71e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "help",
72e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = no_argument,
73e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
74e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'h'
75e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
76e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
77e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "input-file",
78e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
79e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
80e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'i'
81e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
82e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
83e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "iostat",
84e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
85e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
86e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'I'
87e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
88e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
89e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "d2c-latencies",
90e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
91e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
92e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'l'
93e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
94e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
95e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "periodic-latencies",
96e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
97e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
98e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'L'
99e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "seeks-per-second",
102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'm'
105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "dev-maps",
108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'M'
111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "output-file",
114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'o'
117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "per-io-dump",
120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'p'
123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "per-io-trees",
126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'P'
129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "q2c-latencies",
132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'q'
135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "active-queue-depth",
138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'Q'
141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "no-remaps",
144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = no_argument,
145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'r'
147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "seeks",
150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 's'
153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "iostat-interval",
156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'S'
159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "time-start",
162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 't'
165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "time-end",
168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'T'
171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "unplug-hist",
174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'u'
177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "version",
180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = no_argument,
181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'V'
183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "verbose",
186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = no_argument,
187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'v'
189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "easy-parse-avgs",
192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = no_argument,
193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'X'
195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = "q2d-latencies",
198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.has_arg = required_argument,
199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.flag = NULL,
200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.val = 'z'
201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	},
202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	{
203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.name = NULL,
204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat};
206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char usage_str[] = \
208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"\n[ -a               | --seek-absolute ]\n" \
209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -A               | --all-data ]\n" \
210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -B <output name> | --dump-blocknos=<output name> ]\n" \
211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -d <seconds>     | --range-delta=<seconds> ]\n" \
212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -D <dev;...>     | --devices=<dev;...> ]\n" \
213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -e <exe,...>     | --exes=<exe,...>  ]\n" \
214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -h               | --help ]\n" \
215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -i <input name>  | --input-file=<input name> ]\n" \
216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -I <output name> | --iostat=<output name> ]\n" \
217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -l <output name> | --d2c-latencies=<output name> ]\n" \
218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -L <freq>        | --periodic-latencies=<freq> ]\n" \
219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -m <output name> | --seeks-per-second=<output name> ]\n" \
220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -M <dev map>     | --dev-maps=<dev map>\n" \
221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -o <output name> | --output-file=<output name> ]\n" \
222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -p <output name> | --per-io-dump=<output name> ]\n" \
223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -P <output name> | --per-io-trees=<output name> ]\n" \
224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -q <output name> | --q2c-latencies=<output name> ]\n" \
225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -Q <output name> | --active-queue-depth=<output name> ]\n" \
226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -r               | --no-remaps ]\n" \
227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -s <output name> | --seeks=<output name> ]\n" \
228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -S <interval>    | --iostat-interval=<interval> ]\n" \
229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -t <sec>         | --time-start=<sec> ]\n" \
230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -T <sec>         | --time-end=<sec> ]\n" \
231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -u <output name> | --unplug-hist=<output name> ]\n" \
232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -V               | --version ]\n" \
233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -v               | --verbose ]\n" \
234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -X               | --easy-parse-avgs ]\n" \
235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"[ -z <output name> | --q2d-latencies=<output name> ]\n" \
236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	"\n";
237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void usage(char *prog)
239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(stderr, "Usage: %s %s %s", prog, bt_timeline_version,
241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		usage_str);
242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic FILE *setup_ofile(char *fname)
245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (fname) {
247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		char *buf;
248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		FILE *ofp = my_fopen(fname, "w");
249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (!ofp) {
251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			perror(fname);
252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			exit(1);
253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		buf = malloc(SETBUFFER_SIZE);
256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		setbuffer(ofp, buf, SETBUFFER_SIZE);
257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		add_file(ofp, fname);
259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		add_buf(buf);
260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		return ofp;
262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
264e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return NULL;
265e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
266e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
267e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic FILE *std_open(char *output_name, char *sfx, char *msg)
268e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
269e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *fp;
270e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	char fname[strlen(output_name) + 32];
271e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
272e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	sprintf(fname, "%s.%s", output_name, sfx);
273e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fp = my_fopen(fname, "w");
274e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (fp == NULL) {
275e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		perror(fname);
276e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		exit(1);
277e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
278e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (verbose)
279e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		printf("Sending %s to %s\n", msg, fname);
280e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
281e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return fp;
282e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
283e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
284e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid handle_args(int argc, char *argv[])
285e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
286e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int c;
287e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
288e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) != -1) {
289e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		switch (c) {
290e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'a':
291e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			seek_absolute = 1;
292e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
293e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'A':
294e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_all_data = 1;
295e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
296e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'B':
297e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			bno_dump_name = optarg;
298e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
299e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'd':
300e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			sscanf(optarg, "%lf", &range_delta);
301e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
302e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'D':
303e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			devices = optarg;
304e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
305e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'e':
306e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			exes = optarg;
307e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
308e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'h':
309e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			usage(argv[0]);
310e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			exit(0);
311e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'i':
312e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			input_name = optarg;
313e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
314e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'l':
315e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			d2c_name = optarg;
316e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
317e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'L':
318e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			plat_freq = atof(optarg);
319e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
320e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'I':
321e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			iostat_name = strdup(optarg);
322e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
323e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'm':
324e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			sps_name = optarg;
325e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
326e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'M':
327e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			if (dev_map_read(optarg))
328e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				exit(1);
329e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
330e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'o':
331e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_name = optarg;
332e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
333e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'p':
334e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			per_io_name = strdup(optarg);
335e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
336e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'P':
337e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			per_io_trees = optarg;
338e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
339e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'q':
340e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			q2c_name = optarg;
341e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
342e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'Q':
343e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			aqd_name = optarg;
344e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
345e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'r':
346e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			ignore_remaps = 1;
347e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
348e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 's':
349e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			seek_name = optarg;
350e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
351e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'S': {
352e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			unsigned int interval;
353e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
354e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			sscanf(optarg, "%u", &interval);
355e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			iostat_interval = (__u64)interval * 1000000000LL;
356e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
357e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
358e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 't':
359e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			sscanf(optarg, "%lf", &t_astart);
360e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			time_bounded = 1;
361e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
362e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'T':
363e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			sscanf(optarg, "%lf", &t_aend);
364e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			time_bounded = 1;
365e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
366e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'u':
367e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			unplug_hist_name = optarg;
368e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
369e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'v':
370e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			verbose = 1;
371e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
372e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'V':
373e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			printf("%s version %s\n", argv[0], bt_timeline_version);
374e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			exit(0);
375e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'X':
376e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			easy_parse_avgs++;
377e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
378e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		case 'z':
379e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			q2d_name = optarg;
380e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			break;
381e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		default:
382e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			usage(argv[0]);
383e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			exit(1);
384e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
385e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
386e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
387e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (input_name == NULL) {
388e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		usage(argv[0]);
389e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		exit(1);
390e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
391e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
392e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (sps_name && !seek_name) {
393e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(stderr, "FATAL: -m option requires -s options\n");
394e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		exit(1);
395e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
396e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
397e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	setup_ifile(input_name);
398e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
399e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (output_name == NULL) {
400e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		rngs_ofp = avgs_ofp = msgs_ofp = stdout;
401e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		easy_parse_avgs = 0;
402e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	} else {
403e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		rngs_ofp = std_open(output_name, "dat", "range data");
404e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		avgs_ofp = std_open(output_name, "avg", "stats data");
405e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		msgs_ofp = std_open(output_name, "msg", "K messages");
406e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (easy_parse_avgs) {
407e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			xavgs_ofp = std_open(output_name, "xvg",
408e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat					     "EZ stats data");
409e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
410e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
411e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
412e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	iostat_ofp = setup_ofile(iostat_name);
413e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	per_io_ofp = setup_ofile(per_io_name);
414e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
415