--- old/usr/src/cmd/latencytop/common/latencytop.c	Thu Apr 11 14:30:36 2024
+++ /dev/null	Thu Apr 11 08:00:00 2024
@@ -1,569 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 2008-2009, Intel Corporation.
- * All Rights Reserved.
- */
-
-#include <unistd.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <libgen.h>
-#include <signal.h>
-#include "latencytop.h"
-
-#define	CMPOPT(a, b)	strncmp((a), (b), sizeof (b))
-
-/*
- * This variable is used to check if "dynamic variable drop" in dtrace
- * has happened.
- */
-boolean_t lt_drop_detected = 0;
-
-lt_config_t g_config;
-
-typedef enum {
-	LT_CMDOPT_INTERVAL,
-	LT_CMDOPT_LOG_FILE,
-	LT_CMDOPT_LOG_LEVEL,
-	LT_CMDOPT_LOG_INTERVAL,
-	LT_CMDOPT_CONFIG_FILE,
-	LT_CMDOPT_F_FILTER,
-	LT_CMDOPT_F_SCHED,
-	LT_CMDOPT_F_SOBJ,
-	LT_CMDOPT_F_LOW,
-	LT_CMDOPT_SELECT,
-	LT_CMDOPT__LAST	/* Must be the last one */
-} lt_cmd_option_id_t;
-
-/*
- * Check for duplicate command line options.
- * Returns TRUE if duplicate options with different values are found,
- * returns FALSE otherwise.
- */
-static int
-check_opt_dup(lt_cmd_option_id_t id, uint64_t value) {
-
-	static int opt_set[(int)LT_CMDOPT__LAST];
-	static uint64_t opt_val[(int)LT_CMDOPT__LAST];
-
-	const char *errmsg[] = {
-		"-t is set more than once with different values.",
-		"-o is set more than once.",
-		"-k is set more than once with different values.",
-		"-l is set more than once with different values.",
-		"-c is set more than once.",
-		"-f [no]filter is set more than once with different values.",
-		"-f [no]sched is set more than once with different values.",
-		"-f [no]sobj is set more than once with different values.",
-		"-f [no]low is set more than once with different values.",
-		"-s is set more than once with different values."
-	};
-
-	g_assert(sizeof (errmsg)/sizeof (errmsg[0]) == (int)LT_CMDOPT__LAST);
-
-	if (!opt_set[(int)id]) {
-		opt_set[(int)id] = TRUE;
-		opt_val[(int)id] = value;
-		return (FALSE);
-	}
-
-	if (opt_val[(int)id] != value) {
-		(void) fprintf(stderr, "%s\n", errmsg[(int)id]);
-		return (TRUE);
-	}
-
-	return (FALSE);
-}
-
-/*
- * Print command-line help message.
- */
-static void
-print_usage(const char *execname, int long_help)
-{
-	char buffer[PATH_MAX];
-	(void) snprintf(buffer, sizeof (buffer), "%s", execname);
-
-	if (!long_help) {
-		/* Print short help to stderr. */
-		(void) fprintf(stderr, "Usage: %s [option(s)], ",
-		    basename(buffer));
-		(void) fprintf(stderr, "use '%s -h' for details.\n",
-		    basename(buffer));
-		return;
-	}
-
-	(void) printf("Usage: %s [option(s)]\n", basename(buffer));
-	(void) printf("Options:\n"
-	    "    -h, --help\n"
-	    "        Print this help.\n"
-	    "    -t, --interval TIME\n"
-	    "        Set refresh interval to TIME. "
-	    "Valid range [1...60] seconds, default = 5\n"
-	/*
-	 * Option "-c, --config FILE" is not user-visible for now.
-	 * When we have chance to properly document the format of translation
-	 * rules, we'll make it user-visible.
-	 */
-	    "    -o, --output-log-file FILE\n"
-	    "        Output kernel log to FILE. Default = "
-	    DEFAULT_KLOG_FILE "\n"
-	    "    -k, --kernel-log-level LEVEL\n"
-	    "        Set kernel log level to LEVEL.\n"
-	    "        0(default) = None, 1 = Unmapped, 2 = Mapped, 3 = All.\n"
-	    "    -f, --feature [no]feature1,[no]feature2,...\n"
-	    "        Enable/disable features in LatencyTOP.\n"
-	    "        [no]filter:\n"
-	    "        Filter large interruptible latencies, e.g. sleep.\n"
-	    "        [no]sched:\n"
-	    "        Monitors sched (PID=0).\n"
-	    "        [no]sobj:\n"
-	    "        Monitors synchronization objects.\n"
-	    "        [no]low:\n"
-	    "        Lower overhead by sampling small latencies.\n"
-	    "    -l, --log-period TIME\n"
-	    "        Write and restart log every TIME seconds, TIME >= 60\n"
-	    "    -s --select [ pid=<pid> | pgid=<pgid> ]\n"
-	    "        Monitor only the given process or processes in the "
-	    "given process group.\n");
-}
-
-/*
- * Properly exit latencytop when it receives SIGINT or SIGTERM.
- */
-/* ARGSUSED */
-static void
-signal_handler(int sig)
-{
-	lt_gpipe_break("q");
-}
-
-/*
- * Convert string to integer. It returns error if extra characters are found.
- */
-static int
-to_int(const char *str, int *result)
-{
-	char *tail = NULL;
-	long ret;
-
-	if (str == NULL || result == NULL) {
-		return (-1);
-	}
-
-	ret = strtol(str, &tail, 10);
-
-	if (tail != NULL && *tail != '\0') {
-		return (-1);
-	}
-
-	*result = (int)ret;
-
-	return (0);
-}
-
-/*
- * The main function.
- */
-int
-main(int argc, char *argv[])
-{
-	const char *opt_string = "t:o:k:hf:l:c:s:";
-	struct option const longopts[] = {
-		{"interval", required_argument, NULL, 't'},
-		{"output-log-file", required_argument, NULL, 'o'},
-		{"kernel-log-level", required_argument, NULL, 'k'},
-		{"help", no_argument, NULL, 'h'},
-		{"feature", required_argument, NULL, 'f'},
-		{"log-period", required_argument, NULL, 'l'},
-		{"config", required_argument, NULL, 'c'},
-		{"select", required_argument, NULL, 's'},
-		{NULL, 0, NULL, 0}
-	};
-
-	int optc;
-	int longind = 0;
-	int running = 1;
-	int unknown_option = FALSE;
-	int refresh_interval = 5;
-	int klog_level = 0;
-	int log_interval = 0;
-	long long last_logged = 0;
-	char *token = NULL;
-	int retval = 0;
-	int gpipe;
-	int err;
-	uint64_t collect_end;
-	uint64_t current_time;
-	uint64_t delta_time;
-	char logfile[PATH_MAX] = "";
-	int select_id;
-	int select_value;
-	char *select_str;
-	boolean_t no_dtrace_cleanup = B_TRUE;
-
-	lt_gpipe_init();
-	(void) signal(SIGINT, signal_handler);
-	(void) signal(SIGTERM, signal_handler);
-
-	/* Default global settings */
-	g_config.lt_cfg_enable_filter = 0;
-	g_config.lt_cfg_trace_sched = 0;
-	g_config.lt_cfg_trace_syncobj = 1;
-	g_config.lt_cfg_low_overhead_mode = 0;
-	g_config.lt_cfg_trace_pid = 0;
-	g_config.lt_cfg_trace_pgid = 0;
-	/* dtrace snapshot every 1 second */
-	g_config.lt_cfg_snap_interval = 1000;
-#ifdef EMBED_CONFIGS
-	g_config.lt_cfg_config_name = NULL;
-#else
-	g_config.lt_cfg_config_name = lt_strdup(DEFAULT_CONFIG_NAME);
-#endif
-
-	/* Parse command line arguments. */
-	while ((optc = getopt_long(argc, argv, opt_string,
-	    longopts, &longind)) != -1) {
-		switch (optc) {
-		case 'h':
-			print_usage(argv[0], TRUE);
-			goto end_none;
-		case 't':
-			if (to_int(optarg, &refresh_interval) != 0 ||
-			    refresh_interval < 1 || refresh_interval > 60) {
-				lt_display_error(
-				    "Invalid refresh interval: %s\n", optarg);
-				unknown_option = TRUE;
-			} else if (check_opt_dup(LT_CMDOPT_INTERVAL,
-			    refresh_interval)) {
-				unknown_option = TRUE;
-			}
-
-			break;
-		case 'k':
-			if (to_int(optarg, &klog_level) != 0 ||
-			    lt_klog_set_log_level(klog_level) != 0) {
-				lt_display_error(
-				    "Invalid log level: %s\n", optarg);
-				unknown_option = TRUE;
-			} else if (check_opt_dup(LT_CMDOPT_LOG_LEVEL,
-			    refresh_interval)) {
-				unknown_option = TRUE;
-			}
-
-			break;
-		case 'o':
-			if (check_opt_dup(LT_CMDOPT_LOG_FILE, optind)) {
-				unknown_option = TRUE;
-			} else if (strlen(optarg) >= sizeof (logfile)) {
-				lt_display_error(
-				    "Log file name is too long: %s\n",
-				    optarg);
-				unknown_option = TRUE;
-			} else {
-				(void) strncpy(logfile, optarg,
-				    sizeof (logfile));
-			}
-
-			break;
-		case 'f':
-			for (token = strtok(optarg, ","); token != NULL;
-			    token = strtok(NULL, ",")) {
-				int v = TRUE;
-
-				if (strncmp(token, "no", 2) == 0) {
-					v = FALSE;
-					token = &token[2];
-				}
-
-				if (CMPOPT(token, "filter") == 0) {
-					if (check_opt_dup(LT_CMDOPT_F_FILTER,
-					    v)) {
-						unknown_option = TRUE;
-					} else {
-						g_config.lt_cfg_enable_filter
-						    = v;
-					}
-				} else if (CMPOPT(token, "sched") == 0) {
-					if (check_opt_dup(LT_CMDOPT_F_SCHED,
-					    v)) {
-						unknown_option = TRUE;
-					} else {
-						g_config.lt_cfg_trace_sched
-						    = v;
-					}
-				} else if (CMPOPT(token, "sobj") == 0) {
-					if (check_opt_dup(LT_CMDOPT_F_SOBJ,
-					    v)) {
-						unknown_option = TRUE;
-					} else {
-						g_config.lt_cfg_trace_syncobj
-						    = v;
-					}
-				} else if (CMPOPT(token, "low") == 0) {
-					if (check_opt_dup(LT_CMDOPT_F_LOW,
-					    v)) {
-						unknown_option = TRUE;
-					} else {
-						g_config.
-						    lt_cfg_low_overhead_mode
-						    = v;
-					}
-				} else {
-					lt_display_error(
-					    "Unknown feature: %s\n", token);
-					unknown_option = TRUE;
-				}
-			}
-
-			break;
-		case 'l':
-			if (to_int(optarg, &log_interval) != 0 ||
-			    log_interval < 60) {
-				lt_display_error(
-				    "Invalid log interval: %s\n", optarg);
-				unknown_option = TRUE;
-			} else if (check_opt_dup(LT_CMDOPT_LOG_INTERVAL,
-			    log_interval)) {
-				unknown_option = TRUE;
-			}
-
-			break;
-		case 'c':
-			if (strlen(optarg) >= PATH_MAX) {
-				lt_display_error(
-				    "Configuration name is too long.\n");
-				unknown_option = TRUE;
-			} else if (check_opt_dup(LT_CMDOPT_CONFIG_FILE,
-			    optind)) {
-				unknown_option = TRUE;
-			} else {
-				g_config.lt_cfg_config_name =
-				    lt_strdup(optarg);
-			}
-
-			break;
-		case 's':
-			if (strncmp(optarg, "pid=", 4) == 0) {
-				select_id = 0;
-				select_str = &optarg[4];
-			} else if (strncmp(optarg, "pgid=", 5) == 0) {
-				select_id = 1;
-				select_str = &optarg[5];
-			} else {
-				lt_display_error(
-				    "Invalid select option: %s\n", optarg);
-				unknown_option = TRUE;
-				break;
-			}
-
-			if (to_int(select_str, &select_value) != 0) {
-				lt_display_error(
-				    "Invalid select option: %s\n", optarg);
-				unknown_option = TRUE;
-				break;
-			}
-
-			if (select_value <= 0) {
-				lt_display_error(
-				    "Process/process group ID must be "
-				    "greater than 0: %s\n", optarg);
-				unknown_option = TRUE;
-				break;
-			}
-
-			if (check_opt_dup(LT_CMDOPT_SELECT,
-			    (((uint64_t)select_id) << 32) | select_value)) {
-				unknown_option = TRUE;
-				break;
-			}
-
-			if (select_id == 0) {
-				g_config.lt_cfg_trace_pid = select_value;
-			} else {
-				g_config.lt_cfg_trace_pgid = select_value;
-			}
-			break;
-		default:
-			unknown_option = TRUE;
-			break;
-		}
-	}
-
-	if (!unknown_option && strlen(logfile) > 0) {
-		err = lt_klog_set_log_file(logfile);
-
-		if (err == -1) {
-			lt_display_error("Log file name is too long: %s\n",
-			    logfile);
-			unknown_option = TRUE;
-		} else if (err == -2) {
-			lt_display_error("Cannot write to log file: %s\n",
-			    logfile);
-			unknown_option = TRUE;
-		}
-	}
-
-	/* Throw error for invalid/junk arguments */
-	if (optind  < argc) {
-		int tmpind = optind;
-		(void) fprintf(stderr, "Unknown option(s): ");
-
-		while (tmpind < argc) {
-			(void) fprintf(stderr, "%s ", argv[tmpind++]);
-		}
-
-		(void) fprintf(stderr, "\n");
-		unknown_option = TRUE;
-	}
-
-	if (unknown_option) {
-		print_usage(argv[0], FALSE);
-		retval = 1;
-		goto end_none;
-	}
-
-	(void) printf("%s\n%s\n", TITLE, COPYRIGHT);
-
-	/*
-	 * Initialization
-	 */
-	lt_klog_init();
-
-	if (lt_table_init() != 0) {
-		lt_display_error("Unable to load configuration table.\n");
-		retval = 1;
-		goto end_notable;
-	}
-
-	if (lt_dtrace_init() != 0) {
-		lt_display_error("Unable to initialize dtrace.\n");
-		retval = 1;
-		goto end_nodtrace;
-	}
-
-	last_logged = lt_millisecond();
-
-	(void) printf("Collecting data for %d seconds...\n",
-	    refresh_interval);
-
-	gpipe = lt_gpipe_readfd();
-	collect_end = last_logged + refresh_interval * 1000;
-	for (;;) {
-		fd_set read_fd;
-		struct timeval timeout;
-		int tsleep = collect_end - lt_millisecond();
-
-		if (tsleep <= 0) {
-			break;
-		}
-
-		/*
-		 * Interval when we call dtrace_status() and collect
-		 * aggregated data.
-		 */
-		if (tsleep > g_config.lt_cfg_snap_interval) {
-			tsleep = g_config.lt_cfg_snap_interval;
-		}
-
-		timeout.tv_sec = tsleep / 1000;
-		timeout.tv_usec = (tsleep % 1000) * 1000;
-
-		FD_ZERO(&read_fd);
-		FD_SET(gpipe, &read_fd);
-
-		if (select(gpipe + 1, &read_fd, NULL, NULL, &timeout) > 0) {
-			goto end_ubreak;
-		}
-
-		(void) lt_dtrace_work(0);
-	}
-
-	lt_display_init();
-
-	do {
-		current_time = lt_millisecond();
-
-		lt_stat_clear_all();
-		(void) lt_dtrace_collect();
-
-		delta_time = current_time;
-		current_time = lt_millisecond();
-		delta_time = current_time - delta_time;
-
-		if (log_interval > 0 &&
-		    current_time - last_logged > log_interval * 1000) {
-			lt_klog_write();
-			last_logged = current_time;
-		}
-
-		running = lt_display_loop(refresh_interval * 1000 -
-		    delta_time);
-
-		/*
-		 * This is to avoid dynamic variable drop
-		 * in DTrace.
-		 */
-		if (lt_drop_detected == B_TRUE) {
-			if (lt_dtrace_deinit() != 0) {
-				no_dtrace_cleanup = B_FALSE;
-				retval = 1;
-				break;
-			}
-
-			lt_drop_detected = B_FALSE;
-			if (lt_dtrace_init() != 0) {
-				retval = 1;
-				break;
-			}
-		}
-	} while (running != 0);
-
-	lt_klog_write();
-
-	/* Cleanup */
-	lt_display_deinit();
-
-end_ubreak:
-	if (no_dtrace_cleanup == B_FALSE || lt_dtrace_deinit() != 0)
-		retval = 1;
-
-	lt_stat_free_all();
-
-end_nodtrace:
-	lt_table_deinit();
-
-end_notable:
-	lt_klog_deinit();
-
-end_none:
-	lt_gpipe_deinit();
-
-	if (g_config.lt_cfg_config_name != NULL) {
-		free(g_config.lt_cfg_config_name);
-	}
-
-	return (retval);
-}
--- /dev/null	Thu Apr 11 08:00:00 2024
+++ new/usr/src/cmd/latencytop/latencytop.c	Thu Apr 11 14:30:36 2024
@@ -0,0 +1,570 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2008-2009, Intel Corporation.
+ * All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <libgen.h>
+#include <signal.h>
+#include "latencytop.h"
+
+#define	CMPOPT(a, b)	strncmp((a), (b), sizeof (b))
+
+/*
+ * This variable is used to check if "dynamic variable drop" in dtrace
+ * has happened.
+ */
+boolean_t lt_drop_detected = 0;
+
+lt_config_t g_config;
+
+typedef enum {
+	LT_CMDOPT_INTERVAL,
+	LT_CMDOPT_LOG_FILE,
+	LT_CMDOPT_LOG_LEVEL,
+	LT_CMDOPT_LOG_INTERVAL,
+	LT_CMDOPT_CONFIG_FILE,
+	LT_CMDOPT_F_FILTER,
+	LT_CMDOPT_F_SCHED,
+	LT_CMDOPT_F_SOBJ,
+	LT_CMDOPT_F_LOW,
+	LT_CMDOPT_SELECT,
+	LT_CMDOPT__LAST	/* Must be the last one */
+} lt_cmd_option_id_t;
+
+/*
+ * Check for duplicate command line options.
+ * Returns TRUE if duplicate options with different values are found,
+ * returns FALSE otherwise.
+ */
+static int
+check_opt_dup(lt_cmd_option_id_t id, uint64_t value)
+{
+
+	static int opt_set[(int)LT_CMDOPT__LAST];
+	static uint64_t opt_val[(int)LT_CMDOPT__LAST];
+
+	const char *errmsg[] = {
+		"-t is set more than once with different values.",
+		"-o is set more than once.",
+		"-k is set more than once with different values.",
+		"-l is set more than once with different values.",
+		"-c is set more than once.",
+		"-f [no]filter is set more than once with different values.",
+		"-f [no]sched is set more than once with different values.",
+		"-f [no]sobj is set more than once with different values.",
+		"-f [no]low is set more than once with different values.",
+		"-s is set more than once with different values."
+	};
+
+	g_assert(sizeof (errmsg)/sizeof (errmsg[0]) == (int)LT_CMDOPT__LAST);
+
+	if (!opt_set[(int)id]) {
+		opt_set[(int)id] = TRUE;
+		opt_val[(int)id] = value;
+		return (FALSE);
+	}
+
+	if (opt_val[(int)id] != value) {
+		(void) fprintf(stderr, "%s\n", errmsg[(int)id]);
+		return (TRUE);
+	}
+
+	return (FALSE);
+}
+
+/*
+ * Print command-line help message.
+ */
+static void
+print_usage(const char *execname, int long_help)
+{
+	char buffer[PATH_MAX];
+	(void) snprintf(buffer, sizeof (buffer), "%s", execname);
+
+	if (!long_help) {
+		/* Print short help to stderr. */
+		(void) fprintf(stderr, "Usage: %s [option(s)], ",
+		    basename(buffer));
+		(void) fprintf(stderr, "use '%s -h' for details.\n",
+		    basename(buffer));
+		return;
+	}
+
+	(void) printf("Usage: %s [option(s)]\n", basename(buffer));
+	(void) printf("Options:\n"
+	    "    -h, --help\n"
+	    "        Print this help.\n"
+	    "    -t, --interval TIME\n"
+	    "        Set refresh interval to TIME. "
+	    "Valid range [1...60] seconds, default = 5\n"
+	/*
+	 * Option "-c, --config FILE" is not user-visible for now.
+	 * When we have chance to properly document the format of translation
+	 * rules, we'll make it user-visible.
+	 */
+	    "    -o, --output-log-file FILE\n"
+	    "        Output kernel log to FILE. Default = "
+	    DEFAULT_KLOG_FILE "\n"
+	    "    -k, --kernel-log-level LEVEL\n"
+	    "        Set kernel log level to LEVEL.\n"
+	    "        0(default) = None, 1 = Unmapped, 2 = Mapped, 3 = All.\n"
+	    "    -f, --feature [no]feature1,[no]feature2,...\n"
+	    "        Enable/disable features in LatencyTOP.\n"
+	    "        [no]filter:\n"
+	    "        Filter large interruptible latencies, e.g. sleep.\n"
+	    "        [no]sched:\n"
+	    "        Monitors sched (PID=0).\n"
+	    "        [no]sobj:\n"
+	    "        Monitors synchronization objects.\n"
+	    "        [no]low:\n"
+	    "        Lower overhead by sampling small latencies.\n"
+	    "    -l, --log-period TIME\n"
+	    "        Write and restart log every TIME seconds, TIME >= 60\n"
+	    "    -s --select [ pid=<pid> | pgid=<pgid> ]\n"
+	    "        Monitor only the given process or processes in the "
+	    "given process group.\n");
+}
+
+/*
+ * Properly exit latencytop when it receives SIGINT or SIGTERM.
+ */
+/* ARGSUSED */
+static void
+signal_handler(int sig)
+{
+	lt_gpipe_break("q");
+}
+
+/*
+ * Convert string to integer. It returns error if extra characters are found.
+ */
+static int
+to_int(const char *str, int *result)
+{
+	char *tail = NULL;
+	long ret;
+
+	if (str == NULL || result == NULL) {
+		return (-1);
+	}
+
+	ret = strtol(str, &tail, 10);
+
+	if (tail != NULL && *tail != '\0') {
+		return (-1);
+	}
+
+	*result = (int)ret;
+
+	return (0);
+}
+
+/*
+ * The main function.
+ */
+int
+main(int argc, char *argv[])
+{
+	const char *opt_string = "t:o:k:hf:l:c:s:";
+	struct option const longopts[] = {
+		{"interval", required_argument, NULL, 't'},
+		{"output-log-file", required_argument, NULL, 'o'},
+		{"kernel-log-level", required_argument, NULL, 'k'},
+		{"help", no_argument, NULL, 'h'},
+		{"feature", required_argument, NULL, 'f'},
+		{"log-period", required_argument, NULL, 'l'},
+		{"config", required_argument, NULL, 'c'},
+		{"select", required_argument, NULL, 's'},
+		{NULL, 0, NULL, 0}
+	};
+
+	int optc;
+	int longind = 0;
+	int running = 1;
+	int unknown_option = FALSE;
+	int refresh_interval = 5;
+	int klog_level = 0;
+	int log_interval = 0;
+	long long last_logged = 0;
+	char *token = NULL;
+	int retval = 0;
+	int gpipe;
+	int err;
+	uint64_t collect_end;
+	uint64_t current_time;
+	uint64_t delta_time;
+	char logfile[PATH_MAX] = "";
+	int select_id;
+	int select_value;
+	char *select_str;
+	boolean_t no_dtrace_cleanup = B_TRUE;
+
+	lt_gpipe_init();
+	(void) signal(SIGINT, signal_handler);
+	(void) signal(SIGTERM, signal_handler);
+
+	/* Default global settings */
+	g_config.lt_cfg_enable_filter = 0;
+	g_config.lt_cfg_trace_sched = 0;
+	g_config.lt_cfg_trace_syncobj = 1;
+	g_config.lt_cfg_low_overhead_mode = 0;
+	g_config.lt_cfg_trace_pid = 0;
+	g_config.lt_cfg_trace_pgid = 0;
+	/* dtrace snapshot every 1 second */
+	g_config.lt_cfg_snap_interval = 1000;
+#ifdef EMBED_CONFIGS
+	g_config.lt_cfg_config_name = NULL;
+#else
+	g_config.lt_cfg_config_name = lt_strdup(DEFAULT_CONFIG_NAME);
+#endif
+
+	/* Parse command line arguments. */
+	while ((optc = getopt_long(argc, argv, opt_string,
+	    longopts, &longind)) != -1) {
+		switch (optc) {
+		case 'h':
+			print_usage(argv[0], TRUE);
+			goto end_none;
+		case 't':
+			if (to_int(optarg, &refresh_interval) != 0 ||
+			    refresh_interval < 1 || refresh_interval > 60) {
+				lt_display_error(
+				    "Invalid refresh interval: %s\n", optarg);
+				unknown_option = TRUE;
+			} else if (check_opt_dup(LT_CMDOPT_INTERVAL,
+			    refresh_interval)) {
+				unknown_option = TRUE;
+			}
+
+			break;
+		case 'k':
+			if (to_int(optarg, &klog_level) != 0 ||
+			    lt_klog_set_log_level(klog_level) != 0) {
+				lt_display_error(
+				    "Invalid log level: %s\n", optarg);
+				unknown_option = TRUE;
+			} else if (check_opt_dup(LT_CMDOPT_LOG_LEVEL,
+			    refresh_interval)) {
+				unknown_option = TRUE;
+			}
+
+			break;
+		case 'o':
+			if (check_opt_dup(LT_CMDOPT_LOG_FILE, optind)) {
+				unknown_option = TRUE;
+			} else if (strlen(optarg) >= sizeof (logfile)) {
+				lt_display_error(
+				    "Log file name is too long: %s\n",
+				    optarg);
+				unknown_option = TRUE;
+			} else {
+				(void) strncpy(logfile, optarg,
+				    sizeof (logfile));
+			}
+
+			break;
+		case 'f':
+			for (token = strtok(optarg, ","); token != NULL;
+			    token = strtok(NULL, ",")) {
+				int v = TRUE;
+
+				if (strncmp(token, "no", 2) == 0) {
+					v = FALSE;
+					token = &token[2];
+				}
+
+				if (CMPOPT(token, "filter") == 0) {
+					if (check_opt_dup(LT_CMDOPT_F_FILTER,
+					    v)) {
+						unknown_option = TRUE;
+					} else {
+						g_config.lt_cfg_enable_filter
+						    = v;
+					}
+				} else if (CMPOPT(token, "sched") == 0) {
+					if (check_opt_dup(LT_CMDOPT_F_SCHED,
+					    v)) {
+						unknown_option = TRUE;
+					} else {
+						g_config.lt_cfg_trace_sched
+						    = v;
+					}
+				} else if (CMPOPT(token, "sobj") == 0) {
+					if (check_opt_dup(LT_CMDOPT_F_SOBJ,
+					    v)) {
+						unknown_option = TRUE;
+					} else {
+						g_config.lt_cfg_trace_syncobj
+						    = v;
+					}
+				} else if (CMPOPT(token, "low") == 0) {
+					if (check_opt_dup(LT_CMDOPT_F_LOW,
+					    v)) {
+						unknown_option = TRUE;
+					} else {
+						g_config.
+						    lt_cfg_low_overhead_mode
+						    = v;
+					}
+				} else {
+					lt_display_error(
+					    "Unknown feature: %s\n", token);
+					unknown_option = TRUE;
+				}
+			}
+
+			break;
+		case 'l':
+			if (to_int(optarg, &log_interval) != 0 ||
+			    log_interval < 60) {
+				lt_display_error(
+				    "Invalid log interval: %s\n", optarg);
+				unknown_option = TRUE;
+			} else if (check_opt_dup(LT_CMDOPT_LOG_INTERVAL,
+			    log_interval)) {
+				unknown_option = TRUE;
+			}
+
+			break;
+		case 'c':
+			if (strlen(optarg) >= PATH_MAX) {
+				lt_display_error(
+				    "Configuration name is too long.\n");
+				unknown_option = TRUE;
+			} else if (check_opt_dup(LT_CMDOPT_CONFIG_FILE,
+			    optind)) {
+				unknown_option = TRUE;
+			} else {
+				g_config.lt_cfg_config_name =
+				    lt_strdup(optarg);
+			}
+
+			break;
+		case 's':
+			if (strncmp(optarg, "pid=", 4) == 0) {
+				select_id = 0;
+				select_str = &optarg[4];
+			} else if (strncmp(optarg, "pgid=", 5) == 0) {
+				select_id = 1;
+				select_str = &optarg[5];
+			} else {
+				lt_display_error(
+				    "Invalid select option: %s\n", optarg);
+				unknown_option = TRUE;
+				break;
+			}
+
+			if (to_int(select_str, &select_value) != 0) {
+				lt_display_error(
+				    "Invalid select option: %s\n", optarg);
+				unknown_option = TRUE;
+				break;
+			}
+
+			if (select_value <= 0) {
+				lt_display_error(
+				    "Process/process group ID must be "
+				    "greater than 0: %s\n", optarg);
+				unknown_option = TRUE;
+				break;
+			}
+
+			if (check_opt_dup(LT_CMDOPT_SELECT,
+			    (((uint64_t)select_id) << 32) | select_value)) {
+				unknown_option = TRUE;
+				break;
+			}
+
+			if (select_id == 0) {
+				g_config.lt_cfg_trace_pid = select_value;
+			} else {
+				g_config.lt_cfg_trace_pgid = select_value;
+			}
+			break;
+		default:
+			unknown_option = TRUE;
+			break;
+		}
+	}
+
+	if (!unknown_option && strlen(logfile) > 0) {
+		err = lt_klog_set_log_file(logfile);
+
+		if (err == -1) {
+			lt_display_error("Log file name is too long: %s\n",
+			    logfile);
+			unknown_option = TRUE;
+		} else if (err == -2) {
+			lt_display_error("Cannot write to log file: %s\n",
+			    logfile);
+			unknown_option = TRUE;
+		}
+	}
+
+	/* Throw error for invalid/junk arguments */
+	if (optind  < argc) {
+		int tmpind = optind;
+		(void) fprintf(stderr, "Unknown option(s): ");
+
+		while (tmpind < argc) {
+			(void) fprintf(stderr, "%s ", argv[tmpind++]);
+		}
+
+		(void) fprintf(stderr, "\n");
+		unknown_option = TRUE;
+	}
+
+	if (unknown_option) {
+		print_usage(argv[0], FALSE);
+		retval = 1;
+		goto end_none;
+	}
+
+	(void) printf("%s\n%s\n", TITLE, COPYRIGHT);
+
+	/*
+	 * Initialization
+	 */
+	lt_klog_init();
+
+	if (lt_table_init() != 0) {
+		lt_display_error("Unable to load configuration table.\n");
+		retval = 1;
+		goto end_notable;
+	}
+
+	if (lt_dtrace_init() != 0) {
+		lt_display_error("Unable to initialize dtrace.\n");
+		retval = 1;
+		goto end_nodtrace;
+	}
+
+	last_logged = lt_millisecond();
+
+	(void) printf("Collecting data for %d seconds...\n",
+	    refresh_interval);
+
+	gpipe = lt_gpipe_readfd();
+	collect_end = last_logged + refresh_interval * 1000;
+	for (;;) {
+		fd_set read_fd;
+		struct timeval timeout;
+		int tsleep = collect_end - lt_millisecond();
+
+		if (tsleep <= 0) {
+			break;
+		}
+
+		/*
+		 * Interval when we call dtrace_status() and collect
+		 * aggregated data.
+		 */
+		if (tsleep > g_config.lt_cfg_snap_interval) {
+			tsleep = g_config.lt_cfg_snap_interval;
+		}
+
+		timeout.tv_sec = tsleep / 1000;
+		timeout.tv_usec = (tsleep % 1000) * 1000;
+
+		FD_ZERO(&read_fd);
+		FD_SET(gpipe, &read_fd);
+
+		if (select(gpipe + 1, &read_fd, NULL, NULL, &timeout) > 0) {
+			goto end_ubreak;
+		}
+
+		(void) lt_dtrace_work(0);
+	}
+
+	lt_display_init();
+
+	do {
+		current_time = lt_millisecond();
+
+		lt_stat_clear_all();
+		(void) lt_dtrace_collect();
+
+		delta_time = current_time;
+		current_time = lt_millisecond();
+		delta_time = current_time - delta_time;
+
+		if (log_interval > 0 &&
+		    current_time - last_logged > log_interval * 1000) {
+			lt_klog_write();
+			last_logged = current_time;
+		}
+
+		running = lt_display_loop(refresh_interval * 1000 -
+		    delta_time);
+
+		/*
+		 * This is to avoid dynamic variable drop
+		 * in DTrace.
+		 */
+		if (lt_drop_detected == B_TRUE) {
+			if (lt_dtrace_deinit() != 0) {
+				no_dtrace_cleanup = B_FALSE;
+				retval = 1;
+				break;
+			}
+
+			lt_drop_detected = B_FALSE;
+			if (lt_dtrace_init() != 0) {
+				retval = 1;
+				break;
+			}
+		}
+	} while (running != 0);
+
+	lt_klog_write();
+
+	/* Cleanup */
+	lt_display_deinit();
+
+end_ubreak:
+	if (no_dtrace_cleanup == B_FALSE || lt_dtrace_deinit() != 0)
+		retval = 1;
+
+	lt_stat_free_all();
+
+end_nodtrace:
+	lt_table_deinit();
+
+end_notable:
+	lt_klog_deinit();
+
+end_none:
+	lt_gpipe_deinit();
+
+	if (g_config.lt_cfg_config_name != NULL) {
+		free(g_config.lt_cfg_config_name);
+	}
+
+	return (retval);
+}
