X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Flttngtop.c;h=9baaff3f94bfc0aa9b8b0a9699a5f03197eb19de;hb=d2f1452b66e796412c4b0c1c73608b156659a650;hp=ef03a9672034a339094f3b462d4c978c9aef8f9a;hpb=b1acd2b342a35dc6c5a8036fb0280321203e89b7;p=lttngtop.git diff --git a/src/lttngtop.c b/src/lttngtop.c index ef03a96..9baaff3 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -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; } /* @@ -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 \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; }