2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2 only,
7 * as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <urcu/list.h>
26 #include <common/error.h>
27 #include <common/sessiond-comm/sessiond-comm.h>
32 #include "trace-ust.h"
35 * Add UST context to event.
37 static int add_ufilter_to_event(struct ltt_ust_session
*usess
, int domain
,
38 struct ltt_ust_channel
*uchan
, struct ltt_ust_event
*uevent
,
39 struct lttng_filter_bytecode
*bytecode
)
48 uevent
->filter
= (struct lttng_ust_filter_bytecode
*) bytecode
;
49 uevent
->filter
->seqnum
= usess
->filter_seq_num
;
52 case LTTNG_DOMAIN_UST
:
53 ret
= ust_app_set_filter_event_glb(usess
, uchan
, uevent
,
58 usess
->filter_seq_num
++;
65 DBG("Filter UST added to event %s",uevent
->attr
.name
);
75 * Add UST context to tracer.
77 int filter_ust_set(struct ltt_ust_session
*usess
, int domain
,
78 struct lttng_filter_bytecode
*bytecode
, struct lttng_event
*event
,
81 int ret
= LTTNG_OK
, have_event
= 0;
82 struct lttng_ht_iter iter
;
83 struct lttng_ht
*chan_ht
;
84 struct ltt_ust_channel
*uchan
= NULL
;
85 struct ltt_ust_event
*uevent
= NULL
;
88 * Define which channel's hashtable to use from the domain or quit if
92 case LTTNG_DOMAIN_UST
:
93 chan_ht
= usess
->domain_global
.channels
;
96 case LTTNG_DOMAIN_UST_EXEC_NAME
:
97 case LTTNG_DOMAIN_UST_PID
:
98 case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN
:
105 /* Do we have a valid event. */
106 if (event
&& event
->name
[0] != '\0') {
110 /* Get UST channel if defined */
111 if (strlen(channel_name
) != 0) {
112 uchan
= trace_ust_find_channel_by_name(chan_ht
, channel_name
);
114 ret
= LTTNG_ERR_UST_CHAN_NOT_FOUND
;
119 /* If UST channel specified and event name, get UST event ref */
120 if (uchan
&& have_event
) {
121 uevent
= trace_ust_find_event(uchan
->events
, event
->name
, bytecode
,
123 if (uevent
== NULL
) {
124 ret
= LTTNG_ERR_UST_EVENT_NOT_FOUND
;
129 /* At this point, we have 4 possibilities */
131 if (uchan
&& uevent
) { /* Add filter to event in channel */
132 ret
= add_ufilter_to_event(usess
, domain
, uchan
, uevent
,
134 } else if (uchan
&& !have_event
) { /* Add filter to channel */
135 ERR("Cannot add filter to channel");
136 ret
= LTTNG_ERR_FATAL
; /* not supported. */
138 } else if (!uchan
&& have_event
) { /* Add filter to event */
139 /* Add context to event without having the channel name */
140 cds_lfht_for_each_entry(chan_ht
->ht
, &iter
.iter
, uchan
, node
.node
) {
141 uevent
= trace_ust_find_event(uchan
->events
, event
->name
, bytecode
,
143 if (uevent
!= NULL
) {
144 ret
= add_ufilter_to_event(usess
, domain
, uchan
, uevent
, bytecode
);
146 * LTTng UST does not allowed the same event to be registered
147 * multiple time in different or the same channel. So, if we
148 * found our event, we stop.
153 ret
= LTTNG_ERR_UST_EVENT_NOT_FOUND
;
155 } else if (!uchan
&& !have_event
) { /* Add filter all events, all channels */
156 ERR("Cannot add filter to channel");
157 ret
= LTTNG_ERR_FATAL
; /* not supported. */
162 /* Must handle both local internal error and UST code. */
165 case -LTTNG_UST_ERR_EXIST
:
166 ret
= LTTNG_ERR_FILTER_EXIST
;
169 ret
= LTTNG_ERR_FATAL
;
172 case -LTTNG_UST_ERR_INVAL
:
173 ret
= LTTNG_ERR_FILTER_INVAL
;
176 case -LTTNG_UST_ERR_NOSYS
:
177 ret
= LTTNG_ERR_UNKNOWN_DOMAIN
;