2 * Copyright (C) 2011 EfficiOS Inc.
3 * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * SPDX-License-Identifier: GPL-2.0-only
11 #include "context.hpp"
13 #include "trace-ust.hpp"
14 #include "ust-app.hpp"
16 #include <common/error.hpp>
17 #include <common/sessiond-comm/sessiond-comm.hpp>
18 #include <common/urcu.hpp>
22 #include <urcu/list.h>
25 * Add kernel context to all channel.
27 * Assumes the ownership of kctx.
29 static int add_kctx_all_channels(struct ltt_kernel_session
*ksession
,
30 struct ltt_kernel_context
*kctx
)
34 LTTNG_ASSERT(ksession
);
37 DBG("Adding kernel context to all channels");
39 /* Go over all channels */
41 lttng::urcu::list_iteration_adapter
<ltt_kernel_channel
, <t_kernel_channel::list
>(
42 ksession
->channel_list
.head
)) {
43 struct ltt_kernel_context
*kctx_copy
;
45 kctx_copy
= trace_kernel_copy_context(kctx
);
47 PERROR("zmalloc ltt_kernel_context");
48 ret
= -LTTNG_ERR_NOMEM
;
52 /* Ownership of kctx_copy is transferred to the callee. */
53 ret
= kernel_add_channel_context(kchan
, kctx_copy
);
63 trace_kernel_destroy_context(kctx
);
68 * Add kernel context to a specific channel.
70 * Assumes the ownership of kctx.
72 static int add_kctx_to_channel(struct ltt_kernel_context
*kctx
, struct ltt_kernel_channel
*kchan
)
79 DBG("Add kernel context to channel '%s'", kchan
->channel
->name
);
81 /* Ownership of kctx is transferred to the callee. */
82 ret
= kernel_add_channel_context(kchan
, kctx
);
95 * Add UST context to channel.
97 static int add_uctx_to_channel(struct ltt_ust_session
*usess
,
98 enum lttng_domain_type domain
,
99 struct ltt_ust_channel
*uchan
,
100 const struct lttng_event_context
*ctx
)
103 struct ltt_ust_context
*new_uctx
= nullptr;
109 /* Check if context is duplicate */
111 lttng::urcu::list_iteration_adapter
<ltt_ust_context
, <t_ust_context::list
>(
113 if (trace_ust_match_context(uctx_it
, ctx
)) {
114 ret
= LTTNG_ERR_UST_CONTEXT_EXIST
;
120 case LTTNG_DOMAIN_JUL
:
121 case LTTNG_DOMAIN_LOG4J
:
122 case LTTNG_DOMAIN_LOG4J2
:
126 if (ctx
->ctx
!= LTTNG_EVENT_CONTEXT_APP_CONTEXT
) {
127 /* Other contexts are not needed by the agent. */
130 agt
= trace_ust_find_agent(usess
, domain
);
133 agt
= agent_create(domain
);
135 ret
= -LTTNG_ERR_NOMEM
;
138 agent_add(agt
, usess
->agents
);
140 ret
= agent_add_context(ctx
, agt
);
141 if (ret
!= LTTNG_OK
) {
145 ret
= agent_enable_context(ctx
, domain
);
146 if (ret
!= LTTNG_OK
) {
151 case LTTNG_DOMAIN_UST
:
157 /* Create ltt UST context */
158 new_uctx
= trace_ust_create_context(ctx
);
159 if (new_uctx
== nullptr) {
160 ret
= LTTNG_ERR_UST_CONTEXT_INVAL
;
164 /* Add ltt UST context node to ltt UST channel */
165 lttng_ht_add_ulong(uchan
->ctx
, &new_uctx
->node
);
166 cds_list_add_tail(&new_uctx
->list
, &uchan
->ctx_list
);
168 if (!usess
->active
) {
172 ret
= ust_app_add_ctx_channel_glb(usess
, uchan
, new_uctx
);
177 DBG("Context UST %d added to channel %s", new_uctx
->ctx
.ctx
, uchan
->name
);
188 * Add kernel context to tracer.
190 int context_kernel_add(struct ltt_kernel_session
*ksession
,
191 const struct lttng_event_context
*ctx
,
192 const char *channel_name
)
195 struct ltt_kernel_channel
*kchan
;
196 struct ltt_kernel_context
*kctx
;
198 LTTNG_ASSERT(ksession
);
200 LTTNG_ASSERT(channel_name
);
202 kctx
= trace_kernel_create_context(nullptr);
204 ret
= -LTTNG_ERR_NOMEM
;
208 /* Setup kernel context structure */
210 case LTTNG_EVENT_CONTEXT_PID
:
211 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PID
;
213 case LTTNG_EVENT_CONTEXT_PROCNAME
:
214 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PROCNAME
;
216 case LTTNG_EVENT_CONTEXT_PRIO
:
217 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PRIO
;
219 case LTTNG_EVENT_CONTEXT_NICE
:
220 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_NICE
;
222 case LTTNG_EVENT_CONTEXT_VPID
:
223 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VPID
;
225 case LTTNG_EVENT_CONTEXT_TID
:
226 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_TID
;
228 case LTTNG_EVENT_CONTEXT_VTID
:
229 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VTID
;
231 case LTTNG_EVENT_CONTEXT_PPID
:
232 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PPID
;
234 case LTTNG_EVENT_CONTEXT_VPPID
:
235 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VPPID
;
237 case LTTNG_EVENT_CONTEXT_HOSTNAME
:
238 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_HOSTNAME
;
240 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER
:
241 case LTTNG_EVENT_CONTEXT_PERF_COUNTER
:
242 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PERF_CPU_COUNTER
;
244 case LTTNG_EVENT_CONTEXT_INTERRUPTIBLE
:
245 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_INTERRUPTIBLE
;
247 case LTTNG_EVENT_CONTEXT_PREEMPTIBLE
:
248 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PREEMPTIBLE
;
250 case LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE
:
251 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_NEED_RESCHEDULE
;
253 case LTTNG_EVENT_CONTEXT_MIGRATABLE
:
254 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_MIGRATABLE
;
256 case LTTNG_EVENT_CONTEXT_CALLSTACK_KERNEL
:
257 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_KERNEL
;
259 case LTTNG_EVENT_CONTEXT_CALLSTACK_USER
:
260 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_USER
;
262 case LTTNG_EVENT_CONTEXT_CGROUP_NS
:
263 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_CGROUP_NS
;
265 case LTTNG_EVENT_CONTEXT_IPC_NS
:
266 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_IPC_NS
;
268 case LTTNG_EVENT_CONTEXT_MNT_NS
:
269 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_MNT_NS
;
271 case LTTNG_EVENT_CONTEXT_NET_NS
:
272 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_NET_NS
;
274 case LTTNG_EVENT_CONTEXT_PID_NS
:
275 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PID_NS
;
277 case LTTNG_EVENT_CONTEXT_TIME_NS
:
278 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_TIME_NS
;
280 case LTTNG_EVENT_CONTEXT_USER_NS
:
281 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_USER_NS
;
283 case LTTNG_EVENT_CONTEXT_UTS_NS
:
284 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_UTS_NS
;
286 case LTTNG_EVENT_CONTEXT_UID
:
287 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_UID
;
289 case LTTNG_EVENT_CONTEXT_EUID
:
290 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_EUID
;
292 case LTTNG_EVENT_CONTEXT_SUID
:
293 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_SUID
;
295 case LTTNG_EVENT_CONTEXT_GID
:
296 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_GID
;
298 case LTTNG_EVENT_CONTEXT_EGID
:
299 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_EGID
;
301 case LTTNG_EVENT_CONTEXT_SGID
:
302 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_SGID
;
304 case LTTNG_EVENT_CONTEXT_VUID
:
305 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VUID
;
307 case LTTNG_EVENT_CONTEXT_VEUID
:
308 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VEUID
;
310 case LTTNG_EVENT_CONTEXT_VSUID
:
311 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VSUID
;
313 case LTTNG_EVENT_CONTEXT_VGID
:
314 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VGID
;
316 case LTTNG_EVENT_CONTEXT_VEGID
:
317 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VEGID
;
319 case LTTNG_EVENT_CONTEXT_VSGID
:
320 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VSGID
;
323 ret
= LTTNG_ERR_KERN_CONTEXT_FAIL
;
327 kctx
->ctx
.u
.perf_counter
.type
= ctx
->u
.perf_counter
.type
;
328 kctx
->ctx
.u
.perf_counter
.config
= ctx
->u
.perf_counter
.config
;
329 strncpy(kctx
->ctx
.u
.perf_counter
.name
, ctx
->u
.perf_counter
.name
, LTTNG_SYMBOL_NAME_LEN
);
330 kctx
->ctx
.u
.perf_counter
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
332 if (*channel_name
== '\0') {
333 ret
= add_kctx_all_channels(ksession
, kctx
);
334 /* Ownership of kctx is transferred to the callee. */
336 if (ret
!= LTTNG_OK
) {
340 /* Get kernel channel */
341 kchan
= trace_kernel_get_channel_by_name(channel_name
, ksession
);
342 if (kchan
== nullptr) {
343 ret
= LTTNG_ERR_KERN_CHAN_NOT_FOUND
;
347 ret
= add_kctx_to_channel(kctx
, kchan
);
348 /* Ownership of kctx is transferred to the callee. */
350 if (ret
!= LTTNG_OK
) {
359 trace_kernel_destroy_context(kctx
);
365 * Add UST context to tracer.
367 int context_ust_add(struct ltt_ust_session
*usess
,
368 enum lttng_domain_type domain
,
369 const struct lttng_event_context
*ctx
,
370 const char *channel_name
)
373 struct lttng_ht
*chan_ht
;
374 ltt_ust_channel
*uchan
= nullptr;
378 LTTNG_ASSERT(channel_name
);
380 const lttng::urcu::read_lock_guard read_lock
;
382 chan_ht
= usess
->domain_global
.channels
;
384 /* Get UST channel if defined */
385 if (channel_name
[0] != '\0') {
386 uchan
= trace_ust_find_channel_by_name(chan_ht
, channel_name
);
387 if (uchan
== nullptr) {
388 ret
= LTTNG_ERR_UST_CHAN_NOT_FOUND
;
394 /* Add ctx to channel */
395 ret
= add_uctx_to_channel(usess
, domain
, uchan
, ctx
);
397 /* Add ctx all events, all channels */
398 for (auto *iterated_uchan
:
399 lttng::urcu::lfht_iteration_adapter
<ltt_ust_channel
,
400 decltype(ltt_ust_channel::node
),
401 <t_ust_channel::node
>(*chan_ht
->ht
)) {
402 ret
= add_uctx_to_channel(usess
, domain
, iterated_uchan
, ctx
);
404 ERR("Failed to add context to channel %s", iterated_uchan
->name
);
411 case LTTNG_ERR_UST_CONTEXT_EXIST
:
414 case -LTTNG_ERR_NOMEM
:
415 ret
= LTTNG_ERR_FATAL
;
418 ret
= LTTNG_ERR_UST_CONTEXT_INVAL
;
421 ret
= LTTNG_ERR_UNKNOWN_DOMAIN
;
424 if (ret
!= 0 && ret
!= LTTNG_OK
) {
425 ret
= ret
> 0 ? ret
: LTTNG_ERR_UNK
;