xref: /onnv-gate/usr/src/cmd/latencytop/common/latencytop.c (revision 11789:6c7658a179ca)
110673SKrishnendu.Sadhukhan@Sun.COM /*
210673SKrishnendu.Sadhukhan@Sun.COM  * CDDL HEADER START
310673SKrishnendu.Sadhukhan@Sun.COM  *
410673SKrishnendu.Sadhukhan@Sun.COM  * The contents of this file are subject to the terms of the
510673SKrishnendu.Sadhukhan@Sun.COM  * Common Development and Distribution License (the "License").
610673SKrishnendu.Sadhukhan@Sun.COM  * You may not use this file except in compliance with the License.
710673SKrishnendu.Sadhukhan@Sun.COM  *
810673SKrishnendu.Sadhukhan@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910673SKrishnendu.Sadhukhan@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1010673SKrishnendu.Sadhukhan@Sun.COM  * See the License for the specific language governing permissions
1110673SKrishnendu.Sadhukhan@Sun.COM  * and limitations under the License.
1210673SKrishnendu.Sadhukhan@Sun.COM  *
1310673SKrishnendu.Sadhukhan@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1410673SKrishnendu.Sadhukhan@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510673SKrishnendu.Sadhukhan@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1610673SKrishnendu.Sadhukhan@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1710673SKrishnendu.Sadhukhan@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1810673SKrishnendu.Sadhukhan@Sun.COM  *
1910673SKrishnendu.Sadhukhan@Sun.COM  * CDDL HEADER END
2010673SKrishnendu.Sadhukhan@Sun.COM  */
2110673SKrishnendu.Sadhukhan@Sun.COM /*
2210673SKrishnendu.Sadhukhan@Sun.COM  * Copyright (c) 2008-2009, Intel Corporation.
2310673SKrishnendu.Sadhukhan@Sun.COM  * All Rights Reserved.
2410673SKrishnendu.Sadhukhan@Sun.COM  */
2510673SKrishnendu.Sadhukhan@Sun.COM 
2610673SKrishnendu.Sadhukhan@Sun.COM #include <unistd.h>
2710673SKrishnendu.Sadhukhan@Sun.COM #include <getopt.h>
2810673SKrishnendu.Sadhukhan@Sun.COM #include <stdio.h>
2910673SKrishnendu.Sadhukhan@Sun.COM #include <string.h>
3010673SKrishnendu.Sadhukhan@Sun.COM #include <stdlib.h>
3110673SKrishnendu.Sadhukhan@Sun.COM #include <limits.h>
3210673SKrishnendu.Sadhukhan@Sun.COM #include <libgen.h>
3310673SKrishnendu.Sadhukhan@Sun.COM #include <signal.h>
3410673SKrishnendu.Sadhukhan@Sun.COM #include "latencytop.h"
3510673SKrishnendu.Sadhukhan@Sun.COM 
3610673SKrishnendu.Sadhukhan@Sun.COM #define	CMPOPT(a, b)	strncmp((a), (b), sizeof (b))
3710673SKrishnendu.Sadhukhan@Sun.COM 
3810883SKrishnendu.Sadhukhan@Sun.COM /*
3910883SKrishnendu.Sadhukhan@Sun.COM  * This variable is used to check if "dynamic variable drop" in dtrace
4010883SKrishnendu.Sadhukhan@Sun.COM  * has happened.
4110883SKrishnendu.Sadhukhan@Sun.COM  */
4210883SKrishnendu.Sadhukhan@Sun.COM boolean_t lt_drop_detected = 0;
4310883SKrishnendu.Sadhukhan@Sun.COM 
4410673SKrishnendu.Sadhukhan@Sun.COM lt_config_t g_config;
4510673SKrishnendu.Sadhukhan@Sun.COM 
4610673SKrishnendu.Sadhukhan@Sun.COM typedef enum {
4710673SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_INTERVAL,
4810673SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_LOG_FILE,
4910673SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_LOG_LEVEL,
5010673SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_LOG_INTERVAL,
5110673SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_CONFIG_FILE,
5210673SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_F_FILTER,
5310673SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_F_SCHED,
5410673SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_F_SOBJ,
5510673SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_F_LOW,
56*11789SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT_SELECT,
57*11789SKrishnendu.Sadhukhan@Sun.COM 	LT_CMDOPT__LAST	/* Must be the last one */
5810673SKrishnendu.Sadhukhan@Sun.COM } lt_cmd_option_id_t;
5910673SKrishnendu.Sadhukhan@Sun.COM 
6010673SKrishnendu.Sadhukhan@Sun.COM /*
6110673SKrishnendu.Sadhukhan@Sun.COM  * Check for duplicate command line options.
6210673SKrishnendu.Sadhukhan@Sun.COM  * Returns TRUE if duplicate options with different values are found,
6310673SKrishnendu.Sadhukhan@Sun.COM  * returns FALSE otherwise.
6410673SKrishnendu.Sadhukhan@Sun.COM  */
6510673SKrishnendu.Sadhukhan@Sun.COM static int
check_opt_dup(lt_cmd_option_id_t id,uint64_t value)6610673SKrishnendu.Sadhukhan@Sun.COM check_opt_dup(lt_cmd_option_id_t id, uint64_t value) {
6710673SKrishnendu.Sadhukhan@Sun.COM 
6810673SKrishnendu.Sadhukhan@Sun.COM 	static int opt_set[(int)LT_CMDOPT__LAST];
6910673SKrishnendu.Sadhukhan@Sun.COM 	static uint64_t opt_val[(int)LT_CMDOPT__LAST];
7010673SKrishnendu.Sadhukhan@Sun.COM 
7110673SKrishnendu.Sadhukhan@Sun.COM 	const char *errmsg[] = {
7210673SKrishnendu.Sadhukhan@Sun.COM 		"-t is set more than once with different values.",
7310673SKrishnendu.Sadhukhan@Sun.COM 		"-o is set more than once.",
7410673SKrishnendu.Sadhukhan@Sun.COM 		"-k is set more than once with different values.",
7510673SKrishnendu.Sadhukhan@Sun.COM 		"-l is set more than once with different values.",
7610673SKrishnendu.Sadhukhan@Sun.COM 		"-c is set more than once.",
7710673SKrishnendu.Sadhukhan@Sun.COM 		"-f [no]filter is set more than once with different values.",
7810673SKrishnendu.Sadhukhan@Sun.COM 		"-f [no]sched is set more than once with different values.",
7910673SKrishnendu.Sadhukhan@Sun.COM 		"-f [no]sobj is set more than once with different values.",
8010673SKrishnendu.Sadhukhan@Sun.COM 		"-f [no]low is set more than once with different values.",
81*11789SKrishnendu.Sadhukhan@Sun.COM 		"-s is set more than once with different values."
8210673SKrishnendu.Sadhukhan@Sun.COM 	};
8310673SKrishnendu.Sadhukhan@Sun.COM 
8410673SKrishnendu.Sadhukhan@Sun.COM 	g_assert(sizeof (errmsg)/sizeof (errmsg[0]) == (int)LT_CMDOPT__LAST);
8510673SKrishnendu.Sadhukhan@Sun.COM 
8610673SKrishnendu.Sadhukhan@Sun.COM 	if (!opt_set[(int)id]) {
8710673SKrishnendu.Sadhukhan@Sun.COM 		opt_set[(int)id] = TRUE;
8810673SKrishnendu.Sadhukhan@Sun.COM 		opt_val[(int)id] = value;
8910673SKrishnendu.Sadhukhan@Sun.COM 		return (FALSE);
9010673SKrishnendu.Sadhukhan@Sun.COM 	}
9110673SKrishnendu.Sadhukhan@Sun.COM 
9210673SKrishnendu.Sadhukhan@Sun.COM 	if (opt_val[(int)id] != value) {
9310673SKrishnendu.Sadhukhan@Sun.COM 		(void) fprintf(stderr, "%s\n", errmsg[(int)id]);
9410673SKrishnendu.Sadhukhan@Sun.COM 		return (TRUE);
9510673SKrishnendu.Sadhukhan@Sun.COM 	}
9610673SKrishnendu.Sadhukhan@Sun.COM 
9710673SKrishnendu.Sadhukhan@Sun.COM 	return (FALSE);
9810673SKrishnendu.Sadhukhan@Sun.COM }
9910673SKrishnendu.Sadhukhan@Sun.COM 
10010673SKrishnendu.Sadhukhan@Sun.COM /*
10110673SKrishnendu.Sadhukhan@Sun.COM  * Print command-line help message.
10210673SKrishnendu.Sadhukhan@Sun.COM  */
10310673SKrishnendu.Sadhukhan@Sun.COM static void
print_usage(const char * execname,int long_help)10410673SKrishnendu.Sadhukhan@Sun.COM print_usage(const char *execname, int long_help)
10510673SKrishnendu.Sadhukhan@Sun.COM {
10610673SKrishnendu.Sadhukhan@Sun.COM 	char buffer[PATH_MAX];
10710673SKrishnendu.Sadhukhan@Sun.COM 	(void) snprintf(buffer, sizeof (buffer), "%s", execname);
10810673SKrishnendu.Sadhukhan@Sun.COM 
10910673SKrishnendu.Sadhukhan@Sun.COM 	if (!long_help) {
11010673SKrishnendu.Sadhukhan@Sun.COM 		/* Print short help to stderr. */
11110673SKrishnendu.Sadhukhan@Sun.COM 		(void) fprintf(stderr, "Usage: %s [option(s)], ",
11210673SKrishnendu.Sadhukhan@Sun.COM 		    basename(buffer));
11310673SKrishnendu.Sadhukhan@Sun.COM 		(void) fprintf(stderr, "use '%s -h' for details.\n",
11410673SKrishnendu.Sadhukhan@Sun.COM 		    basename(buffer));
11510673SKrishnendu.Sadhukhan@Sun.COM 		return;
11610673SKrishnendu.Sadhukhan@Sun.COM 	}
11710673SKrishnendu.Sadhukhan@Sun.COM 
11810673SKrishnendu.Sadhukhan@Sun.COM 	(void) printf("Usage: %s [option(s)]\n", basename(buffer));
11910673SKrishnendu.Sadhukhan@Sun.COM 	(void) printf("Options:\n"
12010673SKrishnendu.Sadhukhan@Sun.COM 	    "    -h, --help\n"
12110673SKrishnendu.Sadhukhan@Sun.COM 	    "        Print this help.\n"
12210673SKrishnendu.Sadhukhan@Sun.COM 	    "    -t, --interval TIME\n"
12310673SKrishnendu.Sadhukhan@Sun.COM 	    "        Set refresh interval to TIME. "
12410673SKrishnendu.Sadhukhan@Sun.COM 	    "Valid range [1...60] seconds, default = 5\n"
12510673SKrishnendu.Sadhukhan@Sun.COM 	/*
12610673SKrishnendu.Sadhukhan@Sun.COM 	 * Option "-c, --config FILE" is not user-visible for now.
12710673SKrishnendu.Sadhukhan@Sun.COM 	 * When we have chance to properly document the format of translation
12810673SKrishnendu.Sadhukhan@Sun.COM 	 * rules, we'll make it user-visible.
12910673SKrishnendu.Sadhukhan@Sun.COM 	 */
13010673SKrishnendu.Sadhukhan@Sun.COM 	    "    -o, --output-log-file FILE\n"
13110673SKrishnendu.Sadhukhan@Sun.COM 	    "        Output kernel log to FILE. Default = "
13210673SKrishnendu.Sadhukhan@Sun.COM 	    DEFAULT_KLOG_FILE "\n"
13310673SKrishnendu.Sadhukhan@Sun.COM 	    "    -k, --kernel-log-level LEVEL\n"
13410673SKrishnendu.Sadhukhan@Sun.COM 	    "        Set kernel log level to LEVEL.\n"
13510673SKrishnendu.Sadhukhan@Sun.COM 	    "        0(default) = None, 1 = Unmapped, 2 = Mapped, 3 = All.\n"
13610673SKrishnendu.Sadhukhan@Sun.COM 	    "    -f, --feature [no]feature1,[no]feature2,...\n"
13710673SKrishnendu.Sadhukhan@Sun.COM 	    "        Enable/disable features in LatencyTOP.\n"
13810673SKrishnendu.Sadhukhan@Sun.COM 	    "        [no]filter:\n"
13910673SKrishnendu.Sadhukhan@Sun.COM 	    "        Filter large interruptible latencies, e.g. sleep.\n"
14010673SKrishnendu.Sadhukhan@Sun.COM 	    "        [no]sched:\n"
14110673SKrishnendu.Sadhukhan@Sun.COM 	    "        Monitors sched (PID=0).\n"
14210673SKrishnendu.Sadhukhan@Sun.COM 	    "        [no]sobj:\n"
14310673SKrishnendu.Sadhukhan@Sun.COM 	    "        Monitors synchronization objects.\n"
14410673SKrishnendu.Sadhukhan@Sun.COM 	    "        [no]low:\n"
14510673SKrishnendu.Sadhukhan@Sun.COM 	    "        Lower overhead by sampling small latencies.\n"
14610673SKrishnendu.Sadhukhan@Sun.COM 	    "    -l, --log-period TIME\n"
147*11789SKrishnendu.Sadhukhan@Sun.COM 	    "        Write and restart log every TIME seconds, TIME >= 60\n"
148*11789SKrishnendu.Sadhukhan@Sun.COM 	    "    -s --select [ pid=<pid> | pgid=<pgid> ]\n"
149*11789SKrishnendu.Sadhukhan@Sun.COM 	    "        Monitor only the given process or processes in the "
150*11789SKrishnendu.Sadhukhan@Sun.COM 	    "given process group.\n");
15110673SKrishnendu.Sadhukhan@Sun.COM }
15210673SKrishnendu.Sadhukhan@Sun.COM 
15310673SKrishnendu.Sadhukhan@Sun.COM /*
15410673SKrishnendu.Sadhukhan@Sun.COM  * Properly exit latencytop when it receives SIGINT or SIGTERM.
15510673SKrishnendu.Sadhukhan@Sun.COM  */
15610673SKrishnendu.Sadhukhan@Sun.COM /* ARGSUSED */
15710673SKrishnendu.Sadhukhan@Sun.COM static void
signal_handler(int sig)15810673SKrishnendu.Sadhukhan@Sun.COM signal_handler(int sig)
15910673SKrishnendu.Sadhukhan@Sun.COM {
16010673SKrishnendu.Sadhukhan@Sun.COM 	lt_gpipe_break("q");
16110673SKrishnendu.Sadhukhan@Sun.COM }
16210673SKrishnendu.Sadhukhan@Sun.COM 
16310673SKrishnendu.Sadhukhan@Sun.COM /*
16410673SKrishnendu.Sadhukhan@Sun.COM  * Convert string to integer. It returns error if extra characters are found.
16510673SKrishnendu.Sadhukhan@Sun.COM  */
16610673SKrishnendu.Sadhukhan@Sun.COM static int
to_int(const char * str,int * result)16710673SKrishnendu.Sadhukhan@Sun.COM to_int(const char *str, int *result)
16810673SKrishnendu.Sadhukhan@Sun.COM {
16910673SKrishnendu.Sadhukhan@Sun.COM 	char *tail = NULL;
17010673SKrishnendu.Sadhukhan@Sun.COM 	long ret;
17110673SKrishnendu.Sadhukhan@Sun.COM 
17210673SKrishnendu.Sadhukhan@Sun.COM 	if (str == NULL || result == NULL) {
17310673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
17410673SKrishnendu.Sadhukhan@Sun.COM 	}
17510673SKrishnendu.Sadhukhan@Sun.COM 
17610673SKrishnendu.Sadhukhan@Sun.COM 	ret = strtol(str, &tail, 10);
17710673SKrishnendu.Sadhukhan@Sun.COM 
17810673SKrishnendu.Sadhukhan@Sun.COM 	if (tail != NULL && *tail != '\0') {
17910673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
18010673SKrishnendu.Sadhukhan@Sun.COM 	}
18110673SKrishnendu.Sadhukhan@Sun.COM 
18210673SKrishnendu.Sadhukhan@Sun.COM 	*result = (int)ret;
18310673SKrishnendu.Sadhukhan@Sun.COM 
18410673SKrishnendu.Sadhukhan@Sun.COM 	return (0);
18510673SKrishnendu.Sadhukhan@Sun.COM }
18610673SKrishnendu.Sadhukhan@Sun.COM 
18710673SKrishnendu.Sadhukhan@Sun.COM /*
18810673SKrishnendu.Sadhukhan@Sun.COM  * The main function.
18910673SKrishnendu.Sadhukhan@Sun.COM  */
19010673SKrishnendu.Sadhukhan@Sun.COM int
main(int argc,char * argv[])19110673SKrishnendu.Sadhukhan@Sun.COM main(int argc, char *argv[])
19210673SKrishnendu.Sadhukhan@Sun.COM {
193*11789SKrishnendu.Sadhukhan@Sun.COM 	const char *opt_string = "t:o:k:hf:l:c:s:";
19410673SKrishnendu.Sadhukhan@Sun.COM 	struct option const longopts[] = {
19510673SKrishnendu.Sadhukhan@Sun.COM 		{"interval", required_argument, NULL, 't'},
19610673SKrishnendu.Sadhukhan@Sun.COM 		{"output-log-file", required_argument, NULL, 'o'},
19710673SKrishnendu.Sadhukhan@Sun.COM 		{"kernel-log-level", required_argument, NULL, 'k'},
19810673SKrishnendu.Sadhukhan@Sun.COM 		{"help", no_argument, NULL, 'h'},
19910673SKrishnendu.Sadhukhan@Sun.COM 		{"feature", required_argument, NULL, 'f'},
20010673SKrishnendu.Sadhukhan@Sun.COM 		{"log-period", required_argument, NULL, 'l'},
20110673SKrishnendu.Sadhukhan@Sun.COM 		{"config", required_argument, NULL, 'c'},
202*11789SKrishnendu.Sadhukhan@Sun.COM 		{"select", required_argument, NULL, 's'},
20310673SKrishnendu.Sadhukhan@Sun.COM 		{NULL, 0, NULL, 0}
20410673SKrishnendu.Sadhukhan@Sun.COM 	};
20510673SKrishnendu.Sadhukhan@Sun.COM 
20610673SKrishnendu.Sadhukhan@Sun.COM 	int optc;
20710673SKrishnendu.Sadhukhan@Sun.COM 	int longind = 0;
20810673SKrishnendu.Sadhukhan@Sun.COM 	int running = 1;
20910673SKrishnendu.Sadhukhan@Sun.COM 	int unknown_option = FALSE;
21010673SKrishnendu.Sadhukhan@Sun.COM 	int refresh_interval = 5;
21110673SKrishnendu.Sadhukhan@Sun.COM 	int klog_level = 0;
21210673SKrishnendu.Sadhukhan@Sun.COM 	int log_interval = 0;
21310673SKrishnendu.Sadhukhan@Sun.COM 	long long last_logged = 0;
21410673SKrishnendu.Sadhukhan@Sun.COM 	char *token = NULL;
21510673SKrishnendu.Sadhukhan@Sun.COM 	int retval = 0;
21610673SKrishnendu.Sadhukhan@Sun.COM 	int gpipe;
21710673SKrishnendu.Sadhukhan@Sun.COM 	int err;
21810673SKrishnendu.Sadhukhan@Sun.COM 	uint64_t collect_end;
21910673SKrishnendu.Sadhukhan@Sun.COM 	uint64_t current_time;
22010673SKrishnendu.Sadhukhan@Sun.COM 	uint64_t delta_time;
22110673SKrishnendu.Sadhukhan@Sun.COM 	char logfile[PATH_MAX] = "";
222*11789SKrishnendu.Sadhukhan@Sun.COM 	int select_id;
223*11789SKrishnendu.Sadhukhan@Sun.COM 	int select_value;
224*11789SKrishnendu.Sadhukhan@Sun.COM 	char *select_str;
22510883SKrishnendu.Sadhukhan@Sun.COM 	boolean_t no_dtrace_cleanup = B_TRUE;
22610673SKrishnendu.Sadhukhan@Sun.COM 
22710673SKrishnendu.Sadhukhan@Sun.COM 	lt_gpipe_init();
22810673SKrishnendu.Sadhukhan@Sun.COM 	(void) signal(SIGINT, signal_handler);
22910673SKrishnendu.Sadhukhan@Sun.COM 	(void) signal(SIGTERM, signal_handler);
23010673SKrishnendu.Sadhukhan@Sun.COM 
23110673SKrishnendu.Sadhukhan@Sun.COM 	/* Default global settings */
23210673SKrishnendu.Sadhukhan@Sun.COM 	g_config.lt_cfg_enable_filter = 0;
23310673SKrishnendu.Sadhukhan@Sun.COM 	g_config.lt_cfg_trace_sched = 0;
23410673SKrishnendu.Sadhukhan@Sun.COM 	g_config.lt_cfg_trace_syncobj = 1;
23510673SKrishnendu.Sadhukhan@Sun.COM 	g_config.lt_cfg_low_overhead_mode = 0;
236*11789SKrishnendu.Sadhukhan@Sun.COM 	g_config.lt_cfg_trace_pid = 0;
237*11789SKrishnendu.Sadhukhan@Sun.COM 	g_config.lt_cfg_trace_pgid = 0;
23810673SKrishnendu.Sadhukhan@Sun.COM 	/* dtrace snapshot every 1 second */
23910673SKrishnendu.Sadhukhan@Sun.COM 	g_config.lt_cfg_snap_interval = 1000;
24010673SKrishnendu.Sadhukhan@Sun.COM #ifdef EMBED_CONFIGS
24110673SKrishnendu.Sadhukhan@Sun.COM 	g_config.lt_cfg_config_name = NULL;
24210673SKrishnendu.Sadhukhan@Sun.COM #else
24310673SKrishnendu.Sadhukhan@Sun.COM 	g_config.lt_cfg_config_name = lt_strdup(DEFAULT_CONFIG_NAME);
24410673SKrishnendu.Sadhukhan@Sun.COM #endif
24510673SKrishnendu.Sadhukhan@Sun.COM 
24610673SKrishnendu.Sadhukhan@Sun.COM 	/* Parse command line arguments. */
24710673SKrishnendu.Sadhukhan@Sun.COM 	while ((optc = getopt_long(argc, argv, opt_string,
24810673SKrishnendu.Sadhukhan@Sun.COM 	    longopts, &longind)) != -1) {
24910673SKrishnendu.Sadhukhan@Sun.COM 		switch (optc) {
25010673SKrishnendu.Sadhukhan@Sun.COM 		case 'h':
25110673SKrishnendu.Sadhukhan@Sun.COM 			print_usage(argv[0], TRUE);
25210673SKrishnendu.Sadhukhan@Sun.COM 			goto end_none;
25310673SKrishnendu.Sadhukhan@Sun.COM 		case 't':
25410673SKrishnendu.Sadhukhan@Sun.COM 			if (to_int(optarg, &refresh_interval) != 0 ||
25510673SKrishnendu.Sadhukhan@Sun.COM 			    refresh_interval < 1 || refresh_interval > 60) {
25610673SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
25710673SKrishnendu.Sadhukhan@Sun.COM 				    "Invalid refresh interval: %s\n", optarg);
25810673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
25910673SKrishnendu.Sadhukhan@Sun.COM 			} else if (check_opt_dup(LT_CMDOPT_INTERVAL,
26010673SKrishnendu.Sadhukhan@Sun.COM 			    refresh_interval)) {
26110673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
26210673SKrishnendu.Sadhukhan@Sun.COM 			}
26310673SKrishnendu.Sadhukhan@Sun.COM 
26410673SKrishnendu.Sadhukhan@Sun.COM 			break;
26510673SKrishnendu.Sadhukhan@Sun.COM 		case 'k':
26610673SKrishnendu.Sadhukhan@Sun.COM 			if (to_int(optarg, &klog_level) != 0 ||
26710673SKrishnendu.Sadhukhan@Sun.COM 			    lt_klog_set_log_level(klog_level) != 0) {
26810673SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
26910673SKrishnendu.Sadhukhan@Sun.COM 				    "Invalid log level: %s\n", optarg);
27010673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
27110673SKrishnendu.Sadhukhan@Sun.COM 			} else if (check_opt_dup(LT_CMDOPT_LOG_LEVEL,
27210673SKrishnendu.Sadhukhan@Sun.COM 			    refresh_interval)) {
27310673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
27410673SKrishnendu.Sadhukhan@Sun.COM 			}
27510673SKrishnendu.Sadhukhan@Sun.COM 
27610673SKrishnendu.Sadhukhan@Sun.COM 			break;
27710673SKrishnendu.Sadhukhan@Sun.COM 		case 'o':
27810673SKrishnendu.Sadhukhan@Sun.COM 			if (check_opt_dup(LT_CMDOPT_LOG_FILE, optind)) {
27910673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
28010673SKrishnendu.Sadhukhan@Sun.COM 			} else if (strlen(optarg) >= sizeof (logfile)) {
28110673SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
28210673SKrishnendu.Sadhukhan@Sun.COM 				    "Log file name is too long: %s\n",
28310673SKrishnendu.Sadhukhan@Sun.COM 				    optarg);
28410673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
28510673SKrishnendu.Sadhukhan@Sun.COM 			} else {
28610673SKrishnendu.Sadhukhan@Sun.COM 				(void) strncpy(logfile, optarg,
28710673SKrishnendu.Sadhukhan@Sun.COM 				    sizeof (logfile));
28810673SKrishnendu.Sadhukhan@Sun.COM 			}
28910673SKrishnendu.Sadhukhan@Sun.COM 
29010673SKrishnendu.Sadhukhan@Sun.COM 			break;
29110673SKrishnendu.Sadhukhan@Sun.COM 		case 'f':
29210673SKrishnendu.Sadhukhan@Sun.COM 			for (token = strtok(optarg, ","); token != NULL;
29310673SKrishnendu.Sadhukhan@Sun.COM 			    token = strtok(NULL, ",")) {
29410673SKrishnendu.Sadhukhan@Sun.COM 				int v = TRUE;
29510673SKrishnendu.Sadhukhan@Sun.COM 
29610673SKrishnendu.Sadhukhan@Sun.COM 				if (strncmp(token, "no", 2) == 0) {
29710673SKrishnendu.Sadhukhan@Sun.COM 					v = FALSE;
29810673SKrishnendu.Sadhukhan@Sun.COM 					token = &token[2];
29910673SKrishnendu.Sadhukhan@Sun.COM 				}
30010673SKrishnendu.Sadhukhan@Sun.COM 
30110673SKrishnendu.Sadhukhan@Sun.COM 				if (CMPOPT(token, "filter") == 0) {
30210673SKrishnendu.Sadhukhan@Sun.COM 					if (check_opt_dup(LT_CMDOPT_F_FILTER,
30310673SKrishnendu.Sadhukhan@Sun.COM 					    v)) {
30410673SKrishnendu.Sadhukhan@Sun.COM 						unknown_option = TRUE;
30510673SKrishnendu.Sadhukhan@Sun.COM 					} else {
30610673SKrishnendu.Sadhukhan@Sun.COM 						g_config.lt_cfg_enable_filter
30710673SKrishnendu.Sadhukhan@Sun.COM 						    = v;
30810673SKrishnendu.Sadhukhan@Sun.COM 					}
30910673SKrishnendu.Sadhukhan@Sun.COM 				} else if (CMPOPT(token, "sched") == 0) {
31010673SKrishnendu.Sadhukhan@Sun.COM 					if (check_opt_dup(LT_CMDOPT_F_SCHED,
31110673SKrishnendu.Sadhukhan@Sun.COM 					    v)) {
31210673SKrishnendu.Sadhukhan@Sun.COM 						unknown_option = TRUE;
31310673SKrishnendu.Sadhukhan@Sun.COM 					} else {
31410673SKrishnendu.Sadhukhan@Sun.COM 						g_config.lt_cfg_trace_sched
31510673SKrishnendu.Sadhukhan@Sun.COM 						    = v;
31610673SKrishnendu.Sadhukhan@Sun.COM 					}
31710673SKrishnendu.Sadhukhan@Sun.COM 				} else if (CMPOPT(token, "sobj") == 0) {
31810673SKrishnendu.Sadhukhan@Sun.COM 					if (check_opt_dup(LT_CMDOPT_F_SOBJ,
31910673SKrishnendu.Sadhukhan@Sun.COM 					    v)) {
32010673SKrishnendu.Sadhukhan@Sun.COM 						unknown_option = TRUE;
32110673SKrishnendu.Sadhukhan@Sun.COM 					} else {
32210673SKrishnendu.Sadhukhan@Sun.COM 						g_config.lt_cfg_trace_syncobj
32310673SKrishnendu.Sadhukhan@Sun.COM 						    = v;
32410673SKrishnendu.Sadhukhan@Sun.COM 					}
32510673SKrishnendu.Sadhukhan@Sun.COM 				} else if (CMPOPT(token, "low") == 0) {
32610673SKrishnendu.Sadhukhan@Sun.COM 					if (check_opt_dup(LT_CMDOPT_F_LOW,
32710673SKrishnendu.Sadhukhan@Sun.COM 					    v)) {
32810673SKrishnendu.Sadhukhan@Sun.COM 						unknown_option = TRUE;
32910673SKrishnendu.Sadhukhan@Sun.COM 					} else {
33010673SKrishnendu.Sadhukhan@Sun.COM 						g_config.
33110673SKrishnendu.Sadhukhan@Sun.COM 						    lt_cfg_low_overhead_mode
33210673SKrishnendu.Sadhukhan@Sun.COM 						    = v;
33310673SKrishnendu.Sadhukhan@Sun.COM 					}
33410673SKrishnendu.Sadhukhan@Sun.COM 				} else {
33510673SKrishnendu.Sadhukhan@Sun.COM 					lt_display_error(
33610673SKrishnendu.Sadhukhan@Sun.COM 					    "Unknown feature: %s\n", token);
33710673SKrishnendu.Sadhukhan@Sun.COM 					unknown_option = TRUE;
33810673SKrishnendu.Sadhukhan@Sun.COM 				}
33910673SKrishnendu.Sadhukhan@Sun.COM 			}
34010673SKrishnendu.Sadhukhan@Sun.COM 
34110673SKrishnendu.Sadhukhan@Sun.COM 			break;
34210673SKrishnendu.Sadhukhan@Sun.COM 		case 'l':
34310673SKrishnendu.Sadhukhan@Sun.COM 			if (to_int(optarg, &log_interval) != 0 ||
34410673SKrishnendu.Sadhukhan@Sun.COM 			    log_interval < 60) {
34510673SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
34610673SKrishnendu.Sadhukhan@Sun.COM 				    "Invalid log interval: %s\n", optarg);
34710673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
34810673SKrishnendu.Sadhukhan@Sun.COM 			} else if (check_opt_dup(LT_CMDOPT_LOG_INTERVAL,
34910673SKrishnendu.Sadhukhan@Sun.COM 			    log_interval)) {
35010673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
35110673SKrishnendu.Sadhukhan@Sun.COM 			}
35210673SKrishnendu.Sadhukhan@Sun.COM 
35310673SKrishnendu.Sadhukhan@Sun.COM 			break;
35410673SKrishnendu.Sadhukhan@Sun.COM 		case 'c':
35510673SKrishnendu.Sadhukhan@Sun.COM 			if (strlen(optarg) >= PATH_MAX) {
35610673SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
35710673SKrishnendu.Sadhukhan@Sun.COM 				    "Configuration name is too long.\n");
35810673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
35910673SKrishnendu.Sadhukhan@Sun.COM 			} else if (check_opt_dup(LT_CMDOPT_CONFIG_FILE,
36010673SKrishnendu.Sadhukhan@Sun.COM 			    optind)) {
36110673SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
36210673SKrishnendu.Sadhukhan@Sun.COM 			} else {
36310673SKrishnendu.Sadhukhan@Sun.COM 				g_config.lt_cfg_config_name =
36410673SKrishnendu.Sadhukhan@Sun.COM 				    lt_strdup(optarg);
36510673SKrishnendu.Sadhukhan@Sun.COM 			}
36610673SKrishnendu.Sadhukhan@Sun.COM 
36710673SKrishnendu.Sadhukhan@Sun.COM 			break;
368*11789SKrishnendu.Sadhukhan@Sun.COM 		case 's':
369*11789SKrishnendu.Sadhukhan@Sun.COM 			if (strncmp(optarg, "pid=", 4) == 0) {
370*11789SKrishnendu.Sadhukhan@Sun.COM 				select_id = 0;
371*11789SKrishnendu.Sadhukhan@Sun.COM 				select_str = &optarg[4];
372*11789SKrishnendu.Sadhukhan@Sun.COM 			} else if (strncmp(optarg, "pgid=", 5) == 0) {
373*11789SKrishnendu.Sadhukhan@Sun.COM 				select_id = 1;
374*11789SKrishnendu.Sadhukhan@Sun.COM 				select_str = &optarg[5];
375*11789SKrishnendu.Sadhukhan@Sun.COM 			} else {
376*11789SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
377*11789SKrishnendu.Sadhukhan@Sun.COM 				    "Invalid select option: %s\n", optarg);
378*11789SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
379*11789SKrishnendu.Sadhukhan@Sun.COM 				break;
380*11789SKrishnendu.Sadhukhan@Sun.COM 			}
381*11789SKrishnendu.Sadhukhan@Sun.COM 
382*11789SKrishnendu.Sadhukhan@Sun.COM 			if (to_int(select_str, &select_value) != 0) {
383*11789SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
384*11789SKrishnendu.Sadhukhan@Sun.COM 				    "Invalid select option: %s\n", optarg);
385*11789SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
386*11789SKrishnendu.Sadhukhan@Sun.COM 				break;
387*11789SKrishnendu.Sadhukhan@Sun.COM 			}
388*11789SKrishnendu.Sadhukhan@Sun.COM 
389*11789SKrishnendu.Sadhukhan@Sun.COM 			if (select_value <= 0) {
390*11789SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
391*11789SKrishnendu.Sadhukhan@Sun.COM 				    "Process/process group ID must be "
392*11789SKrishnendu.Sadhukhan@Sun.COM 				    "greater than 0: %s\n", optarg);
393*11789SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
394*11789SKrishnendu.Sadhukhan@Sun.COM 				break;
395*11789SKrishnendu.Sadhukhan@Sun.COM 			}
396*11789SKrishnendu.Sadhukhan@Sun.COM 
397*11789SKrishnendu.Sadhukhan@Sun.COM 			if (check_opt_dup(LT_CMDOPT_SELECT,
398*11789SKrishnendu.Sadhukhan@Sun.COM 			    (((uint64_t)select_id) << 32) | select_value)) {
399*11789SKrishnendu.Sadhukhan@Sun.COM 				unknown_option = TRUE;
400*11789SKrishnendu.Sadhukhan@Sun.COM 				break;
401*11789SKrishnendu.Sadhukhan@Sun.COM 			}
402*11789SKrishnendu.Sadhukhan@Sun.COM 
403*11789SKrishnendu.Sadhukhan@Sun.COM 			if (select_id == 0) {
404*11789SKrishnendu.Sadhukhan@Sun.COM 				g_config.lt_cfg_trace_pid = select_value;
405*11789SKrishnendu.Sadhukhan@Sun.COM 			} else {
406*11789SKrishnendu.Sadhukhan@Sun.COM 				g_config.lt_cfg_trace_pgid = select_value;
407*11789SKrishnendu.Sadhukhan@Sun.COM 			}
408*11789SKrishnendu.Sadhukhan@Sun.COM 			break;
40910673SKrishnendu.Sadhukhan@Sun.COM 		default:
41010673SKrishnendu.Sadhukhan@Sun.COM 			unknown_option = TRUE;
41110673SKrishnendu.Sadhukhan@Sun.COM 			break;
41210673SKrishnendu.Sadhukhan@Sun.COM 		}
41310673SKrishnendu.Sadhukhan@Sun.COM 	}
41410673SKrishnendu.Sadhukhan@Sun.COM 
41510673SKrishnendu.Sadhukhan@Sun.COM 	if (!unknown_option && strlen(logfile) > 0) {
41610673SKrishnendu.Sadhukhan@Sun.COM 		err = lt_klog_set_log_file(logfile);
41710673SKrishnendu.Sadhukhan@Sun.COM 
41810673SKrishnendu.Sadhukhan@Sun.COM 		if (err == -1) {
41910673SKrishnendu.Sadhukhan@Sun.COM 			lt_display_error("Log file name is too long: %s\n",
42010673SKrishnendu.Sadhukhan@Sun.COM 			    logfile);
42110673SKrishnendu.Sadhukhan@Sun.COM 			unknown_option = TRUE;
42210673SKrishnendu.Sadhukhan@Sun.COM 		} else if (err == -2) {
42310673SKrishnendu.Sadhukhan@Sun.COM 			lt_display_error("Cannot write to log file: %s\n",
42410673SKrishnendu.Sadhukhan@Sun.COM 			    logfile);
42510673SKrishnendu.Sadhukhan@Sun.COM 			unknown_option = TRUE;
42610673SKrishnendu.Sadhukhan@Sun.COM 		}
42710673SKrishnendu.Sadhukhan@Sun.COM 	}
42810673SKrishnendu.Sadhukhan@Sun.COM 
42910673SKrishnendu.Sadhukhan@Sun.COM 	/* Throw error for invalid/junk arguments */
43010673SKrishnendu.Sadhukhan@Sun.COM 	if (optind  < argc) {
43110673SKrishnendu.Sadhukhan@Sun.COM 		int tmpind = optind;
43210673SKrishnendu.Sadhukhan@Sun.COM 		(void) fprintf(stderr, "Unknown option(s): ");
43310673SKrishnendu.Sadhukhan@Sun.COM 
43410673SKrishnendu.Sadhukhan@Sun.COM 		while (tmpind < argc) {
43510673SKrishnendu.Sadhukhan@Sun.COM 			(void) fprintf(stderr, "%s ", argv[tmpind++]);
43610673SKrishnendu.Sadhukhan@Sun.COM 		}
43710673SKrishnendu.Sadhukhan@Sun.COM 
43810673SKrishnendu.Sadhukhan@Sun.COM 		(void) fprintf(stderr, "\n");
43910673SKrishnendu.Sadhukhan@Sun.COM 		unknown_option = TRUE;
44010673SKrishnendu.Sadhukhan@Sun.COM 	}
44110673SKrishnendu.Sadhukhan@Sun.COM 
44210673SKrishnendu.Sadhukhan@Sun.COM 	if (unknown_option) {
44310673SKrishnendu.Sadhukhan@Sun.COM 		print_usage(argv[0], FALSE);
44410673SKrishnendu.Sadhukhan@Sun.COM 		retval = 1;
44510673SKrishnendu.Sadhukhan@Sun.COM 		goto end_none;
44610673SKrishnendu.Sadhukhan@Sun.COM 	}
44710673SKrishnendu.Sadhukhan@Sun.COM 
44810673SKrishnendu.Sadhukhan@Sun.COM 	(void) printf("%s\n%s\n", TITLE, COPYRIGHT);
44910673SKrishnendu.Sadhukhan@Sun.COM 
45010673SKrishnendu.Sadhukhan@Sun.COM 	/*
45110673SKrishnendu.Sadhukhan@Sun.COM 	 * Initialization
45210673SKrishnendu.Sadhukhan@Sun.COM 	 */
45310673SKrishnendu.Sadhukhan@Sun.COM 	lt_klog_init();
45410673SKrishnendu.Sadhukhan@Sun.COM 
45510673SKrishnendu.Sadhukhan@Sun.COM 	if (lt_table_init() != 0) {
45610673SKrishnendu.Sadhukhan@Sun.COM 		lt_display_error("Unable to load configuration table.\n");
45710673SKrishnendu.Sadhukhan@Sun.COM 		retval = 1;
45810673SKrishnendu.Sadhukhan@Sun.COM 		goto end_notable;
45910673SKrishnendu.Sadhukhan@Sun.COM 	}
46010673SKrishnendu.Sadhukhan@Sun.COM 
46110673SKrishnendu.Sadhukhan@Sun.COM 	if (lt_dtrace_init() != 0) {
46210673SKrishnendu.Sadhukhan@Sun.COM 		lt_display_error("Unable to initialize dtrace.\n");
46310673SKrishnendu.Sadhukhan@Sun.COM 		retval = 1;
46410673SKrishnendu.Sadhukhan@Sun.COM 		goto end_nodtrace;
46510673SKrishnendu.Sadhukhan@Sun.COM 	}
46610673SKrishnendu.Sadhukhan@Sun.COM 
46710673SKrishnendu.Sadhukhan@Sun.COM 	last_logged = lt_millisecond();
46810673SKrishnendu.Sadhukhan@Sun.COM 
46910673SKrishnendu.Sadhukhan@Sun.COM 	(void) printf("Collecting data for %d seconds...\n",
47010673SKrishnendu.Sadhukhan@Sun.COM 	    refresh_interval);
47110673SKrishnendu.Sadhukhan@Sun.COM 
47210673SKrishnendu.Sadhukhan@Sun.COM 	gpipe = lt_gpipe_readfd();
47310673SKrishnendu.Sadhukhan@Sun.COM 	collect_end = last_logged + refresh_interval * 1000;
47410673SKrishnendu.Sadhukhan@Sun.COM 	for (;;) {
47510673SKrishnendu.Sadhukhan@Sun.COM 		fd_set read_fd;
47610673SKrishnendu.Sadhukhan@Sun.COM 		struct timeval timeout;
47710673SKrishnendu.Sadhukhan@Sun.COM 		int tsleep = collect_end - lt_millisecond();
47810673SKrishnendu.Sadhukhan@Sun.COM 
47910673SKrishnendu.Sadhukhan@Sun.COM 		if (tsleep <= 0) {
48010673SKrishnendu.Sadhukhan@Sun.COM 			break;
48110673SKrishnendu.Sadhukhan@Sun.COM 		}
48210673SKrishnendu.Sadhukhan@Sun.COM 
48310883SKrishnendu.Sadhukhan@Sun.COM 		/*
484*11789SKrishnendu.Sadhukhan@Sun.COM 		 * Interval when we call dtrace_status() and collect
48510883SKrishnendu.Sadhukhan@Sun.COM 		 * aggregated data.
48610883SKrishnendu.Sadhukhan@Sun.COM 		 */
48710883SKrishnendu.Sadhukhan@Sun.COM 		if (tsleep > g_config.lt_cfg_snap_interval) {
48810883SKrishnendu.Sadhukhan@Sun.COM 			tsleep = g_config.lt_cfg_snap_interval;
48910673SKrishnendu.Sadhukhan@Sun.COM 		}
49010673SKrishnendu.Sadhukhan@Sun.COM 
49110673SKrishnendu.Sadhukhan@Sun.COM 		timeout.tv_sec = tsleep / 1000;
49210673SKrishnendu.Sadhukhan@Sun.COM 		timeout.tv_usec = (tsleep % 1000) * 1000;
49310673SKrishnendu.Sadhukhan@Sun.COM 
49410673SKrishnendu.Sadhukhan@Sun.COM 		FD_ZERO(&read_fd);
49510673SKrishnendu.Sadhukhan@Sun.COM 		FD_SET(gpipe, &read_fd);
49610673SKrishnendu.Sadhukhan@Sun.COM 
49710673SKrishnendu.Sadhukhan@Sun.COM 		if (select(gpipe + 1, &read_fd, NULL, NULL, &timeout) > 0) {
49810673SKrishnendu.Sadhukhan@Sun.COM 			goto end_ubreak;
49910673SKrishnendu.Sadhukhan@Sun.COM 		}
50010673SKrishnendu.Sadhukhan@Sun.COM 
50110673SKrishnendu.Sadhukhan@Sun.COM 		(void) lt_dtrace_work(0);
50210673SKrishnendu.Sadhukhan@Sun.COM 	}
50310673SKrishnendu.Sadhukhan@Sun.COM 
50410673SKrishnendu.Sadhukhan@Sun.COM 	lt_display_init();
50510673SKrishnendu.Sadhukhan@Sun.COM 
50610673SKrishnendu.Sadhukhan@Sun.COM 	do {
50710673SKrishnendu.Sadhukhan@Sun.COM 		current_time = lt_millisecond();
50810673SKrishnendu.Sadhukhan@Sun.COM 
50910673SKrishnendu.Sadhukhan@Sun.COM 		lt_stat_clear_all();
51010673SKrishnendu.Sadhukhan@Sun.COM 		(void) lt_dtrace_collect();
51110673SKrishnendu.Sadhukhan@Sun.COM 
51210673SKrishnendu.Sadhukhan@Sun.COM 		delta_time = current_time;
51310673SKrishnendu.Sadhukhan@Sun.COM 		current_time = lt_millisecond();
51410673SKrishnendu.Sadhukhan@Sun.COM 		delta_time = current_time - delta_time;
51510673SKrishnendu.Sadhukhan@Sun.COM 
51610673SKrishnendu.Sadhukhan@Sun.COM 		if (log_interval > 0 &&
51710673SKrishnendu.Sadhukhan@Sun.COM 		    current_time - last_logged > log_interval * 1000) {
51810673SKrishnendu.Sadhukhan@Sun.COM 			lt_klog_write();
51910673SKrishnendu.Sadhukhan@Sun.COM 			last_logged = current_time;
52010673SKrishnendu.Sadhukhan@Sun.COM 		}
52110673SKrishnendu.Sadhukhan@Sun.COM 
52210673SKrishnendu.Sadhukhan@Sun.COM 		running = lt_display_loop(refresh_interval * 1000 -
52310673SKrishnendu.Sadhukhan@Sun.COM 		    delta_time);
52410883SKrishnendu.Sadhukhan@Sun.COM 
52510883SKrishnendu.Sadhukhan@Sun.COM 		/*
52610883SKrishnendu.Sadhukhan@Sun.COM 		 * This is to avoid dynamic variable drop
52710883SKrishnendu.Sadhukhan@Sun.COM 		 * in DTrace.
52810883SKrishnendu.Sadhukhan@Sun.COM 		 */
52910883SKrishnendu.Sadhukhan@Sun.COM 		if (lt_drop_detected == B_TRUE) {
53010883SKrishnendu.Sadhukhan@Sun.COM 			if (lt_dtrace_deinit() != 0) {
53110883SKrishnendu.Sadhukhan@Sun.COM 				no_dtrace_cleanup = B_FALSE;
53210883SKrishnendu.Sadhukhan@Sun.COM 				retval = 1;
53310883SKrishnendu.Sadhukhan@Sun.COM 				break;
53410883SKrishnendu.Sadhukhan@Sun.COM 			}
53510883SKrishnendu.Sadhukhan@Sun.COM 
53610883SKrishnendu.Sadhukhan@Sun.COM 			lt_drop_detected = B_FALSE;
53710883SKrishnendu.Sadhukhan@Sun.COM 			if (lt_dtrace_init() != 0) {
53810883SKrishnendu.Sadhukhan@Sun.COM 				retval = 1;
53910883SKrishnendu.Sadhukhan@Sun.COM 				break;
54010883SKrishnendu.Sadhukhan@Sun.COM 			}
54110883SKrishnendu.Sadhukhan@Sun.COM 		}
54210673SKrishnendu.Sadhukhan@Sun.COM 	} while (running != 0);
54310673SKrishnendu.Sadhukhan@Sun.COM 
54410673SKrishnendu.Sadhukhan@Sun.COM 	lt_klog_write();
54510673SKrishnendu.Sadhukhan@Sun.COM 
54610673SKrishnendu.Sadhukhan@Sun.COM 	/* Cleanup */
54710673SKrishnendu.Sadhukhan@Sun.COM 	lt_display_deinit();
54810673SKrishnendu.Sadhukhan@Sun.COM 
54910673SKrishnendu.Sadhukhan@Sun.COM end_ubreak:
55010883SKrishnendu.Sadhukhan@Sun.COM 	if (no_dtrace_cleanup == B_FALSE || lt_dtrace_deinit() != 0)
55110883SKrishnendu.Sadhukhan@Sun.COM 		retval = 1;
55210883SKrishnendu.Sadhukhan@Sun.COM 
55310673SKrishnendu.Sadhukhan@Sun.COM 	lt_stat_free_all();
55410673SKrishnendu.Sadhukhan@Sun.COM 
55510673SKrishnendu.Sadhukhan@Sun.COM end_nodtrace:
55610673SKrishnendu.Sadhukhan@Sun.COM 	lt_table_deinit();
55710673SKrishnendu.Sadhukhan@Sun.COM 
55810673SKrishnendu.Sadhukhan@Sun.COM end_notable:
55910673SKrishnendu.Sadhukhan@Sun.COM 	lt_klog_deinit();
56010673SKrishnendu.Sadhukhan@Sun.COM 
56110673SKrishnendu.Sadhukhan@Sun.COM end_none:
56210673SKrishnendu.Sadhukhan@Sun.COM 	lt_gpipe_deinit();
56310673SKrishnendu.Sadhukhan@Sun.COM 
56410673SKrishnendu.Sadhukhan@Sun.COM 	if (g_config.lt_cfg_config_name != NULL) {
56510673SKrishnendu.Sadhukhan@Sun.COM 		free(g_config.lt_cfg_config_name);
56610673SKrishnendu.Sadhukhan@Sun.COM 	}
56710673SKrishnendu.Sadhukhan@Sun.COM 
56810673SKrishnendu.Sadhukhan@Sun.COM 	return (retval);
56910673SKrishnendu.Sadhukhan@Sun.COM }
570