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
)
33 struct ltt_kernel_channel
*kchan
;
35 LTTNG_ASSERT(ksession
);
38 DBG("Adding kernel context to all channels");
40 /* Go over all channels */
41 cds_list_for_each_entry (kchan
, &ksession
->channel_list
.head
, list
) {
42 struct ltt_kernel_context
*kctx_copy
;
44 kctx_copy
= trace_kernel_copy_context(kctx
);
46 PERROR("zmalloc ltt_kernel_context");
47 ret
= -LTTNG_ERR_NOMEM
;
51 /* Ownership of kctx_copy is transferred to the callee. */
52 ret
= kernel_add_channel_context(kchan
, kctx_copy
);
62 trace_kernel_destroy_context(kctx
);
67 * Add kernel context to a specific channel.
69 * Assumes the ownership of kctx.
71 static int add_kctx_to_channel(struct ltt_kernel_context
*kctx
, struct ltt_kernel_channel
*kchan
)
78 DBG("Add kernel context to channel '%s'", kchan
->channel
->name
);
80 /* Ownership of kctx is transferred to the callee. */
81 ret
= kernel_add_channel_context(kchan
, kctx
);
94 * Add UST context to channel.
96 static int add_uctx_to_channel(struct ltt_ust_session
*usess
,
97 enum lttng_domain_type domain
,
98 struct ltt_ust_channel
*uchan
,
99 const struct lttng_event_context
*ctx
)
102 struct ltt_ust_context
*uctx
= nullptr;
108 /* Check if context is duplicate */
109 cds_list_for_each_entry (uctx
, &uchan
->ctx_list
, list
) {
110 if (trace_ust_match_context(uctx
, ctx
)) {
111 ret
= LTTNG_ERR_UST_CONTEXT_EXIST
;
118 case LTTNG_DOMAIN_JUL
:
119 case LTTNG_DOMAIN_LOG4J
:
123 if (ctx
->ctx
!= LTTNG_EVENT_CONTEXT_APP_CONTEXT
) {
124 /* Other contexts are not needed by the agent. */
127 agt
= trace_ust_find_agent(usess
, domain
);
130 agt
= agent_create(domain
);
132 ret
= -LTTNG_ERR_NOMEM
;
135 agent_add(agt
, usess
->agents
);
137 ret
= agent_add_context(ctx
, agt
);
138 if (ret
!= LTTNG_OK
) {
142 ret
= agent_enable_context(ctx
, domain
);
143 if (ret
!= LTTNG_OK
) {
148 case LTTNG_DOMAIN_UST
:
154 /* Create ltt UST context */
155 uctx
= trace_ust_create_context(ctx
);
156 if (uctx
== nullptr) {
157 ret
= LTTNG_ERR_UST_CONTEXT_INVAL
;
161 /* Add ltt UST context node to ltt UST channel */
162 lttng_ht_add_ulong(uchan
->ctx
, &uctx
->node
);
163 cds_list_add_tail(&uctx
->list
, &uchan
->ctx_list
);
165 if (!usess
->active
) {
169 ret
= ust_app_add_ctx_channel_glb(usess
, uchan
, uctx
);
174 DBG("Context UST %d added to channel %s", uctx
->ctx
.ctx
, uchan
->name
);
185 * Add kernel context to tracer.
187 int context_kernel_add(struct ltt_kernel_session
*ksession
,
188 const struct lttng_event_context
*ctx
,
189 const char *channel_name
)
192 struct ltt_kernel_channel
*kchan
;
193 struct ltt_kernel_context
*kctx
;
195 LTTNG_ASSERT(ksession
);
197 LTTNG_ASSERT(channel_name
);
199 kctx
= trace_kernel_create_context(nullptr);
201 ret
= -LTTNG_ERR_NOMEM
;
205 /* Setup kernel context structure */
207 case LTTNG_EVENT_CONTEXT_PID
:
208 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PID
;
210 case LTTNG_EVENT_CONTEXT_PROCNAME
:
211 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PROCNAME
;
213 case LTTNG_EVENT_CONTEXT_PRIO
:
214 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PRIO
;
216 case LTTNG_EVENT_CONTEXT_NICE
:
217 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_NICE
;
219 case LTTNG_EVENT_CONTEXT_VPID
:
220 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VPID
;
222 case LTTNG_EVENT_CONTEXT_TID
:
223 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_TID
;
225 case LTTNG_EVENT_CONTEXT_VTID
:
226 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VTID
;
228 case LTTNG_EVENT_CONTEXT_PPID
:
229 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PPID
;
231 case LTTNG_EVENT_CONTEXT_VPPID
:
232 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VPPID
;
234 case LTTNG_EVENT_CONTEXT_HOSTNAME
:
235 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_HOSTNAME
;
237 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER
:
238 case LTTNG_EVENT_CONTEXT_PERF_COUNTER
:
239 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PERF_CPU_COUNTER
;
241 case LTTNG_EVENT_CONTEXT_INTERRUPTIBLE
:
242 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_INTERRUPTIBLE
;
244 case LTTNG_EVENT_CONTEXT_PREEMPTIBLE
:
245 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PREEMPTIBLE
;
247 case LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE
:
248 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_NEED_RESCHEDULE
;
250 case LTTNG_EVENT_CONTEXT_MIGRATABLE
:
251 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_MIGRATABLE
;
253 case LTTNG_EVENT_CONTEXT_CALLSTACK_KERNEL
:
254 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_KERNEL
;
256 case LTTNG_EVENT_CONTEXT_CALLSTACK_USER
:
257 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_USER
;
259 case LTTNG_EVENT_CONTEXT_CGROUP_NS
:
260 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_CGROUP_NS
;
262 case LTTNG_EVENT_CONTEXT_IPC_NS
:
263 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_IPC_NS
;
265 case LTTNG_EVENT_CONTEXT_MNT_NS
:
266 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_MNT_NS
;
268 case LTTNG_EVENT_CONTEXT_NET_NS
:
269 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_NET_NS
;
271 case LTTNG_EVENT_CONTEXT_PID_NS
:
272 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_PID_NS
;
274 case LTTNG_EVENT_CONTEXT_TIME_NS
:
275 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_TIME_NS
;
277 case LTTNG_EVENT_CONTEXT_USER_NS
:
278 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_USER_NS
;
280 case LTTNG_EVENT_CONTEXT_UTS_NS
:
281 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_UTS_NS
;
283 case LTTNG_EVENT_CONTEXT_UID
:
284 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_UID
;
286 case LTTNG_EVENT_CONTEXT_EUID
:
287 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_EUID
;
289 case LTTNG_EVENT_CONTEXT_SUID
:
290 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_SUID
;
292 case LTTNG_EVENT_CONTEXT_GID
:
293 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_GID
;
295 case LTTNG_EVENT_CONTEXT_EGID
:
296 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_EGID
;
298 case LTTNG_EVENT_CONTEXT_SGID
:
299 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_SGID
;
301 case LTTNG_EVENT_CONTEXT_VUID
:
302 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VUID
;
304 case LTTNG_EVENT_CONTEXT_VEUID
:
305 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VEUID
;
307 case LTTNG_EVENT_CONTEXT_VSUID
:
308 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VSUID
;
310 case LTTNG_EVENT_CONTEXT_VGID
:
311 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VGID
;
313 case LTTNG_EVENT_CONTEXT_VEGID
:
314 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VEGID
;
316 case LTTNG_EVENT_CONTEXT_VSGID
:
317 kctx
->ctx
.ctx
= LTTNG_KERNEL_ABI_CONTEXT_VSGID
;
320 ret
= LTTNG_ERR_KERN_CONTEXT_FAIL
;
324 kctx
->ctx
.u
.perf_counter
.type
= ctx
->u
.perf_counter
.type
;
325 kctx
->ctx
.u
.perf_counter
.config
= ctx
->u
.perf_counter
.config
;
326 strncpy(kctx
->ctx
.u
.perf_counter
.name
, ctx
->u
.perf_counter
.name
, LTTNG_SYMBOL_NAME_LEN
);
327 kctx
->ctx
.u
.perf_counter
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
329 if (*channel_name
== '\0') {
330 ret
= add_kctx_all_channels(ksession
, kctx
);
331 /* Ownership of kctx is transferred to the callee. */
333 if (ret
!= LTTNG_OK
) {
337 /* Get kernel channel */
338 kchan
= trace_kernel_get_channel_by_name(channel_name
, ksession
);
339 if (kchan
== nullptr) {
340 ret
= LTTNG_ERR_KERN_CHAN_NOT_FOUND
;
344 ret
= add_kctx_to_channel(kctx
, kchan
);
345 /* Ownership of kctx is transferred to the callee. */
347 if (ret
!= LTTNG_OK
) {
356 trace_kernel_destroy_context(kctx
);
362 * Add UST context to tracer.
364 int context_ust_add(struct ltt_ust_session
*usess
,
365 enum lttng_domain_type domain
,
366 const struct lttng_event_context
*ctx
,
367 const char *channel_name
)
370 struct lttng_ht_iter iter
;
371 struct lttng_ht
*chan_ht
;
372 struct ltt_ust_channel
*uchan
= nullptr;
376 LTTNG_ASSERT(channel_name
);
378 lttng::urcu::read_lock_guard read_lock
;
380 chan_ht
= usess
->domain_global
.channels
;
382 /* Get UST channel if defined */
383 if (channel_name
[0] != '\0') {
384 uchan
= trace_ust_find_channel_by_name(chan_ht
, channel_name
);
385 if (uchan
== nullptr) {
386 ret
= LTTNG_ERR_UST_CHAN_NOT_FOUND
;
392 /* Add ctx to channel */
393 ret
= add_uctx_to_channel(usess
, domain
, uchan
, ctx
);
395 /* Add ctx all events, all channels */
396 cds_lfht_for_each_entry (chan_ht
->ht
, &iter
.iter
, uchan
, node
.node
) {
397 ret
= add_uctx_to_channel(usess
, domain
, uchan
, ctx
);
399 ERR("Failed to add context to channel %s", uchan
->name
);
406 case LTTNG_ERR_UST_CONTEXT_EXIST
:
409 case -LTTNG_ERR_NOMEM
:
410 ret
= LTTNG_ERR_FATAL
;
413 ret
= LTTNG_ERR_UST_CONTEXT_INVAL
;
416 ret
= LTTNG_ERR_UNKNOWN_DOMAIN
;
419 if (ret
!= 0 && ret
!= LTTNG_OK
) {
420 ret
= ret
> 0 ? ret
: LTTNG_ERR_UNK
;