2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <urcu/list.h>
25 #include <common/error.h>
26 #include <common/sessiond-comm/sessiond-comm.h>
31 #include "trace-ust.h"
34 * Add kernel context to all channel.
36 static int add_kctx_all_channels(struct ltt_kernel_session
*ksession
,
37 struct lttng_kernel_context
*kctx
)
40 struct ltt_kernel_channel
*kchan
;
45 DBG("Adding kernel context to all channels");
47 /* Go over all channels */
48 cds_list_for_each_entry(kchan
, &ksession
->channel_list
.head
, list
) {
49 ret
= kernel_add_channel_context(kchan
, kctx
);
51 ret
= LTTNG_ERR_KERN_CONTEXT_FAIL
;
63 * Add kernel context to a specific channel.
65 static int add_kctx_to_channel(struct lttng_kernel_context
*kctx
,
66 struct ltt_kernel_channel
*kchan
)
73 DBG("Add kernel context to channel '%s'", kchan
->channel
->name
);
75 ret
= kernel_add_channel_context(kchan
, kctx
);
77 ret
= LTTNG_ERR_KERN_CONTEXT_FAIL
;
88 * Add UST context to channel.
90 static int add_uctx_to_channel(struct ltt_ust_session
*usess
, int domain
,
91 struct ltt_ust_channel
*uchan
, struct lttng_event_context
*ctx
)
94 struct ltt_ust_context
*uctx
;
95 struct lttng_ht_iter iter
;
96 struct lttng_ht_node_ulong
*uctx_node
;
102 /* Create ltt UST context */
103 uctx
= trace_ust_create_context(ctx
);
110 case LTTNG_DOMAIN_UST
:
111 ret
= ust_app_add_ctx_channel_glb(usess
, uchan
, uctx
);
123 /* Lookup context before adding it */
124 lttng_ht_lookup(uchan
->ctx
, (void *)((unsigned long)uctx
->ctx
.ctx
), &iter
);
125 uctx_node
= lttng_ht_iter_get_node_ulong(&iter
);
126 if (uctx_node
!= NULL
) {
132 /* Add ltt UST context node to ltt UST channel */
133 lttng_ht_add_unique_ulong(uchan
->ctx
, &uctx
->node
);
135 cds_list_add_tail(&uctx
->list
, &uchan
->ctx_list
);
137 DBG("Context UST %d added to channel %s", uctx
->ctx
.ctx
, uchan
->name
);
147 * Add kernel context to tracer.
149 int context_kernel_add(struct ltt_kernel_session
*ksession
,
150 struct lttng_event_context
*ctx
, char *channel_name
)
153 struct ltt_kernel_channel
*kchan
;
154 struct lttng_kernel_context kctx
;
158 assert(channel_name
);
160 /* Setup kernel context structure */
162 case LTTNG_EVENT_CONTEXT_PID
:
163 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_PID
;
165 case LTTNG_EVENT_CONTEXT_PERF_COUNTER
:
166 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_PERF_COUNTER
;
168 case LTTNG_EVENT_CONTEXT_PROCNAME
:
169 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_PROCNAME
;
171 case LTTNG_EVENT_CONTEXT_PRIO
:
172 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_PRIO
;
174 case LTTNG_EVENT_CONTEXT_NICE
:
175 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_NICE
;
177 case LTTNG_EVENT_CONTEXT_VPID
:
178 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_VPID
;
180 case LTTNG_EVENT_CONTEXT_TID
:
181 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_TID
;
183 case LTTNG_EVENT_CONTEXT_VTID
:
184 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_VTID
;
186 case LTTNG_EVENT_CONTEXT_PPID
:
187 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_PPID
;
189 case LTTNG_EVENT_CONTEXT_VPPID
:
190 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_VPPID
;
192 case LTTNG_EVENT_CONTEXT_HOSTNAME
:
193 kctx
.ctx
= LTTNG_KERNEL_CONTEXT_HOSTNAME
;
196 return LTTNG_ERR_KERN_CONTEXT_FAIL
;
199 kctx
.u
.perf_counter
.type
= ctx
->u
.perf_counter
.type
;
200 kctx
.u
.perf_counter
.config
= ctx
->u
.perf_counter
.config
;
201 strncpy(kctx
.u
.perf_counter
.name
, ctx
->u
.perf_counter
.name
,
202 LTTNG_SYMBOL_NAME_LEN
);
203 kctx
.u
.perf_counter
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
205 if (*channel_name
== '\0') {
206 ret
= add_kctx_all_channels(ksession
, &kctx
);
207 if (ret
!= LTTNG_OK
) {
211 /* Get kernel channel */
212 kchan
= trace_kernel_get_channel_by_name(channel_name
, ksession
);
214 ret
= LTTNG_ERR_KERN_CHAN_NOT_FOUND
;
218 ret
= add_kctx_to_channel(&kctx
, kchan
);
219 if (ret
!= LTTNG_OK
) {
231 * Add UST context to tracer.
233 int context_ust_add(struct ltt_ust_session
*usess
, int domain
,
234 struct lttng_event_context
*ctx
, char *channel_name
)
237 struct lttng_ht_iter iter
;
238 struct lttng_ht
*chan_ht
;
239 struct ltt_ust_channel
*uchan
= NULL
;
243 assert(channel_name
);
248 * Define which channel's hashtable to use from the domain or quit if
252 case LTTNG_DOMAIN_UST
:
253 chan_ht
= usess
->domain_global
.channels
;
256 case LTTNG_DOMAIN_UST_EXEC_NAME
:
257 case LTTNG_DOMAIN_UST_PID
:
258 case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN
:
265 /* Get UST channel if defined */
266 if (channel_name
[0] != '\0') {
267 uchan
= trace_ust_find_channel_by_name(chan_ht
, channel_name
);
269 ret
= LTTNG_ERR_UST_CHAN_NOT_FOUND
;
275 /* Add ctx to channel */
276 ret
= add_uctx_to_channel(usess
, domain
, uchan
, ctx
);
279 /* Add ctx all events, all channels */
280 cds_lfht_for_each_entry(chan_ht
->ht
, &iter
.iter
, uchan
, node
.node
) {
281 ret
= add_uctx_to_channel(usess
, domain
, uchan
, ctx
);
283 ERR("Context failed for channel %s", uchan
->name
);
292 ret
= LTTNG_ERR_UST_CONTEXT_EXIST
;
295 ret
= LTTNG_ERR_FATAL
;
298 ret
= LTTNG_ERR_UST_CONTEXT_INVAL
;
301 ret
= LTTNG_ERR_UNKNOWN_DOMAIN
;