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>
28 #ifdef CONFIG_LTTNG_TOOLS_HAVE_UST
29 #include <ust/lttng-ust-ctl.h>
30 #include <ust/lttng-ust-abi.h>
32 #include "lttng-ust-ctl.h"
33 #include "lttng-ust-abi.h"
37 #include "kernel-ctl.h"
40 * Add kernel context to an event of a specific channel.
42 static int add_kctx_to_event(struct lttng_kernel_context
*kctx
,
43 struct ltt_kernel_channel
*kchan
, char *event_name
)
46 struct ltt_kernel_event
*kevent
;
48 DBG("Add kernel context to event %s", event_name
);
50 kevent
= trace_kernel_get_event_by_name(event_name
, kchan
);
52 ret
= kernel_add_event_context(kevent
, kctx
);
66 * Add kernel context to all channel.
68 * If event_name is specified, add context to event instead.
70 static int add_kctx_all_channels(struct ltt_kernel_session
*ksession
,
71 struct lttng_kernel_context
*kctx
, char *event_name
)
73 int ret
, no_event
= 0, found
= 0;
74 struct ltt_kernel_channel
*kchan
;
76 if (strlen(event_name
) == 0) {
80 DBG("Adding kernel context to all channels (event: %s)", event_name
);
82 /* Go over all channels */
83 cds_list_for_each_entry(kchan
, &ksession
->channel_list
.head
, list
) {
85 ret
= kernel_add_channel_context(kchan
, kctx
);
87 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
91 ret
= add_kctx_to_event(kctx
, kchan
, event_name
);
93 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
95 } else if (ret
== 1) {
96 /* Event found and context added */
103 if (!found
&& !no_event
) {
104 ret
= LTTCOMM_NO_EVENT
;
115 * Add kernel context to a specific channel.
117 * If event_name is specified, add context to that event.
119 static int add_kctx_to_channel(struct lttng_kernel_context
*kctx
,
120 struct ltt_kernel_channel
*kchan
, char *event_name
)
122 int ret
, no_event
= 0, found
= 0;
124 if (strlen(event_name
) == 0) {
128 DBG("Add kernel context to channel '%s', event '%s'",
129 kchan
->channel
->name
, event_name
);
132 ret
= kernel_add_channel_context(kchan
, kctx
);
134 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
138 ret
= add_kctx_to_event(kctx
, kchan
, event_name
);
140 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
142 } else if (ret
== 1) {
143 /* Event found and context added */
148 if (!found
&& !no_event
) {
149 ret
= LTTCOMM_NO_EVENT
;
160 * Add kernel context to tracer.
162 int context_kernel_add(struct ltt_kernel_session
*ksession
,
163 struct lttng_event_context
*ctx
, char *event_name
,
167 struct ltt_kernel_channel
*kchan
;
168 struct lttng_kernel_context kctx
;
170 /* Setup kernel context structure */
172 kctx
.u
.perf_counter
.type
= ctx
->u
.perf_counter
.type
;
173 kctx
.u
.perf_counter
.config
= ctx
->u
.perf_counter
.config
;
174 strncpy(kctx
.u
.perf_counter
.name
, ctx
->u
.perf_counter
.name
,
175 LTTNG_SYMBOL_NAME_LEN
);
176 kctx
.u
.perf_counter
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
178 if (strlen(channel_name
) == 0) {
179 ret
= add_kctx_all_channels(ksession
, &kctx
, event_name
);
180 if (ret
!= LTTCOMM_OK
) {
184 /* Get kernel channel */
185 kchan
= trace_kernel_get_channel_by_name(channel_name
, ksession
);
187 ret
= LTTCOMM_KERN_CHAN_NOT_FOUND
;
191 ret
= add_kctx_to_channel(&kctx
, kchan
, event_name
);
192 if (ret
!= LTTCOMM_OK
) {
208 * Add UST context to an event of a specific channel.
210 static int add_ustctx_to_event(struct ltt_ust_session
*ustsession
,
211 struct lttng_ust_context
*ustctx
,
212 struct ltt_ust_channel
*ustchan
, char *event_name
)
215 struct ltt_ust_event
*ustevent
;
216 struct object_data
*context_data
; /* FIXME: currently a memleak */
218 DBG("Add UST context to event %s", event_name
);
220 ustevent
= trace_ust_get_event_by_name(event_name
, ustchan
);
221 if (ustevent
!= NULL
) {
222 ret
= ustctl_add_context(ustsession
->sock
, ustctx
,
223 ustevent
->obj
, &context_data
);
237 * Add UST context to all channel.
239 * If event_name is specified, add context to event instead.
241 static int add_ustctx_all_channels(struct ltt_ust_session
*ustsession
,
242 struct lttng_ust_context
*ustctx
, char *event_name
)
244 int ret
, no_event
= 0, found
= 0;
245 struct ltt_ust_channel
*ustchan
;
246 struct object_data
*context_data
; /* FIXME: currently a memleak */
248 if (strlen(event_name
) == 0) {
252 DBG("Adding ust context to all channels (event: %s)", event_name
);
254 /* Go over all channels */
255 cds_list_for_each_entry(ustchan
, &ustsession
->channels
.head
, list
) {
257 ret
= ustctl_add_context(ustsession
->sock
,
258 ustctx
, ustchan
->obj
, &context_data
);
260 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
264 ret
= add_ustctx_to_event(ustsession
, ustctx
, ustchan
, event_name
);
266 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
268 } else if (ret
== 1) {
269 /* Event found and context added */
276 if (!found
&& !no_event
) {
277 ret
= LTTCOMM_NO_EVENT
;
288 * Add UST context to a specific channel.
290 * If event_name is specified, add context to that event.
292 static int add_ustctx_to_channel(struct ltt_ust_session
*ustsession
,
293 struct lttng_ust_context
*ustctx
,
294 struct ltt_ust_channel
*ustchan
, char *event_name
)
296 int ret
, no_event
= 0, found
= 0;
297 struct object_data
*context_data
; /* FIXME: currently a memleak */
299 if (strlen(event_name
) == 0) {
303 DBG("Add UST context to channel '%s', event '%s'",
304 ustchan
->name
, event_name
);
307 ret
= ustctl_add_context(ustsession
->sock
, ustctx
,
308 ustchan
->obj
, &context_data
);
310 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
314 ret
= add_ustctx_to_event(ustsession
, ustctx
, ustchan
, event_name
);
316 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
318 } else if (ret
== 1) {
319 /* Event found and context added */
324 if (!found
&& !no_event
) {
325 ret
= LTTCOMM_NO_EVENT
;
336 * Add UST context to tracer.
338 int context_ust_add(struct ltt_ust_session
*ustsession
,
339 struct lttng_event_context
*ctx
, char *event_name
,
343 struct ltt_ust_channel
*ustchan
;
344 struct lttng_ust_context ustctx
;
346 /* Setup UST context structure */
347 ustctx
.ctx
= ctx
->ctx
;
349 if (strlen(channel_name
) == 0) {
350 ret
= add_ustctx_all_channels(ustsession
, &ustctx
, event_name
);
351 if (ret
!= LTTCOMM_OK
) {
355 /* Get UST channel */
356 ustchan
= trace_ust_get_channel_by_name(channel_name
, ustsession
);
357 if (ustchan
== NULL
) {
358 ret
= LTTCOMM_UST_CHAN_NOT_FOUND
;
362 ret
= add_ustctx_to_channel(ustsession
, &ustctx
, ustchan
, event_name
);
363 if (ret
!= LTTCOMM_OK
) {