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
, char *event_name
,
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 an event name */
106 if (strlen(event_name
) != 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_by_name(uchan
->events
, event_name
);
122 if (uevent
== NULL
) {
123 ret
= LTTNG_ERR_UST_EVENT_NOT_FOUND
;
128 /* At this point, we have 4 possibilities */
130 if (uchan
&& uevent
) { /* Add filter to event in channel */
131 ret
= add_ufilter_to_event(usess
, domain
, uchan
, uevent
,
133 } else if (uchan
&& !have_event
) { /* Add filter to channel */
134 ERR("Cannot add filter to channel");
135 ret
= LTTNG_ERR_FATAL
; /* not supported. */
137 } else if (!uchan
&& have_event
) { /* Add filter to event */
138 /* Add context to event without having the channel name */
139 cds_lfht_for_each_entry(chan_ht
->ht
, &iter
.iter
, uchan
, node
.node
) {
140 uevent
= trace_ust_find_event_by_name(uchan
->events
, event_name
);
141 if (uevent
!= NULL
) {
142 ret
= add_ufilter_to_event(usess
, domain
, uchan
, uevent
, bytecode
);
144 * LTTng UST does not allowed the same event to be registered
145 * multiple time in different or the same channel. So, if we
146 * found our event, we stop.
151 ret
= LTTNG_ERR_UST_EVENT_NOT_FOUND
;
153 } else if (!uchan
&& !have_event
) { /* Add filter all events, all channels */
154 ERR("Cannot add filter to channel");
155 ret
= LTTNG_ERR_FATAL
; /* not supported. */
160 /* Must handle both local internal error and UST code. */
163 case -LTTNG_UST_ERR_EXIST
:
164 ret
= LTTNG_ERR_FILTER_EXIST
;
167 ret
= LTTNG_ERR_FATAL
;
170 case -LTTNG_UST_ERR_INVAL
:
171 ret
= LTTNG_ERR_FILTER_INVAL
;
174 case -LTTNG_UST_ERR_NOSYS
:
175 ret
= LTTNG_ERR_UNKNOWN_DOMAIN
;