2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; only version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include <urcu/list.h>
25 #include <lttng-sessiond-comm.h>
29 #include "hashtable.h"
30 #include "kernel-ctl.h"
33 * Add kernel context to an event of a specific channel.
35 static int add_kctx_to_event(struct lttng_kernel_context
*kctx
,
36 struct ltt_kernel_channel
*kchan
, char *event_name
)
39 struct ltt_kernel_event
*kevent
;
41 DBG("Add kernel context to event %s", event_name
);
43 kevent
= trace_kernel_get_event_by_name(event_name
, kchan
);
45 ret
= kernel_add_event_context(kevent
, kctx
);
59 * Add kernel context to all channel.
61 * If event_name is specified, add context to event instead.
63 static int add_kctx_all_channels(struct ltt_kernel_session
*ksession
,
64 struct lttng_kernel_context
*kctx
, char *event_name
)
66 int ret
, no_event
= 0, found
= 0;
67 struct ltt_kernel_channel
*kchan
;
69 if (strlen(event_name
) == 0) {
73 DBG("Adding kernel context to all channels (event: %s)", event_name
);
75 /* Go over all channels */
76 cds_list_for_each_entry(kchan
, &ksession
->channel_list
.head
, list
) {
78 ret
= kernel_add_channel_context(kchan
, kctx
);
80 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
84 ret
= add_kctx_to_event(kctx
, kchan
, event_name
);
86 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
88 } else if (ret
== 1) {
89 /* Event found and context added */
96 if (!found
&& !no_event
) {
97 ret
= LTTCOMM_NO_EVENT
;
108 * Add kernel context to a specific channel.
110 * If event_name is specified, add context to that event.
112 static int add_kctx_to_channel(struct lttng_kernel_context
*kctx
,
113 struct ltt_kernel_channel
*kchan
, char *event_name
)
115 int ret
, no_event
= 0, found
= 0;
117 if (strlen(event_name
) == 0) {
121 DBG("Add kernel context to channel '%s', event '%s'",
122 kchan
->channel
->name
, event_name
);
125 ret
= kernel_add_channel_context(kchan
, kctx
);
127 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
131 ret
= add_kctx_to_event(kctx
, kchan
, event_name
);
133 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
135 } else if (ret
== 1) {
136 /* Event found and context added */
141 if (!found
&& !no_event
) {
142 ret
= LTTCOMM_NO_EVENT
;
153 * Add kernel context to tracer.
155 int context_kernel_add(struct ltt_kernel_session
*ksession
,
156 struct lttng_event_context
*ctx
, char *event_name
,
160 struct ltt_kernel_channel
*kchan
;
161 struct lttng_kernel_context kctx
;
163 /* Setup kernel context structure */
165 kctx
.u
.perf_counter
.type
= ctx
->u
.perf_counter
.type
;
166 kctx
.u
.perf_counter
.config
= ctx
->u
.perf_counter
.config
;
167 strncpy(kctx
.u
.perf_counter
.name
, ctx
->u
.perf_counter
.name
,
168 LTTNG_SYMBOL_NAME_LEN
);
169 kctx
.u
.perf_counter
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
171 if (strlen(channel_name
) == 0) {
172 ret
= add_kctx_all_channels(ksession
, &kctx
, event_name
);
173 if (ret
!= LTTCOMM_OK
) {
177 /* Get kernel channel */
178 kchan
= trace_kernel_get_channel_by_name(channel_name
, ksession
);
180 ret
= LTTCOMM_KERN_CHAN_NOT_FOUND
;
184 ret
= add_kctx_to_channel(&kctx
, kchan
, event_name
);
185 if (ret
!= LTTCOMM_OK
) {
201 * Add UST context to an event of a specific channel.
204 static int add_ustctx_to_event(struct ltt_ust_session
*ustsession
,
205 struct lttng_ust_context
*ustctx
,
206 struct ltt_ust_channel
*ustchan
, char *event_name
)
209 struct ltt_ust_event
*ustevent
;
210 struct object_data
*context_data
; /* FIXME: currently a memleak */
212 DBG("Add UST context to event %s", event_name
);
214 ustevent
= trace_ust_find_event_by_name(ustchan
->events
, event_name
);
215 if (ustevent
!= NULL
) {
216 ret
= ustctl_add_context(ustsession
->sock
, ustctx
,
217 ustevent
->obj
, &context_data
);
232 * Add UST context to all channel.
234 * If event_name is specified, add context to event instead.
236 static int add_ustctx_all_channels(struct ltt_ust_session
*ustsession
,
237 struct lttng_ust_context
*ustctx
, char *event_name
,
238 struct cds_lfht
*channels
)
241 int ret
, no_event
= 0, found
= 0;
242 struct ltt_ust_channel
*ustchan
;
243 struct object_data
*context_data
; /* FIXME: currently a memleak */
245 if (strlen(event_name
) == 0) {
249 DBG("Adding ust context to all channels (event: %s)", event_name
);
251 struct cds_lfht_node
*node
;
252 struct cds_lfht_iter iter
;
255 hashtable_get_first(channels
, &iter
);
256 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
257 ustchan
= caa_container_of(node
, struct ltt_ust_channel
, node
);
259 //ret = ustctl_add_context(ustsession->sock,
260 // ustctx, ustchan->obj, &context_data);
262 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
266 ret
= add_ustctx_to_event(ustsession
, ustctx
, ustchan
, event_name
);
268 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
270 } else if (ret
== 1) {
271 /* Event found and context added */
276 hashtable_get_next(channels
, &iter
);
278 if (!found
&& !no_event
) {
279 ret
= LTTCOMM_NO_EVENT
;
291 * Add UST context to a specific channel.
293 * If event_name is specified, add context to that event.
295 static int add_ustctx_to_channel(struct ltt_ust_session
*ustsession
,
296 struct lttng_ust_context
*ustctx
,
297 struct ltt_ust_channel
*ustchan
, char *event_name
)
300 int ret
, no_event
= 0, found
= 0;
301 struct object_data
*context_data
; /* FIXME: currently a memleak */
303 if (strlen(event_name
) == 0) {
307 DBG("Add UST context to channel '%s', event '%s'",
308 ustchan
->name
, event_name
);
311 //ret = ustctl_add_context(ustsession->sock, ustctx,
312 // ustchan->obj, &context_data);
314 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
318 ret
= add_ustctx_to_event(ustsession
, ustctx
, ustchan
, event_name
);
320 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
322 } else if (ret
== 1) {
323 /* Event found and context added */
328 if (!found
&& !no_event
) {
329 ret
= LTTCOMM_NO_EVENT
;
342 * Add UST context to tracer.
344 int context_ust_add(struct ltt_ust_session
*ustsession
,
345 struct lttng_event_context
*ctx
, char *event_name
,
346 char *channel_name
, int domain
)
349 struct cds_lfht
*chan_ht
= NULL
;
350 struct ltt_ust_channel
*ustchan
;
351 struct lttng_ust_context ustctx
;
353 /* Setup UST context structure */
354 ustctx
.ctx
= ctx
->ctx
;
357 case LTTNG_DOMAIN_UST
:
358 chan_ht
= ustsession
->domain_global
.channels
;
362 if (strlen(channel_name
) == 0) {
363 ret
= add_ustctx_all_channels(ustsession
, &ustctx
, event_name
, chan_ht
);
364 if (ret
!= LTTCOMM_OK
) {
368 /* Get UST channel */
369 ustchan
= trace_ust_find_channel_by_name(chan_ht
, channel_name
);
370 if (ustchan
== NULL
) {
371 ret
= LTTCOMM_UST_CHAN_NOT_FOUND
;
375 ret
= add_ustctx_to_channel(ustsession
, &ustctx
, ustchan
, event_name
);
376 if (ret
!= LTTCOMM_OK
) {