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 "hashtable.h"
38 #include "kernel-ctl.h"
41 * Add kernel context to an event of a specific channel.
43 static int add_kctx_to_event(struct lttng_kernel_context
*kctx
,
44 struct ltt_kernel_channel
*kchan
, char *event_name
)
47 struct ltt_kernel_event
*kevent
;
49 DBG("Add kernel context to event %s", event_name
);
51 kevent
= trace_kernel_get_event_by_name(event_name
, kchan
);
53 ret
= kernel_add_event_context(kevent
, kctx
);
67 * Add kernel context to all channel.
69 * If event_name is specified, add context to event instead.
71 static int add_kctx_all_channels(struct ltt_kernel_session
*ksession
,
72 struct lttng_kernel_context
*kctx
, char *event_name
)
74 int ret
, no_event
= 0, found
= 0;
75 struct ltt_kernel_channel
*kchan
;
77 if (strlen(event_name
) == 0) {
81 DBG("Adding kernel context to all channels (event: %s)", event_name
);
83 /* Go over all channels */
84 cds_list_for_each_entry(kchan
, &ksession
->channel_list
.head
, list
) {
86 ret
= kernel_add_channel_context(kchan
, kctx
);
88 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
92 ret
= add_kctx_to_event(kctx
, kchan
, event_name
);
94 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
96 } else if (ret
== 1) {
97 /* Event found and context added */
104 if (!found
&& !no_event
) {
105 ret
= LTTCOMM_NO_EVENT
;
116 * Add kernel context to a specific channel.
118 * If event_name is specified, add context to that event.
120 static int add_kctx_to_channel(struct lttng_kernel_context
*kctx
,
121 struct ltt_kernel_channel
*kchan
, char *event_name
)
123 int ret
, no_event
= 0, found
= 0;
125 if (strlen(event_name
) == 0) {
129 DBG("Add kernel context to channel '%s', event '%s'",
130 kchan
->channel
->name
, event_name
);
133 ret
= kernel_add_channel_context(kchan
, kctx
);
135 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
139 ret
= add_kctx_to_event(kctx
, kchan
, event_name
);
141 ret
= LTTCOMM_KERN_CONTEXT_FAIL
;
143 } else if (ret
== 1) {
144 /* Event found and context added */
149 if (!found
&& !no_event
) {
150 ret
= LTTCOMM_NO_EVENT
;
161 * Add kernel context to tracer.
163 int context_kernel_add(struct ltt_kernel_session
*ksession
,
164 struct lttng_event_context
*ctx
, char *event_name
,
168 struct ltt_kernel_channel
*kchan
;
169 struct lttng_kernel_context kctx
;
171 /* Setup kernel context structure */
173 kctx
.u
.perf_counter
.type
= ctx
->u
.perf_counter
.type
;
174 kctx
.u
.perf_counter
.config
= ctx
->u
.perf_counter
.config
;
175 strncpy(kctx
.u
.perf_counter
.name
, ctx
->u
.perf_counter
.name
,
176 LTTNG_SYMBOL_NAME_LEN
);
177 kctx
.u
.perf_counter
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
179 if (strlen(channel_name
) == 0) {
180 ret
= add_kctx_all_channels(ksession
, &kctx
, event_name
);
181 if (ret
!= LTTCOMM_OK
) {
185 /* Get kernel channel */
186 kchan
= trace_kernel_get_channel_by_name(channel_name
, ksession
);
188 ret
= LTTCOMM_KERN_CHAN_NOT_FOUND
;
192 ret
= add_kctx_to_channel(&kctx
, kchan
, event_name
);
193 if (ret
!= LTTCOMM_OK
) {
209 * Add UST context to an event of a specific channel.
212 static int add_ustctx_to_event(struct ltt_ust_session
*ustsession
,
213 struct lttng_ust_context
*ustctx
,
214 struct ltt_ust_channel
*ustchan
, char *event_name
)
217 struct ltt_ust_event
*ustevent
;
218 struct object_data
*context_data
; /* FIXME: currently a memleak */
220 DBG("Add UST context to event %s", event_name
);
222 ustevent
= trace_ust_find_event_by_name(ustchan
->events
, event_name
);
223 if (ustevent
!= NULL
) {
224 ret
= ustctl_add_context(ustsession
->sock
, ustctx
,
225 ustevent
->obj
, &context_data
);
240 * Add UST context to all channel.
242 * If event_name is specified, add context to event instead.
244 static int add_ustctx_all_channels(struct ltt_ust_session
*ustsession
,
245 struct lttng_ust_context
*ustctx
, char *event_name
,
246 struct cds_lfht
*channels
)
249 int ret
, no_event
= 0, found
= 0;
250 struct ltt_ust_channel
*ustchan
;
251 struct object_data
*context_data
; /* FIXME: currently a memleak */
253 if (strlen(event_name
) == 0) {
257 DBG("Adding ust context to all channels (event: %s)", event_name
);
259 struct cds_lfht_node
*node
;
260 struct cds_lfht_iter iter
;
263 hashtable_get_first(channels
, &iter
);
264 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
265 ustchan
= caa_container_of(node
, struct ltt_ust_channel
, node
);
267 //ret = ustctl_add_context(ustsession->sock,
268 // ustctx, ustchan->obj, &context_data);
270 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
274 ret
= add_ustctx_to_event(ustsession
, ustctx
, ustchan
, event_name
);
276 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
278 } else if (ret
== 1) {
279 /* Event found and context added */
284 hashtable_get_next(channels
, &iter
);
288 if (!found
&& !no_event
) {
289 ret
= LTTCOMM_NO_EVENT
;
302 * Add UST context to a specific channel.
304 * If event_name is specified, add context to that event.
306 static int add_ustctx_to_channel(struct ltt_ust_session
*ustsession
,
307 struct lttng_ust_context
*ustctx
,
308 struct ltt_ust_channel
*ustchan
, char *event_name
)
311 int ret
, no_event
= 0, found
= 0;
312 struct object_data
*context_data
; /* FIXME: currently a memleak */
314 if (strlen(event_name
) == 0) {
318 DBG("Add UST context to channel '%s', event '%s'",
319 ustchan
->name
, event_name
);
322 //ret = ustctl_add_context(ustsession->sock, ustctx,
323 // ustchan->obj, &context_data);
325 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
329 ret
= add_ustctx_to_event(ustsession
, ustctx
, ustchan
, event_name
);
331 ret
= LTTCOMM_UST_CONTEXT_FAIL
;
333 } else if (ret
== 1) {
334 /* Event found and context added */
339 if (!found
&& !no_event
) {
340 ret
= LTTCOMM_NO_EVENT
;
353 * Add UST context to tracer.
355 int context_ust_add(struct ltt_ust_session
*ustsession
,
356 struct lttng_event_context
*ctx
, char *event_name
,
357 char *channel_name
, int domain
)
360 struct cds_lfht
*chan_ht
= NULL
;
361 struct ltt_ust_channel
*ustchan
;
362 struct lttng_ust_context ustctx
;
364 /* Setup UST context structure */
365 ustctx
.ctx
= ctx
->ctx
;
368 case LTTNG_DOMAIN_UST
:
369 chan_ht
= ustsession
->domain_global
.channels
;
373 if (strlen(channel_name
) == 0) {
374 ret
= add_ustctx_all_channels(ustsession
, &ustctx
, event_name
, chan_ht
);
375 if (ret
!= LTTCOMM_OK
) {
379 /* Get UST channel */
380 ustchan
= trace_ust_find_channel_by_name(chan_ht
, channel_name
);
381 if (ustchan
== NULL
) {
382 ret
= LTTCOMM_UST_CHAN_NOT_FOUND
;
386 ret
= add_ustctx_to_channel(ustsession
, &ustctx
, ustchan
, event_name
);
387 if (ret
!= LTTCOMM_OK
) {