sync lttng and babeltrace last headers for live
[lttngtop.git] / src / lttngtop.c
index ef03a9672034a339094f3b462d4c978c9aef8f9a..ec8839c37220e41595c8d162637936a61b4b4799 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 Julien Desfossez
+ * Copyright (C) 2013 Julien Desfossez
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License Version 2 as
 #include "common.h"
 #include "network-live.h"
 
-#include "lttng-index.h"
+#include "ctf-index.h"
 
 #define DEFAULT_FILE_ARRAY_SIZE 1
 
 const char *opt_input_path;
 static int opt_textdump;
 static int opt_child;
+static int opt_begin;
 
 int quit = 0;
 
@@ -68,6 +69,7 @@ pthread_t timer_thread;
 
 unsigned long refresh_display = 1 * NSEC_PER_SEC;
 unsigned long last_display_update = 0;
+unsigned long last_event_ts = 0;
 
 /* list of FDs available for being read with snapshots */
 struct bt_mmap_stream_list mmap_list;
@@ -90,6 +92,7 @@ enum {
        OPT_HOSTNAME,
        OPT_RELAY_HOSTNAME,
        OPT_KPROBES,
+       OPT_BEGIN,
 };
 
 static struct poptOption long_options[] = {
@@ -97,6 +100,7 @@ static struct poptOption long_options[] = {
        { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL },
        { "textdump", 't', POPT_ARG_NONE, NULL, OPT_TEXTDUMP, NULL, NULL },
        { "child", 'f', POPT_ARG_NONE, NULL, OPT_CHILD, NULL, NULL },
+       { "begin", 'b', POPT_ARG_NONE, NULL, OPT_BEGIN, NULL, NULL },
        { "pid", 'p', POPT_ARG_STRING, &opt_tid, OPT_PID, NULL, NULL },
        { "hostname", 'n', POPT_ARG_STRING, &opt_hostname, OPT_HOSTNAME, NULL, NULL },
        { "relay-hostname", 'r', POPT_ARG_STRING, &opt_relay_hostname,
@@ -105,11 +109,13 @@ static struct poptOption long_options[] = {
        { NULL, 0, 0, NULL, 0, NULL, NULL },
 };
 
+#ifdef LTTNGTOP_MMAP_LIVE
 static void handle_textdump_sigterm(int signal)
 {
        quit = 1;
        lttng_destroy_session("test");
 }
+#endif
 
 void *refresh_thread(void *p)
 {
@@ -215,6 +221,12 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat
 
        timestamp = bt_ctf_get_timestamp(call_data);
 
+       /* can happen in network live when tracing is idle */
+       if (timestamp < last_event_ts)
+               goto end_stop;
+
+       last_event_ts = timestamp;
+
        start = format_timestamp(timestamp);
        ts_nsec_start = timestamp % NSEC_PER_SEC;
 
@@ -262,6 +274,8 @@ end:
        return BT_CB_OK;
 error:
        return BT_CB_ERROR_STOP;
+end_stop:
+       return BT_CB_OK_STOP;
 }
 
 enum bt_cb_ret handle_kprobes(struct bt_ctf_event *call_data, void *private_data)
@@ -292,6 +306,12 @@ enum bt_cb_ret check_timestamp(struct bt_ctf_event *call_data, void *private_dat
        if (timestamp == -1ULL)
                goto error;
 
+       /* can happen in network live when tracing is idle */
+       if (timestamp < last_event_ts)
+               goto end_stop;
+
+       last_event_ts = timestamp;
+
        if (last_display_update == 0)
                last_display_update = timestamp;
 
@@ -308,6 +328,9 @@ enum bt_cb_ret check_timestamp(struct bt_ctf_event *call_data, void *private_dat
 error:
        fprintf(stderr, "check_timestamp callback error\n");
        return BT_CB_ERROR_STOP;
+
+end_stop:
+       return BT_CB_OK_STOP;
 }
 
 /*
@@ -517,14 +540,16 @@ void init_lttngtop()
 void usage(FILE *fp)
 {
        fprintf(fp, "LTTngTop %s\n\n", VERSION);
-       fprintf(fp, "Usage : lttngtop [OPTIONS] [TRACE]\n");
-       fprintf(fp, "  TRACE                    Path to the trace to analyse (no trace path for live tracing)\n");
+       fprintf(fp, "Usage : lttngtop [OPTIONS] TRACE\n");
+       fprintf(fp, "  TRACE                    Path to the trace to analyse (-r for network live tracing, nothing for mmap live streaming)\n");
        fprintf(fp, "  -h, --help               This help message\n");
        fprintf(fp, "  -t, --textdump           Display live events in text-only\n");
        fprintf(fp, "  -p, --pid                Comma-separated list of PIDs to display\n");
        fprintf(fp, "  -f, --child              Follow threads associated with selected PIDs\n");
        fprintf(fp, "  -n, --hostname           Comma-separated list of hostnames to display (require hostname context in trace)\n");
        fprintf(fp, "  -k, --kprobes            Comma-separated list of kprobes to insert (same format as lttng enable-event)\n");
+       fprintf(fp, "  -r, --relay-hostname     Network live streaming : hostname of the lttng-relayd (default port)\n");
+       fprintf(fp, "  -b, --begin              Network live streaming : read the trace for the beginning of the recording\n");
 }
 
 /*
@@ -644,6 +669,10 @@ static int parse_options(int argc, char **argv)
                                        tmp_str = strtok(NULL, ",");
                                }
                                break;
+                       case OPT_BEGIN:
+                               /* start reading the live trace from the beginning */
+                               opt_begin = 1;
+                               break;
                        case OPT_HOSTNAME:
                                toggle_filter = 1;
                                tmp_str = strtok(opt_hostname, ",");
@@ -834,7 +863,6 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path,
                metafd = openat(dirfd, "metadata", O_RDONLY);
                if (metafd < 0) {
                        close(dirfd);
-                       ret = -1;
                        continue;
                } else {
                        int trace_id;
@@ -994,40 +1022,14 @@ int main(int argc, char **argv)
                exit(EXIT_SUCCESS);
        }
 
-       if (!opt_input_path) {
+       if (!opt_input_path && !remote_live) {
+               /* mmap live */
+#ifdef LTTNGTOP_MMAP_LIVE
                if (opt_textdump) {
                        signal(SIGTERM, handle_textdump_sigterm);
                        signal(SIGINT, handle_textdump_sigterm);
                }
-               if (remote_live) {
-                       ret = setup_network_live(opt_relay_hostname);
-                       if (ret < 0) {
-                               goto end;
-                       }
-               }
-
-               if (!opt_textdump) {
-                       pthread_create(&display_thread, NULL, ncurses_display, (void *) NULL);
-                       pthread_create(&timer_thread, NULL, refresh_thread, (void *) NULL);
-               }
-
-               ret = open_trace(&bt_ctx);
-               if (ret < 0) {
-                       goto end;
-               }
-
-               ret = check_requirements(bt_ctx);
-               if (ret < 0) {
-                       fprintf(stderr, "[error] some mandatory contexts were missing, exiting.\n");
-                       goto end;
-               }
-
-               iter_trace(bt_ctx);
-
-#ifdef LTTNGTOP_MMAP_LIVE
                mmap_live_loop(bt_ctx);
-#endif
-
                pthread_join(timer_thread, NULL);
                quit = 1;
                pthread_join(display_thread, NULL);
@@ -1036,6 +1038,24 @@ int main(int argc, char **argv)
                lttng_destroy_session("test");
 
                goto end;
+#else
+               fprintf(stderr, "[ERROR] Mmap live support not compiled, specify a "
+                               "trace directory or -r <relayd hostname/IP>\n");
+               usage(stdout);
+               ret = -1;
+               goto end;
+#endif /* LTTNGTOP_MMAP_LIVE */
+       } else if (!opt_input_path && remote_live) {
+               /* network live */
+               ret = setup_network_live(opt_relay_hostname, opt_begin);
+               if (ret < 0) {
+                       goto end;
+               }
+
+               ret = open_trace(&bt_ctx);
+               if (ret < 0) {
+                       goto end;
+               }
        } else {
                //init_lttngtop();
 
@@ -1045,25 +1065,29 @@ int main(int argc, char **argv)
                        fprintf(stderr, "[error] Opening the trace\n");
                        goto end;
                }
+       }
 
-               ret = check_requirements(bt_ctx);
-               if (ret < 0) {
-                       fprintf(stderr, "[error] some mandatory contexts were missing, exiting.\n");
-                       goto end;
-               }
+       ret = check_requirements(bt_ctx);
+       if (ret < 0) {
+               fprintf(stderr, "[error] some mandatory contexts were missing, exiting.\n");
+               goto end;
+       }
+       if (!opt_textdump) {
                pthread_create(&display_thread, NULL, ncurses_display, (void *) NULL);
                pthread_create(&timer_thread, NULL, refresh_thread, (void *) NULL);
+       }
 
-               iter_trace(bt_ctx);
+       iter_trace(bt_ctx);
 
-               pthread_join(display_thread, NULL);
-               quit = 1;
-               pthread_join(timer_thread, NULL);
-       }
+       pthread_join(display_thread, NULL);
+       quit = 1;
+       pthread_join(timer_thread, NULL);
+
+       ret = 0;
 
 end:
        if (bt_ctx)
                bt_context_put(bt_ctx);
 
-       return 0;
+       return ret;
 }
This page took 0.027083 seconds and 4 git commands to generate.