From: David Goulet Date: Thu, 22 Nov 2012 15:22:09 +0000 (-0500) Subject: lttng.h API update: set filter becomes enable event with filter X-Git-Tag: v2.1.0-rc8~3 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=025faf73cdb6942ebf437dc4c4f6631f0134b128;hp=18eace3ba4aeaa6b869c8ad9ec1273381b4cbdee lttng.h API update: set filter becomes enable event with filter The lttng_set_event_filter() is changed to lttng_enable_event_with_filter() taking the same arguments. The lttng UI now only uses this call. Note that the original lttng_enable_event() is still available but will set the filter to NULL. This is done since now UST allows to enable the same event with different filters or/and loglevels. So, the events are still hashed by name but matched by the name/filter/loglevel triplet. In order to add an event to the hash table, those three attributes are needed at the creation time thus adding this API call which takes them all at once. There is some fixes in the match functions and filter setting from the previous commit that were needed to make the overlap.sh tests works. The loglevel_match function is removed because it is now only done in the hash table match function which will eventually get merged making a single loglevel match call site hence this function becomes useless. Furthermore, the filter.c/.h are no longer required since the filter is now added at event creation and CAN NOT be set after. Acked-by: Mathieu Desnoyers Signed-off-by: David Goulet --- diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 9e2d4d129..c6fc60558 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -509,13 +509,15 @@ extern int lttng_enable_event(struct lttng_handle *handle, struct lttng_event *ev, const char *channel_name); /* - * Apply a filter expression to an event. + * Create or enable an event with a specific filter. * - * If event is NULL, the filter is applied to all events of the channel. - * If channel_name is NULL, a lookup of the event's channel is done. - * If both are NULL, the filter is applied to all events of all channels. + * If the event you are trying to enable does not exist, it will be created, + * else it is enabled. + * If event_name is NULL, all events are enabled with that filter. + * If channel_name is NULL, the default channel is used (channel0) and created + * if not found. */ -extern int lttng_set_event_filter(struct lttng_handle *handle, +extern int lttng_enable_event_with_filter(struct lttng_handle *handle, struct lttng_event *event, const char *channel_name, const char *filter_expression); diff --git a/src/bin/lttng-sessiond/Makefile.am b/src/bin/lttng-sessiond/Makefile.am index 9b9a6c81b..3618ed073 100644 --- a/src/bin/lttng-sessiond/Makefile.am +++ b/src/bin/lttng-sessiond/Makefile.am @@ -20,7 +20,7 @@ lttng_sessiond_SOURCES = utils.c utils.h \ lttng-ust-ctl.h lttng-ust-abi.h \ fd-limit.c fd-limit.h \ kernel-consumer.c kernel-consumer.h \ - consumer.h filter.c filter.h \ + consumer.h \ health.c health.h \ cmd.c cmd.h \ testpoint.h diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index eab52342c..b78af9e77 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -1103,52 +1103,12 @@ error: return ret; } -/* - * Command LTTNG_SET_FILTER processed by the client thread. - */ -int cmd_set_filter(struct ltt_session *session, int domain, - char *channel_name, struct lttng_event *event, - struct lttng_filter_bytecode *bytecode) -{ - int ret; - - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - ret = LTTNG_ERR_FATAL; - break; - case LTTNG_DOMAIN_UST: - { - struct ltt_ust_session *usess = session->ust_session; - - ret = filter_ust_set(usess, domain, bytecode, event, channel_name); - if (ret != LTTNG_OK) { - goto error; - } - break; - } -#if 0 - case LTTNG_DOMAIN_UST_EXEC_NAME: - case LTTNG_DOMAIN_UST_PID: - case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: -#endif - default: - ret = LTTNG_ERR_UND; - goto error; - } - - ret = LTTNG_OK; - -error: - return ret; - -} - - /* * Command LTTNG_ENABLE_EVENT processed by the client thread. */ int cmd_enable_event(struct ltt_session *session, int domain, - char *channel_name, struct lttng_event *event, int wpipe) + char *channel_name, struct lttng_event *event, + struct lttng_filter_bytecode *filter, int wpipe) { int ret; struct lttng_channel *attr; @@ -1231,7 +1191,7 @@ int cmd_enable_event(struct ltt_session *session, int domain, } /* At this point, the session and channel exist on the tracer */ - ret = event_ust_enable_tracepoint(usess, domain, uchan, event); + ret = event_ust_enable_tracepoint(usess, domain, uchan, event, filter); if (ret != LTTNG_OK) { goto error; } @@ -1257,7 +1217,8 @@ error: * Command LTTNG_ENABLE_ALL_EVENT processed by the client thread. */ int cmd_enable_event_all(struct ltt_session *session, int domain, - char *channel_name, int event_type, int wpipe) + char *channel_name, int event_type, + struct lttng_filter_bytecode *filter, int wpipe) { int ret; struct lttng_channel *attr; @@ -1364,7 +1325,8 @@ int cmd_enable_event_all(struct ltt_session *session, int domain, switch (event_type) { case LTTNG_EVENT_ALL: case LTTNG_EVENT_TRACEPOINT: - ret = event_ust_enable_all_tracepoints(usess, domain, uchan); + ret = event_ust_enable_all_tracepoints(usess, domain, uchan, + filter); if (ret != LTTNG_OK) { goto error; } diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index 5cbd1da24..c8619a0f6 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -19,7 +19,6 @@ #define CMD_H #include "context.h" -#include "filter.h" #include "session.h" /* @@ -50,9 +49,11 @@ int cmd_set_filter(struct ltt_session *session, int domain, char *channel_name, struct lttng_event *event, struct lttng_filter_bytecode *bytecode); int cmd_enable_event(struct ltt_session *session, int domain, - char *channel_name, struct lttng_event *event, int wpipe); + char *channel_name, struct lttng_event *event, + struct lttng_filter_bytecode *filter, int wpipe); int cmd_enable_event_all(struct ltt_session *session, int domain, - char *channel_name, int event_type, int wpipe); + char *channel_name, int event_type, + struct lttng_filter_bytecode *filter, int wpipe); /* Trace session action commands */ int cmd_start_trace(struct ltt_session *session); diff --git a/src/bin/lttng-sessiond/event.c b/src/bin/lttng-sessiond/event.c index 70f6fe62d..402a386ce 100644 --- a/src/bin/lttng-sessiond/event.c +++ b/src/bin/lttng-sessiond/event.c @@ -32,6 +32,9 @@ #include "trace-kernel.h" #include "trace-ust.h" +/* + * Add unique UST event based on the event name, filter bytecode and loglevel. + */ static void add_unique_ust_event(struct lttng_ht *ht, struct ltt_ust_event *event) { @@ -65,32 +68,6 @@ static void init_syscalls_kernel_event(struct lttng_event *event) event->type = LTTNG_EVENT_SYSCALL; } -/* - * Return 1 if loglevels match or 0 on failure. - */ -static int loglevel_match(struct ltt_ust_event *uevent, - enum lttng_ust_loglevel_type log_type, int loglevel) -{ - /* - * For the loglevel type ALL, the loglevel is set to -1 but the event - * received by the session daemon is 0 which does not match the negative - * value in the existing event. - */ - if (log_type == LTTNG_UST_LOGLEVEL_ALL) { - loglevel = -1; - } - - if (uevent == NULL || uevent->attr.loglevel_type != log_type || - uevent->attr.loglevel != loglevel) { - goto no_match; - } - - return 1; - -no_match: - return 0; -} - /* * Disable kernel tracepoint event for a channel from the kernel session. */ @@ -323,13 +300,15 @@ end: * Enable all UST tracepoints for a channel from a UST session. */ int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, - struct ltt_ust_channel *uchan) + struct ltt_ust_channel *uchan, struct lttng_filter_bytecode *filter) { int ret, i, size; struct lttng_ht_iter iter; struct ltt_ust_event *uevent = NULL; struct lttng_event *events = NULL; + rcu_read_lock(); + switch (domain) { case LTTNG_DOMAIN_UST: { @@ -357,7 +336,7 @@ int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, * Check if event exist and if so, continue since it was enable * previously. */ - uevent = trace_ust_find_event(uchan->events, events[i].name, NULL, + uevent = trace_ust_find_event(uchan->events, events[i].name, filter, events[i].loglevel); if (uevent != NULL) { ret = ust_app_enable_event_pid(usess, uchan, uevent, @@ -372,7 +351,7 @@ int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, } /* Create ust event */ - uevent = trace_ust_create_event(&events[i]); + uevent = trace_ust_create_event(&events[i], filter); if (uevent == NULL) { ret = LTTNG_ERR_FATAL; goto error_destroy; @@ -411,6 +390,7 @@ int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, goto error; } + rcu_read_unlock(); return LTTNG_OK; error_destroy: @@ -418,6 +398,7 @@ error_destroy: error: free(events); + rcu_read_unlock(); return ret; } @@ -425,41 +406,27 @@ error: * Enable UST tracepoint event for a channel from a UST session. */ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain, - struct ltt_ust_channel *uchan, struct lttng_event *event) + struct ltt_ust_channel *uchan, struct lttng_event *event, + struct lttng_filter_bytecode *filter) { int ret = LTTNG_OK, to_create = 0; struct ltt_ust_event *uevent; - DBG3("Enable ust: %s l:%d f:%p", event->name, event->loglevel, NULL); - rcu_read_lock(); - uevent = trace_ust_find_event(uchan->events, event->name, NULL, + uevent = trace_ust_find_event(uchan->events, event->name, filter, event->loglevel); if (uevent == NULL) { - uevent = trace_ust_create_event(event); + uevent = trace_ust_create_event(event, filter); if (uevent == NULL) { ret = LTTNG_ERR_UST_ENABLE_FAIL; goto error; } + /* Valid to set it after the goto error since uevent is still NULL */ to_create = 1; } - /* Check loglevels */ - ret = loglevel_match(uevent, event->loglevel_type, event->loglevel); - if (ret == 0) { - /* - * No match meaning that the user tried to enable a known event but - * with a different loglevel. - */ - DBG("Enable event %s does not match existing event %s with loglevel " - "respectively of %d and %d", event->name, uevent->attr.name, - uevent->attr.loglevel, event->loglevel); - ret = LTTNG_ERR_EVENT_EXIST_LOGLEVEL; - goto error; - } - if (uevent->enabled) { /* It's already enabled so everything is OK */ ret = LTTNG_OK; @@ -540,17 +507,18 @@ int event_ust_disable_tracepoint(struct ltt_ust_session *usess, int domain, struct ltt_ust_event *uevent; struct lttng_ht_node_str *node; struct lttng_ht_iter iter; - void *orig_match_fct; struct lttng_ht *ht; ht = uchan->events; - /* Save match function so we can use the event by name match. */ - orig_match_fct = (void *) ht->match_fct; - ht->match_fct = trace_ust_ht_match_event_by_name; - rcu_read_lock(); - lttng_ht_lookup(ht, (void *) event_name, &iter); + + /* + * We use a custom lookup since we need the iterator for the next_duplicate + * call in the do while loop below. + */ + cds_lfht_lookup(ht->ht, ht->hash_fct((void *) event_name, lttng_ht_seed), + trace_ust_ht_match_event_by_name, event_name, &iter.iter); node = lttng_ht_iter_get_node_str(&iter); if (node == NULL) { DBG2("Trace UST event NOT found by name %s", event_name); @@ -560,6 +528,8 @@ int event_ust_disable_tracepoint(struct ltt_ust_session *usess, int domain, do { uevent = caa_container_of(node, struct ltt_ust_event, node); + assert(uevent); + if (uevent->enabled == 0) { /* It's already disabled so everything is OK */ ret = LTTNG_OK; @@ -586,6 +556,9 @@ int event_ust_disable_tracepoint(struct ltt_ust_session *usess, int domain, uevent->enabled = 0; + DBG2("Event UST %s disabled in channel %s", uevent->attr.name, + uchan->name); + /* Get next duplicate event by name. */ cds_lfht_next_duplicate(ht->ht, trace_ust_ht_match_event_by_name, event_name, &iter.iter); @@ -594,10 +567,7 @@ int event_ust_disable_tracepoint(struct ltt_ust_session *usess, int domain, ret = LTTNG_OK; - DBG2("Event UST %s disabled in channel %s", uevent->attr.name, - uchan->name); error: - ht->match_fct = orig_match_fct; rcu_read_unlock(); return ret; } @@ -613,6 +583,8 @@ int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess, int domain, struct ltt_ust_event *uevent = NULL; struct lttng_event *events = NULL; + rcu_read_lock(); + switch (domain) { case LTTNG_DOMAIN_UST: { @@ -620,11 +592,11 @@ int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess, int domain, cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent, node.node) { if (uevent->enabled == 1) { - ret = ust_app_disable_event_glb(usess, uchan, uevent); + ret = event_ust_disable_tracepoint(usess, domain, uchan, + uevent->attr.name); if (ret < 0) { continue; } - uevent->enabled = 0; } } @@ -657,9 +629,11 @@ int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess, int domain, goto error; } + rcu_read_unlock(); return LTTNG_OK; error: free(events); + rcu_read_unlock(); return ret; } diff --git a/src/bin/lttng-sessiond/event.h b/src/bin/lttng-sessiond/event.h index b606d7633..d1c094b25 100644 --- a/src/bin/lttng-sessiond/event.h +++ b/src/bin/lttng-sessiond/event.h @@ -39,11 +39,12 @@ int event_kernel_enable_all(struct ltt_kernel_session *ksession, struct ltt_kernel_channel *kchan, int kernel_tracer_fd); int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain, - struct ltt_ust_channel *uchan, struct lttng_event *event); + struct ltt_ust_channel *uchan, struct lttng_event *event, + struct lttng_filter_bytecode *filter); int event_ust_disable_tracepoint(struct ltt_ust_session *usess, int domain, struct ltt_ust_channel *uchan, char *event_name); int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, - struct ltt_ust_channel *uchan); + struct ltt_ust_channel *uchan, struct lttng_filter_bytecode *filter); int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess, int domain, struct ltt_ust_channel *uchan); diff --git a/src/bin/lttng-sessiond/filter.c b/src/bin/lttng-sessiond/filter.c deleted file mode 100644 index d37773d49..000000000 --- a/src/bin/lttng-sessiond/filter.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2011 - David Goulet - * Copyright (C) 2012 - Mathieu Desnoyers - * - * 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. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include - -#include -#include - -#include "filter.h" -#include "kernel.h" -#include "ust-app.h" -#include "trace-ust.h" - -/* - * Add UST context to event. - */ -static int add_ufilter_to_event(struct ltt_ust_session *usess, int domain, - struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, - struct lttng_filter_bytecode *bytecode) -{ - int ret; - - if (uevent->filter) { - ret = -EEXIST; - goto error; - } - /* Same layout. */ - uevent->filter = (struct lttng_ust_filter_bytecode *) bytecode; - uevent->filter->seqnum = usess->filter_seq_num; - - switch (domain) { - case LTTNG_DOMAIN_UST: - ret = ust_app_set_filter_event_glb(usess, uchan, uevent, - bytecode); - if (ret < 0) { - goto error; - } - usess->filter_seq_num++; - break; - default: - ret = -ENOSYS; - goto error; - } - - DBG("Filter UST added to event %s",uevent->attr.name); - - return 0; - -error: - free(bytecode); - return ret; -} - -/* - * Add UST context to tracer. - */ -int filter_ust_set(struct ltt_ust_session *usess, int domain, - struct lttng_filter_bytecode *bytecode, struct lttng_event *event, - char *channel_name) -{ - int ret = LTTNG_OK, have_event = 0; - struct lttng_ht_iter iter; - struct lttng_ht *chan_ht; - struct ltt_ust_channel *uchan = NULL; - struct ltt_ust_event *uevent = NULL; - - /* - * Define which channel's hashtable to use from the domain or quit if - * unknown domain. - */ - switch (domain) { - case LTTNG_DOMAIN_UST: - chan_ht = usess->domain_global.channels; - break; -#if 0 - case LTTNG_DOMAIN_UST_EXEC_NAME: - case LTTNG_DOMAIN_UST_PID: - case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: -#endif - default: - ret = LTTNG_ERR_UND; - goto error; - } - - /* Do we have a valid event. */ - if (event && event->name[0] != '\0') { - have_event = 1; - } - - /* Get UST channel if defined */ - if (strlen(channel_name) != 0) { - uchan = trace_ust_find_channel_by_name(chan_ht, channel_name); - if (uchan == NULL) { - ret = LTTNG_ERR_UST_CHAN_NOT_FOUND; - goto error; - } - } - - /* If UST channel specified and event name, get UST event ref */ - if (uchan && have_event) { - uevent = trace_ust_find_event(uchan->events, event->name, bytecode, - event->loglevel); - if (uevent == NULL) { - ret = LTTNG_ERR_UST_EVENT_NOT_FOUND; - goto error; - } - } - - /* At this point, we have 4 possibilities */ - - if (uchan && uevent) { /* Add filter to event in channel */ - ret = add_ufilter_to_event(usess, domain, uchan, uevent, - bytecode); - } else if (uchan && !have_event) { /* Add filter to channel */ - ERR("Cannot add filter to channel"); - ret = LTTNG_ERR_FATAL; /* not supported. */ - goto error; - } else if (!uchan && have_event) { /* Add filter to event */ - /* Add context to event without having the channel name */ - cds_lfht_for_each_entry(chan_ht->ht, &iter.iter, uchan, node.node) { - uevent = trace_ust_find_event(uchan->events, event->name, bytecode, - event->loglevel); - if (uevent != NULL) { - ret = add_ufilter_to_event(usess, domain, uchan, uevent, bytecode); - /* - * LTTng UST does not allowed the same event to be registered - * multiple time in different or the same channel. So, if we - * found our event, we stop. - */ - goto end; - } - } - ret = LTTNG_ERR_UST_EVENT_NOT_FOUND; - goto error; - } else if (!uchan && !have_event) { /* Add filter all events, all channels */ - ERR("Cannot add filter to channel"); - ret = LTTNG_ERR_FATAL; /* not supported. */ - goto error; - } - -end: - /* Must handle both local internal error and UST code. */ - switch (ret) { - case -EEXIST: - case -LTTNG_UST_ERR_EXIST: - ret = LTTNG_ERR_FILTER_EXIST; - break; - case -ENOMEM: - ret = LTTNG_ERR_FATAL; - break; - case -EINVAL: - case -LTTNG_UST_ERR_INVAL: - ret = LTTNG_ERR_FILTER_INVAL; - break; - case -ENOSYS: - case -LTTNG_UST_ERR_NOSYS: - ret = LTTNG_ERR_UNKNOWN_DOMAIN; - break; - default: - ret = LTTNG_OK; - break; - } - -error: - return ret; -} diff --git a/src/bin/lttng-sessiond/filter.h b/src/bin/lttng-sessiond/filter.h deleted file mode 100644 index 3ec16bcac..000000000 --- a/src/bin/lttng-sessiond/filter.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2011 - David Goulet - * Copyright (C) 2012 - Mathieu Desnoyers - * - * 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 _LTT_FILTER_H -#define _LTT_FILTER_H - -#include - -#include "trace-kernel.h" -#include "trace-ust.h" -#include "ust-ctl.h" - -struct lttng_filter_bytecode; - -int filter_ust_set(struct ltt_ust_session *usess, int domain, - struct lttng_filter_bytecode *bytecode, struct lttng_event *event, - char *channel_name); - -#endif /* _LTT_FILTER_H */ diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 0a156d8e7..df4760602 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -59,7 +59,6 @@ #include "ust-consumer.h" #include "utils.h" #include "fd-limit.h" -#include "filter.h" #include "health.h" #include "testpoint.h" @@ -2525,7 +2524,7 @@ skip_domain: { ret = cmd_enable_event(cmd_ctx->session, cmd_ctx->lsm->domain.type, cmd_ctx->lsm->u.enable.channel_name, - &cmd_ctx->lsm->u.enable.event, kernel_poll_pipe[1]); + &cmd_ctx->lsm->u.enable.event, NULL, kernel_poll_pipe[1]); break; } case LTTNG_ENABLE_ALL_EVENT: @@ -2534,7 +2533,7 @@ skip_domain: ret = cmd_enable_event_all(cmd_ctx->session, cmd_ctx->lsm->domain.type, cmd_ctx->lsm->u.enable.channel_name, - cmd_ctx->lsm->u.enable.event.type, kernel_poll_pipe[1]); + cmd_ctx->lsm->u.enable.event.type, NULL, kernel_poll_pipe[1]); break; } case LTTNG_LIST_TRACEPOINTS: @@ -2846,15 +2845,15 @@ skip_domain: cmd_ctx->lsm->u.reg.path, cdata); break; } - case LTTNG_SET_FILTER: + case LTTNG_ENABLE_EVENT_WITH_FILTER: { struct lttng_filter_bytecode *bytecode; - if (cmd_ctx->lsm->u.filter.bytecode_len > LTTNG_FILTER_MAX_LEN) { + if (cmd_ctx->lsm->u.enable.bytecode_len > LTTNG_FILTER_MAX_LEN) { ret = LTTNG_ERR_FILTER_INVAL; goto error; } - bytecode = zmalloc(cmd_ctx->lsm->u.filter.bytecode_len); + bytecode = zmalloc(cmd_ctx->lsm->u.enable.bytecode_len); if (!bytecode) { ret = LTTNG_ERR_FILTER_NOMEM; goto error; @@ -2862,7 +2861,7 @@ skip_domain: /* Receive var. len. data */ DBG("Receiving var len data from client ..."); ret = lttcomm_recv_unix_sock(sock, bytecode, - cmd_ctx->lsm->u.filter.bytecode_len); + cmd_ctx->lsm->u.enable.bytecode_len); if (ret <= 0) { DBG("Nothing recv() from client var len data... continuing"); *sock_error = 1; @@ -2871,16 +2870,15 @@ skip_domain: } if (bytecode->len + sizeof(*bytecode) - != cmd_ctx->lsm->u.filter.bytecode_len) { + != cmd_ctx->lsm->u.enable.bytecode_len) { free(bytecode); ret = LTTNG_ERR_FILTER_INVAL; goto error; } - ret = cmd_set_filter(cmd_ctx->session, cmd_ctx->lsm->domain.type, - cmd_ctx->lsm->u.filter.channel_name, - &cmd_ctx->lsm->u.filter.event, - bytecode); + ret = cmd_enable_event(cmd_ctx->session, cmd_ctx->lsm->domain.type, + cmd_ctx->lsm->u.enable.channel_name, + &cmd_ctx->lsm->u.enable.event, bytecode, kernel_poll_pipe[1]); break; } case LTTNG_DATA_PENDING: diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 962255b5c..1fda555ea 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -26,6 +26,11 @@ #include "trace-ust.h" +/* + * Match function for the events hash table lookup. + * + * Matches by name only. Used by the disable command. + */ int trace_ust_ht_match_event_by_name(struct cds_lfht_node *node, const void *_key) { @@ -43,13 +48,19 @@ int trace_ust_ht_match_event_by_name(struct cds_lfht_node *node, goto no_match; } - /* Match. */ + /* Match */ return 1; no_match: return 0; } +/* + * Match function for the hash table lookup. + * + * It matches an ust event based on three attributes which are the event name, + * the filter bytecode and the loglevel. + */ int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key) { struct ltt_ust_event *event; @@ -65,55 +76,43 @@ int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key) /* Event name */ if (strncmp(event->attr.name, key->name, sizeof(event->attr.name)) != 0) { - DBG3("[Match] name failed: %s and %s", - event->attr.name, key->name); goto no_match; } /* Event loglevel. */ if (event->attr.loglevel != key->loglevel) { - if (event->attr.loglevel_type == 0 && key->loglevel == 0 && - event->attr.loglevel == -1) { + if (event->attr.loglevel_type == LTTNG_UST_LOGLEVEL_ALL + && key->loglevel == 0 && event->attr.loglevel == -1) { /* - * This is because on event creation, the loglevel is set to -1 if - * the event loglevel type is ALL so 0 and -1 are accepted for this - * loglevel type. + * Match is accepted. This is because on event creation, the + * loglevel is set to -1 if the event loglevel type is ALL so 0 and + * -1 are accepted for this loglevel type since 0 is the one set by + * the API when receiving an enable event. */ } else { - DBG3("[Match] loglevel failed: %d and %d", - event->attr.loglevel, key->loglevel); goto no_match; } } /* Only one of the filters is NULL, fail. */ if ((key->filter && !event->filter) || (!key->filter && event->filter)) { - DBG3("[Match] filters failed: k:%p and e:%p", - key->filter, event->filter); goto no_match; } - /* Both filters are NULL, success. */ - if (!key->filter && !event->filter) { - goto match; - } - - /* Both filters exists, check length followed by the bytecode. */ - if (event->filter->len == key->filter->len && - memcmp(event->filter->data, key->filter->data, - event->filter->len) == 0) { - goto match; + if (key->filter && event->filter) { + /* Both filters exists, check length followed by the bytecode. */ + if (event->filter->len != key->filter->len || + memcmp(event->filter->data, key->filter->data, + event->filter->len) != 0) { + goto no_match; + } } - DBG3("[Match] filters failed: k:%p and e:%p", - key->filter, event->filter); + /* Match. */ + return 1; no_match: return 0; - -match: - DBG3("[MATCH] %s", key->name); - return 1; } /* @@ -152,7 +151,6 @@ struct ltt_ust_event *trace_ust_find_event(struct lttng_ht *ht, struct lttng_ht_node_str *node; struct lttng_ht_iter iter; struct ltt_ust_ht_key key; - void *orig_match_fct; assert(name); assert(ht); @@ -161,10 +159,6 @@ struct ltt_ust_event *trace_ust_find_event(struct lttng_ht *ht, key.filter = filter; key.loglevel = loglevel; - /* Save match function so we can use the ust app event match. */ - orig_match_fct = (void *) ht->match_fct; - ht->match_fct = trace_ust_ht_match_event; - cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed), trace_ust_ht_match_event, &key, &iter.iter); node = lttng_ht_iter_get_node_str(&iter); @@ -178,8 +172,6 @@ struct ltt_ust_event *trace_ust_find_event(struct lttng_ht *ht, error: DBG2("Trace UST event %s NOT found", key.name); - /* Put back original match function. */ - ht->match_fct = orig_match_fct; return NULL; } @@ -324,7 +316,8 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev) +struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev, + struct lttng_filter_bytecode *filter) { struct ltt_ust_event *lue; @@ -374,6 +367,8 @@ struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev) goto error_free_event; } + /* Same layout. */ + lue->filter = (struct lttng_ust_filter_bytecode *) filter; /* Init node */ lttng_ht_node_init_str(&lue->node, lue->attr.name); diff --git a/src/bin/lttng-sessiond/trace-ust.h b/src/bin/lttng-sessiond/trace-ust.h index efca4d23b..07b4b6829 100644 --- a/src/bin/lttng-sessiond/trace-ust.h +++ b/src/bin/lttng-sessiond/trace-ust.h @@ -154,7 +154,8 @@ struct ltt_ust_session *trace_ust_create_session(char *path, unsigned int session_id, struct lttng_domain *domain); struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *attr, char *path); -struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev); +struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev, + struct lttng_filter_bytecode *filter); struct ltt_ust_metadata *trace_ust_create_metadata(char *path); struct ltt_ust_context *trace_ust_create_context( struct lttng_event_context *ctx); @@ -190,7 +191,8 @@ struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *attr, return NULL; } static inline -struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev) +struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev, + struct lttng_filter_bytecode *filter) { return NULL; } diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 97792d9fe..c81f6e8f5 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -36,6 +36,12 @@ #include "ust-consumer.h" #include "ust-ctl.h" +/* + * Match function for the hash table lookup. + * + * It matches an ust app event based on three attributes which are the event + * name, the filter bytecode and the loglevel. + */ static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key) { struct ust_app_event *event; @@ -56,7 +62,17 @@ static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key) /* Event loglevel. */ if (event->attr.loglevel != key->loglevel) { - goto no_match; + if (event->attr.loglevel_type == LTTNG_UST_LOGLEVEL_ALL + && key->loglevel == 0 && event->attr.loglevel == -1) { + /* + * Match is accepted. This is because on event creation, the + * loglevel is set to -1 if the event loglevel type is ALL so 0 and + * -1 are accepted for this loglevel type since 0 is the one set by + * the API when receiving an enable event. + */ + } else { + goto no_match; + } } /* One of the filters is NULL, fail. */ @@ -64,26 +80,26 @@ static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key) goto no_match; } - /* Both filters are NULL, success. */ - if (!key->filter && !event->filter) { - goto match; - } - - /* Both filters exists, check length followed by the bytecode. */ - if (event->filter->len == key->filter->len && - memcmp(event->filter->data, key->filter->data, - event->filter->len) == 0) { - goto match; + if (key->filter && event->filter) { + /* Both filters exists, check length followed by the bytecode. */ + if (event->filter->len != key->filter->len || + memcmp(event->filter->data, key->filter->data, + event->filter->len) != 0) { + goto no_match; + } } -match: + /* Match. */ return 1; no_match: return 0; - } +/* + * Unique add of an ust app event in the given ht. This uses the custom + * ht_match_ust_app_event match function and the event name as hash. + */ static void add_unique_ust_app_event(struct lttng_ht *ht, struct ust_app_event *event) { @@ -420,6 +436,29 @@ error: return ua_ctx; } +/* + * Allocate a filter and copy the given original filter. + * + * Return allocated filter or NULL on error. + */ +static struct lttng_ust_filter_bytecode *alloc_copy_ust_app_filter( + struct lttng_ust_filter_bytecode *orig_f) +{ + struct lttng_ust_filter_bytecode *filter = NULL; + + /* Copy filter bytecode */ + filter = zmalloc(sizeof(*filter) + orig_f->len); + if (!filter) { + PERROR("zmalloc alloc ust app filter"); + goto error; + } + + memcpy(filter, orig_f, sizeof(*filter) + orig_f->len); + +error: + return filter; +} + /* * Find an ust_app using the sock and return it. RCU read side lock must be * held before calling this helper function. @@ -443,6 +482,12 @@ error: return NULL; } +/* + * Lookup for an ust app event based on event name, filter bytecode and the + * event loglevel. + * + * Return an ust_app_event object or NULL on error. + */ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht, char *name, struct lttng_ust_filter_bytecode *filter, int loglevel) { @@ -450,7 +495,6 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht, struct lttng_ht_node_str *node; struct ust_app_event *event = NULL; struct ust_app_ht_key key; - void *orig_match_fct; assert(name); assert(ht); @@ -460,11 +504,9 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht, key.filter = filter; key.loglevel = loglevel; - /* Save match function so we can use the ust app event match. */ - orig_match_fct = (void *) ht->match_fct; - ht->match_fct = ht_match_ust_app_event; - - lttng_ht_lookup(ht, (void *) &key, &iter); + /* Lookup using the event name as hash and a custom match fct. */ + cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed), + ht_match_ust_app_event, &key, &iter.iter); node = lttng_ht_iter_get_node_str(&iter); if (node == NULL) { goto end; @@ -473,8 +515,6 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht, event = caa_container_of(node, struct ust_app_event, node); end: - /* Put back original match function. */ - ht->match_fct = orig_match_fct; return event; } @@ -788,6 +828,14 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess, health_code_update(&health_thread_cmd); + /* Set filter if one is present. */ + if (ua_event->filter) { + ret = set_ust_event_filter(ua_event, app); + if (ret < 0) { + goto error; + } + } + /* If event not enabled, disable it on the tracer */ if (ua_event->enabled == 0) { ret = disable_ust_event(app, ua_sess, ua_event); @@ -833,13 +881,8 @@ static void shadow_copy_event(struct ust_app_event *ua_event, /* Copy filter bytecode */ if (uevent->filter) { - ua_event->filter = zmalloc(sizeof(*ua_event->filter) + - uevent->filter->len); - if (!ua_event->filter) { - return; - } - memcpy(ua_event->filter, uevent->filter, - sizeof(*ua_event->filter) + uevent->filter->len); + ua_event->filter = alloc_copy_ust_app_filter(uevent->filter); + /* Filter might be NULL here in case of ENONEM. */ } } @@ -1080,35 +1123,6 @@ error: return ret; } -/* - * Set UST filter for the event on the tracer. - */ -static -int set_ust_app_event_filter(struct ust_app_session *ua_sess, - struct ust_app_event *ua_event, - struct lttng_filter_bytecode *bytecode, - struct ust_app *app) -{ - int ret = 0; - - DBG2("UST app adding context to event %s", ua_event->name); - - /* Copy filter bytecode */ - ua_event->filter = zmalloc(sizeof(*ua_event->filter) + bytecode->len); - if (!ua_event->filter) { - return -ENOMEM; - } - memcpy(ua_event->filter, bytecode, - sizeof(*ua_event->filter) + bytecode->len); - ret = set_ust_event_filter(ua_event, app); - if (ret < 0) { - goto error; - } - -error: - return ret; -} - /* * Enable on the tracer side a ust app event for the session and channel. */ @@ -2671,62 +2685,6 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess, return ret; } -/* - * Add context to a specific event in a channel for global UST domain. - */ -int ust_app_set_filter_event_glb(struct ltt_ust_session *usess, - struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, - struct lttng_filter_bytecode *bytecode) -{ - int ret = 0; - struct lttng_ht_node_str *ua_chan_node; - struct lttng_ht_iter iter, uiter; - struct ust_app_session *ua_sess; - struct ust_app_event *ua_event; - struct ust_app_channel *ua_chan = NULL; - struct ust_app *app; - - rcu_read_lock(); - - cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { - if (!app->compatible) { - /* - * TODO: In time, we should notice the caller of this error by - * telling him that this is a version error. - */ - continue; - } - ua_sess = lookup_session_by_app(usess, app); - if (ua_sess == NULL) { - continue; - } - - /* Lookup channel in the ust app session */ - lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &uiter); - ua_chan_node = lttng_ht_iter_get_node_str(&uiter); - if (ua_chan_node == NULL) { - continue; - } - ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, - node); - - ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name, - (struct lttng_ust_filter_bytecode *) bytecode, - uevent->attr.loglevel); - if (ua_event == NULL) { - continue; - } - - ret = set_ust_app_event_filter(ua_sess, ua_event, bytecode, app); - if (ret < 0) { - continue; - } - } - - rcu_read_unlock(); - return ret; -} - /* * Enable event for a channel from a UST session for a specific PID. */ diff --git a/src/bin/lttng-sessiond/ust-app.h b/src/bin/lttng-sessiond/ust-app.h index 72adf50aa..d713f223b 100644 --- a/src/bin/lttng-sessiond/ust-app.h +++ b/src/bin/lttng-sessiond/ust-app.h @@ -174,9 +174,6 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent); int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct ltt_ust_context *uctx); -int ust_app_set_filter_event_glb(struct ltt_ust_session *usess, - struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, - struct lttng_filter_bytecode *bytecode); void ust_app_global_update(struct ltt_ust_session *usess, int sock); void ust_app_clean_list(void); @@ -348,13 +345,6 @@ int ust_app_calibrate_glb(struct lttng_ust_calibrate *calibrate) { return 0; } -static inline -int ust_app_set_filter_event_glb(struct ltt_ust_session *usess, - struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, - struct lttng_filter_bytecode *bytecode) -{ - return 0; -} #endif /* HAVE_LIBLTTNG_UST_CTL */ diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c index cdd137cc9..1a53448c6 100644 --- a/src/bin/lttng/commands/enable_events.c +++ b/src/bin/lttng/commands/enable_events.c @@ -301,7 +301,6 @@ int loglevel_str_to_value(const char *inputstr) static int enable_events(char *session_name) { int err, ret = CMD_SUCCESS, warn = 0; - unsigned int event_enabled = 0; char *event_name, *channel_name = NULL; struct lttng_event ev; struct lttng_domain dom; @@ -367,62 +366,60 @@ static int enable_events(char *session_name) } } - /* Reset flag before enabling a new event. */ - event_enabled = 0; - - ret = lttng_enable_event(handle, &ev, channel_name); - if (ret < 0) { - switch (-ret) { - case LTTNG_ERR_KERN_EVENT_EXIST: - WARN("Kernel events already enabled (channel %s, session %s)", - channel_name, session_name); - break; - default: - ERR("Events: %s (channel %s, session %s)", - lttng_strerror(ret), channel_name, session_name); - break; + if (!opt_filter) { + ret = lttng_enable_event(handle, &ev, channel_name); + if (ret < 0) { + switch (-ret) { + case LTTNG_ERR_KERN_EVENT_EXIST: + WARN("Kernel events already enabled (channel %s, session %s)", + channel_name, session_name); + break; + default: + ERR("Events: %s (channel %s, session %s)", + lttng_strerror(ret), channel_name, session_name); + break; + } + goto end; } - goto end; - } - event_enabled = 1; - switch (opt_event_type) { - case LTTNG_EVENT_TRACEPOINT: - if (opt_loglevel) { - MSG("All %s tracepoints are enabled in channel %s for loglevel %s", - opt_kernel ? "kernel" : "UST", channel_name, - opt_loglevel); - } else { - MSG("All %s tracepoints are enabled in channel %s", - opt_kernel ? "kernel" : "UST", channel_name); + switch (opt_event_type) { + case LTTNG_EVENT_TRACEPOINT: + if (opt_loglevel) { + MSG("All %s tracepoints are enabled in channel %s for loglevel %s", + opt_kernel ? "kernel" : "UST", channel_name, + opt_loglevel); + } else { + MSG("All %s tracepoints are enabled in channel %s", + opt_kernel ? "kernel" : "UST", channel_name); + } + break; + case LTTNG_EVENT_SYSCALL: + if (opt_kernel) { + MSG("All kernel system calls are enabled in channel %s", + channel_name); + } + break; + case LTTNG_EVENT_ALL: + if (opt_loglevel) { + MSG("All %s events are enabled in channel %s for loglevel %s", + opt_kernel ? "kernel" : "UST", channel_name, + opt_loglevel); + } else { + MSG("All %s events are enabled in channel %s", + opt_kernel ? "kernel" : "UST", channel_name); + } + break; + default: + /* + * We should not be here since lttng_enable_event should have + * failed on the event type. + */ + goto error; } - break; - case LTTNG_EVENT_SYSCALL: - if (opt_kernel) { - MSG("All kernel system calls are enabled in channel %s", - channel_name); - } - break; - case LTTNG_EVENT_ALL: - if (opt_loglevel) { - MSG("All %s events are enabled in channel %s for loglevel %s", - opt_kernel ? "kernel" : "UST", channel_name, - opt_loglevel); - } else { - MSG("All %s events are enabled in channel %s", - opt_kernel ? "kernel" : "UST", channel_name); - } - break; - default: - /* - * We should not be here since lttng_enable_event should have - * failed on the event type. - */ - goto error; } - if (opt_filter && event_enabled) { - ret = lttng_set_event_filter(handle, &ev, channel_name, + if (opt_filter) { + ret = lttng_enable_event_with_filter(handle, &ev, channel_name, opt_filter); if (ret < 0) { fprintf(stderr, "Ret filter: %d\n", ret); @@ -437,19 +434,6 @@ static int enable_events(char *session_name) ERR("%s", lttng_strerror(ret)); default: ERR("Setting filter: '%s'", opt_filter); - /* - * The event was successfully enabled before so when - * failing to set a filter, disable the event. This has - * been discussed in bug #343 on why we do that. - */ - err = lttng_disable_event(handle, ev.name, channel_name); - if (err < 0) { - ERR("Disabling all events after filter error: %s", - lttng_strerror(err)); - } else { - WARN("All events of channel %s have been disabled due " - "to a filter error", channel_name); - } break; } goto error; @@ -564,30 +548,29 @@ static int enable_events(char *session_name) goto error; } - /* Reset flag before enabling a new event. */ - event_enabled = 0; - - ret = lttng_enable_event(handle, &ev, channel_name); - if (ret < 0) { - /* Turn ret to positive value to handle the positive error code */ - switch (-ret) { - case LTTNG_ERR_KERN_EVENT_EXIST: - WARN("Kernel event %s already enabled (channel %s, session %s)", - event_name, channel_name, session_name); - break; - default: - ERR("Event %s: %s (channel %s, session %s)", event_name, - lttng_strerror(ret), channel_name, session_name); - break; + if (!opt_filter) { + ret = lttng_enable_event(handle, &ev, channel_name); + if (ret < 0) { + /* Turn ret to positive value to handle the positive error code */ + switch (-ret) { + case LTTNG_ERR_KERN_EVENT_EXIST: + WARN("Kernel event %s already enabled (channel %s, session %s)", + event_name, channel_name, session_name); + break; + default: + ERR("Event %s: %s (channel %s, session %s)", event_name, + lttng_strerror(ret), channel_name, session_name); + break; + } + warn = 1; + } else { + MSG("%s event %s created in channel %s", + opt_kernel ? "kernel": "UST", event_name, channel_name); } - warn = 1; - } else { - MSG("%s event %s created in channel %s", - opt_kernel ? "kernel": "UST", event_name, channel_name); - event_enabled = 1; } - if (opt_filter && event_enabled) { - ret = lttng_set_event_filter(handle, &ev, channel_name, + + if (opt_filter) { + ret = lttng_enable_event_with_filter(handle, &ev, channel_name, opt_filter); if (ret < 0) { switch (-ret) { @@ -602,19 +585,6 @@ static int enable_events(char *session_name) default: ERR("Setting filter for event %s: '%s'", ev.name, opt_filter); - /* - * The event was successfully enabled before so when - * failing to set a filter, disable the event. This has - * been discussed in bug #343 on why we do that. - */ - err = lttng_disable_event(handle, ev.name, channel_name); - if (err < 0) { - ERR("Disabling event %s after filter error: %s", - ev.name, lttng_strerror(err)); - } else { - WARN("Event %s of channel %s has been disabled due " - "to a filter error", ev.name, channel_name); - } break; } goto error; diff --git a/src/common/sessiond-comm/sessiond-comm.h b/src/common/sessiond-comm/sessiond-comm.h index 41f96d8a4..991cf7017 100644 --- a/src/common/sessiond-comm/sessiond-comm.h +++ b/src/common/sessiond-comm/sessiond-comm.h @@ -88,7 +88,7 @@ enum lttcomm_sessiond_command { RELAYD_CLOSE_STREAM, RELAYD_DATA_PENDING, RELAYD_QUIESCENT_CONTROL, - LTTNG_SET_FILTER, + LTTNG_ENABLE_EVENT_WITH_FILTER, LTTNG_HEALTH_CHECK, LTTNG_DATA_PENDING, }; @@ -178,6 +178,8 @@ struct lttcomm_session_msg { struct { char channel_name[LTTNG_SYMBOL_NAME_LEN]; struct lttng_event event; + /* Length of following bytecode for filter. */ + uint32_t bytecode_len; } enable; /* Create channel */ struct { @@ -202,12 +204,6 @@ struct lttcomm_session_msg { /* Number of lttng_uri following */ uint32_t size; } uri; - struct { - char channel_name[LTTNG_SYMBOL_NAME_LEN]; - struct lttng_event event; - /* Length of following bytecode */ - uint32_t bytecode_len; - } filter; } u; }; diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index c9fb293be..6238d9a00 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -827,12 +827,12 @@ int lttng_enable_event(struct lttng_handle *handle, } /* - * Set filter for an event + * Create or enable an event with a filter expression. * * Return negative error value on error. * Return size of returned session payload data if OK. */ -int lttng_set_event_filter(struct lttng_handle *handle, +int lttng_enable_event_with_filter(struct lttng_handle *handle, struct lttng_event *event, const char *channel_name, const char *filter_expression) { @@ -842,14 +842,10 @@ int lttng_set_event_filter(struct lttng_handle *handle, int ret = 0; /* Safety check. */ - if (handle == NULL) { + if (handle == NULL || !filter_expression) { return -LTTNG_ERR_INVALID; } - if (!filter_expression) { - return 0; - } - /* * casting const to non-const, as the underlying function will * use it in read-only mode. @@ -921,17 +917,17 @@ int lttng_set_event_filter(struct lttng_handle *handle, memset(&lsm, 0, sizeof(lsm)); - lsm.cmd_type = LTTNG_SET_FILTER; + lsm.cmd_type = LTTNG_ENABLE_EVENT_WITH_FILTER; /* Copy channel name */ - copy_string(lsm.u.filter.channel_name, channel_name, - sizeof(lsm.u.filter.channel_name)); + copy_string(lsm.u.enable.channel_name, channel_name, + sizeof(lsm.u.enable.channel_name)); /* Copy event name */ if (event) { memcpy(&lsm.u.enable.event, event, sizeof(lsm.u.enable.event)); } - lsm.u.filter.bytecode_len = sizeof(ctx->bytecode->b) + lsm.u.enable.bytecode_len = sizeof(ctx->bytecode->b) + bytecode_get_len(&ctx->bytecode->b); copy_lttng_domain(&lsm.domain, &handle->domain); @@ -940,7 +936,7 @@ int lttng_set_event_filter(struct lttng_handle *handle, sizeof(lsm.session.name)); ret = ask_sessiond_varlen(&lsm, &ctx->bytecode->b, - lsm.u.filter.bytecode_len, NULL); + lsm.u.enable.bytecode_len, NULL); filter_bytecode_free(ctx); filter_ir_free(ctx); diff --git a/tests/tools/test_ust_data_trace.c b/tests/tools/test_ust_data_trace.c index 5d4c91b7e..a9f4bb952 100644 --- a/tests/tools/test_ust_data_trace.c +++ b/tests/tools/test_ust_data_trace.c @@ -158,7 +158,7 @@ static void create_ust_event(void) ev.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; printf("Creating UST event: "); - event = trace_ust_create_event(&ev); + event = trace_ust_create_event(&ev, NULL); assert(event != NULL); PRINT_OK();