xref: /titanic_51/usr/src/cmd/latencytop/common/latencytop.c (revision 15db28971f91c98efb449aebf46024ac72779fa3)
1*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
2*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * CDDL HEADER START
3*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *
4*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * The contents of this file are subject to the terms of the
5*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Common Development and Distribution License (the "License").
6*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * You may not use this file except in compliance with the License.
7*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *
8*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * or http://www.opensolaris.org/os/licensing.
10*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * See the License for the specific language governing permissions
11*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * and limitations under the License.
12*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *
13*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * When distributing Covered Code, include this CDDL HEADER in each
14*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * If applicable, add the following below this CDDL HEADER, with the
16*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * fields enclosed by brackets "[]" replaced with your own identifying
17*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * information: Portions Copyright [yyyy] [name of copyright owner]
18*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *
19*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * CDDL HEADER END
20*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
21*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
22*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Copyright (c) 2008-2009, Intel Corporation.
23*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * All Rights Reserved.
24*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
25*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
26*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <unistd.h>
27*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <getopt.h>
28*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <stdio.h>
29*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <string.h>
30*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <stdlib.h>
31*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <limits.h>
32*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <libgen.h>
33*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <signal.h>
34*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include "latencytop.h"
35*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
36*15db2897SKrishnendu Sadhukhan - Sun Microsystems #define	CMPOPT(a, b)	strncmp((a), (b), sizeof (b))
37*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
38*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_config_t g_config;
39*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
40*15db2897SKrishnendu Sadhukhan - Sun Microsystems typedef enum {
41*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT_INTERVAL,
42*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT_LOG_FILE,
43*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT_LOG_LEVEL,
44*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT_LOG_INTERVAL,
45*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT_CONFIG_FILE,
46*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT_F_FILTER,
47*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT_F_SCHED,
48*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT_F_SOBJ,
49*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT_F_LOW,
50*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	LT_CMDOPT__LAST	/* Must be last one */
51*15db2897SKrishnendu Sadhukhan - Sun Microsystems } lt_cmd_option_id_t;
52*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
53*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
54*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Check for duplicate command line options.
55*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Returns TRUE if duplicate options with different values are found,
56*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * returns FALSE otherwise.
57*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
58*15db2897SKrishnendu Sadhukhan - Sun Microsystems static int
59*15db2897SKrishnendu Sadhukhan - Sun Microsystems check_opt_dup(lt_cmd_option_id_t id, uint64_t value) {
60*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
61*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	static int opt_set[(int)LT_CMDOPT__LAST];
62*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	static uint64_t opt_val[(int)LT_CMDOPT__LAST];
63*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
64*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	const char *errmsg[] = {
65*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"-t is set more than once with different values.",
66*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"-o is set more than once.",
67*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"-k is set more than once with different values.",
68*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"-l is set more than once with different values.",
69*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"-c is set more than once.",
70*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"-f [no]filter is set more than once with different values.",
71*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"-f [no]sched is set more than once with different values.",
72*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"-f [no]sobj is set more than once with different values.",
73*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"-f [no]low is set more than once with different values.",
74*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	};
75*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
76*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(sizeof (errmsg)/sizeof (errmsg[0]) == (int)LT_CMDOPT__LAST);
77*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
78*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (!opt_set[(int)id]) {
79*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		opt_set[(int)id] = TRUE;
80*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		opt_val[(int)id] = value;
81*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (FALSE);
82*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
83*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
84*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (opt_val[(int)id] != value) {
85*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) fprintf(stderr, "%s\n", errmsg[(int)id]);
86*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (TRUE);
87*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
88*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
89*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (FALSE);
90*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
91*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
92*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
93*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Print command-line help message.
94*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
95*15db2897SKrishnendu Sadhukhan - Sun Microsystems static void
96*15db2897SKrishnendu Sadhukhan - Sun Microsystems print_usage(const char *execname, int long_help)
97*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
98*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	char buffer[PATH_MAX];
99*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) snprintf(buffer, sizeof (buffer), "%s", execname);
100*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
101*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (!long_help) {
102*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		/* Print short help to stderr. */
103*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) fprintf(stderr, "Usage: %s [option(s)], ",
104*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    basename(buffer));
105*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) fprintf(stderr, "use '%s -h' for details.\n",
106*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    basename(buffer));
107*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
108*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
109*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
110*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) printf("Usage: %s [option(s)]\n", basename(buffer));
111*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) printf("Options:\n"
112*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "    -h, --help\n"
113*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Print this help.\n"
114*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "    -t, --interval TIME\n"
115*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Set refresh interval to TIME. "
116*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "Valid range [1...60] seconds, default = 5\n"
117*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	/*
118*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	 * Option "-c, --config FILE" is not user-visible for now.
119*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	 * When we have chance to properly document the format of translation
120*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	 * rules, we'll make it user-visible.
121*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	 */
122*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "    -o, --output-log-file FILE\n"
123*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Output kernel log to FILE. Default = "
124*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    DEFAULT_KLOG_FILE "\n"
125*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "    -k, --kernel-log-level LEVEL\n"
126*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Set kernel log level to LEVEL.\n"
127*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        0(default) = None, 1 = Unmapped, 2 = Mapped, 3 = All.\n"
128*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "    -f, --feature [no]feature1,[no]feature2,...\n"
129*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Enable/disable features in LatencyTOP.\n"
130*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        [no]filter:\n"
131*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Filter large interruptible latencies, e.g. sleep.\n"
132*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        [no]sched:\n"
133*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Monitors sched (PID=0).\n"
134*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        [no]sobj:\n"
135*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Monitors synchronization objects.\n"
136*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        [no]low:\n"
137*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Lower overhead by sampling small latencies.\n"
138*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "    -l, --log-period TIME\n"
139*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    "        Write and restart log every TIME seconds, TIME >= 60\n");
140*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
141*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
142*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
143*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Properly exit latencytop when it receives SIGINT or SIGTERM.
144*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
145*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* ARGSUSED */
146*15db2897SKrishnendu Sadhukhan - Sun Microsystems static void
147*15db2897SKrishnendu Sadhukhan - Sun Microsystems signal_handler(int sig)
148*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
149*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_gpipe_break("q");
150*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
151*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
152*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
153*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Convert string to integer. It returns error if extra characters are found.
154*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
155*15db2897SKrishnendu Sadhukhan - Sun Microsystems static int
156*15db2897SKrishnendu Sadhukhan - Sun Microsystems to_int(const char *str, int *result)
157*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
158*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	char *tail = NULL;
159*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	long ret;
160*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
161*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (str == NULL || result == NULL) {
162*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
163*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
164*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
165*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret = strtol(str, &tail, 10);
166*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
167*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (tail != NULL && *tail != '\0') {
168*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
169*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
170*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
171*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	*result = (int)ret;
172*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
173*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (0);
174*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
175*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
176*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
177*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * The main function.
178*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
179*15db2897SKrishnendu Sadhukhan - Sun Microsystems int
180*15db2897SKrishnendu Sadhukhan - Sun Microsystems main(int argc, char *argv[])
181*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
182*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	const char *opt_string = "t:o:k:hf:l:c:";
183*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	struct option const longopts[] = {
184*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		{"interval", required_argument, NULL, 't'},
185*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		{"output-log-file", required_argument, NULL, 'o'},
186*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		{"kernel-log-level", required_argument, NULL, 'k'},
187*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		{"help", no_argument, NULL, 'h'},
188*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		{"feature", required_argument, NULL, 'f'},
189*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		{"log-period", required_argument, NULL, 'l'},
190*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		{"config", required_argument, NULL, 'c'},
191*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		{NULL, 0, NULL, 0}
192*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	};
193*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
194*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int optc;
195*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int longind = 0;
196*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int running = 1;
197*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int unknown_option = FALSE;
198*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int refresh_interval = 5;
199*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int klog_level = 0;
200*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int log_interval = 0;
201*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	long long last_logged = 0;
202*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	char *token = NULL;
203*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int retval = 0;
204*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int gpipe;
205*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int err;
206*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t collect_end;
207*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t current_time;
208*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t delta_time;
209*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	char logfile[PATH_MAX] = "";
210*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
211*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_gpipe_init();
212*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) signal(SIGINT, signal_handler);
213*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) signal(SIGTERM, signal_handler);
214*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
215*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Default global settings */
216*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_config.lt_cfg_enable_filter = 0;
217*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_config.lt_cfg_trace_sched = 0;
218*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_config.lt_cfg_trace_syncobj = 1;
219*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_config.lt_cfg_low_overhead_mode = 0;
220*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* dtrace snapshot every 1 second */
221*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_config.lt_cfg_snap_interval = 1000;
222*15db2897SKrishnendu Sadhukhan - Sun Microsystems #ifdef EMBED_CONFIGS
223*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_config.lt_cfg_config_name = NULL;
224*15db2897SKrishnendu Sadhukhan - Sun Microsystems #else
225*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_config.lt_cfg_config_name = lt_strdup(DEFAULT_CONFIG_NAME);
226*15db2897SKrishnendu Sadhukhan - Sun Microsystems #endif
227*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
228*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Parse command line arguments. */
229*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	while ((optc = getopt_long(argc, argv, opt_string,
230*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    longopts, &longind)) != -1) {
231*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		switch (optc) {
232*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		case 'h':
233*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			print_usage(argv[0], TRUE);
234*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			goto end_none;
235*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		case 't':
236*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			if (to_int(optarg, &refresh_interval) != 0 ||
237*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    refresh_interval < 1 || refresh_interval > 60) {
238*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				lt_display_error(
239*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    "Invalid refresh interval: %s\n", optarg);
240*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
241*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			} else if (check_opt_dup(LT_CMDOPT_INTERVAL,
242*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    refresh_interval)) {
243*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
244*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			}
245*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
246*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
247*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		case 'k':
248*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			if (to_int(optarg, &klog_level) != 0 ||
249*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    lt_klog_set_log_level(klog_level) != 0) {
250*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				lt_display_error(
251*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    "Invalid log level: %s\n", optarg);
252*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
253*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			} else if (check_opt_dup(LT_CMDOPT_LOG_LEVEL,
254*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    refresh_interval)) {
255*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
256*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			}
257*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
258*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
259*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		case 'o':
260*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			if (check_opt_dup(LT_CMDOPT_LOG_FILE, optind)) {
261*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
262*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			} else if (strlen(optarg) >= sizeof (logfile)) {
263*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				lt_display_error(
264*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    "Log file name is too long: %s\n",
265*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    optarg);
266*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
267*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			} else {
268*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				(void) strncpy(logfile, optarg,
269*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    sizeof (logfile));
270*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			}
271*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
272*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
273*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		case 'f':
274*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			for (token = strtok(optarg, ","); token != NULL;
275*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    token = strtok(NULL, ",")) {
276*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				int v = TRUE;
277*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
278*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				if (strncmp(token, "no", 2) == 0) {
279*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					v = FALSE;
280*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					token = &token[2];
281*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				}
282*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
283*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				if (CMPOPT(token, "filter") == 0) {
284*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					if (check_opt_dup(LT_CMDOPT_F_FILTER,
285*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					    v)) {
286*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						unknown_option = TRUE;
287*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					} else {
288*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						g_config.lt_cfg_enable_filter
289*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						    = v;
290*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					}
291*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				} else if (CMPOPT(token, "sched") == 0) {
292*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					if (check_opt_dup(LT_CMDOPT_F_SCHED,
293*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					    v)) {
294*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						unknown_option = TRUE;
295*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					} else {
296*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						g_config.lt_cfg_trace_sched
297*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						    = v;
298*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					}
299*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				} else if (CMPOPT(token, "sobj") == 0) {
300*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					if (check_opt_dup(LT_CMDOPT_F_SOBJ,
301*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					    v)) {
302*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						unknown_option = TRUE;
303*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					} else {
304*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						g_config.lt_cfg_trace_syncobj
305*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						    = v;
306*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					}
307*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				} else if (CMPOPT(token, "low") == 0) {
308*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					if (check_opt_dup(LT_CMDOPT_F_LOW,
309*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					    v)) {
310*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						unknown_option = TRUE;
311*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					} else {
312*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						g_config.
313*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						    lt_cfg_low_overhead_mode
314*15db2897SKrishnendu Sadhukhan - Sun Microsystems 						    = v;
315*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					}
316*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				} else {
317*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					lt_display_error(
318*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					    "Unknown feature: %s\n", token);
319*15db2897SKrishnendu Sadhukhan - Sun Microsystems 					unknown_option = TRUE;
320*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				}
321*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			}
322*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
323*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
324*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		case 'l':
325*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			if (to_int(optarg, &log_interval) != 0 ||
326*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    log_interval < 60) {
327*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				lt_display_error(
328*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    "Invalid log interval: %s\n", optarg);
329*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
330*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			} else if (check_opt_dup(LT_CMDOPT_LOG_INTERVAL,
331*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    log_interval)) {
332*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
333*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			}
334*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
335*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
336*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		case 'c':
337*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			if (strlen(optarg) >= PATH_MAX) {
338*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				lt_display_error(
339*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    "Configuration name is too long.\n");
340*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
341*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			} else if (check_opt_dup(LT_CMDOPT_CONFIG_FILE,
342*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    optind)) {
343*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				unknown_option = TRUE;
344*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			} else {
345*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				g_config.lt_cfg_config_name =
346*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    lt_strdup(optarg);
347*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			}
348*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
349*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
350*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		default:
351*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			unknown_option = TRUE;
352*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
353*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
354*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
355*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
356*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (!unknown_option && strlen(logfile) > 0) {
357*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		err = lt_klog_set_log_file(logfile);
358*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
359*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (err == -1) {
360*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			lt_display_error("Log file name is too long: %s\n",
361*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    logfile);
362*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			unknown_option = TRUE;
363*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		} else if (err == -2) {
364*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			lt_display_error("Cannot write to log file: %s\n",
365*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    logfile);
366*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			unknown_option = TRUE;
367*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
368*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
369*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
370*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Throw error for invalid/junk arguments */
371*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (optind  < argc) {
372*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		int tmpind = optind;
373*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) fprintf(stderr, "Unknown option(s): ");
374*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
375*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		while (tmpind < argc) {
376*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			(void) fprintf(stderr, "%s ", argv[tmpind++]);
377*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
378*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
379*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) fprintf(stderr, "\n");
380*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		unknown_option = TRUE;
381*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
382*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
383*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (unknown_option) {
384*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		print_usage(argv[0], FALSE);
385*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		retval = 1;
386*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		goto end_none;
387*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
388*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
389*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) printf("%s\n%s\n", TITLE, COPYRIGHT);
390*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
391*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	/*
392*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	 * Initialization
393*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	 */
394*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_klog_init();
395*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
396*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (lt_table_init() != 0) {
397*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Unable to load configuration table.\n");
398*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		retval = 1;
399*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		goto end_notable;
400*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
401*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
402*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (lt_dtrace_init() != 0) {
403*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Unable to initialize dtrace.\n");
404*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		retval = 1;
405*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		goto end_nodtrace;
406*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
407*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
408*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	last_logged = lt_millisecond();
409*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
410*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) printf("Collecting data for %d seconds...\n",
411*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    refresh_interval);
412*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
413*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	gpipe = lt_gpipe_readfd();
414*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	collect_end = last_logged + refresh_interval * 1000;
415*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	for (;;) {
416*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		fd_set read_fd;
417*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		struct timeval timeout;
418*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		int tsleep = collect_end - lt_millisecond();
419*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
420*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (tsleep <= 0) {
421*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
422*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
423*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
424*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (tsleep > g_config.lt_cfg_snap_interval * 1000) {
425*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			tsleep = g_config.lt_cfg_snap_interval * 1000;
426*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
427*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
428*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		timeout.tv_sec = tsleep / 1000;
429*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		timeout.tv_usec = (tsleep % 1000) * 1000;
430*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
431*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		FD_ZERO(&read_fd);
432*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		FD_SET(gpipe, &read_fd);
433*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
434*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (select(gpipe + 1, &read_fd, NULL, NULL, &timeout) > 0) {
435*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			goto end_ubreak;
436*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
437*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
438*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) lt_dtrace_work(0);
439*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
440*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
441*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_display_init();
442*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
443*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	do {
444*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		current_time = lt_millisecond();
445*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
446*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_stat_clear_all();
447*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) lt_dtrace_collect();
448*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
449*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		delta_time = current_time;
450*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		current_time = lt_millisecond();
451*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		delta_time = current_time - delta_time;
452*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
453*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (log_interval > 0 &&
454*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    current_time - last_logged > log_interval * 1000) {
455*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			lt_klog_write();
456*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			last_logged = current_time;
457*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
458*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
459*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		running = lt_display_loop(refresh_interval * 1000 -
460*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    delta_time);
461*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} while (running != 0);
462*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
463*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_klog_write();
464*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
465*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Cleanup */
466*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_display_deinit();
467*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
468*15db2897SKrishnendu Sadhukhan - Sun Microsystems end_ubreak:
469*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_dtrace_deinit();
470*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_free_all();
471*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
472*15db2897SKrishnendu Sadhukhan - Sun Microsystems end_nodtrace:
473*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_table_deinit();
474*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
475*15db2897SKrishnendu Sadhukhan - Sun Microsystems end_notable:
476*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_klog_deinit();
477*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
478*15db2897SKrishnendu Sadhukhan - Sun Microsystems end_none:
479*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_gpipe_deinit();
480*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
481*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (g_config.lt_cfg_config_name != NULL) {
482*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		free(g_config.lt_cfg_config_name);
483*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
484*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
485*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (retval);
486*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
487