From: David Goulet Date: Fri, 26 Aug 2011 16:23:22 +0000 (-0400) Subject: Add UST trace data structure and functions X-Git-Tag: v2.0-pre13~23 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=97ee3a894d61db2c12b0fe09ee22f76140449a6f Add UST trace data structure and functions Signed-off-by: David Goulet --- diff --git a/include/lttng-ust.h b/include/lttng-ust.h index 284b24cbc..abfd613b9 100644 --- a/include/lttng-ust.h +++ b/include/lttng-ust.h @@ -4,7 +4,8 @@ /* * Taken from the lttng-ust-abi.h in the UST 2.0 git tree * - * Copyright 2010-2011 (c) - Mathieu Desnoyers + * Copyright 2010-2011 - Mathieu Desnoyers + * Copyright 2011 - David Goulet * * LTTng-UST ABI header * @@ -13,10 +14,13 @@ #include -#define LTTNG_UST_SYM_NAME_LEN 128 +#define LTTNG_UST_SYM_NAME_LEN 128 -#define LTTNG_UST_COMM_VERSION_MAJOR 0 -#define LTTNG_UST_COMM_VERSION_MINOR 1 +#define LTTNG_UST_COMM_VERSION_MAJOR 0 +#define LTTNG_UST_COMM_VERSION_MINOR 1 + +/* See lttng-ust.h enum lttng_ust_output */ +#define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_UST_MMAP enum lttng_ust_instrumentation { LTTNG_UST_TRACEPOINT = 0, diff --git a/ltt-sessiond/Makefile.am b/ltt-sessiond/Makefile.am index 1603b29c6..6cffbd738 100644 --- a/ltt-sessiond/Makefile.am +++ b/ltt-sessiond/Makefile.am @@ -7,6 +7,7 @@ bin_PROGRAMS = ltt-sessiond ltt_sessiond_SOURCES = utils.c utils.h \ trace-kernel.c trace-kernel.h \ + trace-ust.c trace-ust.h \ session.c session.h \ traceable-app.c traceable-app.h \ ust-ctl.c ust-ctl.h \ diff --git a/ltt-sessiond/trace-ust.c b/ltt-sessiond/trace-ust.c new file mode 100644 index 000000000..957ac770b --- /dev/null +++ b/ltt-sessiond/trace-ust.c @@ -0,0 +1,326 @@ +/* + * 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 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. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include +#include + +#include "trace-ust.h" + +/* + * Find the channel name for the given ust session. + */ +struct ltt_ust_channel *trace_ust_get_channel_by_name( + char *name, struct ltt_ust_session *session) +{ + struct ltt_ust_channel *chan; + + if (session == NULL) { + ERR("Undefine session"); + goto error; + } + + cds_list_for_each_entry(chan, &session->channels.head, list) { + if (strcmp(name, chan->name) == 0) { + DBG("Found UST channel by name %s", name); + return chan; + } + } + +error: + return NULL; +} + +/* + * Find the event name for the given channel. + */ +struct ltt_ust_event *trace_ust_get_event_by_name( + char *name, struct ltt_ust_channel *channel) +{ + struct ltt_ust_event *ev; + + if (channel == NULL) { + ERR("Undefine channel"); + goto error; + } + + cds_list_for_each_entry(ev, &channel->events.head, list) { + if (strcmp(name, ev->event->name) == 0) { + DBG("Found UST event by name %s for channel %s", name, + channel->name); + return ev; + } + } + +error: + return NULL; +} + +/* + * Allocate and initialize a ust session data structure. + * + * Return pointer to structure or NULL. + */ +struct ltt_ust_session *trace_ust_create_session(void) +{ + struct ltt_ust_session *lus; + + /* Allocate a new ltt ust session */ + lus = malloc(sizeof(struct ltt_ust_session)); + if (lus == NULL) { + perror("create ust session malloc"); + goto error; + } + + /* Init data structure */ + lus->handle = -1; + lus->enabled = 1; + lus->uconsumer_fds_sent = 0; + lus->path = NULL; + lus->metadata = NULL; + lus->channels.count = 0; + CDS_INIT_LIST_HEAD(&lus->channels.head); + + return lus; + +error: + return NULL; +} + +/* + * Allocate and initialize a ust channel data structure. + * + * Return pointer to structure or NULL. + */ +struct ltt_ust_channel *trace_ust_create_channel(char *name, char *path, + struct lttng_ust_channel *chan) +{ + int ret; + struct ltt_ust_channel *luc; + + luc = malloc(sizeof(struct ltt_ust_channel)); + if (luc == NULL) { + perror("ltt_ust_channel malloc"); + goto error; + } + + luc->attr = malloc(sizeof(struct lttng_ust_channel)); + if (luc->attr == NULL) { + perror("lttng_ust_channel malloc"); + goto error; + } + memcpy(luc->attr, chan, sizeof(struct lttng_ust_channel)); + + luc->handle = -1; + luc->enabled = 1; + luc->ctx = NULL; + luc->events.count = 0; + CDS_INIT_LIST_HEAD(&luc->events.head); + + /* Copy channel name */ + strncpy(luc->name, name, LTTNG_UST_SYM_NAME_LEN); + luc->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + + /* Set trace output path */ + ret = asprintf(&luc->trace_path, "%s", path); + if (ret < 0) { + perror("asprintf ust create channel"); + goto error; + } + + return luc; + +error: + return NULL; +} + +/* + * Allocate and initialize a ust event. Set name and event type. + * + * Return pointer to structure or NULL. + */ +struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev) +{ + struct ltt_ust_event *lue; + struct lttng_ust_event *event; + + lue = malloc(sizeof(struct ltt_ust_event)); + event = malloc(sizeof(struct lttng_ust_event)); + if (lue == NULL || event == NULL) { + perror("ust event malloc"); + goto error; + } + + switch (ev->type) { + case LTTNG_EVENT_PROBE: + event->instrumentation = LTTNG_UST_PROBE; + break; + case LTTNG_EVENT_FUNCTION: + event->instrumentation = LTTNG_UST_FUNCTION; + break; + case LTTNG_EVENT_FUNCTION_ENTRY: + event->instrumentation = LTTNG_UST_FUNCTION; + break; + case LTTNG_EVENT_TRACEPOINT: + event->instrumentation = LTTNG_UST_TRACEPOINT; + break; + default: + ERR("Unknown ust instrumentation type (%d)", ev->type); + goto error; + } + + /* Copy event name */ + strncpy(event->name, ev->name, LTTNG_UST_SYM_NAME_LEN); + event->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + + /* Setting up a ust event */ + lue->handle = -1; + lue->event = event; + lue->enabled = 1; + lue->ctx = NULL; + + return lue; + +error: + return NULL; +} + +/* + * Allocate and initialize a ust metadata. + * + * Return pointer to structure or NULL. + */ +struct ltt_ust_metadata *trace_ust_create_metadata(char *path) +{ + int ret; + struct ltt_ust_metadata *lum; + struct lttng_ust_channel *attr; + + lum = malloc(sizeof(struct ltt_ust_metadata)); + attr = malloc(sizeof(struct lttng_ust_channel)); + if (lum == NULL || attr == NULL) { + perror("ust metadata malloc"); + goto error; + } + + /* Set default attributes */ + attr->overwrite = DEFAULT_CHANNEL_OVERWRITE; + attr->subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + attr->num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; + attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; + attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; + attr->output = DEFAULT_UST_CHANNEL_OUTPUT; + + lum->attr = attr; + lum->handle = -1; + /* Set metadata trace path */ + ret = asprintf(&lum->trace_path, "%s/metadata", path); + if (ret < 0) { + perror("asprintf ust metadata"); + goto error; + } + + return lum; + +error: + return NULL; +} + +/* + * Cleanup ust event structure. + */ +void trace_ust_destroy_event(struct ltt_ust_event *event) +{ + DBG("[trace] Destroy ust event %s", event->event->name); + + /* Free attributes */ + free(event->event); + free(event->ctx); + + /* Remove from event list */ + cds_list_del(&event->list); + free(event); +} + +/* + * Cleanup ust channel structure. + */ +void trace_ust_destroy_channel(struct ltt_ust_channel *channel) +{ + struct ltt_ust_event *event, *etmp; + + DBG("[trace] Destroy ust channel %d", channel->handle); + + free(channel->trace_path); + /* Free attributes structure */ + free(channel->attr); + free(channel->ctx); + + /* For each event in the channel list */ + cds_list_for_each_entry_safe(event, etmp, &channel->events.head, list) { + trace_ust_destroy_event(event); + } + + /* Remove from channel list */ + cds_list_del(&channel->list); + free(channel); +} + +/* + * Cleanup ust metadata structure. + */ +void trace_ust_destroy_metadata(struct ltt_ust_metadata *metadata) +{ + DBG("[trace] Destroy ust metadata %d", metadata->handle); + + /* Free attributes */ + free(metadata->attr); + free(metadata->trace_path); + + free(metadata); +} + +/* + * Cleanup ust session structure + */ +void trace_ust_destroy_session(struct ltt_ust_session *session) +{ + struct ltt_ust_channel *channel, *ctmp; + + DBG("[trace] Destroy ust session %d", session->handle); + + /* Extra safety */ + if (session == NULL) { + return; + } + + if (session->metadata != NULL) { + trace_ust_destroy_metadata(session->metadata); + } + + cds_list_for_each_entry_safe(channel, ctmp, &session->channels.head, list) { + trace_ust_destroy_channel(channel); + } + + free(session->path); + free(session); +} diff --git a/ltt-sessiond/trace-ust.h b/ltt-sessiond/trace-ust.h new file mode 100644 index 000000000..fa86cb94f --- /dev/null +++ b/ltt-sessiond/trace-ust.h @@ -0,0 +1,104 @@ +/* + * 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 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. + */ + +#ifndef _LTT_TRACE_UST_H +#define _LTT_TRACE_UST_H + +#include +#include + +#include +#include + +/* UST event list */ +struct ltt_ust_event_list { + unsigned int count; + struct cds_list_head head; +}; + +/* UST Channel list */ +struct ltt_ust_channel_list { + unsigned int count; + struct cds_list_head head; +}; + +/* UST event */ +struct ltt_ust_event { + int handle; + int enabled; + struct lttng_ust_context *ctx; + struct lttng_ust_event *event; + struct cds_list_head list; +}; + +/* UST channel */ +struct ltt_ust_channel { + int handle; + int enabled; + char *name; + char *trace_path; /* Trace file path name */ + struct lttng_ust_context *ctx; + struct lttng_ust_channel *attr; + struct ltt_ust_event_list events; + struct cds_list_head list; +}; + +/* UST Metadata */ +struct ltt_ust_metadata { + int handle; + char *trace_path; /* Trace file path name */ + struct lttng_ust_channel *attr; +}; + +/* UST session */ +struct ltt_ust_session { + int handle; + int enabled; + int uconsumer_fds_sent; + char *path; + struct ltt_ust_metadata *metadata; + struct ltt_ust_channel_list channels; +}; + +/* + * Lookup functions. NULL is returned if not found. + */ +struct ltt_ust_event *trace_ust_get_event_by_name( + char *name, struct ltt_ust_channel *channel); +struct ltt_ust_channel *trace_ust_get_channel_by_name( + char *name, struct ltt_ust_session *session); + +/* + * Create functions malloc() the data structure. + */ +struct ltt_ust_session *trace_ust_create_session(void); +struct ltt_ust_channel *trace_ust_create_channel(char *name, char *path, + struct lttng_ust_channel *attr); +struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev); +struct ltt_ust_metadata *trace_ust_create_metadata(char *path); + +/* + * Destroy functions free() the data structure and remove from linked list if + * it's applies. + */ +void trace_ust_destroy_session(struct ltt_ust_session *session); +void trace_ust_destroy_metadata(struct ltt_ust_metadata *metadata); +void trace_ust_destroy_channel(struct ltt_ust_channel *channel); +void trace_ust_destroy_event(struct ltt_ust_event *event); + +#endif /* _LTT_TRACE_UST_H */