lttng-view: make babeltrace2 the default viewer
[lttng-tools.git] / src / bin / lttng / commands / view.c
index dac2c3e247b4e3607bafeb6de7db7c5a3799e6da..3e2ce40ef1591c05143f7b8928427b7dd0da7da9 100644 (file)
@@ -30,7 +30,13 @@ static char *opt_session_name;
 static char *opt_viewer;
 static char *opt_trace_path;
 static const char *babeltrace_bin = CONFIG_BABELTRACE_BIN;
-//static const char *lttv_gui_bin = CONFIG_LTTV_GUI_BIN;
+static const char *babeltrace2_bin = CONFIG_BABELTRACE2_BIN;
+
+#ifdef LTTNG_EMBED_HELP
+static const char help_msg[] =
+#include <lttng-view.1.h>
+;
+#endif
 
 enum {
        OPT_HELP = 1,
@@ -50,7 +56,7 @@ static struct poptOption long_options[] = {
  * This is needed for each viewer since we are using execvp().
  */
 static const char *babeltrace_opts[] = { "babeltrace" };
-//static const char *lttv_gui_opts[] = { "lttv-gui", "-t", };
+static const char *babeltrace2_opts[] = { "babeltrace2" };
 
 /*
  * Type is also use as the index in the viewers array. So please, make sure
@@ -58,7 +64,7 @@ static const char *babeltrace_opts[] = { "babeltrace" };
  */
 enum viewer_type {
        VIEWER_BABELTRACE    = 0,
-       VIEWER_LTTV_GUI      = 1,
+       VIEWER_BABELTRACE2   = 1,
        VIEWER_USER_DEFINED  = 2,
 };
 
@@ -66,47 +72,23 @@ enum viewer_type {
  * NOTE: "lttv" is a shell command and it's not working for exec() family
  * functions so we might think of removing this wrapper or using bash.
  */
-static struct viewers {
+static const struct viewers {
        const char *exec_name;
        enum viewer_type type;
 } viewers[] = {
        { "babeltrace", VIEWER_BABELTRACE },
-       { "lttv-gui", VIEWER_LTTV_GUI },
+       { "babeltrace2", VIEWER_BABELTRACE2 },
        { NULL, VIEWER_USER_DEFINED },
 };
 
 /* Is the session we are trying to view is in live mode. */
 static int session_live_mode;
 
-/*
- * usage
- */
-static void usage(FILE *ofp)
-{
-       fprintf(ofp, "usage: lttng view [SESSION_NAME] [OPTIONS]\n");
-       fprintf(ofp, "\n");
-       fprintf(ofp, "By default, the babeltrace viewer will be used for text viewing\n");
-       fprintf(ofp, "\n");
-       fprintf(ofp, "Where SESSION_NAME is an optional session name. If not specified, lttng will\n");
-       fprintf(ofp, "get it from the configuration file (.lttngrc).\n");
-       fprintf(ofp, "\n");
-       fprintf(ofp, "Options:\n");
-       fprintf(ofp, "  -h, --help               Show this help\n");
-       fprintf(ofp, "      --list-options       Simple listing of options\n");
-       fprintf(ofp, "  -t, --trace-path PATH    Trace directory path for the viewer\n");
-       fprintf(ofp, "  -e, --viewer CMD         Specify viewer and/or options to use\n");
-       fprintf(ofp, "                           This will completely override the default viewers so\n");
-       fprintf(ofp, "                           please make sure to specify the full command. The trace\n");
-       fprintf(ofp, "                           directory path of the session will be appended at the end\n");
-       fprintf(ofp, "                           to the arguments\n");
-       fprintf(ofp, "\n");
-}
-
-static struct viewers *parse_options(void)
+static const struct viewers *parse_options(void)
 {
        if (opt_viewer == NULL) {
                /* Default is babeltrace */
-               return &(viewers[VIEWER_BABELTRACE]);
+               return &(viewers[VIEWER_BABELTRACE2]);
        }
 
        /*
@@ -187,7 +169,6 @@ static char **alloc_argv_from_local_opts(const char **opts, size_t opts_len,
        char **argv;
        size_t size, mem_len;
 
-
        /* Add one for the NULL terminating element. */
        mem_len = opts_len + 1;
        if (session_live_mode) {
@@ -206,7 +187,7 @@ static char **alloc_argv_from_local_opts(const char **opts, size_t opts_len,
                goto error;
        }
 
-       memcpy(argv, opts, size);
+       memcpy(argv, opts, sizeof(char *) * opts_len);
 
        if (session_live_mode) {
                argv[opts_len] = "-i";
@@ -230,7 +211,7 @@ static int spawn_viewer(const char *trace_path)
        int ret = 0;
        struct stat status;
        const char *viewer_bin = NULL;
-       struct viewers *viewer;
+       const struct viewers *viewer;
        char **argv = NULL;
 
        /* Check for --viewer options */
@@ -240,7 +221,17 @@ static int spawn_viewer(const char *trace_path)
                goto error;
        }
 
+retry_viewer:
        switch (viewer->type) {
+       case VIEWER_BABELTRACE2:
+               if (stat(babeltrace2_bin, &status) == 0) {
+                       viewer_bin = babeltrace2_bin;
+               } else {
+                       viewer_bin = viewer->exec_name;
+               }
+               argv = alloc_argv_from_local_opts(babeltrace2_opts,
+                               ARRAY_SIZE(babeltrace2_opts), trace_path);
+               break;
        case VIEWER_BABELTRACE:
                if (stat(babeltrace_bin, &status) == 0) {
                        viewer_bin = babeltrace_bin;
@@ -272,17 +263,27 @@ static int spawn_viewer(const char *trace_path)
 
        ret = execvp(viewer_bin, argv);
        if (ret) {
-               if (errno == ENOENT) {
-                       ERR("%s not found on the system", viewer_bin);
+               if (errno == ENOENT && viewer->exec_name) {
+                       if (viewer->type == VIEWER_BABELTRACE2) {
+                               /* Fallback to legacy babeltrace. */
+                               DBG("babeltrace2 not installed on the system, falling back to babeltrace 1.x");
+                               viewer = &viewers[VIEWER_BABELTRACE];
+                               free(argv);
+                               argv = NULL;
+                               goto retry_viewer;
+                       } else {
+                               ERR("Viewer \"%s\" not found on the system",
+                                               viewer_bin);
+                       }
                } else {
-                       PERROR("exec: %s", viewer_bin);
+                       PERROR("Failed to launch \"%s\" viewer", viewer_bin);
                }
-               free(argv);
                ret = CMD_FATAL;
                goto error;
        }
 
 error:
+       free(argv);
        return ret;
 }
 
@@ -320,6 +321,7 @@ static int view_trace(void)
        int ret;
        char *session_name, *trace_path = NULL;
        struct lttng_session *sessions = NULL;
+       bool free_trace_path = false;
 
        /*
         * Safety net. If lttng is suid at some point for *any* useless reasons,
@@ -397,6 +399,7 @@ static int view_trace(void)
                                ret = CMD_ERROR;
                                goto free_sessions;
                        }
+                       free_trace_path = true;
                } else {
                        /* Get file system session path. */
                        trace_path = sessions[i].path;
@@ -414,7 +417,7 @@ static int view_trace(void)
        }
 
 free_sessions:
-       if (session_live_mode) {
+       if (session_live_mode && free_trace_path) {
                free(trace_path);
        }
        free(sessions);
@@ -433,6 +436,7 @@ int cmd_view(int argc, const char **argv)
 {
        int opt, ret = CMD_SUCCESS;
        static poptContext pc;
+       const char *leftover = NULL;
 
        pc = poptGetContext(NULL, argc, argv, long_options, 0);
        poptReadDefaultConfig(pc, 0);
@@ -450,7 +454,6 @@ int cmd_view(int argc, const char **argv)
                        list_cmd_options(stdout, long_options);
                        goto end;
                default:
-                       usage(stderr);
                        ret = CMD_UNDEFINED;
                        goto end;
                }
@@ -458,6 +461,13 @@ int cmd_view(int argc, const char **argv)
 
        opt_session_name = (char*) poptGetArg(pc);
 
+       leftover = poptGetArg(pc);
+       if (leftover) {
+               ERR("Unknown argument: %s", leftover);
+               ret = CMD_ERROR;
+               goto end;
+       }
+
        ret = view_trace();
 
 end:
This page took 0.027771 seconds and 5 git commands to generate.