Rewrite the add context command of sessiond
[lttng-tools.git] / ltt-sessiond / context.c
diff --git a/ltt-sessiond/context.c b/ltt-sessiond/context.c
new file mode 100644 (file)
index 0000000..dc77122
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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;
+}
This page took 0.024612 seconds and 4 git commands to generate.