X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Ftrace.c;h=5cd053652451678e56b25cc50dbe6037701b2765;hp=1cddb31fac9c6bb68a8a9f401e6567a08941f33d;hb=d686b40f66ea5df5ac0b9405991bbc33348b0a88;hpb=20fe210416ef1cc0e9b85e5a40c58344e3185fd6 diff --git a/ltt-sessiond/trace.c b/ltt-sessiond/trace.c index 1cddb31fa..5cd053652 100644 --- a/ltt-sessiond/trace.c +++ b/ltt-sessiond/trace.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 - David Goulet + * 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 @@ -17,199 +17,277 @@ */ #define _GNU_SOURCE -#include -#include #include #include #include +#include #include -#include -#include "liblttsessiondcomm.h" #include "lttngerr.h" -#include "trace.h" -#include "session.h" #include "ltt-sessiond.h" - -static struct ltt_ust_trace *find_session_ust_trace_by_pid( - struct ltt_session *session, pid_t pid); +#include "trace.h" /* - * find_session_ust_trace_by_pid + * trace_create_kernel_session + * + * Allocate and initialize a kernel session data structure. * - * Iterate over the session ust_traces and - * return a pointer or NULL if not found. + * Return pointer to structure or NULL. */ -static struct ltt_ust_trace *find_session_ust_trace_by_pid( - struct ltt_session *session, pid_t pid) +struct ltt_kernel_session *trace_create_kernel_session(void) { - struct ltt_ust_trace *iter; + struct ltt_kernel_session *lks; - cds_list_for_each_entry(iter, &session->ust_traces, list) { - if (iter->pid == pid) { - /* Found */ - return iter; - } + /* Allocate a new ltt kernel session */ + lks = malloc(sizeof(struct ltt_kernel_session)); + if (lks == NULL) { + perror("create kernel session malloc"); + goto error; } + /* Init data structure */ + lks->fd = 0; + lks->metadata_stream_fd = 0; + lks->channel_count = 0; + lks->stream_count_global = 0; + lks->metadata = NULL; + CDS_INIT_LIST_HEAD(&lks->channel_list.head); + + return lks; + +error: return NULL; } /* - * get_trace_count_per_session + * trace_create_kernel_channel * - * Return the total count of traces (ust and kernel) - * for the specified session. + * Allocate and initialize a kernel channel data structure. + * + * Return pointer to structure or NULL. */ -int get_trace_count_per_session(struct ltt_session *session) +struct ltt_kernel_channel *trace_create_kernel_channel(void) { - return session->ust_trace_count + session->kern_session_count; + 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"); + 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->fd = 0; + lkc->stream_count = 0; + lkc->channel = chan; + /* 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); + if (ret < 0) { + perror("asprintf kernel create channel"); + goto error; + } + + return lkc; + +error: + return NULL; } /* - * get_traces_per_session + * trace_create_kernel_event + * + * Allocate and initialize a kernel event. Set name and event type. * - * Fill the lttng_trace array of all the - * available trace of the session. + * Return pointer to structure or NULL. */ -void get_traces_per_session(struct ltt_session *session, struct lttng_trace *traces) +struct ltt_kernel_event *trace_create_kernel_event(char *name, + enum lttng_kernel_instrumentation type) { - int i = 0; - struct ltt_ust_trace *ust_iter; - struct lttng_trace trace; - - DBG("Getting userspace traces for session %s", session->name); - - /* Getting userspace traces */ - cds_list_for_each_entry(ust_iter, &session->ust_traces, list) { - trace.type = USERSPACE; - trace.pid = ust_iter->pid; - strncpy(trace.name, ust_iter->name, sizeof(trace.name)); - trace.name[sizeof(trace.name) - 1] = '\0'; - memcpy(&traces[i], &trace, sizeof(trace)); - memset(&trace, 0, sizeof(trace)); - i++; + struct ltt_kernel_event *lke; + struct lttng_kernel_event *attr; + + lke = malloc(sizeof(struct ltt_kernel_event)); + attr = malloc(sizeof(struct lttng_kernel_event)); + if (lke == NULL || attr == NULL) { + perror("kernel event malloc"); + goto error; } - DBG("Getting kernel traces for session %s", session->name); + /* Init event attribute */ + attr->instrumentation = type; + strncpy(attr->name, name, LTTNG_SYM_NAME_LEN); + /* Setting up a kernel event */ + lke->fd = 0; + lke->event = attr; - /* Getting kernel traces */ - if (session->kern_session_count > 0) { - trace.type = KERNEL; - strncpy(trace.name, "kernel", 6); - memcpy(&traces[i], &trace, sizeof(trace)); - } + return lke; + +error: + return NULL; } /* - * ust_create_trace + * trace_create_kernel_metadata * - * Create an userspace trace using pid. - * This trace is then appended to the current session - * ust trace list. + * Allocate and initialize a kernel metadata. + * + * Return pointer to structure or NULL. */ -int ust_create_trace(struct command_ctx *cmd_ctx) +struct ltt_kernel_metadata *trace_create_kernel_metadata(void) { int ret; - struct ltt_ust_trace *trace; - - DBG("Creating trace for pid %d", cmd_ctx->lsm->pid); + struct ltt_kernel_metadata *lkm; + struct lttng_kernel_channel *attr; - trace = malloc(sizeof(struct ltt_ust_trace)); - if (trace == NULL) { - perror("malloc"); - ret = -1; + lkm = malloc(sizeof(struct ltt_kernel_metadata)); + attr = malloc(sizeof(struct lttng_kernel_channel)); + if (lkm == NULL || attr == NULL) { + perror("kernel metadata malloc"); goto error; } - /* Init */ - trace->pid = cmd_ctx->lsm->pid; - trace->shmid = 0; - /* NOTE: to be removed. Trace name will no longer be - * required for LTTng userspace tracer. For now, we set it - * to 'auto' for API compliance. - */ - snprintf(trace->name, 5, "auto"); - - ret = ustctl_create_trace(cmd_ctx->ust_sock, trace->name); + /* 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; + + /* Init metadata */ + lkm->fd = 0; + lkm->conf = attr; + /* Set default metadata path */ + ret = asprintf(&lkm->pathname, "%s/metadata", DEFAULT_TRACE_OUTPUT); if (ret < 0) { - ret = LTTCOMM_CREATE_FAIL; - goto error_create; - } - - /* Check if current session is valid */ - if (cmd_ctx->session) { - cds_list_add(&trace->list, &cmd_ctx->session->ust_traces); - cmd_ctx->session->ust_trace_count++; + perror("asprintf kernel metadata"); + goto error; } - return LTTCOMM_OK; + return lkm; -error_create: - free(trace); error: - return ret; + return NULL; } /* - * ust_start_trace + * trace_create_kernel_stream + * + * Allocate and initialize a kernel stream. The stream is set to ACTIVE_FD by + * default. * - * Start a trace. This trace, identified by the pid, must be - * in the current session ust_traces list. + * Return pointer to structure or NULL. */ -int ust_start_trace(struct command_ctx *cmd_ctx) +struct ltt_kernel_stream *trace_create_kernel_stream(void) { - int ret; - struct ltt_ust_trace *trace; - - DBG("Starting trace for pid %d", cmd_ctx->lsm->pid); + struct ltt_kernel_stream *lks; - trace = find_session_ust_trace_by_pid(cmd_ctx->session, cmd_ctx->lsm->pid); - if (trace == NULL) { - ret = LTTCOMM_NO_TRACE; + lks = malloc(sizeof(struct ltt_kernel_stream)); + if (lks == NULL) { + perror("kernel stream malloc"); goto error; } - ret = ustctl_start_trace(cmd_ctx->ust_sock, "auto"); - if (ret < 0) { - ret = LTTCOMM_START_FAIL; - goto error; - } + /* Init stream */ + lks->fd = 0; + lks->pathname = NULL; + lks->state = 0; - ret = LTTCOMM_OK; + return lks; error: - return ret; + return NULL; } -/* - * ust_stop_trace - * - * Stop a trace. This trace, identified by the pid, must be - * in the current session ust_traces list. - */ -int ust_stop_trace(struct command_ctx *cmd_ctx) +void trace_destroy_kernel_stream(struct ltt_kernel_stream *stream) { - int ret; - struct ltt_ust_trace *trace; + 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); +} - DBG("Stopping trace for pid %d", cmd_ctx->lsm->pid); +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); +} - trace = find_session_ust_trace_by_pid(cmd_ctx->session, cmd_ctx->lsm->pid); - if (trace == NULL) { - ret = LTTCOMM_NO_TRACE; - goto error; +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); } - ret = ustctl_stop_trace(cmd_ctx->ust_sock, trace->name); - if (ret < 0) { - ret = LTTCOMM_STOP_FAIL; - goto error; + /* For each event in the channel list */ + cds_list_for_each_entry(event, &channel->events_list.head, list) { + trace_destroy_kernel_event(event); } - ret = LTTCOMM_OK; + /* Remove from channel list */ + cds_list_del(&channel->list); + free(channel); +} -error: - return ret; +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); + DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd); + close(session->metadata_stream_fd); + + trace_destroy_kernel_metadata(session->metadata); + + cds_list_for_each_entry(channel, &session->channel_list.head, list) { + trace_destroy_kernel_channel(channel); + } + + free(session); +}