Clean-up: remove redundant exit labels from sessiond initialization
[lttng-tools.git] / src / bin / lttng-sessiond / trace-kernel.c
CommitLineData
54012638
DG
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
d14d33bf
AM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
54012638
DG
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
d14d33bf
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
54012638
DG
16 */
17
6c1c0768 18#define _LGPL_SOURCE
54012638
DG
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
c363b55d 22#include <unistd.h>
54012638 23
dcabc190
FD
24#include <lttng/event.h>
25#include <lttng/lttng-error.h>
26#include <lttng/userspace-probe.h>
27#include <lttng/userspace-probe-internal.h>
28
990570ed
DG
29#include <common/common.h>
30#include <common/defaults.h>
1e307fab 31
00e2e675 32#include "consumer.h"
62499ad6 33#include "trace-kernel.h"
e9404c27
JG
34#include "lttng-sessiond.h"
35#include "notification-thread-commands.h"
54012638 36
19e70852 37/*
050349bb 38 * Find the channel name for the given kernel session.
19e70852 39 */
62499ad6 40struct ltt_kernel_channel *trace_kernel_get_channel_by_name(
19e70852
DG
41 char *name, struct ltt_kernel_session *session)
42{
43 struct ltt_kernel_channel *chan;
44
0525e9ae
DG
45 assert(session);
46 assert(name);
19e70852 47
85076754
MD
48 /*
49 * If we receive an empty string for channel name, it means the
50 * default channel name is requested.
51 */
52 if (name[0] == '\0')
53 name = DEFAULT_CHANNEL_NAME;
54
54d01ffb
DG
55 DBG("Trying to find channel %s", name);
56
19e70852
DG
57 cds_list_for_each_entry(chan, &session->channel_list.head, list) {
58 if (strcmp(name, chan->channel->name) == 0) {
59 DBG("Found channel by name %s", name);
60 return chan;
61 }
62 }
63
19e70852
DG
64 return NULL;
65}
66
00a62084
MD
67/*
68 * Find the event for the given channel.
69 */
70struct ltt_kernel_event *trace_kernel_find_event(
71 char *name, struct ltt_kernel_channel *channel,
72 enum lttng_event_type type,
73 struct lttng_filter_bytecode *filter)
74{
75 struct ltt_kernel_event *ev;
76 int found = 0;
77
78 assert(name);
79 assert(channel);
80
81 cds_list_for_each_entry(ev, &channel->events_list.head, list) {
82 if (type != LTTNG_EVENT_ALL && ev->type != type) {
83 continue;
84 }
85 if (strcmp(name, ev->event->name)) {
86 continue;
87 }
88 if ((ev->filter && !filter) || (!ev->filter && filter)) {
89 continue;
90 }
91 if (ev->filter && filter) {
92 if (ev->filter->len != filter->len ||
93 memcmp(ev->filter->data, filter->data,
94 filter->len) != 0) {
95 continue;
96 }
97 }
98 found = 1;
99 break;
100 }
101 if (found) {
102 DBG("Found event %s for channel %s", name,
103 channel->channel->name);
104 return ev;
105 } else {
106 return NULL;
107 }
108}
109
19e70852 110/*
050349bb 111 * Find the event name for the given channel.
19e70852 112 */
62499ad6 113struct ltt_kernel_event *trace_kernel_get_event_by_name(
d0ae4ea8
MD
114 char *name, struct ltt_kernel_channel *channel,
115 enum lttng_event_type type)
19e70852
DG
116{
117 struct ltt_kernel_event *ev;
00a62084 118 int found = 0;
19e70852 119
0525e9ae
DG
120 assert(name);
121 assert(channel);
19e70852
DG
122
123 cds_list_for_each_entry(ev, &channel->events_list.head, list) {
00a62084 124 if (type != LTTNG_EVENT_ALL && ev->type != type) {
d0ae4ea8 125 continue;
19e70852 126 }
00a62084
MD
127 if (strcmp(name, ev->event->name)) {
128 continue;
129 }
130 found = 1;
131 break;
132 }
133 if (found) {
134 DBG("Found event %s for channel %s", name,
135 channel->channel->name);
136 return ev;
137 } else {
138 return NULL;
19e70852 139 }
19e70852
DG
140}
141
54012638 142/*
050349bb 143 * Allocate and initialize a kernel session data structure.
54012638 144 *
050349bb 145 * Return pointer to structure or NULL.
54012638 146 */
dec56f6c 147struct ltt_kernel_session *trace_kernel_create_session(void)
54012638 148{
a4b92340 149 struct ltt_kernel_session *lks = NULL;
54012638
DG
150
151 /* Allocate a new ltt kernel session */
ba7f0ae5 152 lks = zmalloc(sizeof(struct ltt_kernel_session));
54012638 153 if (lks == NULL) {
df0f840b 154 PERROR("create kernel session zmalloc");
a4b92340 155 goto alloc_error;
54012638
DG
156 }
157
158 /* Init data structure */
03550b58
MD
159 lks->fd = -1;
160 lks->metadata_stream_fd = -1;
54012638
DG
161 lks->channel_count = 0;
162 lks->stream_count_global = 0;
163 lks->metadata = NULL;
164 CDS_INIT_LIST_HEAD(&lks->channel_list.head);
165
00e2e675
DG
166 lks->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
167 if (lks->consumer == NULL) {
168 goto error;
169 }
170
54012638
DG
171 return lks;
172
173error:
a4b92340
DG
174 free(lks);
175
176alloc_error:
54012638
DG
177 return NULL;
178}
179
180/*
050349bb 181 * Allocate and initialize a kernel channel data structure.
54012638 182 *
050349bb 183 * Return pointer to structure or NULL.
54012638 184 */
00e2e675 185struct ltt_kernel_channel *trace_kernel_create_channel(
fdd9eb17 186 struct lttng_channel *chan)
54012638 187{
54012638 188 struct ltt_kernel_channel *lkc;
61a5b6b1 189 struct lttng_channel_extended *extended = NULL;
54012638 190
0525e9ae
DG
191 assert(chan);
192
ba7f0ae5 193 lkc = zmalloc(sizeof(struct ltt_kernel_channel));
f3ed775e 194 if (lkc == NULL) {
df0f840b 195 PERROR("ltt_kernel_channel zmalloc");
54012638
DG
196 goto error;
197 }
198
ba7f0ae5 199 lkc->channel = zmalloc(sizeof(struct lttng_channel));
f3ed775e 200 if (lkc->channel == NULL) {
df0f840b 201 PERROR("lttng_channel zmalloc");
e9404c27
JG
202 goto error;
203 }
204
205 extended = zmalloc(sizeof(struct lttng_channel_extended));
206 if (!extended) {
207 PERROR("lttng_channel_channel zmalloc");
f3ed775e
DG
208 goto error;
209 }
210 memcpy(lkc->channel, chan, sizeof(struct lttng_channel));
e9404c27
JG
211 memcpy(extended, chan->attr.extended.ptr, sizeof(struct lttng_channel_extended));
212 lkc->channel->attr.extended.ptr = extended;
213 extended = NULL;
54012638 214
85076754
MD
215 /*
216 * If we receive an empty string for channel name, it means the
217 * default channel name is requested.
218 */
219 if (chan->name[0] == '\0') {
220 strncpy(lkc->channel->name, DEFAULT_CHANNEL_NAME,
221 sizeof(lkc->channel->name));
222 }
bd722d76 223 lkc->channel->name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
85076754 224
03550b58 225 lkc->fd = -1;
54012638 226 lkc->stream_count = 0;
cbbbb275 227 lkc->event_count = 0;
d36b8583 228 lkc->enabled = 1;
753873bf 229 lkc->published_to_notification_thread = false;
54012638
DG
230 /* Init linked list */
231 CDS_INIT_LIST_HEAD(&lkc->events_list.head);
232 CDS_INIT_LIST_HEAD(&lkc->stream_list.head);
645328ae 233 CDS_INIT_LIST_HEAD(&lkc->ctx_list);
54012638
DG
234
235 return lkc;
236
237error:
e9404c27
JG
238 if (lkc) {
239 free(lkc->channel);
240 }
241 free(extended);
242 free(lkc);
54012638
DG
243 return NULL;
244}
245
645328ae
DG
246/*
247 * Allocate and init a kernel context object.
248 *
249 * Return the allocated object or NULL on error.
250 */
251struct ltt_kernel_context *trace_kernel_create_context(
252 struct lttng_kernel_context *ctx)
253{
254 struct ltt_kernel_context *kctx;
255
256 kctx = zmalloc(sizeof(*kctx));
257 if (!kctx) {
258 PERROR("zmalloc kernel context");
259 goto error;
260 }
261
262 if (ctx) {
263 memcpy(&kctx->ctx, ctx, sizeof(kctx->ctx));
264 }
df3c77c8
JG
265error:
266 return kctx;
267}
645328ae 268
df3c77c8
JG
269/*
270 * Allocate and init a kernel context object from an existing kernel context
271 * object.
272 *
273 * Return the allocated object or NULL on error.
274 */
275struct ltt_kernel_context *trace_kernel_copy_context(
276 struct ltt_kernel_context *kctx)
277{
278 struct ltt_kernel_context *kctx_copy;
279
280 assert(kctx);
281 kctx_copy = zmalloc(sizeof(*kctx_copy));
282 if (!kctx_copy) {
283 PERROR("zmalloc ltt_kernel_context");
284 goto error;
285 }
286
287 memcpy(kctx_copy, kctx, sizeof(*kctx_copy));
288 memset(&kctx_copy->list, 0, sizeof(kctx_copy->list));
7b9445b3 289
645328ae 290error:
df3c77c8 291 return kctx_copy;
645328ae
DG
292}
293
54012638 294/*
050349bb 295 * Allocate and initialize a kernel event. Set name and event type.
a969e101 296 * We own filter_expression, and filter.
54012638 297 *
050349bb 298 * Return pointer to structure or NULL.
54012638 299 */
71a3bb01
FD
300enum lttng_error_code trace_kernel_create_event(
301 struct lttng_event *ev, char *filter_expression,
302 struct lttng_filter_bytecode *filter,
303 struct ltt_kernel_event **kernel_event)
54012638 304{
71a3bb01 305 enum lttng_error_code ret;
54012638 306 struct lttng_kernel_event *attr;
71a3bb01 307 struct ltt_kernel_event *local_kernel_event;
dcabc190 308 struct lttng_userspace_probe_location *userspace_probe_location = NULL;
54012638 309
0525e9ae
DG
310 assert(ev);
311
71a3bb01 312 local_kernel_event = zmalloc(sizeof(struct ltt_kernel_event));
ba7f0ae5 313 attr = zmalloc(sizeof(struct lttng_kernel_event));
71a3bb01 314 if (local_kernel_event == NULL || attr == NULL) {
df0f840b 315 PERROR("kernel event zmalloc");
71a3bb01 316 ret = LTTNG_ERR_NOMEM;
54012638
DG
317 goto error;
318 }
319
f3ed775e 320 switch (ev->type) {
7d29a247 321 case LTTNG_EVENT_PROBE:
e6ddca71 322 attr->instrumentation = LTTNG_KERNEL_KPROBE;
7d29a247
DG
323 attr->u.kprobe.addr = ev->attr.probe.addr;
324 attr->u.kprobe.offset = ev->attr.probe.offset;
f3ed775e 325 strncpy(attr->u.kprobe.symbol_name,
dbbb3ec5
DG
326 ev->attr.probe.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN);
327 attr->u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
f3ed775e 328 break;
dcabc190
FD
329 case LTTNG_EVENT_USERSPACE_PROBE:
330 {
87597c2c
JG
331 const struct lttng_userspace_probe_location* location = NULL;
332 const struct lttng_userspace_probe_location_lookup_method *lookup = NULL;
dcabc190
FD
333
334 location = lttng_event_get_userspace_probe_location(ev);
335 if (!location) {
336 ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
337 goto error;
338 }
339
340 /*
341 * From this point on, the specific term 'uprobe' is used
342 * instead of the generic 'userspace probe' because it's the
343 * technology used at the moment for this instrumentation.
344 * LTTng currently implements userspace probes using uprobes.
345 * In the interactions with the kernel tracer, we use the
346 * uprobe term.
347 */
348 attr->instrumentation = LTTNG_KERNEL_UPROBE;
349
350 /*
351 * Only the elf lookup method is supported at the moment.
352 */
353 lookup = lttng_userspace_probe_location_get_lookup_method(
354 location);
355 if (!lookup) {
356 ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
357 goto error;
358 }
359
360 /*
361 * From the kernel tracer's perspective, all userspace probe
362 * event types are all the same: a file and an offset.
363 */
364 switch (lttng_userspace_probe_location_lookup_method_get_type(lookup)) {
365 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
366 /* Get the file descriptor on the target binary. */
367 attr->u.uprobe.fd =
368 lttng_userspace_probe_location_function_get_binary_fd(location);
369
370 /*
371 * Save a reference to the probe location used during
372 * the listing of events. Close its FD since it won't
373 * be needed for listing.
374 */
375 userspace_probe_location =
376 lttng_userspace_probe_location_copy(location);
377 ret = lttng_userspace_probe_location_function_set_binary_fd(
378 userspace_probe_location, -1);
379 if (ret) {
380 goto error;
381 }
382 break;
383 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
384 /* Get the file descriptor on the target binary. */
385 attr->u.uprobe.fd =
386 lttng_userspace_probe_location_tracepoint_get_binary_fd(location);
387
388 /*
389 * Save a reference to the probe location used during the listing of
390 * events. Close its FD since it won't be needed for listing.
391 */
392 userspace_probe_location =
393 lttng_userspace_probe_location_copy(location);
394 ret = lttng_userspace_probe_location_tracepoint_set_binary_fd(
395 userspace_probe_location, -1);
396 if (ret) {
397 goto error;
398 }
399 break;
400 default:
401 DBG("Unsupported lookup method type");
402 ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
403 goto error;
404 }
405 break;
406 }
f3ed775e 407 case LTTNG_EVENT_FUNCTION:
8f0d098b
MD
408 attr->instrumentation = LTTNG_KERNEL_KRETPROBE;
409 attr->u.kretprobe.addr = ev->attr.probe.addr;
410 attr->u.kretprobe.offset = ev->attr.probe.offset;
8f0d098b 411 strncpy(attr->u.kretprobe.symbol_name,
dbbb3ec5
DG
412 ev->attr.probe.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN);
413 attr->u.kretprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
8f0d098b
MD
414 break;
415 case LTTNG_EVENT_FUNCTION_ENTRY:
f3ed775e
DG
416 attr->instrumentation = LTTNG_KERNEL_FUNCTION;
417 strncpy(attr->u.ftrace.symbol_name,
dbbb3ec5
DG
418 ev->attr.ftrace.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN);
419 attr->u.ftrace.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
f3ed775e 420 break;
e6ddca71
DG
421 case LTTNG_EVENT_TRACEPOINT:
422 attr->instrumentation = LTTNG_KERNEL_TRACEPOINT;
f3ed775e 423 break;
a54bd42d
MD
424 case LTTNG_EVENT_SYSCALL:
425 attr->instrumentation = LTTNG_KERNEL_SYSCALL;
0133c199 426 break;
7a3d1328
MD
427 case LTTNG_EVENT_ALL:
428 attr->instrumentation = LTTNG_KERNEL_ALL;
429 break;
f3ed775e
DG
430 default:
431 ERR("Unknown kernel instrumentation type (%d)", ev->type);
71a3bb01 432 ret = LTTNG_ERR_INVALID;
f3ed775e
DG
433 goto error;
434 }
435
436 /* Copy event name */
dbbb3ec5
DG
437 strncpy(attr->name, ev->name, LTTNG_KERNEL_SYM_NAME_LEN);
438 attr->name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
f3ed775e 439
54012638 440 /* Setting up a kernel event */
71a3bb01
FD
441 local_kernel_event->fd = -1;
442 local_kernel_event->event = attr;
443 local_kernel_event->enabled = 1;
444 local_kernel_event->filter_expression = filter_expression;
445 local_kernel_event->filter = filter;
dcabc190 446 local_kernel_event->userspace_probe_location = userspace_probe_location;
54012638 447
71a3bb01
FD
448 *kernel_event = local_kernel_event;
449
450 return LTTNG_OK;
54012638
DG
451
452error:
a969e101
MD
453 free(filter_expression);
454 free(filter);
71a3bb01 455 free(local_kernel_event);
a2c0da86 456 free(attr);
71a3bb01 457 return ret;
54012638
DG
458}
459
460/*
050349bb 461 * Allocate and initialize a kernel metadata.
54012638 462 *
050349bb 463 * Return pointer to structure or NULL.
54012638 464 */
a4b92340 465struct ltt_kernel_metadata *trace_kernel_create_metadata(void)
54012638 466{
54012638 467 struct ltt_kernel_metadata *lkm;
f3ed775e 468 struct lttng_channel *chan;
54012638 469
ba7f0ae5
DG
470 lkm = zmalloc(sizeof(struct ltt_kernel_metadata));
471 chan = zmalloc(sizeof(struct lttng_channel));
f3ed775e 472 if (lkm == NULL || chan == NULL) {
df0f840b 473 PERROR("kernel metadata zmalloc");
54012638
DG
474 goto error;
475 }
476
477 /* Set default attributes */
f3ed775e 478 chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE;
3e230f92 479 chan->attr.subbuf_size = default_get_metadata_subbuf_size();
b389abbe 480 chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM;
6bb9e85f
MD
481 chan->attr.switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER;
482 chan->attr.read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER;
7d452e12 483 chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
54012638
DG
484
485 /* Init metadata */
03550b58 486 lkm->fd = -1;
f3ed775e 487 lkm->conf = chan;
54012638
DG
488
489 return lkm;
490
491error:
a2c0da86
MD
492 free(lkm);
493 free(chan);
54012638
DG
494 return NULL;
495}
496
497/*
050349bb
DG
498 * Allocate and initialize a kernel stream. The stream is set to ACTIVE_FD by
499 * default.
54012638 500 *
050349bb 501 * Return pointer to structure or NULL.
54012638 502 */
00e2e675
DG
503struct ltt_kernel_stream *trace_kernel_create_stream(const char *name,
504 unsigned int count)
54012638 505{
00e2e675 506 int ret;
54012638
DG
507 struct ltt_kernel_stream *lks;
508
0525e9ae
DG
509 assert(name);
510
ba7f0ae5 511 lks = zmalloc(sizeof(struct ltt_kernel_stream));
54012638 512 if (lks == NULL) {
df0f840b 513 PERROR("kernel stream zmalloc");
54012638
DG
514 goto error;
515 }
516
00e2e675 517 /* Set name */
535b8ff4 518 ret = snprintf(lks->name, sizeof(lks->name), "%s_%u", name, count);
00e2e675
DG
519 if (ret < 0) {
520 PERROR("snprintf stream name");
521 goto error;
522 }
523 lks->name[sizeof(lks->name) - 1] = '\0';
524
54012638 525 /* Init stream */
03550b58 526 lks->fd = -1;
54012638 527 lks->state = 0;
ffe60014 528 lks->cpu = count;
54012638
DG
529
530 return lks;
531
532error:
533 return NULL;
534}
c363b55d 535
050349bb
DG
536/*
537 * Cleanup kernel stream structure.
538 */
62499ad6 539void trace_kernel_destroy_stream(struct ltt_kernel_stream *stream)
c363b55d 540{
0525e9ae
DG
541 assert(stream);
542
33a2b854 543 DBG("[trace] Closing stream fd %d", stream->fd);
c363b55d 544 /* Close kernel fd */
03550b58 545 if (stream->fd >= 0) {
c617c0c6
MD
546 int ret;
547
03550b58
MD
548 ret = close(stream->fd);
549 if (ret) {
550 PERROR("close");
551 }
799e2c4f 552 }
c363b55d
DG
553 /* Remove from stream list */
554 cds_list_del(&stream->list);
f9815039 555
c363b55d
DG
556 free(stream);
557}
558
050349bb
DG
559/*
560 * Cleanup kernel event structure.
561 */
62499ad6 562void trace_kernel_destroy_event(struct ltt_kernel_event *event)
c363b55d 563{
0525e9ae
DG
564 assert(event);
565
87eb4ab8 566 if (event->fd >= 0) {
c617c0c6
MD
567 int ret;
568
87eb4ab8
MD
569 DBG("[trace] Closing event fd %d", event->fd);
570 /* Close kernel fd */
799e2c4f
MD
571 ret = close(event->fd);
572 if (ret) {
573 PERROR("close");
574 }
87eb4ab8
MD
575 } else {
576 DBG("[trace] Tearing down event (no associated fd)");
577 }
c363b55d
DG
578
579 /* Remove from event list */
580 cds_list_del(&event->list);
f9815039 581
00a62084
MD
582 free(event->filter_expression);
583 free(event->filter);
584
f9815039 585 free(event->event);
c363b55d
DG
586 free(event);
587}
588
645328ae
DG
589/*
590 * Cleanup kernel context structure.
591 */
592void trace_kernel_destroy_context(struct ltt_kernel_context *ctx)
593{
594 assert(ctx);
595
ba985c3a
JG
596 if (ctx->in_list) {
597 cds_list_del(&ctx->list);
598 }
645328ae
DG
599 free(ctx);
600}
601
050349bb
DG
602/*
603 * Cleanup kernel channel structure.
604 */
62499ad6 605void trace_kernel_destroy_channel(struct ltt_kernel_channel *channel)
c363b55d 606{
af9737e9
DG
607 struct ltt_kernel_stream *stream, *stmp;
608 struct ltt_kernel_event *event, *etmp;
645328ae 609 struct ltt_kernel_context *ctx, *ctmp;
799e2c4f 610 int ret;
e9404c27 611 enum lttng_error_code status;
c363b55d 612
0525e9ae
DG
613 assert(channel);
614
33a2b854 615 DBG("[trace] Closing channel fd %d", channel->fd);
c363b55d 616 /* Close kernel fd */
03550b58
MD
617 if (channel->fd >= 0) {
618 ret = close(channel->fd);
619 if (ret) {
620 PERROR("close");
621 }
799e2c4f 622 }
c363b55d
DG
623
624 /* For each stream in the channel list */
af9737e9 625 cds_list_for_each_entry_safe(stream, stmp, &channel->stream_list.head, list) {
62499ad6 626 trace_kernel_destroy_stream(stream);
c363b55d
DG
627 }
628
629 /* For each event in the channel list */
af9737e9 630 cds_list_for_each_entry_safe(event, etmp, &channel->events_list.head, list) {
62499ad6 631 trace_kernel_destroy_event(event);
c363b55d
DG
632 }
633
645328ae
DG
634 /* For each context in the channel list */
635 cds_list_for_each_entry_safe(ctx, ctmp, &channel->ctx_list, list) {
636 trace_kernel_destroy_context(ctx);
637 }
638
c363b55d
DG
639 /* Remove from channel list */
640 cds_list_del(&channel->list);
f9815039 641
753873bf
JR
642 if (notification_thread_handle
643 && channel->published_to_notification_thread) {
63aaa3dc
JG
644 status = notification_thread_command_remove_channel(
645 notification_thread_handle,
e1f3997a 646 channel->key, LTTNG_DOMAIN_KERNEL);
63aaa3dc
JG
647 assert(status == LTTNG_OK);
648 }
e9404c27 649 free(channel->channel->attr.extended.ptr);
f9815039 650 free(channel->channel);
c363b55d
DG
651 free(channel);
652}
653
050349bb
DG
654/*
655 * Cleanup kernel metadata structure.
656 */
62499ad6 657void trace_kernel_destroy_metadata(struct ltt_kernel_metadata *metadata)
c363b55d 658{
0525e9ae
DG
659 assert(metadata);
660
33a2b854 661 DBG("[trace] Closing metadata fd %d", metadata->fd);
c363b55d 662 /* Close kernel fd */
03550b58 663 if (metadata->fd >= 0) {
c617c0c6
MD
664 int ret;
665
03550b58
MD
666 ret = close(metadata->fd);
667 if (ret) {
668 PERROR("close");
669 }
799e2c4f 670 }
c363b55d 671
f9815039 672 free(metadata->conf);
c363b55d
DG
673 free(metadata);
674}
675
050349bb 676/*
62499ad6 677 * Cleanup kernel session structure
36b588ed
MD
678 *
679 * Should *NOT* be called with RCU read-side lock held.
050349bb 680 */
62499ad6 681void trace_kernel_destroy_session(struct ltt_kernel_session *session)
c363b55d 682{
af9737e9 683 struct ltt_kernel_channel *channel, *ctmp;
799e2c4f 684 int ret;
c363b55d 685
0525e9ae
DG
686 assert(session);
687
33a2b854 688 DBG("[trace] Closing session fd %d", session->fd);
c363b55d 689 /* Close kernel fds */
03550b58
MD
690 if (session->fd >= 0) {
691 ret = close(session->fd);
692 if (ret) {
693 PERROR("close");
694 }
799e2c4f 695 }
f9815039 696
03550b58 697 if (session->metadata_stream_fd >= 0) {
70dc1c34 698 DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd);
799e2c4f
MD
699 ret = close(session->metadata_stream_fd);
700 if (ret) {
701 PERROR("close");
702 }
70dc1c34 703 }
c363b55d 704
d36b8583 705 if (session->metadata != NULL) {
62499ad6 706 trace_kernel_destroy_metadata(session->metadata);
d36b8583 707 }
c363b55d 708
af9737e9 709 cds_list_for_each_entry_safe(channel, ctmp, &session->channel_list.head, list) {
62499ad6 710 trace_kernel_destroy_channel(channel);
c363b55d
DG
711 }
712
00e2e675 713 /* Wipe consumer output object */
6addfa37 714 consumer_output_put(session->consumer);
00e2e675 715
c363b55d
DG
716 free(session);
717}
This page took 0.092705 seconds and 4 git commands to generate.