Commit | Line | Data |
---|---|---|
54d01ffb | 1 | /* |
21cf9b6b | 2 | * Copyright (C) 2011 EfficiOS Inc. |
ab5be9fa | 3 | * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com> |
54d01ffb | 4 | * |
ab5be9fa | 5 | * SPDX-License-Identifier: GPL-2.0-only |
54d01ffb | 6 | * |
54d01ffb DG |
7 | */ |
8 | ||
6c1c0768 | 9 | #define _LGPL_SOURCE |
7972aab2 | 10 | #include <inttypes.h> |
56fff090 | 11 | #include <string.h> |
54d01ffb DG |
12 | #include <unistd.h> |
13 | ||
c9e313bc SM |
14 | #include <common/common.hpp> |
15 | #include <common/defaults.hpp> | |
16 | #include <common/sessiond-comm/sessiond-comm.hpp> | |
17 | ||
18 | #include "channel.hpp" | |
19 | #include "lttng-sessiond.hpp" | |
20 | #include "kernel.hpp" | |
21 | #include "lttng-ust-ctl.hpp" | |
22 | #include "lttng-ust-error.hpp" | |
23 | #include "utils.hpp" | |
24 | #include "ust-app.hpp" | |
25 | #include "agent.hpp" | |
54d01ffb DG |
26 | |
27 | /* | |
28 | * Return allocated channel attributes. | |
29 | */ | |
0a9c6494 DG |
30 | struct lttng_channel *channel_new_default_attr(int dom, |
31 | enum lttng_buffer_type type) | |
54d01ffb DG |
32 | { |
33 | struct lttng_channel *chan; | |
bdf64013 | 34 | const char *channel_name = DEFAULT_CHANNEL_NAME; |
e9404c27 | 35 | struct lttng_channel_extended *extended_attr = NULL; |
54d01ffb | 36 | |
64803277 | 37 | chan = zmalloc<lttng_channel>(); |
54d01ffb | 38 | if (chan == NULL) { |
7885e399 | 39 | PERROR("zmalloc channel init"); |
54d01ffb DG |
40 | goto error_alloc; |
41 | } | |
42 | ||
64803277 | 43 | extended_attr = zmalloc<lttng_channel_extended>(); |
e9404c27 JG |
44 | if (!extended_attr) { |
45 | PERROR("zmalloc channel extended init"); | |
46 | goto error; | |
47 | } | |
48 | ||
49 | chan->attr.extended.ptr = extended_attr; | |
50 | ||
0a9c6494 | 51 | /* Same for all domains. */ |
54d01ffb | 52 | chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; |
0a9c6494 DG |
53 | chan->attr.tracefile_size = DEFAULT_CHANNEL_TRACEFILE_SIZE; |
54 | chan->attr.tracefile_count = DEFAULT_CHANNEL_TRACEFILE_COUNT; | |
54d01ffb DG |
55 | |
56 | switch (dom) { | |
1b1c65fa | 57 | case LTTNG_DOMAIN_KERNEL: |
a0377dfe | 58 | LTTNG_ASSERT(type == LTTNG_BUFFER_GLOBAL); |
3e230f92 SM |
59 | chan->attr.subbuf_size = |
60 | default_get_kernel_channel_subbuf_size(); | |
1b1c65fa MD |
61 | chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; |
62 | chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; | |
6bb9e85f MD |
63 | chan->attr.switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER; |
64 | chan->attr.read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER; | |
ecc48a90 | 65 | chan->attr.live_timer_interval = DEFAULT_KERNEL_CHANNEL_LIVE_TIMER; |
491d1539 | 66 | extended_attr->blocking_timeout = DEFAULT_KERNEL_CHANNEL_BLOCKING_TIMEOUT; |
e9404c27 JG |
67 | extended_attr->monitor_timer_interval = |
68 | DEFAULT_KERNEL_CHANNEL_MONITOR_TIMER; | |
1b1c65fa | 69 | break; |
bdf64013 JG |
70 | case LTTNG_DOMAIN_JUL: |
71 | channel_name = DEFAULT_JUL_CHANNEL_NAME; | |
72 | goto common_ust; | |
73 | case LTTNG_DOMAIN_LOG4J: | |
74 | channel_name = DEFAULT_LOG4J_CHANNEL_NAME; | |
75 | goto common_ust; | |
76 | case LTTNG_DOMAIN_PYTHON: | |
77 | channel_name = DEFAULT_PYTHON_CHANNEL_NAME; | |
78 | goto common_ust; | |
1b1c65fa | 79 | case LTTNG_DOMAIN_UST: |
bdf64013 | 80 | common_ust: |
0a9c6494 DG |
81 | switch (type) { |
82 | case LTTNG_BUFFER_PER_UID: | |
83 | chan->attr.subbuf_size = default_get_ust_uid_channel_subbuf_size(); | |
84 | chan->attr.num_subbuf = DEFAULT_UST_UID_CHANNEL_SUBBUF_NUM; | |
85 | chan->attr.output = DEFAULT_UST_UID_CHANNEL_OUTPUT; | |
86 | chan->attr.switch_timer_interval = | |
87 | DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER; | |
88 | chan->attr.read_timer_interval = | |
89 | DEFAULT_UST_UID_CHANNEL_READ_TIMER; | |
ecc48a90 JD |
90 | chan->attr.live_timer_interval = |
91 | DEFAULT_UST_UID_CHANNEL_LIVE_TIMER; | |
491d1539 | 92 | extended_attr->blocking_timeout = DEFAULT_UST_UID_CHANNEL_BLOCKING_TIMEOUT; |
e9404c27 JG |
93 | extended_attr->monitor_timer_interval = |
94 | DEFAULT_UST_UID_CHANNEL_MONITOR_TIMER; | |
0a9c6494 DG |
95 | break; |
96 | case LTTNG_BUFFER_PER_PID: | |
97 | default: | |
98 | chan->attr.subbuf_size = default_get_ust_pid_channel_subbuf_size(); | |
99 | chan->attr.num_subbuf = DEFAULT_UST_PID_CHANNEL_SUBBUF_NUM; | |
100 | chan->attr.output = DEFAULT_UST_PID_CHANNEL_OUTPUT; | |
101 | chan->attr.switch_timer_interval = | |
102 | DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER; | |
103 | chan->attr.read_timer_interval = | |
104 | DEFAULT_UST_PID_CHANNEL_READ_TIMER; | |
ecc48a90 | 105 | chan->attr.live_timer_interval = |
e9404c27 | 106 | DEFAULT_UST_PID_CHANNEL_LIVE_TIMER; |
491d1539 | 107 | extended_attr->blocking_timeout = DEFAULT_UST_PID_CHANNEL_BLOCKING_TIMEOUT; |
e9404c27 JG |
108 | extended_attr->monitor_timer_interval = |
109 | DEFAULT_UST_PID_CHANNEL_MONITOR_TIMER; | |
0a9c6494 DG |
110 | break; |
111 | } | |
1b1c65fa MD |
112 | break; |
113 | default: | |
114 | goto error; /* Not implemented */ | |
54d01ffb DG |
115 | } |
116 | ||
bdf64013 JG |
117 | if (snprintf(chan->name, sizeof(chan->name), "%s", |
118 | channel_name) < 0) { | |
119 | PERROR("snprintf default channel name"); | |
120 | goto error; | |
121 | } | |
54d01ffb DG |
122 | return chan; |
123 | ||
124 | error: | |
e9404c27 | 125 | free(extended_attr); |
54d01ffb DG |
126 | free(chan); |
127 | error_alloc: | |
128 | return NULL; | |
129 | } | |
130 | ||
e9404c27 JG |
131 | void channel_attr_destroy(struct lttng_channel *channel) |
132 | { | |
133 | if (!channel) { | |
134 | return; | |
135 | } | |
136 | free(channel->attr.extended.ptr); | |
137 | free(channel); | |
138 | } | |
139 | ||
54d01ffb DG |
140 | /* |
141 | * Disable kernel channel of the kernel session. | |
142 | */ | |
143 | int channel_kernel_disable(struct ltt_kernel_session *ksession, | |
144 | char *channel_name) | |
145 | { | |
146 | int ret; | |
147 | struct ltt_kernel_channel *kchan; | |
148 | ||
a0377dfe FD |
149 | LTTNG_ASSERT(ksession); |
150 | LTTNG_ASSERT(channel_name); | |
0525e9ae | 151 | |
54d01ffb DG |
152 | kchan = trace_kernel_get_channel_by_name(channel_name, ksession); |
153 | if (kchan == NULL) { | |
f73fabfd | 154 | ret = LTTNG_ERR_KERN_CHAN_NOT_FOUND; |
54d01ffb | 155 | goto error; |
0525e9ae DG |
156 | } |
157 | ||
158 | /* Only if channel is enabled disable it. */ | |
159 | if (kchan->enabled == 1) { | |
54d01ffb | 160 | ret = kernel_disable_channel(kchan); |
7885e399 | 161 | if (ret < 0 && ret != -EEXIST) { |
f73fabfd | 162 | ret = LTTNG_ERR_KERN_CHAN_DISABLE_FAIL; |
54d01ffb DG |
163 | goto error; |
164 | } | |
165 | } | |
166 | ||
f73fabfd | 167 | ret = LTTNG_OK; |
54d01ffb DG |
168 | |
169 | error: | |
170 | return ret; | |
171 | } | |
172 | ||
173 | /* | |
174 | * Enable kernel channel of the kernel session. | |
175 | */ | |
4878de5c | 176 | enum lttng_error_code channel_kernel_enable(struct ltt_kernel_session *ksession, |
54d01ffb DG |
177 | struct ltt_kernel_channel *kchan) |
178 | { | |
4878de5c | 179 | enum lttng_error_code ret_code; |
54d01ffb | 180 | |
a0377dfe FD |
181 | LTTNG_ASSERT(ksession); |
182 | LTTNG_ASSERT(kchan); | |
0525e9ae | 183 | |
54d01ffb | 184 | if (kchan->enabled == 0) { |
4878de5c JG |
185 | if (kernel_enable_channel(kchan) < 0) { |
186 | ret_code = LTTNG_ERR_KERN_CHAN_ENABLE_FAIL; | |
54d01ffb DG |
187 | goto error; |
188 | } | |
42224349 | 189 | } else { |
4878de5c | 190 | ret_code = LTTNG_ERR_KERN_CHAN_EXIST; |
42224349 | 191 | goto error; |
54d01ffb DG |
192 | } |
193 | ||
4878de5c | 194 | ret_code = LTTNG_OK; |
54d01ffb DG |
195 | |
196 | error: | |
4878de5c | 197 | return ret_code; |
54d01ffb DG |
198 | } |
199 | ||
da9d9d9c MD |
200 | static int channel_validate(struct lttng_channel *attr) |
201 | { | |
202 | /* | |
203 | * The ringbuffer (both in user space and kernel) behaves badly | |
204 | * in overwrite mode and with less than 2 subbuffers so block it | |
205 | * right away and send back an invalid attribute error. | |
206 | */ | |
207 | if (attr->attr.overwrite && attr->attr.num_subbuf < 2) { | |
208 | return -1; | |
209 | } | |
210 | return 0; | |
211 | } | |
212 | ||
491d1539 MD |
213 | static int channel_validate_kernel(struct lttng_channel *attr) |
214 | { | |
215 | /* Kernel channels do not support blocking timeout. */ | |
216 | if (((struct lttng_channel_extended *)attr->attr.extended.ptr)->blocking_timeout) { | |
217 | return -1; | |
218 | } | |
219 | return 0; | |
220 | } | |
221 | ||
54d01ffb DG |
222 | /* |
223 | * Create kernel channel of the kernel session and notify kernel thread. | |
224 | */ | |
4878de5c | 225 | enum lttng_error_code channel_kernel_create(struct ltt_kernel_session *ksession, |
ff4d74e6 | 226 | struct lttng_channel *attr, int kernel_pipe) |
54d01ffb | 227 | { |
4878de5c | 228 | enum lttng_error_code ret_code; |
ff4d74e6 | 229 | struct lttng_channel *defattr = NULL; |
54d01ffb | 230 | |
a0377dfe | 231 | LTTNG_ASSERT(ksession); |
0525e9ae | 232 | |
54d01ffb DG |
233 | /* Creating channel attributes if needed */ |
234 | if (attr == NULL) { | |
0a9c6494 DG |
235 | defattr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL, |
236 | LTTNG_BUFFER_GLOBAL); | |
ff4d74e6 | 237 | if (defattr == NULL) { |
4878de5c | 238 | ret_code = LTTNG_ERR_FATAL; |
54d01ffb DG |
239 | goto error; |
240 | } | |
ff4d74e6 | 241 | attr = defattr; |
54d01ffb DG |
242 | } |
243 | ||
8d5841ea MD |
244 | /* |
245 | * Set the overwrite mode for this channel based on the session | |
246 | * type unless the client explicitly overrides the channel mode. | |
247 | */ | |
248 | if (attr->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE) { | |
249 | attr->attr.overwrite = !!ksession->snapshot_mode; | |
250 | } | |
251 | ||
da9d9d9c MD |
252 | /* Validate common channel properties. */ |
253 | if (channel_validate(attr) < 0) { | |
4878de5c | 254 | ret_code = LTTNG_ERR_INVALID; |
da9d9d9c MD |
255 | goto error; |
256 | } | |
257 | ||
491d1539 | 258 | if (channel_validate_kernel(attr) < 0) { |
4878de5c | 259 | ret_code = LTTNG_ERR_INVALID; |
491d1539 MD |
260 | goto error; |
261 | } | |
262 | ||
4878de5c JG |
263 | /* Channel not found, creating it. */ |
264 | if (kernel_create_channel(ksession, attr) < 0) { | |
265 | ret_code = LTTNG_ERR_KERN_CHAN_FAIL; | |
54d01ffb DG |
266 | goto error; |
267 | } | |
268 | ||
269 | /* Notify kernel thread that there is a new channel */ | |
4878de5c JG |
270 | if (notify_thread_pipe(kernel_pipe) < 0) { |
271 | ret_code = LTTNG_ERR_FATAL; | |
54d01ffb DG |
272 | goto error; |
273 | } | |
274 | ||
4878de5c | 275 | ret_code = LTTNG_OK; |
54d01ffb | 276 | error: |
e9404c27 | 277 | channel_attr_destroy(defattr); |
4878de5c | 278 | return ret_code; |
54d01ffb | 279 | } |
7885e399 DG |
280 | |
281 | /* | |
282 | * Enable UST channel for session and domain. | |
283 | */ | |
4878de5c | 284 | enum lttng_error_code channel_ust_enable(struct ltt_ust_session *usess, |
7885e399 DG |
285 | struct ltt_ust_channel *uchan) |
286 | { | |
4878de5c | 287 | enum lttng_error_code ret_code = LTTNG_OK; |
7885e399 | 288 | |
a0377dfe FD |
289 | LTTNG_ASSERT(usess); |
290 | LTTNG_ASSERT(uchan); | |
0525e9ae | 291 | |
7885e399 DG |
292 | /* If already enabled, everything is OK */ |
293 | if (uchan->enabled) { | |
294 | DBG3("Channel %s already enabled. Skipping", uchan->name); | |
4878de5c | 295 | ret_code = LTTNG_ERR_UST_CHAN_EXIST; |
7885e399 | 296 | goto end; |
88e3c2f5 JG |
297 | } else { |
298 | uchan->enabled = 1; | |
299 | DBG2("Channel %s enabled successfully", uchan->name); | |
300 | } | |
301 | ||
302 | if (!usess->active) { | |
303 | /* | |
304 | * The channel will be activated against the apps | |
305 | * when the session is started as part of the | |
306 | * application channel "synchronize" operation. | |
307 | */ | |
308 | goto end; | |
7885e399 DG |
309 | } |
310 | ||
7972aab2 DG |
311 | DBG2("Channel %s being enabled in UST domain", uchan->name); |
312 | ||
313 | /* | |
314 | * Enable channel for UST global domain on all applications. Ignore return | |
315 | * value here since whatever error we got, it means that the channel was | |
316 | * not created on one or many registered applications and we can not report | |
317 | * this to the user yet. However, at this stage, the channel was | |
318 | * successfully created on the session daemon side so the enable-channel | |
319 | * command is a success. | |
320 | */ | |
d54b4440 | 321 | (void) ust_app_enable_channel_glb(usess, uchan); |
7885e399 | 322 | |
7885e399 DG |
323 | |
324 | end: | |
4878de5c | 325 | return ret_code; |
7885e399 DG |
326 | } |
327 | ||
328 | /* | |
329 | * Create UST channel for session and domain. | |
330 | */ | |
4878de5c | 331 | enum lttng_error_code channel_ust_create(struct ltt_ust_session *usess, |
7972aab2 | 332 | struct lttng_channel *attr, enum lttng_buffer_type type) |
7885e399 | 333 | { |
4878de5c | 334 | enum lttng_error_code ret_code = LTTNG_OK; |
7885e399 DG |
335 | struct ltt_ust_channel *uchan = NULL; |
336 | struct lttng_channel *defattr = NULL; | |
b63d638b | 337 | enum lttng_domain_type domain = LTTNG_DOMAIN_UST; |
f86e086c | 338 | bool chan_published = false; |
7885e399 | 339 | |
a0377dfe | 340 | LTTNG_ASSERT(usess); |
0525e9ae | 341 | |
7885e399 DG |
342 | /* Creating channel attributes if needed */ |
343 | if (attr == NULL) { | |
0a9c6494 | 344 | defattr = channel_new_default_attr(LTTNG_DOMAIN_UST, type); |
7885e399 | 345 | if (defattr == NULL) { |
4878de5c | 346 | ret_code = LTTNG_ERR_FATAL; |
7885e399 DG |
347 | goto error; |
348 | } | |
349 | attr = defattr; | |
b63d638b JG |
350 | } else { |
351 | /* | |
352 | * HACK: Set the channel's subdomain (JUL, Log4j, Python, etc.) | |
353 | * based on the default name. | |
354 | */ | |
355 | if (!strcmp(attr->name, DEFAULT_JUL_CHANNEL_NAME)) { | |
356 | domain = LTTNG_DOMAIN_JUL; | |
357 | } else if (!strcmp(attr->name, DEFAULT_LOG4J_CHANNEL_NAME)) { | |
358 | domain = LTTNG_DOMAIN_LOG4J; | |
359 | } else if (!strcmp(attr->name, DEFAULT_PYTHON_CHANNEL_NAME)) { | |
360 | domain = LTTNG_DOMAIN_PYTHON; | |
361 | } | |
7885e399 DG |
362 | } |
363 | ||
8d5841ea MD |
364 | /* |
365 | * Set the overwrite mode for this channel based on the session | |
366 | * type unless the client explicitly overrides the channel mode. | |
367 | */ | |
368 | if (attr->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE) { | |
369 | attr->attr.overwrite = !!usess->snapshot_mode; | |
370 | } | |
371 | ||
372 | /* Enforce mmap output for snapshot sessions. */ | |
27babd3a | 373 | if (usess->snapshot_mode) { |
27babd3a DG |
374 | attr->attr.output = LTTNG_EVENT_MMAP; |
375 | } | |
376 | ||
da9d9d9c MD |
377 | /* Validate common channel properties. */ |
378 | if (channel_validate(attr) < 0) { | |
4878de5c | 379 | ret_code = LTTNG_ERR_INVALID; |
da9d9d9c MD |
380 | goto error; |
381 | } | |
382 | ||
b024d072 | 383 | /* |
0525e9ae DG |
384 | * Validate UST buffer size and number of buffers: must both be power of 2 |
385 | * and nonzero. We validate right here for UST, because applications will | |
386 | * not report the error to the user (unlike kernel tracing). | |
b024d072 | 387 | */ |
0525e9ae DG |
388 | if (!attr->attr.subbuf_size || |
389 | (attr->attr.subbuf_size & (attr->attr.subbuf_size - 1))) { | |
4878de5c | 390 | ret_code = LTTNG_ERR_INVALID; |
b024d072 MD |
391 | goto error; |
392 | } | |
0525e9ae | 393 | |
12744796 DG |
394 | /* |
395 | * Invalid subbuffer size if it's lower then the page size. | |
396 | */ | |
412d7227 | 397 | if (attr->attr.subbuf_size < the_page_size) { |
4878de5c | 398 | ret_code = LTTNG_ERR_INVALID; |
12744796 DG |
399 | goto error; |
400 | } | |
401 | ||
0525e9ae DG |
402 | if (!attr->attr.num_subbuf || |
403 | (attr->attr.num_subbuf & (attr->attr.num_subbuf - 1))) { | |
4878de5c | 404 | ret_code = LTTNG_ERR_INVALID; |
b024d072 MD |
405 | goto error; |
406 | } | |
407 | ||
a79d84dd | 408 | if (attr->attr.output != LTTNG_EVENT_MMAP) { |
4878de5c | 409 | ret_code = LTTNG_ERR_NOT_SUPPORTED; |
a79d84dd DG |
410 | goto error; |
411 | } | |
412 | ||
1624d5b7 JD |
413 | /* |
414 | * The tracefile_size should not be < to the subbuf_size, otherwise | |
415 | * we won't be able to write the packets on disk | |
416 | */ | |
417 | if ((attr->attr.tracefile_size > 0) && | |
418 | (attr->attr.tracefile_size < attr->attr.subbuf_size)) { | |
4878de5c | 419 | ret_code = LTTNG_ERR_INVALID; |
1624d5b7 JD |
420 | goto error; |
421 | } | |
422 | ||
2e8269f7 DG |
423 | /* Validate buffer type. */ |
424 | switch (type) { | |
425 | case LTTNG_BUFFER_PER_PID: | |
0a9c6494 | 426 | break; |
2e8269f7 DG |
427 | case LTTNG_BUFFER_PER_UID: |
428 | break; | |
429 | default: | |
4878de5c | 430 | ret_code = LTTNG_ERR_BUFFER_NOT_SUPPORTED; |
2e8269f7 DG |
431 | goto error; |
432 | } | |
433 | ||
7885e399 | 434 | /* Create UST channel */ |
b63d638b | 435 | uchan = trace_ust_create_channel(attr, domain); |
7885e399 | 436 | if (uchan == NULL) { |
4878de5c | 437 | ret_code = LTTNG_ERR_FATAL; |
7885e399 DG |
438 | goto error; |
439 | } | |
51755dc8 | 440 | |
58f3ca76 | 441 | uchan->enabled = 1; |
7972aab2 | 442 | if (trace_ust_is_max_id(usess->used_channel_id)) { |
4878de5c | 443 | ret_code = LTTNG_ERR_UST_CHAN_FAIL; |
7972aab2 DG |
444 | goto error; |
445 | } | |
446 | uchan->id = trace_ust_get_next_chan_id(usess); | |
447 | ||
448 | DBG2("Channel %s is being created for UST with buffer %d and id %" PRIu64, | |
449 | uchan->name, type, uchan->id); | |
450 | ||
451 | /* Flag session buffer type. */ | |
452 | if (!usess->buffer_type_changed) { | |
453 | usess->buffer_type = type; | |
454 | usess->buffer_type_changed = 1; | |
455 | } else if (usess->buffer_type != type) { | |
456 | /* Buffer type was already set. Refuse to create channel. */ | |
4878de5c | 457 | ret_code = LTTNG_ERR_BUFFER_TYPE_MISMATCH; |
7885e399 DG |
458 | goto error_free_chan; |
459 | } | |
460 | ||
fc34caaa DG |
461 | /* Adding the channel to the channel hash table. */ |
462 | rcu_read_lock(); | |
ad7a9107 DG |
463 | if (strncmp(uchan->name, DEFAULT_METADATA_NAME, |
464 | sizeof(uchan->name))) { | |
465 | lttng_ht_add_unique_str(usess->domain_global.channels, &uchan->node); | |
f86e086c | 466 | chan_published = true; |
84ad93e8 DG |
467 | } else { |
468 | /* | |
469 | * Copy channel attribute to session if this is metadata so if NO | |
470 | * application exists we can access that data in the shadow copy during | |
471 | * the global update of newly registered application. | |
472 | */ | |
473 | memcpy(&usess->metadata_attr, &uchan->attr, | |
474 | sizeof(usess->metadata_attr)); | |
ad7a9107 | 475 | } |
fc34caaa DG |
476 | rcu_read_unlock(); |
477 | ||
7885e399 | 478 | DBG2("Channel %s created successfully", uchan->name); |
b63d638b JG |
479 | if (domain != LTTNG_DOMAIN_UST) { |
480 | struct agent *agt = trace_ust_find_agent(usess, domain); | |
481 | ||
482 | if (!agt) { | |
483 | agt = agent_create(domain); | |
484 | if (!agt) { | |
4878de5c | 485 | ret_code = LTTNG_ERR_NOMEM; |
f86e086c | 486 | goto error_remove_chan; |
b63d638b JG |
487 | } |
488 | agent_add(agt, usess->agents); | |
489 | } | |
490 | } | |
7885e399 | 491 | |
e9404c27 | 492 | channel_attr_destroy(defattr); |
f73fabfd | 493 | return LTTNG_OK; |
7885e399 | 494 | |
f86e086c MD |
495 | error_remove_chan: |
496 | if (chan_published) { | |
497 | trace_ust_delete_channel(usess->domain_global.channels, uchan); | |
498 | } | |
7885e399 DG |
499 | error_free_chan: |
500 | trace_ust_destroy_channel(uchan); | |
501 | error: | |
e9404c27 | 502 | channel_attr_destroy(defattr); |
4878de5c | 503 | return ret_code; |
7885e399 DG |
504 | } |
505 | ||
506 | /* | |
507 | * Disable UST channel for session and domain. | |
508 | */ | |
7972aab2 | 509 | int channel_ust_disable(struct ltt_ust_session *usess, |
7885e399 DG |
510 | struct ltt_ust_channel *uchan) |
511 | { | |
f73fabfd | 512 | int ret = LTTNG_OK; |
7885e399 | 513 | |
a0377dfe FD |
514 | LTTNG_ASSERT(usess); |
515 | LTTNG_ASSERT(uchan); | |
0525e9ae | 516 | |
7885e399 DG |
517 | /* Already disabled */ |
518 | if (uchan->enabled == 0) { | |
519 | DBG2("Channel UST %s already disabled", uchan->name); | |
520 | goto end; | |
521 | } | |
fbee8987 FD |
522 | |
523 | uchan->enabled = 0; | |
524 | ||
525 | /* | |
526 | * If session is inactive we don't notify the tracer right away. We | |
527 | * wait for the next synchronization. | |
528 | */ | |
88e3c2f5 JG |
529 | if (!usess->active) { |
530 | goto end; | |
531 | } | |
7885e399 | 532 | |
7972aab2 DG |
533 | DBG2("Channel %s being disabled in UST global domain", uchan->name); |
534 | /* Disable channel for global domain */ | |
535 | ret = ust_app_disable_channel_glb(usess, uchan); | |
49c336c1 | 536 | if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) { |
f73fabfd | 537 | ret = LTTNG_ERR_UST_CHAN_DISABLE_FAIL; |
7885e399 DG |
538 | goto error; |
539 | } | |
540 | ||
7885e399 DG |
541 | DBG2("Channel %s disabled successfully", uchan->name); |
542 | ||
f73fabfd | 543 | return LTTNG_OK; |
7885e399 DG |
544 | |
545 | end: | |
546 | error: | |
547 | return ret; | |
548 | } | |
999af9c1 JR |
549 | |
550 | struct lttng_channel *trace_ust_channel_to_lttng_channel( | |
551 | const struct ltt_ust_channel *uchan) | |
552 | { | |
553 | struct lttng_channel *channel = NULL, *ret = NULL; | |
554 | ||
555 | channel = lttng_channel_create_internal(); | |
556 | if (!channel) { | |
557 | ERR("Failed to create lttng_channel during conversion from ltt_ust_channel to lttng_channel"); | |
558 | goto end; | |
559 | } | |
560 | ||
561 | if (lttng_strncpy(channel->name, uchan->name, LTTNG_SYMBOL_NAME_LEN)) { | |
562 | ERR("Failed to set channel name during conversion from ltt_ust_channel to lttng_channel"); | |
563 | goto end; | |
564 | } | |
565 | ||
566 | channel->attr.overwrite = uchan->attr.overwrite; | |
567 | channel->attr.subbuf_size = uchan->attr.subbuf_size; | |
568 | channel->attr.num_subbuf = uchan->attr.num_subbuf; | |
569 | channel->attr.switch_timer_interval = uchan->attr.switch_timer_interval; | |
570 | channel->attr.read_timer_interval = uchan->attr.read_timer_interval; | |
571 | channel->enabled = uchan->enabled; | |
572 | channel->attr.tracefile_size = uchan->tracefile_size; | |
573 | channel->attr.tracefile_count = uchan->tracefile_count; | |
574 | ||
575 | /* | |
576 | * Map enum lttng_ust_output to enum lttng_event_output. | |
577 | */ | |
578 | switch (uchan->attr.output) { | |
579 | case LTTNG_UST_ABI_MMAP: | |
580 | channel->attr.output = LTTNG_EVENT_MMAP; | |
581 | break; | |
582 | default: | |
583 | /* | |
584 | * LTTNG_UST_MMAP is the only supported UST | |
585 | * output mode. | |
586 | */ | |
587 | abort(); | |
588 | break; | |
589 | } | |
590 | ||
591 | lttng_channel_set_blocking_timeout( | |
592 | channel, uchan->attr.u.s.blocking_timeout); | |
593 | lttng_channel_set_monitor_timer_interval( | |
594 | channel, uchan->monitor_timer_interval); | |
595 | ||
596 | ret = channel; | |
597 | channel = NULL; | |
598 | ||
599 | end: | |
600 | lttng_channel_destroy(channel); | |
601 | return ret; | |
602 | } |