filter_expression = NULL;
filter = NULL;
exclusion = NULL;
- if (ret != LTTNG_OK) {
+ if (ret != LTTNG_OK && ret != LTTNG_ERR_UST_EVENT_ENABLED) {
goto error;
}
break;
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* 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,
#include <lttng/lttng.h>
#include <common/error.h>
#include <common/sessiond-comm/sessiond-comm.h>
+#include <common/filter.h>
+#include <common/context.h>
#include "channel.h"
#include "event.h"
return ret;
}
+/*
+ * Check if this event's filter requires the activation of application contexts
+ * and enable them in the agent.
+ */
+static int add_filter_app_ctx(struct lttng_filter_bytecode *bytecode,
+ const char *filter_expression, struct agent *agt)
+{
+ int ret = LTTNG_OK;
+ char *provider_name = NULL, *ctx_name = NULL;
+ struct bytecode_symbol_iterator *it =
+ bytecode_symbol_iterator_create(bytecode);
+
+ if (!it) {
+ ret = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ do {
+ struct lttng_event_context ctx;
+ const char *symbol_name =
+ bytecode_symbol_iterator_get_name(it);
+
+ if (parse_application_context(symbol_name, &provider_name,
+ &ctx_name)) {
+ /* Not an application context. */
+ continue;
+ }
+
+ ctx.ctx = LTTNG_EVENT_CONTEXT_APP_CONTEXT;
+ ctx.u.app_ctx.provider_name = provider_name;
+ ctx.u.app_ctx.ctx_name = ctx_name;
+
+ /* Recognized an application context. */
+ DBG("Enabling event with filter expression \"%s\" requires enabling the %s:%s application context.",
+ filter_expression, provider_name, ctx_name);
+
+ ret = agent_add_context(&ctx, agt);
+ if (ret != LTTNG_OK) {
+ ERR("Failed to add application context %s:%s.",
+ provider_name, ctx_name);
+ goto end;
+ }
+
+ ret = agent_enable_context(&ctx, agt->domain);
+ if (ret != LTTNG_OK) {
+ ERR("Failed to enable application context %s:%s.",
+ provider_name, ctx_name);
+ goto end;
+ }
+
+ free(provider_name);
+ free(ctx_name);
+ provider_name = ctx_name = NULL;
+ } while (bytecode_symbol_iterator_next(it) == 0);
+end:
+ free(provider_name);
+ free(ctx_name);
+ bytecode_symbol_iterator_destroy(it);
+ return ret;
+}
+
/*
* Enable a single agent event for a given UST session.
*
filter_expression ? filter_expression : "NULL");
aevent = agent_find_event(event->name, event->loglevel_type,
- event->loglevel, filter_expression, agt);
+ event->loglevel, filter_expression, agt);
if (!aevent) {
aevent = agent_create_event(event->name, event->loglevel_type,
event->loglevel, filter,
ret = LTTNG_ERR_NOMEM;
goto error;
}
+
created = 1;
}
goto end;
}
+ if (created && filter) {
+ ret = add_filter_app_ctx(filter, filter_expression, agt);
+ if (ret != LTTNG_OK) {
+ goto error;
+ }
+ }
+
ret = agent_enable_event(aevent, agt->domain);
if (ret != LTTNG_OK) {
goto error;
pipe.c pipe.h readwrite.c readwrite.h \
mi-lttng.h mi-lttng.c \
daemonize.c daemonize.h \
- sessiond-comm/unix.c sessiond-comm/unix.h
+ sessiond-comm/unix.c sessiond-comm/unix.h \
+ filter.c filter.h context.c context.h
libcommon_la_LIBADD = \
-luuid \
--- /dev/null
+/*
+ * context.c
+ *
+ * LTTng context utilities.
+ *
+ * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License, version 2.1 only,
+ * as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "context.h"
+#include <stddef.h>
+#include <string.h>
+#include <common/error.h>
+#include <common/macros.h>
+
+int parse_application_context(const char *str, char **out_provider_name,
+ char **out_ctx_name)
+{
+ const char app_ctx_prefix[] = "$app.";
+ char *provider_name = NULL, *ctx_name = NULL;
+ size_t i, len, colon_pos = 0, provider_name_len, ctx_name_len;
+
+ if (!str || !out_provider_name || !out_ctx_name) {
+ goto not_found;
+ }
+
+ len = strlen(str);
+ if (len <= sizeof(app_ctx_prefix) - 1) {
+ goto not_found;
+ }
+
+ /* String starts with $app. */
+ if (strncmp(str, app_ctx_prefix, sizeof(app_ctx_prefix) - 1)) {
+ goto not_found;
+ }
+
+ /* Validate that the ':' separator is present. */
+ for (i = sizeof(app_ctx_prefix); i < len; i++) {
+ const char c = str[i];
+
+ if (c == ':') {
+ colon_pos = i;
+ break;
+ }
+ }
+
+ /*
+ * No colon found or no ctx name ("$app.provider:") or no provider name
+ * given ("$app.:..."), which is invalid.
+ */
+ if (!colon_pos || colon_pos == len ||
+ colon_pos == sizeof(app_ctx_prefix)) {
+ goto not_found;
+ }
+
+ provider_name_len = colon_pos - sizeof(app_ctx_prefix) + 2;
+ provider_name = zmalloc(provider_name_len);
+ if (!provider_name) {
+ PERROR("malloc provider_name");
+ goto not_found;
+ }
+ strncpy(provider_name, str + sizeof(app_ctx_prefix) - 1,
+ provider_name_len - 1);
+
+ ctx_name_len = len - colon_pos;
+ ctx_name = zmalloc(ctx_name_len);
+ if (!ctx_name) {
+ PERROR("malloc ctx_name");
+ goto not_found;
+ }
+ strncpy(ctx_name, str + colon_pos + 1, ctx_name_len - 1);
+
+ *out_provider_name = provider_name;
+ *out_ctx_name = ctx_name;
+ return 0;
+not_found:
+ free(provider_name);
+ free(ctx_name);
+ return -1;
+}
+
--- /dev/null
+/*
+ * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * 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., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LTTNG_COMMON_CONTEXT_H
+#define LTTNG_COMMON_CONTEXT_H
+
+/*
+ * Parse string as an application context of the form
+ * "$app.provider_name:context_name" and return the provider name and context
+ * name separately.
+ *
+ * provider_name and ctx_name are returned only if an application context name
+ * was successfully parsed and must be freed by the caller.
+ *
+ * Returns 0 if the string is a valid application context, else a negative
+ * value on error.
+ */
+int parse_application_context(const char *str, char **provider_name,
+ char **ctx_name);
+
+#endif /* LTTNG_COMMON_CONTEXT_H */
--- /dev/null
+/*
+ * filter.c
+ *
+ * LTTng filter bytecode utilities.
+ *
+ * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License, version 2.1 only,
+ * as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "filter.h"
+#include <stddef.h>
+
+struct bytecode_symbol_iterator {
+ /* No ownership of bytecode is taken. */
+ char *bytecode;
+ size_t offset, len;
+};
+
+struct bytecode_symbol_iterator *bytecode_symbol_iterator_create(
+ struct lttng_filter_bytecode *bytecode)
+{
+ struct bytecode_symbol_iterator *it = NULL;
+
+ if (!bytecode) {
+ goto end;
+ }
+
+ it = zmalloc(sizeof(*it));
+ if (!it) {
+ goto end;
+ }
+
+ it->bytecode = bytecode->data;
+ it->offset = bytecode->reloc_table_offset;
+ it->len = bytecode->len;
+end:
+ return it;
+}
+
+int bytecode_symbol_iterator_next(struct bytecode_symbol_iterator *it)
+{
+ int ret;
+ size_t len;
+
+ if (!it || it->offset >= it->len) {
+ ret = -1;
+ goto end;
+ }
+
+ len = strlen(it->bytecode + it->offset + sizeof(uint16_t)) + 1;
+ it->offset += len + sizeof(uint16_t);
+ ret = it->offset >= it->len ? -1 : 0;
+end:
+ return ret;
+}
+
+int bytecode_symbol_iterator_get_type(struct bytecode_symbol_iterator *it)
+{
+ int ret;
+
+ if (!it) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = *((uint16_t *) (it->bytecode + it->offset));
+end:
+ return ret;
+ }
+
+const char *bytecode_symbol_iterator_get_name(
+ struct bytecode_symbol_iterator *it)
+{
+ const char *ret = NULL;
+
+ if (!it) {
+ goto end;
+ }
+
+ ret = it->bytecode + it->offset + sizeof(uint16_t);
+end:
+ return ret;
+}
+
+void bytecode_symbol_iterator_destroy(struct bytecode_symbol_iterator *it)
+{
+ free(it);
+}
--- /dev/null
+/*
+ * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * 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., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LTTNG_COMMON_FILTER_H
+#define LTTNG_COMMON_FILTER_H
+
+#include <common/sessiond-comm/sessiond-comm.h>
+
+struct bytecode_symbol_iterator;
+
+/*
+ * Create an iterator on a bytecode's symbols. The iterator points to the
+ * first element after creation.
+ */
+struct bytecode_symbol_iterator *bytecode_symbol_iterator_create(
+ struct lttng_filter_bytecode *bytecode);
+
+/*
+ * Advance iterator of one element.
+ *
+ * Returns 0 if a next element exists or a negative value at the end.
+ */
+int bytecode_symbol_iterator_next(struct bytecode_symbol_iterator *it);
+
+int bytecode_symbol_iterator_get_type(struct bytecode_symbol_iterator *it);
+
+const char *bytecode_symbol_iterator_get_name(
+ struct bytecode_symbol_iterator *it);
+
+void bytecode_symbol_iterator_destroy(struct bytecode_symbol_iterator *it);
+
+#endif /* LTTNG_COMMON_FILTER_H */