X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng%2Flttng.c;h=4907a43ba19595cc1b90906a59e2012088007cf8;hp=7ab1125e3240fad20a37babb74ebfdb15c6245f2;hb=ce0b1d61919f37517a6212f7af2afe0fa1b1dcb0;hpb=f0f2dce996c5b9e349bda8ea545c0653770260a8 diff --git a/src/bin/lttng/lttng.c b/src/bin/lttng/lttng.c index 7ab1125e3..4907a43ba 100644 --- a/src/bin/lttng/lttng.c +++ b/src/bin/lttng/lttng.c @@ -1,18 +1,8 @@ /* - * Copyright (c) 2011 David Goulet + * Copyright (C) 2011 David Goulet * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2 only, - * as published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _LGPL_SOURCE @@ -29,11 +19,21 @@ #include #include #include +#include #include "command.h" +#include "version.h" + +static const char *help_msg = +#ifdef LTTNG_EMBED_HELP +#include +#else +NULL +#endif +; /* Variables */ -static char *progname; +static const char *progname; int opt_no_sessiond; char *opt_sessiond_path; @@ -64,84 +64,41 @@ static struct option long_options[] = { /* First level command */ static struct cmd_struct commands[] = { - { "list", cmd_list}, - { "status", cmd_status}, + { "add-context", cmd_add_context}, { "create", cmd_create}, + { "clear", cmd_clear}, { "destroy", cmd_destroy}, - { "start", cmd_start}, - { "stop", cmd_stop}, - { "enable-event", cmd_enable_events}, + { "disable-channel", cmd_disable_channels}, { "disable-event", cmd_disable_events}, { "enable-channel", cmd_enable_channels}, - { "disable-channel", cmd_disable_channels}, - { "add-context", cmd_add_context}, + { "enable-event", cmd_enable_events}, + { "help", NULL}, + { "list", cmd_list}, + { "load", cmd_load}, + { "metadata", cmd_metadata}, + { "regenerate", cmd_regenerate}, + { "rotate", cmd_rotate}, + { "enable-rotation", cmd_enable_rotation}, + { "disable-rotation", cmd_disable_rotation}, + { "save", cmd_save}, { "set-session", cmd_set_session}, - { "version", cmd_version}, - { "calibrate", cmd_calibrate}, - { "view", cmd_view}, { "snapshot", cmd_snapshot}, - { "save", cmd_save}, - { "load", cmd_load}, + { "start", cmd_start}, + { "status", cmd_status}, + { "stop", cmd_stop}, { "track", cmd_track}, { "untrack", cmd_untrack}, - { "metadata", cmd_metadata}, + { "version", cmd_version}, + { "view", cmd_view}, { NULL, NULL} /* Array closure */ }; -static void usage(FILE *ofp) -{ - fprintf(ofp, "LTTng Trace Control " VERSION " - " VERSION_NAME "%s\n\n", - GIT_VERSION[0] == '\0' ? "" : " - " GIT_VERSION); - fprintf(ofp, "usage: lttng [OPTIONS] []\n"); - fprintf(ofp, "\n"); - fprintf(ofp, "Options:\n"); - fprintf(ofp, " -V, --version Show version\n"); - fprintf(ofp, " -h, --help Show this help\n"); - fprintf(ofp, " --list-options Simple listing of lttng options\n"); - fprintf(ofp, " --list-commands Simple listing of lttng commands\n"); - fprintf(ofp, " -v, --verbose Increase verbosity\n"); - fprintf(ofp, " -q, --quiet Quiet mode\n"); - fprintf(ofp, " -m, --mi TYPE Machine Interface mode.\n"); - fprintf(ofp, " Type: xml\n"); - fprintf(ofp, " -g, --group NAME Unix tracing group name. (default: tracing)\n"); - fprintf(ofp, " -n, --no-sessiond Don't spawn a session daemon\n"); - fprintf(ofp, " --sessiond-path PATH Session daemon full path\n"); - fprintf(ofp, " --relayd-path PATH Relayd daemon full path\n"); - fprintf(ofp, "\n"); - fprintf(ofp, "Commands:\n"); - fprintf(ofp, " add-context Add context to event and/or channel\n"); - fprintf(ofp, " calibrate Quantify LTTng overhead\n"); - fprintf(ofp, " create Create tracing session\n"); - fprintf(ofp, " destroy Tear down tracing session\n"); - fprintf(ofp, " enable-channel Enable tracing channel\n"); - fprintf(ofp, " enable-event Enable tracing event\n"); - fprintf(ofp, " disable-channel Disable tracing channel\n"); - fprintf(ofp, " disable-event Disable tracing event\n"); - fprintf(ofp, " list List possible tracing options\n"); - fprintf(ofp, " set-session Set current session name\n"); - fprintf(ofp, " snapshot Snapshot buffers of current session name\n"); - fprintf(ofp, " start Start tracing\n"); - fprintf(ofp, " status Show current session's details\n"); - fprintf(ofp, " stop Stop tracing\n"); - fprintf(ofp, " version Show version information\n"); - fprintf(ofp, " view Start trace viewer\n"); - fprintf(ofp, " save Save session configuration\n"); - fprintf(ofp, " load Load session configuration\n"); - fprintf(ofp, " track Track specific system resources\n"); - fprintf(ofp, " untrack Untrack specific system resources\n"); - fprintf(ofp, " metadata Regenerate the metadata of a session\n"); - fprintf(ofp, "\n"); - fprintf(ofp, "Each command also has its own -h, --help option.\n"); - fprintf(ofp, "\n"); - fprintf(ofp, "Please see the lttng(1) man page for full documentation.\n"); - fprintf(ofp, "See http://lttng.org for updates, bug reports and news.\n"); -} - static void version(FILE *ofp) { - fprintf(ofp, "%s (LTTng Trace Control) " VERSION" - " VERSION_NAME "%s\n", + fprintf(ofp, "%s (LTTng Trace Control) " VERSION" - " VERSION_NAME "%s%s\n", progname, - GIT_VERSION[0] == '\0' ? "" : " - " GIT_VERSION); + GIT_VERSION[0] == '\0' ? "" : " - " GIT_VERSION, + EXTRA_VERSION_NAME[0] == '\0' ? "" : " - " EXTRA_VERSION_NAME); } /* @@ -264,8 +221,14 @@ static int handle_command(int argc, char **argv) goto end; } + /* Special case for help command which needs the commands array */ + if (strcmp(argv[0], "help") == 0) { + ret = cmd_help(argc, (const char**) argv, commands); + goto end; + } + cmd = &commands[i]; - while (cmd->func != NULL) { + while (cmd->name != NULL) { /* Find command */ if (strcmp(argv[0], cmd->name) == 0) { ret = cmd->func(argc, (const char**) argv); @@ -282,6 +245,77 @@ end: return ret; } +static bool command_exists(const char *command) +{ + const struct cmd_struct *cmd = commands; + bool exists = false; + + while (cmd->name != NULL) { + if (!strcmp(command, cmd->name)) { + exists = true; + goto end; + } + cmd++; + } + +end: + return exists; +} + +static void show_basic_help(void) +{ + puts("Usage: lttng [--group=GROUP] [--mi=TYPE] [--no-sessiond | --sessiond-path=PATH]"); + puts(" [--quiet | -v | -vv | -vvv] COMMAND [COMMAND OPTIONS]"); + puts(""); + puts("Available commands:"); + puts(""); + puts("Tracing sessions:"); + puts(" create " CONFIG_CMD_DESCR_CREATE); + puts(" clear " CONFIG_CMD_DESCR_CLEAR); + puts(" destroy " CONFIG_CMD_DESCR_DESTROY); + puts(" load " CONFIG_CMD_DESCR_LOAD); + puts(" regenerate " CONFIG_CMD_DESCR_REGENERATE); + puts(" save " CONFIG_CMD_DESCR_SAVE); + puts(" set-session " CONFIG_CMD_DESCR_SET_SESSION); + puts(""); + puts("Channels:"); + puts(" add-context " CONFIG_CMD_DESCR_ADD_CONTEXT); + puts(" disable-channel " CONFIG_CMD_DESCR_DISABLE_CHANNEL); + puts(" enable-channel " CONFIG_CMD_DESCR_ENABLE_CHANNEL); + puts(""); + puts("Event rules:"); + puts(" disable-event " CONFIG_CMD_DESCR_DISABLE_EVENT); + puts(" enable-event " CONFIG_CMD_DESCR_ENABLE_EVENT); + puts(""); + puts("Status:"); + puts(" list " CONFIG_CMD_DESCR_LIST); + puts(" status " CONFIG_CMD_DESCR_STATUS); + puts(""); + puts("Control:"); + puts(" snapshot " CONFIG_CMD_DESCR_SNAPSHOT); + puts(" start " CONFIG_CMD_DESCR_START); + puts(" stop " CONFIG_CMD_DESCR_STOP); + puts(""); + puts("Tracing session rotation:"); + puts(" disable-rotation " CONFIG_CMD_DESCR_DISABLE_ROTATION); + puts(" enable-rotation " CONFIG_CMD_DESCR_ENABLE_ROTATION); + puts(" rotate " CONFIG_CMD_DESCR_ROTATE); + puts(""); + puts("Resource tracking:"); + puts(" track " CONFIG_CMD_DESCR_TRACK); + puts(" untrack " CONFIG_CMD_DESCR_UNTRACK); + puts(""); + puts("Miscellaneous:"); + puts(" help " CONFIG_CMD_DESCR_HELP); + puts(" version " CONFIG_CMD_DESCR_VERSION); + puts(" view " CONFIG_CMD_DESCR_VIEW); + puts(""); + puts("Run `lttng help COMMAND` or `lttng COMMAND --help` to get help with"); + puts("command COMMAND."); + puts(""); + puts("See `man lttng` for more help with the lttng command."); +} + /* * Parse command line arguments. * @@ -290,7 +324,6 @@ end: static int parse_args(int argc, char **argv) { int opt, ret; - char *user; if (lttng_is_setuid_setgid()) { ERR("'%s' is not allowed to be executed as a setuid/setgid binary for security reasons. Aborting.", argv[0]); @@ -298,7 +331,7 @@ static int parse_args(int argc, char **argv) } if (argc < 2) { - usage(stderr); + show_basic_help(); clean_exit(EXIT_FAILURE); } @@ -309,8 +342,11 @@ static int parse_args(int argc, char **argv) ret = 0; goto end; case 'h': - usage(stdout); - ret = 0; + ret = utils_show_help(1, "lttng", help_msg); + if (ret) { + ERR("Cannot show --help for `lttng`"); + perror("exec"); + } goto end; case 'v': /* There is only 3 possible level of verbosity. (-vvv) */ @@ -335,6 +371,7 @@ static int parse_args(int argc, char **argv) opt_no_sessiond = 1; break; case OPT_SESSION_PATH: + free(opt_sessiond_path); opt_sessiond_path = strdup(optarg); if (!opt_sessiond_path) { ret = -1; @@ -342,6 +379,7 @@ static int parse_args(int argc, char **argv) } break; case OPT_RELAYD_PATH: + free(opt_relayd_path); opt_relayd_path = strdup(optarg); if (!opt_relayd_path) { ret = -1; @@ -357,7 +395,6 @@ static int parse_args(int argc, char **argv) ret = 0; goto end; default: - usage(stderr); ret = 1; goto error; } @@ -368,21 +405,12 @@ static int parse_args(int argc, char **argv) lttng_opt_verbose = 0; } - /* No leftovers, print usage and quit */ + /* No leftovers, quit */ if ((argc - optind) == 0) { - usage(stderr); ret = 1; goto error; } - /* For Mathieu Desnoyers a.k.a. Dr. Tracing */ - user = getenv("USER"); - if (user != NULL && ((strncmp(progname, "drtrace", 7) == 0 || - strncmp("compudj", user, 7) == 0))) { - MSG("%c[%d;%dmWelcome back Dr Tracing!%c[%dm\n", 27,1,33,27,0); - } - /* Thanks Mathieu */ - /* * Handle leftovers which is a first level command with the trailing * options. @@ -390,22 +418,21 @@ static int parse_args(int argc, char **argv) ret = handle_command(argc - optind, argv + optind); switch (ret) { case CMD_WARNING: - WARN("Some command(s) went wrong"); - break; case CMD_ERROR: - ERR("Command error"); break; case CMD_UNDEFINED: - ERR("Undefined command or invalid arguments"); + if (!command_exists(*(argv + optind))) { + MSG("lttng: %s is not an lttng command. See 'lttng --help'.", + *(argv + optind)); + } else { + ERR("Unrecognized argument used with \'%s\' command", + *(argv + optind)); + } break; case CMD_FATAL: - ERR("Fatal error"); - break; case CMD_UNSUPPORTED: - ERR("Unsupported command"); break; case -1: - usage(stderr); ret = 1; break; case 0: