begin or tail in live mode
[lttngtop.git] / src / lttngtop.c
index ef03a9672034a339094f3b462d4c978c9aef8f9a..2800cfac124a208698f47396e89659e8342850d5 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
@@ -59,6 +59,7 @@
 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;
 }
 
 /*
@@ -644,6 +667,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, ",");
@@ -994,40 +1021,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 +1037,21 @@ int main(int argc, char **argv)
                lttng_destroy_session("test");
 
                goto end;
+#else
+               fprintf(stderr, "Mmap live support not compiled\n");
+               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,21 +1061,23 @@ 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);
 
 end:
        if (bt_ctx)
This page took 0.024261 seconds and 4 git commands to generate.