Introduce context.c/.h which contains code to manage lttng context.
The add context command is now based on the lttng domain removing the
LTTNG_KERNEL_ADD_CONTEXT to simply LTTNG_ADD_CONTEXT.
Signed-off-by: David Goulet <david.goulet@polymtl.ca>
struct lttng_event_context *ctx, const char *event_name,
const char *channel_name)
{
- int ret = -1;
-
copy_string(lsm.u.context.channel_name, channel_name, NAME_MAX);
copy_string(lsm.u.context.event_name, event_name, NAME_MAX);
+ copy_lttng_domain(domain);
if (ctx) {
memcpy(&lsm.u.context.ctx, ctx, sizeof(struct lttng_event_context));
}
- if (domain) {
- switch (domain->type) {
- case LTTNG_DOMAIN_KERNEL:
- ret = ask_sessiond(LTTNG_KERNEL_ADD_CONTEXT, NULL);
- break;
- case LTTNG_DOMAIN_UST:
- ret = LTTCOMM_NOT_IMPLEMENTED;
- break;
- default:
- ret = LTTCOMM_UNKNOWN_DOMAIN;
- break;
- };
- }
-
- return ret;
+ return ask_sessiond(LTTNG_ADD_CONTEXT, NULL);
}
/*
enum lttcomm_sessiond_command {
/* Tracer context command */
- LTTNG_KERNEL_ADD_CONTEXT,
+ LTTNG_ADD_CONTEXT,
LTTNG_KERNEL_DISABLE_CHANNEL,
LTTNG_KERNEL_DISABLE_EVENT,
LTTNG_KERNEL_DISABLE_ALL_EVENT,
bin_PROGRAMS = ltt-sessiond
-ltt_sessiond_SOURCES = utils.c trace.c session.c traceable-app.c ust-ctl.c kernel-ctl.c main.c \
- utils.h trace.h session.h traceable-app.h ust-ctl.h kernel-ctl.h ltt-sessiond.h
+ltt_sessiond_SOURCES = utils.c trace.c session.c traceable-app.c ust-ctl.c \
+ kernel-ctl.c context.c main.c \
+ utils.h trace.h session.h traceable-app.h ust-ctl.h \
+ context.h kernel-ctl.h ltt-sessiond.h
ltt_sessiond_LDADD = \
$(top_builddir)/liblttsessiondcomm/liblttsessiondcomm.la \
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <urcu/list.h>
+
+#include "lttngerr.h"
+#include "context.h"
+
+/*
+ * Add kernel context to an event of a specific channel.
+ */
+static int add_kctx_to_event(struct lttng_kernel_context *kctx,
+ struct ltt_kernel_channel *kchan, char *event_name)
+{
+ int ret, found = 0;
+ struct ltt_kernel_event *kevent;
+
+ DBG("Add kernel context to event %s", event_name);
+
+ kevent = get_kernel_event_by_name(event_name, kchan);
+ if (kevent != NULL) {
+ ret = kernel_add_event_context(kevent, kctx);
+ if (ret < 0) {
+ goto error;
+ }
+ found = 1;
+ }
+
+ ret = found;
+
+error:
+ return ret;
+}
+
+/*
+ * Add kernel context to all channel.
+ *
+ * If event_name is specified, add context to event instead.
+ */
+static int add_kctx_all_channels(struct ltt_kernel_session *ksession,
+ struct lttng_kernel_context *kctx, char *event_name)
+{
+ int ret, no_event = 0, found = 0;
+ struct ltt_kernel_channel *kchan;
+
+ if (strlen(event_name) == 0) {
+ no_event = 1;
+ }
+
+ DBG("Adding kernel context to all channels (event: %s)", event_name);
+
+ /* Go over all channels */
+ cds_list_for_each_entry(kchan, &ksession->channel_list.head, list) {
+ if (no_event) {
+ ret = kernel_add_channel_context(kchan, kctx);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_CONTEXT_FAIL;
+ goto error;
+ }
+ } else {
+ ret = add_kctx_to_event(kctx, kchan, event_name);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_CONTEXT_FAIL;
+ goto error;
+ } else if (ret == 1) {
+ /* Event found and context added */
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (!found && !no_event) {
+ ret = LTTCOMM_NO_EVENT;
+ goto error;
+ }
+
+ ret = LTTCOMM_OK;
+
+error:
+ return ret;
+}
+
+/*
+ * Add kernel context to a specific channel.
+ *
+ * If event_name is specified, add context to that event.
+ */
+static int add_kctx_to_channel(struct lttng_kernel_context *kctx,
+ struct ltt_kernel_channel *kchan, char *event_name)
+{
+ int ret, no_event = 0, found = 0;
+
+ if (strlen(event_name) == 0) {
+ no_event = 1;
+ }
+
+ DBG("Add kernel context to channel '%s', event '%s'",
+ kchan->channel->name, event_name);
+
+ if (no_event) {
+ ret = kernel_add_channel_context(kchan, kctx);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_CONTEXT_FAIL;
+ goto error;
+ }
+ } else {
+ ret = add_kctx_to_event(kctx, kchan, event_name);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_CONTEXT_FAIL;
+ goto error;
+ } else if (ret == 1) {
+ /* Event found and context added */
+ found = 1;
+ }
+ }
+
+ if (!found && !no_event) {
+ ret = LTTCOMM_NO_EVENT;
+ goto error;
+ }
+
+ ret = LTTCOMM_OK;
+
+error:
+ return ret;
+}
+
+/*
+ * Add kernel context to tracer.
+ */
+int add_kernel_context(struct ltt_kernel_session *ksession,
+ struct lttng_kernel_context *kctx, char *event_name,
+ char *channel_name)
+{
+ int ret;
+ struct ltt_kernel_channel *kchan;
+
+ if (strlen(channel_name) == 0) {
+ ret = add_kctx_all_channels(ksession, kctx, event_name);
+ if (ret != LTTCOMM_OK) {
+ goto error;
+ }
+ } else {
+ /* Get kernel channel */
+ kchan = get_kernel_channel_by_name(channel_name, ksession);
+ if (kchan == NULL) {
+ ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
+ goto error;
+ }
+
+ ret = add_kctx_to_channel(kctx, kchan, event_name);
+ if (ret != LTTCOMM_OK) {
+ goto error;
+ }
+ }
+
+ ret = LTTCOMM_OK;
+
+error:
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
+ *
+ * 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_CONTEXT_H
+#define _LTT_CONTEXT_H
+
+#include <limits.h>
+#include <urcu/list.h>
+
+#include <lttng/lttng.h>
+
+#include "liblttsessiondcomm.h"
+#include "lttng-kernel.h"
+#include "kernel-ctl.h"
+#include "trace.h"
+
+int add_kernel_context(struct ltt_kernel_session *ksession,
+ struct lttng_kernel_context *kctx, char *event_name,
+ char *channel_name);
+
+#endif /* _LTT_CONTEXT_H */
DBG("Adding context to channel %s", chan->channel->name);
ret = kernctl_add_context(chan->fd, ctx);
if (ret < 0) {
- perror("add context ioctl");
+ if (errno != EEXIST) {
+ perror("add context ioctl");
+ } else {
+ /* If EEXIST, we just ignore the error */
+ ret = 0;
+ }
goto error;
}
#include <urcu/list.h> /* URCU list library (-lurcu) */
#include <lttng/lttng.h>
+#include "context.h"
#include "liblttsessiondcomm.h"
#include "ltt-sessiond.h"
#include "lttngerr.h"
* Check kernel command for kernel session.
*/
switch (cmd_ctx->lsm->cmd_type) {
- case LTTNG_KERNEL_ADD_CONTEXT:
+ case LTTNG_ADD_CONTEXT:
case LTTNG_KERNEL_DISABLE_ALL_EVENT:
case LTTNG_KERNEL_DISABLE_CHANNEL:
case LTTNG_KERNEL_DISABLE_EVENT:
/* Process by command type */
switch (cmd_ctx->lsm->cmd_type) {
- case LTTNG_KERNEL_ADD_CONTEXT:
+ case LTTNG_ADD_CONTEXT:
{
- int found = 0, no_event = 0;
- struct ltt_kernel_channel *chan;
- struct ltt_kernel_event *event;
- struct lttng_kernel_context ctx;
+ struct lttng_kernel_context kctx;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 0);
goto setup_error;
}
- /* Check if event name is given */
- if (strlen(cmd_ctx->lsm->u.context.event_name) == 0) {
- no_event = 1;
- }
-
- /* Create Kernel context */
- ctx.ctx = cmd_ctx->lsm->u.context.ctx.ctx;
- ctx.u.perf_counter.type = cmd_ctx->lsm->u.context.ctx.u.perf_counter.type;
- ctx.u.perf_counter.config = cmd_ctx->lsm->u.context.ctx.u.perf_counter.config;
- strncpy(ctx.u.perf_counter.name,
- cmd_ctx->lsm->u.context.ctx.u.perf_counter.name,
- sizeof(ctx.u.perf_counter.name));
-
- if (strlen(cmd_ctx->lsm->u.context.channel_name) == 0) {
- /* Go over all channels */
- DBG("Adding context to all channels");
- cds_list_for_each_entry(chan,
- &cmd_ctx->session->kernel_session->channel_list.head, list) {
- if (no_event) {
- ret = kernel_add_channel_context(chan, &ctx);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CONTEXT_FAIL;
- goto error;
- }
- } else {
- event = get_kernel_event_by_name(cmd_ctx->lsm->u.context.event_name, chan);
- if (event != NULL) {
- ret = kernel_add_event_context(event, &ctx);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CONTEXT_FAIL;
- goto error;
- }
- found = 1;
- break;
- }
- }
- }
- } else {
- chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.context.channel_name,
- cmd_ctx->session->kernel_session);
- if (chan == NULL) {
- ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ /* Create Kernel context */
+ kctx.ctx = cmd_ctx->lsm->u.context.ctx.ctx;
+ kctx.u.perf_counter.type = cmd_ctx->lsm->u.context.ctx.u.perf_counter.type;
+ kctx.u.perf_counter.config = cmd_ctx->lsm->u.context.ctx.u.perf_counter.config;
+ strncpy(kctx.u.perf_counter.name,
+ cmd_ctx->lsm->u.context.ctx.u.perf_counter.name,
+ LTTNG_SYMBOL_NAME_LEN);
+
+ /* Add kernel context to kernel tracer. See context.c */
+ ret = add_kernel_context(cmd_ctx->session->kernel_session, &kctx,
+ cmd_ctx->lsm->u.context.event_name,
+ cmd_ctx->lsm->u.context.channel_name);
+ if (ret != LTTCOMM_OK) {
goto error;
}
-
- if (no_event) {
- ret = kernel_add_channel_context(chan, &ctx);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CONTEXT_FAIL;
- goto error;
- }
- } else {
- event = get_kernel_event_by_name(cmd_ctx->lsm->u.context.event_name, chan);
- if (event != NULL) {
- ret = kernel_add_event_context(event, &ctx);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CONTEXT_FAIL;
- goto error;
- }
- }
- }
- }
-
- if (!found && !no_event) {
- ret = LTTCOMM_NO_EVENT;
- goto error;
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
}
ret = LTTCOMM_OK;