2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2016 - Jérémie Galarneau <jeremie.galarneau@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"
36 * Add kernel context to all channel.
38 * Assumes the ownership of kctx.
40 static int add_kctx_all_channels(struct ltt_kernel_session
*ksession
,
41 struct ltt_kernel_context
*kctx
)
44 struct ltt_kernel_channel
*kchan
;
49 DBG("Adding kernel context to all channels");
51 /* Go over all channels */
52 cds_list_for_each_entry(kchan
, &ksession
->channel_list
.head
, list
) {
53 struct ltt_kernel_context
*kctx_copy
;
55 kctx_copy
= trace_kernel_copy_context(kctx
);
57 PERROR("zmalloc ltt_kernel_context");
58 ret
= -LTTNG_ERR_NOMEM
;
62 /* Ownership of kctx_copy is transferred to the callee. */
63 ret
= kernel_add_channel_context(kchan
, kctx_copy
);
73 trace_kernel_destroy_context(kctx
);
78 * Add kernel context to a specific channel.
80 * Assumes the ownership of kctx.
82 static int add_kctx_to_channel(struct ltt_kernel_context
*kctx
,
83 struct ltt_kernel_channel
*kchan
)
90 DBG("Add kernel context to channel '%s'", kchan
->channel
->name
);
92 /* Ownership of kctx is transferred to the callee. */
93 ret
= kernel_add_channel_context(kchan
, kctx
);
106 * Add UST context to channel.
108 static int add_uctx_to_channel(struct ltt_ust_session
*usess
,
109 enum lttng_domain_type domain
,
110 struct ltt_ust_channel
*uchan
,
111 const struct lttng_event_context
*ctx
)
114 struct ltt_ust_context
*uctx
= NULL
;
120 /* Check if context is duplicate */
121 cds_list_for_each_entry(uctx
, &uchan
->ctx_list
, list
) {
122 if (trace_ust_match_context(uctx
, ctx
)) {
123 ret
= LTTNG_ERR_UST_CONTEXT_EXIST
;
130 case LTTNG_DOMAIN_JUL
:
131 case LTTNG_DOMAIN_LOG4J
:
135 if (ctx
->ctx
!= LTTNG_EVENT_CONTEXT_APP_CONTEXT
) {
136 /* Other contexts are not needed by the agent. */
139 agt
= trace_ust_find_agent(usess
, domain
);
142 agt
= agent_create(domain
);
144 ret
= -LTTNG_ERR_NOMEM
;
147 agent_add(agt
, usess
->agents
);
149 ret
= agent_add_context(ctx
, agt
);
150 if (ret
!= LTTNG_OK
) {
154 ret
= agent_enable_context(ctx
, domain
);
155 if (ret
!= LTTNG_OK
) {
160 case LTTNG_DOMAIN_UST
:
166 /* Create ltt UST context */
167 uctx
= trace_ust_create_context(ctx
);
169 ret
= LTTNG_ERR_UST_CONTEXT_INVAL
;
173 /* Add ltt UST context node to ltt UST channel */
174 lttng_ht_add_ulong(uchan
->ctx
, &uctx
->node
);
175 cds_list_add_tail(&uctx
->list
, &uchan
->ctx_list
);
177 if (!usess
->active
) {
181 ret
= ust_app_add_ctx_channel_glb(usess
, uchan
, uctx
);
186 DBG("Context UST %d added to channel %s", uctx
->ctx
.ctx
, uchan
->name
);
197 * Add kernel context to tracer.
199 int context_kernel_add(struct ltt_kernel_session
*ksession
,
200 const struct lttng_event_context
*ctx
, char *channel_name
)
203 struct ltt_kernel_channel
*kchan
;
204 struct ltt_kernel_context
*kctx
;
208 assert(channel_name
);
210 kctx
= trace_kernel_create_context(NULL
);
212 ret
= -LTTNG_ERR_NOMEM
;
216 /* Setup kernel context structure */
218 case LTTNG_EVENT_CONTEXT_PID
:
219 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_PID
;
221 case LTTNG_EVENT_CONTEXT_PROCNAME
:
222 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_PROCNAME
;
224 case LTTNG_EVENT_CONTEXT_PRIO
:
225 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_PRIO
;
227 case LTTNG_EVENT_CONTEXT_NICE
:
228 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_NICE
;
230 case LTTNG_EVENT_CONTEXT_VPID
:
231 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_VPID
;
233 case LTTNG_EVENT_CONTEXT_TID
:
234 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_TID
;
236 case LTTNG_EVENT_CONTEXT_VTID
:
237 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_VTID
;
239 case LTTNG_EVENT_CONTEXT_PPID
:
240 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_PPID
;
242 case LTTNG_EVENT_CONTEXT_VPPID
:
243 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_VPPID
;
245 case LTTNG_EVENT_CONTEXT_HOSTNAME
:
246 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_HOSTNAME
;
248 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER
:
249 case LTTNG_EVENT_CONTEXT_PERF_COUNTER
:
250 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_PERF_CPU_COUNTER
;
252 case LTTNG_EVENT_CONTEXT_INTERRUPTIBLE
:
253 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_INTERRUPTIBLE
;
255 case LTTNG_EVENT_CONTEXT_PREEMPTIBLE
:
256 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_PREEMPTIBLE
;
258 case LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE
:
259 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_NEED_RESCHEDULE
;
261 case LTTNG_EVENT_CONTEXT_MIGRATABLE
:
262 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_MIGRATABLE
;
264 case LTTNG_EVENT_CONTEXT_CALLSTACK_KERNEL
:
265 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_CALLSTACK_KERNEL
;
267 case LTTNG_EVENT_CONTEXT_CALLSTACK_USER
:
268 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_CALLSTACK_USER
;
270 case LTTNG_EVENT_CONTEXT_CGROUP_NS
:
271 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_CGROUP_NS
;
273 case LTTNG_EVENT_CONTEXT_IPC_NS
:
274 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_IPC_NS
;
276 case LTTNG_EVENT_CONTEXT_MNT_NS
:
277 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_MNT_NS
;
279 case LTTNG_EVENT_CONTEXT_NET_NS
:
280 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_NET_NS
;
282 case LTTNG_EVENT_CONTEXT_PID_NS
:
283 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_PID_NS
;
285 case LTTNG_EVENT_CONTEXT_USER_NS
:
286 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_USER_NS
;
288 case LTTNG_EVENT_CONTEXT_UTS_NS
:
289 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_UTS_NS
;
291 case LTTNG_EVENT_CONTEXT_UID
:
292 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_UID
;
294 case LTTNG_EVENT_CONTEXT_EUID
:
295 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_EUID
;
297 case LTTNG_EVENT_CONTEXT_SUID
:
298 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_SUID
;
300 case LTTNG_EVENT_CONTEXT_GID
:
301 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_GID
;
303 case LTTNG_EVENT_CONTEXT_EGID
:
304 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_EGID
;
306 case LTTNG_EVENT_CONTEXT_SGID
:
307 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_SGID
;
309 case LTTNG_EVENT_CONTEXT_VUID
:
310 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_VUID
;
312 case LTTNG_EVENT_CONTEXT_VEUID
:
313 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_VEUID
;
315 case LTTNG_EVENT_CONTEXT_VSUID
:
316 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_VSUID
;
318 case LTTNG_EVENT_CONTEXT_VGID
:
319 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_VGID
;
321 case LTTNG_EVENT_CONTEXT_VEGID
:
322 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_VEGID
;
324 case LTTNG_EVENT_CONTEXT_VSGID
:
325 kctx
->ctx
.ctx
= LTTNG_KERNEL_CONTEXT_VSGID
;
328 ret
= LTTNG_ERR_KERN_CONTEXT_FAIL
;
332 kctx
->ctx
.u
.perf_counter
.type
= ctx
->u
.perf_counter
.type
;
333 kctx
->ctx
.u
.perf_counter
.config
= ctx
->u
.perf_counter
.config
;
334 strncpy(kctx
->ctx
.u
.perf_counter
.name
, ctx
->u
.perf_counter
.name
,
335 LTTNG_SYMBOL_NAME_LEN
);
336 kctx
->ctx
.u
.perf_counter
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
338 if (*channel_name
== '\0') {
339 ret
= add_kctx_all_channels(ksession
, kctx
);
340 /* Ownership of kctx is transferred to the callee. */
342 if (ret
!= LTTNG_OK
) {
346 /* Get kernel channel */
347 kchan
= trace_kernel_get_channel_by_name(channel_name
, ksession
);
349 ret
= LTTNG_ERR_KERN_CHAN_NOT_FOUND
;
353 ret
= add_kctx_to_channel(kctx
, kchan
);
354 /* Ownership of kctx is transferred to the callee. */
356 if (ret
!= LTTNG_OK
) {
365 trace_kernel_destroy_context(kctx
);
371 * Add UST context to tracer.
373 int context_ust_add(struct ltt_ust_session
*usess
,
374 enum lttng_domain_type domain
,
375 const struct lttng_event_context
*ctx
,
379 struct lttng_ht_iter iter
;
380 struct lttng_ht
*chan_ht
;
381 struct ltt_ust_channel
*uchan
= NULL
;
385 assert(channel_name
);
389 chan_ht
= usess
->domain_global
.channels
;
391 /* Get UST channel if defined */
392 if (channel_name
[0] != '\0') {
393 uchan
= trace_ust_find_channel_by_name(chan_ht
, channel_name
);
395 ret
= LTTNG_ERR_UST_CHAN_NOT_FOUND
;
401 /* Add ctx to channel */
402 ret
= add_uctx_to_channel(usess
, domain
, uchan
, ctx
);
405 /* Add ctx all events, all channels */
406 cds_lfht_for_each_entry(chan_ht
->ht
, &iter
.iter
, uchan
, node
.node
) {
407 ret
= add_uctx_to_channel(usess
, domain
, uchan
, ctx
);
409 ERR("Failed to add context to channel %s",
418 case LTTNG_ERR_UST_CONTEXT_EXIST
:
421 case -LTTNG_ERR_NOMEM
:
422 ret
= LTTNG_ERR_FATAL
;
425 ret
= LTTNG_ERR_UST_CONTEXT_INVAL
;
428 ret
= LTTNG_ERR_UNKNOWN_DOMAIN
;
431 if (ret
!= 0 && ret
!= LTTNG_OK
) {
432 ret
= ret
> 0 ? ret
: LTTNG_ERR_UNK
;