X-Git-Url: https://git.lttng.org/?p=lttngtop.git;a=blobdiff_plain;f=src%2Flttngtop.c;h=2857d5763c9c32f37fa97be864989b0929b4657f;hp=fde9bf30547e8a320961d4cc6c2493c7cb0330dc;hb=b872c906dbdf4780d0bad7bb01b0fa74af530d68;hpb=4e6aeb3d1a8330c7486b762336f11510baaa433c diff --git a/src/lttngtop.c b/src/lttngtop.c index fde9bf3..2857d57 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "lttngtoptypes.h" #include "cputop.h" @@ -54,12 +55,14 @@ const char *opt_input_path; struct lttngtop *copy; pthread_t display_thread; pthread_t timer_thread; +pthread_t live_trace_thread; unsigned long refresh_display = 1 * NSEC_PER_SEC; unsigned long last_display_update = 0; int quit = 0; /* LIVE */ +pthread_t thread_live_consume; /* list of FDs available for being read with snapshots */ struct mmap_stream_list mmap_list; GPtrArray *lttng_consumer_stream_array; @@ -129,6 +132,29 @@ void *ncurses_display(void *p) } } +/* + * hook on each event to check the timestamp and refresh the display if + * necessary + */ +enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_data) +{ + unsigned long timestamp; + struct tm start; + uint64_t ts_nsec_start; + + + timestamp = bt_ctf_get_timestamp(call_data); + + start = format_timestamp(timestamp); + ts_nsec_start = timestamp % NSEC_PER_SEC; + + printf("%02d:%02d:%02d.%09" PRIu64 " %s\n", start.tm_hour, + start.tm_min, start.tm_sec, ts_nsec_start, + bt_ctf_event_name(call_data)); + + return BT_CB_OK; +} + /* * hook on each event to check the timestamp and refresh the display if * necessary @@ -137,7 +163,7 @@ enum bt_cb_ret check_timestamp(struct bt_ctf_event *call_data, void *private_dat { unsigned long timestamp; - timestamp = bt_ctf_get_real_timestamp(call_data); + timestamp = bt_ctf_get_timestamp(call_data); if (timestamp == -1ULL) goto error; @@ -268,7 +294,7 @@ enum bt_cb_ret fix_process_table(struct bt_ctf_event *call_data, struct processtop *parent, *child; unsigned long timestamp; - timestamp = bt_ctf_get_real_timestamp(call_data); + timestamp = bt_ctf_get_timestamp(call_data); if (timestamp == -1ULL) goto error; @@ -387,6 +413,11 @@ void iter_trace(struct bt_context *bt_ctx) begin_pos.type = BT_SEEK_BEGIN; iter = bt_ctf_iter_create(bt_ctx, &begin_pos, NULL); + bt_ctf_iter_add_callback(iter, 0, NULL, 0, + print_timestamp, + NULL, NULL, NULL); + +#if 0 /* at each event check if we need to refresh */ bt_ctf_iter_add_callback(iter, 0, NULL, 0, check_timestamp, @@ -431,7 +462,7 @@ void iter_trace(struct bt_context *bt_ctx) "lttng_statedump_file_descriptor"), NULL, 0, handle_statedump_file_descriptor, NULL, NULL, NULL); - +#endif while ((event = bt_ctf_iter_read_event(iter)) != NULL) { ret = bt_iter_next(bt_ctf_get_iter(iter)); if (ret < 0) @@ -641,87 +672,6 @@ int check_requirements(struct bt_context *ctx) return ret; } -void dump_snapshot() -{ - struct lttng_consumer_stream *iter; - unsigned long spos; - struct mmap_stream *new_snapshot; - - int ret = 0; - int i; - /* - * try lock mutex ressource courante (overrun) - * if fail : overrun - * stop trace (flush implicite avant stop) - * lttng_consumer_take_snapshot - * read timestamp packet end (use time as end pos) - * - stream_packet_context - * - reculer de 1 subbuf : pos - max_subbuff_size - * - * - position de fin (take_snapshot) - * - mov_pos_slow ( fin - max_subbuff_size) lire timestamp packet end - * - prend min(end) (activité sur tous les streams) - * - * start trace - * unlock mutex - */ - - helper_kernctl_buffer_flush(consumerd_metadata); - for (i = 0; i < lttng_consumer_stream_array->len; i++) { - iter = g_ptr_array_index(lttng_consumer_stream_array, i); - helper_kernctl_buffer_flush(helper_get_lttng_consumer_stream_wait_fd(iter)); - ret = helper_lttng_consumer_take_snapshot(ctx, iter); - if (ret != 0) { - ret = errno; - perror("lttng_consumer_take_snapshots"); - goto end; - } - } - for (i = 0; i < lttng_consumer_stream_array->len; i++) { - iter = g_ptr_array_index(lttng_consumer_stream_array, i); - //cds_list_for_each_entry(iter2, &mmap_stream_list.head, list) { - - ret = helper_lttng_consumer_get_produced_snapshot(ctx, iter, &spos); - if (ret != 0) { - ret = errno; - perror("helper_lttng_consumer_get_produced_snapshot"); - goto end; - } - //while (iter->last_pos < spos) { FIXME : last_pos does not exists - new_snapshot = g_new0(struct mmap_stream, 1); - new_snapshot->fd = helper_get_lttng_consumer_stream_wait_fd(iter); - //FIXME new_snapshot->last_pos = iter->last_pos; /* not last_pos, pos for the snapshot */ -// fprintf(stderr,"ADDING AVAILABLE SNAPSHOT ON FD %d AT POSITION %lu\n", -// new_snapshot->kconsumerd_fd->wait_fd, -// new_snapshot->last_pos); - g_ptr_array_add(available_snapshots, new_snapshot); - //FIXME iter->last_pos += iter->chan->max_sb_size; - //} - } - - if (!metadata_ready) { -// fprintf(stderr, "BLOCKING BEFORE METADATA\n"); - sem_wait(&metadata_available); -// fprintf(stderr,"OPENING TRACE\n"); - if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { - fprintf(stderr,"NO METADATA FILE, SKIPPING\n"); - return; - } - metadata_ready = 1; - metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); - } - - if (!trace_opened) { - //bt_ctx = bt_context_create(); -// ret = bt_context_add_trace(ctx, NULL, "ctf", ctf_move_mmap_pos_slow, mmap_list, metadata_fp); - trace_opened = 1; - } - //iter_trace(bt_ctx); - -end: - return; -} - ssize_t read_subbuffer(struct lttng_consumer_stream *kconsumerd_fd, struct lttng_consumer_local_data *ctx) { @@ -732,7 +682,6 @@ ssize_t read_subbuffer(struct lttng_consumer_stream *kconsumerd_fd, if (helper_get_lttng_consumer_stream_output(kconsumerd_fd) == LTTNG_EVENT_SPLICE) { /* Get the next subbuffer */ - printf("get_next : %d\n", infd); err = helper_kernctl_get_next_subbuf(infd); if (err != 0) { ret = errno; @@ -747,7 +696,6 @@ ssize_t read_subbuffer(struct lttng_consumer_stream *kconsumerd_fd, perror("Getting sub-buffer len failed."); goto end; } - printf("len : %ld\n", len); /* splice the subbuffer to the tracefile */ ret = helper_lttng_consumer_on_read_subbuffer_splice(ctx, kconsumerd_fd, len); @@ -758,8 +706,6 @@ ssize_t read_subbuffer(struct lttng_consumer_stream *kconsumerd_fd, */ fprintf(stderr,"Error splicing to tracefile\n"); } - printf("ret : %ld\n", ret); - printf("put_next : %d\n", infd); err = helper_kernctl_put_next_subbuf(infd); if (err != 0) { ret = errno; @@ -785,8 +731,7 @@ int on_update_fd(int key, uint32_t state) int on_recv_fd(struct lttng_consumer_stream *kconsumerd_fd) { int ret; - struct mmap_stream *new_info; - size_t tmp_mmap_len; + struct mmap_stream *new_mmap_stream; /* Opening the tracefile in write mode */ if (helper_get_lttng_consumer_stream_path_name(kconsumerd_fd) != NULL) { @@ -800,30 +745,13 @@ int on_recv_fd(struct lttng_consumer_stream *kconsumerd_fd) } if (helper_get_lttng_consumer_stream_output(kconsumerd_fd) == LTTNG_EVENT_MMAP) { - new_info = malloc(sizeof(struct mmap_stream)); - new_info->fd = helper_get_lttng_consumer_stream_wait_fd(kconsumerd_fd); - bt_list_add(&new_info->list, &mmap_list.head); - - /* get the len of the mmap region */ - ret = helper_kernctl_get_mmap_len(helper_get_lttng_consumer_stream_wait_fd(kconsumerd_fd), - &tmp_mmap_len); - if (ret != 0) { - ret = errno; - perror("helper_kernctl_get_mmap_len"); - goto end; - } - helper_set_lttng_consumer_stream_mmap_len(kconsumerd_fd, tmp_mmap_len); - - helper_set_lttng_consumer_stream_mmap_base(kconsumerd_fd, - mmap(NULL, helper_get_lttng_consumer_stream_mmap_len(kconsumerd_fd), - PROT_READ, MAP_PRIVATE, helper_get_lttng_consumer_stream_wait_fd(kconsumerd_fd), 0)); - if (helper_get_lttng_consumer_stream_mmap_base(kconsumerd_fd) == MAP_FAILED) { - perror("Error mmaping"); - ret = -1; - goto end; - } + new_mmap_stream = malloc(sizeof(struct mmap_stream)); + new_mmap_stream->fd = helper_get_lttng_consumer_stream_wait_fd( + kconsumerd_fd); + bt_list_add(&new_mmap_stream->list, &mmap_list.head); g_ptr_array_add(lttng_consumer_stream_array, kconsumerd_fd); + /* keep mmap FDs internally */ ret = 1; } else { consumerd_metadata = helper_get_lttng_consumer_stream_wait_fd(kconsumerd_fd); @@ -835,6 +763,35 @@ end: return ret; } +void *live_consume() +{ + struct bt_context *bt_ctx = NULL; + int ret; + + if (!metadata_ready) { + sem_wait(&metadata_available); + if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { + fprintf(stderr,"no metadata\n"); + return NULL; + } + metadata_ready = 1; + metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); + } + + if (!trace_opened) { + bt_ctx = bt_context_create(); + ret = bt_context_add_trace(bt_ctx, NULL, "ctf", + lttngtop_ctf_packet_seek, &mmap_list, metadata_fp); + if (ret < 0) { + printf("Error adding trace\n"); + return NULL; + } + trace_opened = 1; + } + iter_trace(bt_ctx); + + return NULL; +} int setup_consumer(char *command_sock_path, pthread_t *threads, struct lttng_consumer_local_data *ctx) @@ -854,14 +811,14 @@ int setup_consumer(char *command_sock_path, pthread_t *threads, ret = pthread_create(&threads[0], NULL, helper_lttng_consumer_thread_receive_fds, (void *) ctx); if (ret != 0) { - perror("pthread_create"); + perror("pthread_create receive fd"); goto end; } /* Create thread to manage the polling/writing of traces */ ret = pthread_create(&threads[1], NULL, helper_lttng_consumer_thread_poll_fds, (void *) ctx); if (ret != 0) { - perror("pthread_create"); + perror("pthread_create poll fd"); goto end; } @@ -869,7 +826,7 @@ end: return ret; } -int setup_live_tracing() +void *setup_live_tracing() { struct lttng_domain dom; struct lttng_channel chan; @@ -898,6 +855,7 @@ int setup_live_tracing() ret = system("rm -rf /tmp/livesession"); + lttng_destroy_session("test"); if ((ret = lttng_create_session("test", "/tmp/livesession")) < 0) { fprintf(stderr,"error creating the session : %s\n", helper_lttcomm_get_readable_code(ret)); @@ -916,25 +874,27 @@ int setup_live_tracing() } strcpy(chan.name, channel_name); - chan.attr.overwrite = 1; -// chan.attr.subbuf_size = 32768; - chan.attr.subbuf_size = 1048576; /* 1MB */ + chan.attr.overwrite = 0; + chan.attr.subbuf_size = 32768; +// chan.attr.subbuf_size = 1048576; /* 1MB */ chan.attr.num_subbuf = 4; chan.attr.switch_timer_interval = 0; chan.attr.read_timer_interval = 200; chan.attr.output = LTTNG_EVENT_MMAP; if ((ret = lttng_enable_channel(handle, &chan)) < 0) { - fprintf(stderr,"error creating channel : %s\n", helper_lttcomm_get_readable_code(ret)); + fprintf(stderr,"error creating channel : %s\n", + helper_lttcomm_get_readable_code(ret)); goto end; } - sprintf(ev.name, "sched_switch"); + memset(&ev, '\0', sizeof(struct lttng_event)); + //sprintf(ev.name, "sched_switch"); ev.type = LTTNG_EVENT_TRACEPOINT; - //if ((ret = lttng_enable_event(handle, NULL, channel_name)) < 0) { if ((ret = lttng_enable_event(handle, &ev, channel_name)) < 0) { - fprintf(stderr,"error enabling event : %s\n", helper_lttcomm_get_readable_code(ret)); + fprintf(stderr,"error enabling event : %s\n", + helper_lttcomm_get_readable_code(ret)); goto end; } @@ -948,15 +908,19 @@ int setup_live_tracing() lttng_add_context(handle, &kctxtid, NULL, NULL); if ((ret = lttng_start_tracing("test")) < 0) { - fprintf(stderr,"error starting tracing : %s\n", helper_lttcomm_get_readable_code(ret)); + fprintf(stderr,"error starting tracing : %s\n", + helper_lttcomm_get_readable_code(ret)); goto end; } helper_kernctl_buffer_flush(consumerd_metadata); - sleep(10); - lttng_stop_tracing("test"); - lttng_destroy_session("test"); + /* Create thread to manage the polling/writing of traces */ + ret = pthread_create(&thread_live_consume, NULL, live_consume, NULL); + if (ret != 0) { + perror("pthread_create"); + goto end; + } /* block until metadata is ready */ sem_init(&metadata_available, 0, 0); @@ -964,7 +928,7 @@ int setup_live_tracing() //init_lttngtop(); end: - return ret; + return NULL; } int main(int argc, char **argv) @@ -982,8 +946,15 @@ int main(int argc, char **argv) } if (!opt_input_path) { - printf("live tracing enabled\n"); - setup_live_tracing(); + pthread_create(&live_trace_thread, NULL, setup_live_tracing, (void *) NULL); + sleep(2000); + printf("STOPPING\n"); + lttng_stop_tracing("test"); + printf("DESTROYING\n"); + lttng_destroy_session("test"); + + printf("CANCELLING\n"); + pthread_cancel(live_trace_thread); goto end; } else { init_lttngtop();