X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Ftrace.c;h=e0aeac685e28a312b71fc773fa4ab05ca3eccb89;hp=8b1d15e105b730501bd149cd67088e8d12800356;hb=e6ddca715d6dedb6ee25fe4392a6e1f9626b2544;hpb=540126381ff8f3b1e2b3357329fe105fc0bb5e4c diff --git a/ltt-sessiond/trace.c b/ltt-sessiond/trace.c index 8b1d15e10..e0aeac685 100644 --- a/ltt-sessiond/trace.c +++ b/ltt-sessiond/trace.c @@ -20,11 +20,65 @@ #include #include #include +#include #include -#include "ltt-sessiond.h" +#include "lttngerr.h" #include "trace.h" +/* + * get_kernel_channel_by_name + * + * Find the channel name for the given kernel session. + */ +struct ltt_kernel_channel *get_kernel_channel_by_name( + char *name, struct ltt_kernel_session *session) +{ + struct ltt_kernel_channel *chan; + + if (session == NULL) { + ERR("Undefine session"); + goto error; + } + + cds_list_for_each_entry(chan, &session->channel_list.head, list) { + if (strcmp(name, chan->channel->name) == 0) { + DBG("Found channel by name %s", name); + return chan; + } + } + +error: + return NULL; +} + +/* + * get_kernel_event_by_name + * + * Find the event name for the given channel. + */ +struct ltt_kernel_event *get_kernel_event_by_name( + char *name, struct ltt_kernel_channel *channel) +{ + struct ltt_kernel_event *ev; + + if (channel == NULL) { + ERR("Undefine channel"); + goto error; + } + + cds_list_for_each_entry(ev, &channel->events_list.head, list) { + if (strcmp(name, ev->event->name) == 0) { + DBG("Found event by name %s for channel %s", name, + channel->channel->name); + return ev; + } + } + +error: + return NULL; +} + /* * trace_create_kernel_session * @@ -64,34 +118,32 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_kernel_channel *trace_create_kernel_channel(void) +struct ltt_kernel_channel *trace_create_kernel_channel(struct lttng_channel *chan, char *path) { int ret; struct ltt_kernel_channel *lkc; - struct lttng_kernel_channel *chan; lkc = malloc(sizeof(struct ltt_kernel_channel)); - chan = malloc(sizeof(struct lttng_kernel_channel)); - if (lkc == NULL || chan == NULL) { - perror("kernel channel malloc"); + if (lkc == NULL) { + perror("ltt_kernel_channel malloc"); goto error; } - /* Default value to channel */ - chan->overwrite = DEFAULT_KERNEL_OVERWRITE; - chan->subbuf_size = DEFAULT_KERNEL_SUBBUF_SIZE; - chan->num_subbuf = DEFAULT_KERNEL_SUBBUF_NUM; - chan->switch_timer_interval = DEFAULT_KERNEL_SWITCH_TIMER; - chan->read_timer_interval = DEFAULT_KERNEL_READ_TIMER; + lkc->channel = malloc(sizeof(struct lttng_channel)); + if (lkc->channel == NULL) { + perror("lttng_channel malloc"); + goto error; + } + memcpy(lkc->channel, chan, sizeof(struct lttng_channel)); lkc->fd = 0; lkc->stream_count = 0; - lkc->channel = chan; + lkc->enabled = 1; /* Init linked list */ CDS_INIT_LIST_HEAD(&lkc->events_list.head); CDS_INIT_LIST_HEAD(&lkc->stream_list.head); /* Set default trace output path */ - ret = asprintf(&lkc->pathname, "%s", DEFAULT_TRACE_OUTPUT); + ret = asprintf(&lkc->pathname, "%s", path); if (ret < 0) { perror("asprintf kernel create channel"); goto error; @@ -110,8 +162,7 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_kernel_event *trace_create_kernel_event(char *name, - enum lttng_kernel_instrumentation type) +struct ltt_kernel_event *trace_create_kernel_event(struct lttng_event *ev) { struct ltt_kernel_event *lke; struct lttng_kernel_event *attr; @@ -123,12 +174,34 @@ struct ltt_kernel_event *trace_create_kernel_event(char *name, goto error; } - /* Init event attribute */ - attr->instrumentation = type; - strncpy(attr->name, name, LTTNG_SYM_NAME_LEN); + switch (ev->type) { + case LTTNG_EVENT_KPROBE: + attr->instrumentation = LTTNG_KERNEL_KPROBE; + attr->u.kprobe.addr = ev->attr.kprobe.addr; + attr->u.kprobe.offset = ev->attr.kprobe.offset; + strncpy(attr->u.kprobe.symbol_name, + ev->attr.kprobe.symbol_name, LTTNG_SYM_NAME_LEN); + break; + case LTTNG_EVENT_FUNCTION: + attr->instrumentation = LTTNG_KERNEL_FUNCTION; + strncpy(attr->u.ftrace.symbol_name, + ev->attr.ftrace.symbol_name, LTTNG_SYM_NAME_LEN); + break; + case LTTNG_EVENT_TRACEPOINT: + attr->instrumentation = LTTNG_KERNEL_TRACEPOINT; + break; + default: + ERR("Unknown kernel instrumentation type (%d)", ev->type); + goto error; + } + + /* Copy event name */ + strncpy(attr->name, ev->name, LTTNG_SYM_NAME_LEN); + /* Setting up a kernel event */ lke->fd = 0; lke->event = attr; + lke->enabled = 1; return lke; @@ -143,31 +216,32 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_kernel_metadata *trace_create_kernel_metadata(void) +struct ltt_kernel_metadata *trace_create_kernel_metadata(char *path) { int ret; struct ltt_kernel_metadata *lkm; - struct lttng_kernel_channel *attr; + struct lttng_channel *chan; lkm = malloc(sizeof(struct ltt_kernel_metadata)); - attr = malloc(sizeof(struct lttng_kernel_channel)); - if (lkm == NULL || attr == NULL) { + chan = malloc(sizeof(struct lttng_channel)); + if (lkm == NULL || chan == NULL) { perror("kernel metadata malloc"); goto error; } /* Set default attributes */ - attr->overwrite = DEFAULT_KERNEL_OVERWRITE; - attr->subbuf_size = DEFAULT_KERNEL_SUBBUF_SIZE; - attr->num_subbuf = DEFAULT_KERNEL_SUBBUF_NUM; - attr->switch_timer_interval = DEFAULT_KERNEL_SWITCH_TIMER; - attr->read_timer_interval = DEFAULT_KERNEL_READ_TIMER; + chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; + chan->attr.subbuf_size = DEFAULT_CHANNEL_SUBBUF_SIZE; + chan->attr.num_subbuf = DEFAULT_CHANNEL_SUBBUF_NUM; + chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; + chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; + chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; /* Init metadata */ lkm->fd = 0; - lkm->conf = attr; + lkm->conf = chan; /* Set default metadata path */ - ret = asprintf(&lkm->pathname, "%s/metadata", DEFAULT_TRACE_OUTPUT); + ret = asprintf(&lkm->pathname, "%s/metadata", path); if (ret < 0) { perror("asprintf kernel metadata"); goto error; @@ -207,3 +281,89 @@ struct ltt_kernel_stream *trace_create_kernel_stream(void) error: return NULL; } + +void trace_destroy_kernel_stream(struct ltt_kernel_stream *stream) +{ + DBG("[trace] Closing stream fd %d", stream->fd); + /* Close kernel fd */ + close(stream->fd); + free(stream->pathname); + + /* Remove from stream list */ + cds_list_del(&stream->list); + free(stream); +} + +void trace_destroy_kernel_event(struct ltt_kernel_event *event) +{ + DBG("[trace] Closing event fd %d", event->fd); + /* Close kernel fd */ + close(event->fd); + /* Free attributes */ + free(event->event); + + /* Remove from event list */ + cds_list_del(&event->list); + free(event); +} + +void trace_destroy_kernel_channel(struct ltt_kernel_channel *channel) +{ + struct ltt_kernel_stream *stream; + struct ltt_kernel_event *event; + + DBG("[trace] Closing channel fd %d", channel->fd); + /* Close kernel fd */ + close(channel->fd); + free(channel->pathname); + /* Free attributes structure */ + free(channel->channel); + + /* For each stream in the channel list */ + cds_list_for_each_entry(stream, &channel->stream_list.head, list) { + trace_destroy_kernel_stream(stream); + } + + /* For each event in the channel list */ + cds_list_for_each_entry(event, &channel->events_list.head, list) { + trace_destroy_kernel_event(event); + } + + /* Remove from channel list */ + cds_list_del(&channel->list); + free(channel); +} + +void trace_destroy_kernel_metadata(struct ltt_kernel_metadata *metadata) +{ + DBG("[trace] Closing metadata fd %d", metadata->fd); + /* Close kernel fd */ + close(metadata->fd); + /* Free attributes */ + free(metadata->conf); + + free(metadata); +} + +void trace_destroy_kernel_session(struct ltt_kernel_session *session) +{ + struct ltt_kernel_channel *channel; + + DBG("[trace] Closing session fd %d", session->fd); + /* Close kernel fds */ + close(session->fd); + if (session->metadata_stream_fd != 0) { + DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd); + close(session->metadata_stream_fd); + } + + if (session->metadata != NULL) { + trace_destroy_kernel_metadata(session->metadata); + } + + cds_list_for_each_entry(channel, &session->channel_list.head, list) { + trace_destroy_kernel_channel(channel); + } + + free(session); +}