X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Ftrace-kernel.c;h=d889b6ab6582570587c9c4a66cdcf51fad30943a;hp=d1225c07c4f286f3b15c392dff0ed63133783bd1;hb=36b588eddce05ef840bd247f6a58316925b9a0a2;hpb=10a8a2237343699e3923d87e24dbf2d7fe225377 diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index d1225c07c..d889b6ab6 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -1,19 +1,18 @@ /* * Copyright (C) 2011 - David Goulet * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; only version 2 - * of the License. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 only, + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _GNU_SOURCE @@ -22,9 +21,10 @@ #include #include -#include -#include +#include +#include +#include "consumer.h" #include "trace-kernel.h" /* @@ -35,10 +35,8 @@ struct ltt_kernel_channel *trace_kernel_get_channel_by_name( { struct ltt_kernel_channel *chan; - if (session == NULL) { - ERR("Undefine session"); - goto error; - } + assert(session); + assert(name); DBG("Trying to find channel %s", name); @@ -49,7 +47,6 @@ struct ltt_kernel_channel *trace_kernel_get_channel_by_name( } } -error: return NULL; } @@ -61,10 +58,8 @@ struct ltt_kernel_event *trace_kernel_get_event_by_name( { struct ltt_kernel_event *ev; - if (channel == NULL) { - ERR("Undefine channel"); - goto error; - } + assert(name); + assert(channel); cds_list_for_each_entry(ev, &channel->events_list.head, list) { if (strcmp(name, ev->event->name) == 0) { @@ -74,7 +69,6 @@ struct ltt_kernel_event *trace_kernel_get_event_by_name( } } -error: return NULL; } @@ -83,37 +77,44 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_kernel_session *trace_kernel_create_session(char *path) +struct ltt_kernel_session *trace_kernel_create_session(void) { - int ret; - struct ltt_kernel_session *lks; + struct ltt_kernel_session *lks = NULL; /* Allocate a new ltt kernel session */ lks = zmalloc(sizeof(struct ltt_kernel_session)); if (lks == NULL) { - perror("create kernel session zmalloc"); - goto error; + PERROR("create kernel session zmalloc"); + goto alloc_error; } /* Init data structure */ - lks->fd = 0; - lks->metadata_stream_fd = 0; + lks->fd = -1; + lks->metadata_stream_fd = -1; lks->channel_count = 0; lks->stream_count_global = 0; lks->metadata = NULL; - lks->consumer_fd = 0; CDS_INIT_LIST_HEAD(&lks->channel_list.head); - /* Set session path */ - ret = asprintf(&lks->trace_path, "%s/kernel", path); - if (ret < 0) { - perror("asprintf kernel traces path"); + lks->consumer = consumer_create_output(CONSUMER_DST_LOCAL); + if (lks->consumer == NULL) { goto error; } + /* + * The tmp_consumer stays NULL until a set_consumer_uri command is + * executed. At this point, the consumer should be nullify until an + * enable_consumer command. This assignment is symbolic since we've zmalloc + * the struct. + */ + lks->tmp_consumer = NULL; + return lks; error: + free(lks); + +alloc_error: return NULL; } @@ -122,25 +123,28 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_kernel_channel *trace_kernel_create_channel(struct lttng_channel *chan, char *path) +struct ltt_kernel_channel *trace_kernel_create_channel( + struct lttng_channel *chan) { - int ret; struct ltt_kernel_channel *lkc; + assert(chan); + lkc = zmalloc(sizeof(struct ltt_kernel_channel)); if (lkc == NULL) { - perror("ltt_kernel_channel zmalloc"); + PERROR("ltt_kernel_channel zmalloc"); goto error; } lkc->channel = zmalloc(sizeof(struct lttng_channel)); if (lkc->channel == NULL) { - perror("lttng_channel zmalloc"); + PERROR("lttng_channel zmalloc"); + free(lkc); goto error; } memcpy(lkc->channel, chan, sizeof(struct lttng_channel)); - lkc->fd = 0; + lkc->fd = -1; lkc->stream_count = 0; lkc->event_count = 0; lkc->enabled = 1; @@ -148,12 +152,6 @@ struct ltt_kernel_channel *trace_kernel_create_channel(struct lttng_channel *cha /* 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", path); - if (ret < 0) { - perror("asprintf kernel create channel"); - goto error; - } return lkc; @@ -171,10 +169,12 @@ struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev) struct ltt_kernel_event *lke; struct lttng_kernel_event *attr; + assert(ev); + lke = zmalloc(sizeof(struct ltt_kernel_event)); attr = zmalloc(sizeof(struct lttng_kernel_event)); if (lke == NULL || attr == NULL) { - perror("kernel event zmalloc"); + PERROR("kernel event zmalloc"); goto error; } @@ -184,8 +184,8 @@ struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev) attr->u.kprobe.addr = ev->attr.probe.addr; attr->u.kprobe.offset = ev->attr.probe.offset; strncpy(attr->u.kprobe.symbol_name, - ev->attr.probe.symbol_name, LTTNG_SYM_NAME_LEN); - attr->u.kprobe.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + ev->attr.probe.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN); + attr->u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; break; case LTTNG_EVENT_FUNCTION: attr->instrumentation = LTTNG_KERNEL_KRETPROBE; @@ -193,14 +193,14 @@ struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev) attr->u.kretprobe.offset = ev->attr.probe.offset; attr->u.kretprobe.offset = ev->attr.probe.offset; strncpy(attr->u.kretprobe.symbol_name, - ev->attr.probe.symbol_name, LTTNG_SYM_NAME_LEN); - attr->u.kretprobe.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + ev->attr.probe.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN); + attr->u.kretprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; break; case LTTNG_EVENT_FUNCTION_ENTRY: attr->instrumentation = LTTNG_KERNEL_FUNCTION; strncpy(attr->u.ftrace.symbol_name, - ev->attr.ftrace.symbol_name, LTTNG_SYM_NAME_LEN); - attr->u.ftrace.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + ev->attr.ftrace.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN); + attr->u.ftrace.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; break; case LTTNG_EVENT_TRACEPOINT: attr->instrumentation = LTTNG_KERNEL_TRACEPOINT; @@ -217,18 +217,19 @@ struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev) } /* Copy event name */ - strncpy(attr->name, ev->name, LTTNG_SYM_NAME_LEN); - attr->name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + strncpy(attr->name, ev->name, LTTNG_KERNEL_SYM_NAME_LEN); + attr->name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; /* Setting up a kernel event */ - lke->fd = 0; + lke->fd = -1; lke->event = attr; lke->enabled = 1; - lke->ctx = NULL; return lke; error: + free(lke); + free(attr); return NULL; } @@ -237,40 +238,35 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_kernel_metadata *trace_kernel_create_metadata(char *path) +struct ltt_kernel_metadata *trace_kernel_create_metadata(void) { - int ret; struct ltt_kernel_metadata *lkm; struct lttng_channel *chan; lkm = zmalloc(sizeof(struct ltt_kernel_metadata)); chan = zmalloc(sizeof(struct lttng_channel)); if (lkm == NULL || chan == NULL) { - perror("kernel metadata zmalloc"); + PERROR("kernel metadata zmalloc"); goto error; } /* Set default attributes */ chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - chan->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_metadata_subbuf_size(); chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; - chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; - chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; + chan->attr.switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER; + chan->attr.read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER; chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; /* Init metadata */ - lkm->fd = 0; + lkm->fd = -1; lkm->conf = chan; - /* Set default metadata path */ - ret = asprintf(&lkm->pathname, "%s/metadata", path); - if (ret < 0) { - perror("asprintf kernel metadata"); - goto error; - } return lkm; error: + free(lkm); + free(chan); return NULL; } @@ -280,20 +276,32 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_kernel_stream *trace_kernel_create_stream(void) +struct ltt_kernel_stream *trace_kernel_create_stream(const char *name, + unsigned int count) { + int ret; struct ltt_kernel_stream *lks; + assert(name); + lks = zmalloc(sizeof(struct ltt_kernel_stream)); if (lks == NULL) { - perror("kernel stream zmalloc"); + PERROR("kernel stream zmalloc"); goto error; } + /* Set name */ + ret = snprintf(lks->name, sizeof(lks->name), "%s_%d", name, count); + if (ret < 0) { + PERROR("snprintf stream name"); + goto error; + } + lks->name[sizeof(lks->name) - 1] = '\0'; + /* Init stream */ - lks->fd = 0; - lks->pathname = NULL; + lks->fd = -1; lks->state = 0; + lks->cpu = count; return lks; @@ -306,13 +314,21 @@ error: */ void trace_kernel_destroy_stream(struct ltt_kernel_stream *stream) { + assert(stream); + DBG("[trace] Closing stream fd %d", stream->fd); /* Close kernel fd */ - close(stream->fd); + if (stream->fd >= 0) { + int ret; + + ret = close(stream->fd); + if (ret) { + PERROR("close"); + } + } /* Remove from stream list */ cds_list_del(&stream->list); - free(stream->pathname); free(stream); } @@ -321,15 +337,25 @@ void trace_kernel_destroy_stream(struct ltt_kernel_stream *stream) */ void trace_kernel_destroy_event(struct ltt_kernel_event *event) { - DBG("[trace] Closing event fd %d", event->fd); - /* Close kernel fd */ - close(event->fd); + assert(event); + + if (event->fd >= 0) { + int ret; + + DBG("[trace] Closing event fd %d", event->fd); + /* Close kernel fd */ + ret = close(event->fd); + if (ret) { + PERROR("close"); + } + } else { + DBG("[trace] Tearing down event (no associated fd)"); + } /* Remove from event list */ cds_list_del(&event->list); free(event->event); - free(event->ctx); free(event); } @@ -340,10 +366,18 @@ void trace_kernel_destroy_channel(struct ltt_kernel_channel *channel) { struct ltt_kernel_stream *stream, *stmp; struct ltt_kernel_event *event, *etmp; + int ret; + + assert(channel); DBG("[trace] Closing channel fd %d", channel->fd); /* Close kernel fd */ - close(channel->fd); + if (channel->fd >= 0) { + ret = close(channel->fd); + if (ret) { + PERROR("close"); + } + } /* For each stream in the channel list */ cds_list_for_each_entry_safe(stream, stmp, &channel->stream_list.head, list) { @@ -358,7 +392,6 @@ void trace_kernel_destroy_channel(struct ltt_kernel_channel *channel) /* Remove from channel list */ cds_list_del(&channel->list); - free(channel->pathname); free(channel->channel); free(channel->ctx); free(channel); @@ -369,29 +402,50 @@ void trace_kernel_destroy_channel(struct ltt_kernel_channel *channel) */ void trace_kernel_destroy_metadata(struct ltt_kernel_metadata *metadata) { + assert(metadata); + DBG("[trace] Closing metadata fd %d", metadata->fd); /* Close kernel fd */ - close(metadata->fd); + if (metadata->fd >= 0) { + int ret; + + ret = close(metadata->fd); + if (ret) { + PERROR("close"); + } + } free(metadata->conf); - free(metadata->pathname); free(metadata); } /* * Cleanup kernel session structure + * + * Should *NOT* be called with RCU read-side lock held. */ void trace_kernel_destroy_session(struct ltt_kernel_session *session) { struct ltt_kernel_channel *channel, *ctmp; + int ret; + + assert(session); DBG("[trace] Closing session fd %d", session->fd); /* Close kernel fds */ - close(session->fd); + if (session->fd >= 0) { + ret = close(session->fd); + if (ret) { + PERROR("close"); + } + } - if (session->metadata_stream_fd != 0) { + if (session->metadata_stream_fd >= 0) { DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd); - close(session->metadata_stream_fd); + ret = close(session->metadata_stream_fd); + if (ret) { + PERROR("close"); + } } if (session->metadata != NULL) { @@ -402,6 +456,9 @@ void trace_kernel_destroy_session(struct ltt_kernel_session *session) trace_kernel_destroy_channel(channel); } - free(session->trace_path); + /* Wipe consumer output object */ + consumer_destroy_output(session->consumer); + consumer_destroy_output(session->tmp_consumer); + free(session); }