b3b549187ecd57fcf5f7d989de230bc00ae6abbf
[lttng-tools.git] / src / bin / lttng-sessiond / context.cpp
1 /*
2 * Copyright (C) 2011 EfficiOS Inc.
3 * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9 #define _LGPL_SOURCE
10 #include "agent.hpp"
11 #include "context.hpp"
12 #include "kernel.hpp"
13 #include "trace-ust.hpp"
14 #include "ust-app.hpp"
15
16 #include <common/error.hpp>
17 #include <common/sessiond-comm/sessiond-comm.hpp>
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <urcu/list.h>
22
23 /*
24 * Add kernel context to all channel.
25 *
26 * Assumes the ownership of kctx.
27 */
28 static int add_kctx_all_channels(struct ltt_kernel_session *ksession,
29 struct ltt_kernel_context *kctx)
30 {
31 int ret;
32 struct ltt_kernel_channel *kchan;
33
34 LTTNG_ASSERT(ksession);
35 LTTNG_ASSERT(kctx);
36
37 DBG("Adding kernel context to all channels");
38
39 /* Go over all channels */
40 cds_list_for_each_entry (kchan, &ksession->channel_list.head, list) {
41 struct ltt_kernel_context *kctx_copy;
42
43 kctx_copy = trace_kernel_copy_context(kctx);
44 if (!kctx_copy) {
45 PERROR("zmalloc ltt_kernel_context");
46 ret = -LTTNG_ERR_NOMEM;
47 goto error;
48 }
49
50 /* Ownership of kctx_copy is transferred to the callee. */
51 ret = kernel_add_channel_context(kchan, kctx_copy);
52 kctx_copy = nullptr;
53 if (ret != 0) {
54 goto error;
55 }
56 }
57
58 ret = LTTNG_OK;
59
60 error:
61 trace_kernel_destroy_context(kctx);
62 return ret;
63 }
64
65 /*
66 * Add kernel context to a specific channel.
67 *
68 * Assumes the ownership of kctx.
69 */
70 static int add_kctx_to_channel(struct ltt_kernel_context *kctx, struct ltt_kernel_channel *kchan)
71 {
72 int ret;
73
74 LTTNG_ASSERT(kchan);
75 LTTNG_ASSERT(kctx);
76
77 DBG("Add kernel context to channel '%s'", kchan->channel->name);
78
79 /* Ownership of kctx is transferred to the callee. */
80 ret = kernel_add_channel_context(kchan, kctx);
81 kctx = nullptr;
82 if (ret != 0) {
83 goto error;
84 }
85
86 ret = LTTNG_OK;
87
88 error:
89 return ret;
90 }
91
92 /*
93 * Add UST context to channel.
94 */
95 static int add_uctx_to_channel(struct ltt_ust_session *usess,
96 enum lttng_domain_type domain,
97 struct ltt_ust_channel *uchan,
98 const struct lttng_event_context *ctx)
99 {
100 int ret;
101 struct ltt_ust_context *uctx = nullptr;
102
103 LTTNG_ASSERT(usess);
104 LTTNG_ASSERT(uchan);
105 LTTNG_ASSERT(ctx);
106
107 /* Check if context is duplicate */
108 cds_list_for_each_entry (uctx, &uchan->ctx_list, list) {
109 if (trace_ust_match_context(uctx, ctx)) {
110 ret = LTTNG_ERR_UST_CONTEXT_EXIST;
111 goto duplicate;
112 }
113 }
114 uctx = nullptr;
115
116 switch (domain) {
117 case LTTNG_DOMAIN_JUL:
118 case LTTNG_DOMAIN_LOG4J:
119 {
120 struct agent *agt;
121
122 if (ctx->ctx != LTTNG_EVENT_CONTEXT_APP_CONTEXT) {
123 /* Other contexts are not needed by the agent. */
124 break;
125 }
126 agt = trace_ust_find_agent(usess, domain);
127
128 if (!agt) {
129 agt = agent_create(domain);
130 if (!agt) {
131 ret = -LTTNG_ERR_NOMEM;
132 goto error;
133 }
134 agent_add(agt, usess->agents);
135 }
136 ret = agent_add_context(ctx, agt);
137 if (ret != LTTNG_OK) {
138 goto error;
139 }
140
141 ret = agent_enable_context(ctx, domain);
142 if (ret != LTTNG_OK) {
143 goto error;
144 }
145 break;
146 }
147 case LTTNG_DOMAIN_UST:
148 break;
149 default:
150 abort();
151 }
152
153 /* Create ltt UST context */
154 uctx = trace_ust_create_context(ctx);
155 if (uctx == nullptr) {
156 ret = LTTNG_ERR_UST_CONTEXT_INVAL;
157 goto error;
158 }
159
160 /* Add ltt UST context node to ltt UST channel */
161 lttng_ht_add_ulong(uchan->ctx, &uctx->node);
162 cds_list_add_tail(&uctx->list, &uchan->ctx_list);
163
164 if (!usess->active) {
165 goto end;
166 }
167
168 ret = ust_app_add_ctx_channel_glb(usess, uchan, uctx);
169 if (ret < 0) {
170 goto error;
171 }
172 end:
173 DBG("Context UST %d added to channel %s", uctx->ctx.ctx, uchan->name);
174
175 return 0;
176
177 error:
178 free(uctx);
179 duplicate:
180 return ret;
181 }
182
183 /*
184 * Add kernel context to tracer.
185 */
186 int context_kernel_add(struct ltt_kernel_session *ksession,
187 const struct lttng_event_context *ctx,
188 const char *channel_name)
189 {
190 int ret;
191 struct ltt_kernel_channel *kchan;
192 struct ltt_kernel_context *kctx;
193
194 LTTNG_ASSERT(ksession);
195 LTTNG_ASSERT(ctx);
196 LTTNG_ASSERT(channel_name);
197
198 kctx = trace_kernel_create_context(nullptr);
199 if (!kctx) {
200 ret = -LTTNG_ERR_NOMEM;
201 goto error;
202 }
203
204 /* Setup kernel context structure */
205 switch (ctx->ctx) {
206 case LTTNG_EVENT_CONTEXT_PID:
207 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_PID;
208 break;
209 case LTTNG_EVENT_CONTEXT_PROCNAME:
210 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_PROCNAME;
211 break;
212 case LTTNG_EVENT_CONTEXT_PRIO:
213 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_PRIO;
214 break;
215 case LTTNG_EVENT_CONTEXT_NICE:
216 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_NICE;
217 break;
218 case LTTNG_EVENT_CONTEXT_VPID:
219 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_VPID;
220 break;
221 case LTTNG_EVENT_CONTEXT_TID:
222 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_TID;
223 break;
224 case LTTNG_EVENT_CONTEXT_VTID:
225 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_VTID;
226 break;
227 case LTTNG_EVENT_CONTEXT_PPID:
228 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_PPID;
229 break;
230 case LTTNG_EVENT_CONTEXT_VPPID:
231 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_VPPID;
232 break;
233 case LTTNG_EVENT_CONTEXT_HOSTNAME:
234 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_HOSTNAME;
235 break;
236 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER:
237 case LTTNG_EVENT_CONTEXT_PERF_COUNTER:
238 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_PERF_CPU_COUNTER;
239 break;
240 case LTTNG_EVENT_CONTEXT_INTERRUPTIBLE:
241 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_INTERRUPTIBLE;
242 break;
243 case LTTNG_EVENT_CONTEXT_PREEMPTIBLE:
244 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_PREEMPTIBLE;
245 break;
246 case LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE:
247 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_NEED_RESCHEDULE;
248 break;
249 case LTTNG_EVENT_CONTEXT_MIGRATABLE:
250 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_MIGRATABLE;
251 break;
252 case LTTNG_EVENT_CONTEXT_CALLSTACK_KERNEL:
253 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_KERNEL;
254 break;
255 case LTTNG_EVENT_CONTEXT_CALLSTACK_USER:
256 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_USER;
257 break;
258 case LTTNG_EVENT_CONTEXT_CGROUP_NS:
259 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_CGROUP_NS;
260 break;
261 case LTTNG_EVENT_CONTEXT_IPC_NS:
262 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_IPC_NS;
263 break;
264 case LTTNG_EVENT_CONTEXT_MNT_NS:
265 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_MNT_NS;
266 break;
267 case LTTNG_EVENT_CONTEXT_NET_NS:
268 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_NET_NS;
269 break;
270 case LTTNG_EVENT_CONTEXT_PID_NS:
271 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_PID_NS;
272 break;
273 case LTTNG_EVENT_CONTEXT_TIME_NS:
274 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_TIME_NS;
275 break;
276 case LTTNG_EVENT_CONTEXT_USER_NS:
277 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_USER_NS;
278 break;
279 case LTTNG_EVENT_CONTEXT_UTS_NS:
280 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_UTS_NS;
281 break;
282 case LTTNG_EVENT_CONTEXT_UID:
283 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_UID;
284 break;
285 case LTTNG_EVENT_CONTEXT_EUID:
286 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_EUID;
287 break;
288 case LTTNG_EVENT_CONTEXT_SUID:
289 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_SUID;
290 break;
291 case LTTNG_EVENT_CONTEXT_GID:
292 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_GID;
293 break;
294 case LTTNG_EVENT_CONTEXT_EGID:
295 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_EGID;
296 break;
297 case LTTNG_EVENT_CONTEXT_SGID:
298 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_SGID;
299 break;
300 case LTTNG_EVENT_CONTEXT_VUID:
301 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_VUID;
302 break;
303 case LTTNG_EVENT_CONTEXT_VEUID:
304 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_VEUID;
305 break;
306 case LTTNG_EVENT_CONTEXT_VSUID:
307 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_VSUID;
308 break;
309 case LTTNG_EVENT_CONTEXT_VGID:
310 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_VGID;
311 break;
312 case LTTNG_EVENT_CONTEXT_VEGID:
313 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_VEGID;
314 break;
315 case LTTNG_EVENT_CONTEXT_VSGID:
316 kctx->ctx.ctx = LTTNG_KERNEL_ABI_CONTEXT_VSGID;
317 break;
318 default:
319 ret = LTTNG_ERR_KERN_CONTEXT_FAIL;
320 goto error;
321 }
322
323 kctx->ctx.u.perf_counter.type = ctx->u.perf_counter.type;
324 kctx->ctx.u.perf_counter.config = ctx->u.perf_counter.config;
325 strncpy(kctx->ctx.u.perf_counter.name, ctx->u.perf_counter.name, LTTNG_SYMBOL_NAME_LEN);
326 kctx->ctx.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
327
328 if (*channel_name == '\0') {
329 ret = add_kctx_all_channels(ksession, kctx);
330 /* Ownership of kctx is transferred to the callee. */
331 kctx = nullptr;
332 if (ret != LTTNG_OK) {
333 goto error;
334 }
335 } else {
336 /* Get kernel channel */
337 kchan = trace_kernel_get_channel_by_name(channel_name, ksession);
338 if (kchan == nullptr) {
339 ret = LTTNG_ERR_KERN_CHAN_NOT_FOUND;
340 goto error;
341 }
342
343 ret = add_kctx_to_channel(kctx, kchan);
344 /* Ownership of kctx is transferred to the callee. */
345 kctx = nullptr;
346 if (ret != LTTNG_OK) {
347 goto error;
348 }
349 }
350
351 ret = LTTNG_OK;
352
353 error:
354 if (kctx) {
355 trace_kernel_destroy_context(kctx);
356 }
357 return ret;
358 }
359
360 /*
361 * Add UST context to tracer.
362 */
363 int context_ust_add(struct ltt_ust_session *usess,
364 enum lttng_domain_type domain,
365 const struct lttng_event_context *ctx,
366 const char *channel_name)
367 {
368 int ret = LTTNG_OK;
369 struct lttng_ht_iter iter;
370 struct lttng_ht *chan_ht;
371 struct ltt_ust_channel *uchan = nullptr;
372
373 LTTNG_ASSERT(usess);
374 LTTNG_ASSERT(ctx);
375 LTTNG_ASSERT(channel_name);
376
377 rcu_read_lock();
378
379 chan_ht = usess->domain_global.channels;
380
381 /* Get UST channel if defined */
382 if (channel_name[0] != '\0') {
383 uchan = trace_ust_find_channel_by_name(chan_ht, channel_name);
384 if (uchan == nullptr) {
385 ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
386 goto error;
387 }
388 }
389
390 if (uchan) {
391 /* Add ctx to channel */
392 ret = add_uctx_to_channel(usess, domain, uchan, ctx);
393 } else {
394 rcu_read_lock();
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);
398 if (ret) {
399 ERR("Failed to add context to channel %s", uchan->name);
400 continue;
401 }
402 }
403 rcu_read_unlock();
404 }
405
406 switch (ret) {
407 case LTTNG_ERR_UST_CONTEXT_EXIST:
408 break;
409 case -ENOMEM:
410 case -LTTNG_ERR_NOMEM:
411 ret = LTTNG_ERR_FATAL;
412 break;
413 case -EINVAL:
414 ret = LTTNG_ERR_UST_CONTEXT_INVAL;
415 break;
416 case -ENOSYS:
417 ret = LTTNG_ERR_UNKNOWN_DOMAIN;
418 break;
419 default:
420 if (ret != 0 && ret != LTTNG_OK) {
421 ret = ret > 0 ? ret : LTTNG_ERR_UNK;
422 } else {
423 ret = LTTNG_OK;
424 }
425 break;
426 }
427
428 error:
429 rcu_read_unlock();
430 return ret;
431 }
This page took 0.037209 seconds and 4 git commands to generate.