Fix: leftover use of channel fd as identifier
[lttng-tools.git] / src / bin / lttng-sessiond / kernel.c
CommitLineData
20fe2104
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.
20fe2104
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.
20fe2104
DG
16 */
17
6c1c0768 18#define _LGPL_SOURCE
7b395890 19#include <fcntl.h>
20fe2104
DG
20#include <stdlib.h>
21#include <stdio.h>
f34daff7 22#include <string.h>
8c0faa1d 23#include <unistd.h>
77c7c900 24#include <inttypes.h>
20fe2104 25
990570ed 26#include <common/common.h>
db758600 27#include <common/kernel-ctl/kernel-ctl.h>
c052142c 28#include <common/kernel-ctl/kernel-ioctl.h>
42224349 29#include <common/sessiond-comm/sessiond-comm.h>
1e307fab 30
2f77fc4b 31#include "consumer.h"
4771f025 32#include "kernel.h"
6dc3064a 33#include "kernel-consumer.h"
096102bd 34#include "kern-modules.h"
834978fd 35#include "utils.h"
20fe2104 36
e1f3997a
JD
37/*
38 * Key used to reference a channel between the sessiond and the consumer. This
39 * is only read and updated with the session_list lock held.
40 */
41static uint64_t next_kernel_channel_key;
42
d65106b1 43/*
050349bb 44 * Add context on a kernel channel.
df3c77c8
JG
45 *
46 * Assumes the ownership of ctx.
d65106b1
DG
47 */
48int kernel_add_channel_context(struct ltt_kernel_channel *chan,
645328ae 49 struct ltt_kernel_context *ctx)
d65106b1
DG
50{
51 int ret;
52
0525e9ae
DG
53 assert(chan);
54 assert(ctx);
55
d65106b1 56 DBG("Adding context to channel %s", chan->channel->name);
645328ae 57 ret = kernctl_add_context(chan->fd, &ctx->ctx);
d65106b1 58 if (ret < 0) {
32af2c95 59 switch (-ret) {
1ae5e83e
JD
60 case ENOSYS:
61 /* Exists but not available for this kernel */
62 ret = LTTNG_ERR_KERN_CONTEXT_UNAVAILABLE;
63 goto error;
64 case EEXIST:
b579acd9
DG
65 /* If EEXIST, we just ignore the error */
66 ret = 0;
1ae5e83e
JD
67 goto end;
68 default:
69 PERROR("add context ioctl");
70 ret = LTTNG_ERR_KERN_CONTEXT_FAIL;
71 goto error;
b579acd9 72 }
d65106b1 73 }
21ed98c1 74 ret = 0;
d65106b1 75
1ae5e83e 76end:
645328ae 77 cds_list_add_tail(&ctx->list, &chan->ctx_list);
ba985c3a 78 ctx->in_list = true;
df3c77c8 79 ctx = NULL;
d65106b1 80error:
df3c77c8
JG
81 if (ctx) {
82 trace_kernel_destroy_context(ctx);
83 }
d65106b1
DG
84 return ret;
85}
86
20fe2104 87/*
050349bb
DG
88 * Create a new kernel session, register it to the kernel tracer and add it to
89 * the session daemon session.
20fe2104 90 */
8c0faa1d 91int kernel_create_session(struct ltt_session *session, int tracer_fd)
20fe2104
DG
92{
93 int ret;
94 struct ltt_kernel_session *lks;
95
0525e9ae
DG
96 assert(session);
97
54012638 98 /* Allocate data structure */
dec56f6c 99 lks = trace_kernel_create_session();
20fe2104 100 if (lks == NULL) {
54012638 101 ret = -1;
20fe2104
DG
102 goto error;
103 }
104
54012638 105 /* Kernel tracer session creation */
20fe2104
DG
106 ret = kernctl_create_session(tracer_fd);
107 if (ret < 0) {
df0f840b 108 PERROR("ioctl kernel create session");
20fe2104
DG
109 goto error;
110 }
111
20fe2104 112 lks->fd = ret;
7b395890
DG
113 /* Prevent fd duplication after execlp() */
114 ret = fcntl(lks->fd, F_SETFD, FD_CLOEXEC);
115 if (ret < 0) {
df0f840b 116 PERROR("fcntl session fd");
7b395890
DG
117 }
118
53632229 119 lks->id = session->id;
3bd1e081 120 lks->consumer_fds_sent = 0;
8c0faa1d 121 session->kernel_session = lks;
8c0faa1d
DG
122
123 DBG("Kernel session created (fd: %d)", lks->fd);
20fe2104
DG
124
125 return 0;
126
127error:
5f62c685
DG
128 if (lks) {
129 trace_kernel_destroy_session(lks);
130 }
20fe2104
DG
131 return ret;
132}
133
134/*
050349bb
DG
135 * Create a kernel channel, register it to the kernel tracer and add it to the
136 * kernel session.
20fe2104 137 */
050349bb 138int kernel_create_channel(struct ltt_kernel_session *session,
fdd9eb17 139 struct lttng_channel *chan)
20fe2104
DG
140{
141 int ret;
142 struct ltt_kernel_channel *lkc;
20fe2104 143
0525e9ae
DG
144 assert(session);
145 assert(chan);
0525e9ae 146
54012638 147 /* Allocate kernel channel */
fdd9eb17 148 lkc = trace_kernel_create_channel(chan);
54012638 149 if (lkc == NULL) {
20fe2104
DG
150 goto error;
151 }
152
ecc48a90 153 DBG3("Kernel create channel %s with attr: %d, %" PRIu64 ", %" PRIu64 ", %u, %u, %d, %d",
fdd9eb17 154 chan->name, lkc->channel->attr.overwrite,
173af62f
DG
155 lkc->channel->attr.subbuf_size, lkc->channel->attr.num_subbuf,
156 lkc->channel->attr.switch_timer_interval, lkc->channel->attr.read_timer_interval,
ecc48a90 157 lkc->channel->attr.live_timer_interval, lkc->channel->attr.output);
173af62f 158
54012638 159 /* Kernel tracer channel creation */
f3ed775e 160 ret = kernctl_create_channel(session->fd, &lkc->channel->attr);
20fe2104 161 if (ret < 0) {
df0f840b 162 PERROR("ioctl kernel create channel");
20fe2104
DG
163 goto error;
164 }
165
54012638 166 /* Setup the channel fd */
20fe2104 167 lkc->fd = ret;
7b395890
DG
168 /* Prevent fd duplication after execlp() */
169 ret = fcntl(lkc->fd, F_SETFD, FD_CLOEXEC);
170 if (ret < 0) {
df0f840b 171 PERROR("fcntl session fd");
7b395890
DG
172 }
173
54012638 174 /* Add channel to session */
8c0faa1d
DG
175 cds_list_add(&lkc->list, &session->channel_list.head);
176 session->channel_count++;
fb5f35b6 177 lkc->session = session;
e1f3997a 178 lkc->key = ++next_kernel_channel_key;
20fe2104 179
e1f3997a
JD
180 DBG("Kernel channel %s created (fd: %d, key: %" PRIu64 ")",
181 lkc->channel->name, lkc->fd, lkc->key);
20fe2104
DG
182
183 return 0;
184
185error:
5f62c685
DG
186 if (lkc) {
187 free(lkc->channel);
188 free(lkc);
189 }
54012638 190 return -1;
20fe2104 191}
f34daff7
DG
192
193/*
050349bb
DG
194 * Create a kernel event, enable it to the kernel tracer and add it to the
195 * channel event list of the kernel session.
49d21f93 196 * We own filter_expression and filter.
f34daff7 197 */
050349bb 198int kernel_create_event(struct lttng_event *ev,
00a62084
MD
199 struct ltt_kernel_channel *channel,
200 char *filter_expression,
201 struct lttng_filter_bytecode *filter)
f34daff7
DG
202{
203 int ret;
204 struct ltt_kernel_event *event;
f34daff7 205
0525e9ae
DG
206 assert(ev);
207 assert(channel);
208
a969e101 209 /* We pass ownership of filter_expression and filter */
00a62084
MD
210 event = trace_kernel_create_event(ev, filter_expression,
211 filter);
54012638 212 if (event == NULL) {
d87bfb32 213 ret = -1;
f34daff7
DG
214 goto error;
215 }
216
f3ed775e
DG
217 ret = kernctl_create_event(channel->fd, event->event);
218 if (ret < 0) {
32af2c95 219 switch (-ret) {
bd29c13d
DG
220 case EEXIST:
221 break;
222 case ENOSYS:
223 WARN("Event type not implemented");
224 break;
8197a339
DG
225 case ENOENT:
226 WARN("Event %s not found!", ev->name);
227 break;
bd29c13d 228 default:
d87bfb32
DG
229 PERROR("create event ioctl");
230 }
e953ef25 231 goto free_event;
8c0faa1d 232 }
f34daff7 233
d0ae4ea8 234 event->type = ev->type;
f3ed775e 235 event->fd = ret;
7b395890
DG
236 /* Prevent fd duplication after execlp() */
237 ret = fcntl(event->fd, F_SETFD, FD_CLOEXEC);
238 if (ret < 0) {
df0f840b 239 PERROR("fcntl session fd");
7b395890
DG
240 }
241
00a62084
MD
242 if (filter) {
243 ret = kernctl_filter(event->fd, filter);
244 if (ret) {
245 goto filter_error;
246 }
247 }
248
249 ret = kernctl_enable(event->fd);
250 if (ret < 0) {
32af2c95 251 switch (-ret) {
00a62084
MD
252 case EEXIST:
253 ret = LTTNG_ERR_KERN_EVENT_EXIST;
254 break;
255 default:
256 PERROR("enable kernel event");
257 break;
258 }
259 goto enable_error;
260 }
261
f3ed775e
DG
262 /* Add event to event list */
263 cds_list_add(&event->list, &channel->events_list.head);
cbbbb275
DG
264 channel->event_count++;
265
e953ef25
DG
266 DBG("Event %s created (fd: %d)", ev->name, event->fd);
267
268 return 0;
269
00a62084
MD
270enable_error:
271filter_error:
272 {
273 int closeret;
274
275 closeret = close(event->fd);
276 if (closeret) {
277 PERROR("close event fd");
278 }
279 }
e953ef25
DG
280free_event:
281 free(event);
282error:
d87bfb32 283 return ret;
e953ef25
DG
284}
285
26cc6b4e 286/*
050349bb 287 * Disable a kernel channel.
26cc6b4e
DG
288 */
289int kernel_disable_channel(struct ltt_kernel_channel *chan)
290{
291 int ret;
292
0525e9ae
DG
293 assert(chan);
294
26cc6b4e
DG
295 ret = kernctl_disable(chan->fd);
296 if (ret < 0) {
df0f840b 297 PERROR("disable chan ioctl");
26cc6b4e
DG
298 goto error;
299 }
300
301 chan->enabled = 0;
e1f3997a
JD
302 DBG("Kernel channel %s disabled (fd: %d, key: %" PRIu64 ")",
303 chan->channel->name, chan->fd, chan->key);
26cc6b4e
DG
304
305 return 0;
306
307error:
308 return ret;
309}
310
d36b8583 311/*
050349bb 312 * Enable a kernel channel.
d36b8583
DG
313 */
314int kernel_enable_channel(struct ltt_kernel_channel *chan)
315{
316 int ret;
317
0525e9ae
DG
318 assert(chan);
319
d36b8583 320 ret = kernctl_enable(chan->fd);
32af2c95 321 if (ret < 0 && ret != -EEXIST) {
df0f840b 322 PERROR("Enable kernel chan");
d36b8583
DG
323 goto error;
324 }
325
326 chan->enabled = 1;
e1f3997a
JD
327 DBG("Kernel channel %s enabled (fd: %d, key: %" PRIu64 ")",
328 chan->channel->name, chan->fd, chan->key);
d36b8583
DG
329
330 return 0;
331
332error:
333 return ret;
334}
335
19e70852 336/*
050349bb 337 * Enable a kernel event.
19e70852
DG
338 */
339int kernel_enable_event(struct ltt_kernel_event *event)
340{
341 int ret;
342
0525e9ae
DG
343 assert(event);
344
19e70852 345 ret = kernctl_enable(event->fd);
42224349 346 if (ret < 0) {
32af2c95 347 switch (-ret) {
42224349 348 case EEXIST:
f73fabfd 349 ret = LTTNG_ERR_KERN_EVENT_EXIST;
42224349
DG
350 break;
351 default:
352 PERROR("enable kernel event");
353 break;
354 }
19e70852
DG
355 goto error;
356 }
357
358 event->enabled = 1;
359 DBG("Kernel event %s enabled (fd: %d)", event->event->name, event->fd);
360
361 return 0;
362
363error:
d36b8583 364 return ret;
19e70852
DG
365}
366
e953ef25 367/*
050349bb 368 * Disable a kernel event.
e953ef25 369 */
19e70852 370int kernel_disable_event(struct ltt_kernel_event *event)
e953ef25
DG
371{
372 int ret;
19e70852 373
0525e9ae
DG
374 assert(event);
375
19e70852 376 ret = kernctl_disable(event->fd);
42224349 377 if (ret < 0) {
32af2c95 378 switch (-ret) {
42224349 379 case EEXIST:
f73fabfd 380 ret = LTTNG_ERR_KERN_EVENT_EXIST;
42224349
DG
381 break;
382 default:
383 PERROR("disable kernel event");
384 break;
385 }
19e70852 386 goto error;
e953ef25 387 }
f3ed775e 388
19e70852
DG
389 event->enabled = 0;
390 DBG("Kernel event %s disabled (fd: %d)", event->event->name, event->fd);
391
f34daff7
DG
392 return 0;
393
394error:
d36b8583 395 return ret;
f34daff7 396}
aaf26714 397
6e911cad 398
ccf10263
MD
399int kernel_track_pid(struct ltt_kernel_session *session, int pid)
400{
7c493d31
MD
401 int ret;
402
ccf10263
MD
403 DBG("Kernel track PID %d for session id %" PRIu64 ".",
404 pid, session->id);
7c493d31
MD
405 ret = kernctl_track_pid(session->fd, pid);
406 if (!ret) {
407 return LTTNG_OK;
408 }
32af2c95 409 switch (-ret) {
7c493d31
MD
410 case EINVAL:
411 return LTTNG_ERR_INVALID;
412 case ENOMEM:
413 return LTTNG_ERR_NOMEM;
414 case EEXIST:
415 return LTTNG_ERR_PID_TRACKED;
416 default:
417 return LTTNG_ERR_UNK;
418 }
ccf10263
MD
419}
420
421int kernel_untrack_pid(struct ltt_kernel_session *session, int pid)
422{
7c493d31
MD
423 int ret;
424
ccf10263
MD
425 DBG("Kernel untrack PID %d for session id %" PRIu64 ".",
426 pid, session->id);
7c493d31
MD
427 ret = kernctl_untrack_pid(session->fd, pid);
428 if (!ret) {
429 return LTTNG_OK;
430 }
32af2c95 431 switch (-ret) {
7c493d31
MD
432 case EINVAL:
433 return LTTNG_ERR_INVALID;
434 case ENOMEM:
435 return LTTNG_ERR_NOMEM;
436 case ENOENT:
437 return LTTNG_ERR_PID_NOT_TRACKED;
438 default:
439 return LTTNG_ERR_UNK;
440 }
ccf10263
MD
441}
442
a5dfbb9d
MD
443ssize_t kernel_list_tracker_pids(struct ltt_kernel_session *session,
444 int **_pids)
445{
446 int fd, ret;
447 int pid;
448 ssize_t nbmem, count = 0;
449 FILE *fp;
450 int *pids;
451
452 fd = kernctl_list_tracker_pids(session->fd);
453 if (fd < 0) {
454 PERROR("kernel tracker pids list");
455 goto error;
456 }
457
458 fp = fdopen(fd, "r");
459 if (fp == NULL) {
460 PERROR("kernel tracker pids list fdopen");
461 goto error_fp;
462 }
463
464 nbmem = KERNEL_TRACKER_PIDS_INIT_LIST_SIZE;
465 pids = zmalloc(sizeof(*pids) * nbmem);
466 if (pids == NULL) {
467 PERROR("alloc list pids");
468 count = -ENOMEM;
469 goto end;
470 }
471
472 while (fscanf(fp, "process { pid = %u; };\n", &pid) == 1) {
473 if (count >= nbmem) {
474 int *new_pids;
475 size_t new_nbmem;
476
477 new_nbmem = nbmem << 1;
478 DBG("Reallocating pids list from %zu to %zu entries",
479 nbmem, new_nbmem);
480 new_pids = realloc(pids, new_nbmem * sizeof(*new_pids));
481 if (new_pids == NULL) {
482 PERROR("realloc list events");
483 free(pids);
484 count = -ENOMEM;
485 goto end;
486 }
487 /* Zero the new memory */
488 memset(new_pids + nbmem, 0,
489 (new_nbmem - nbmem) * sizeof(*new_pids));
490 nbmem = new_nbmem;
491 pids = new_pids;
492 }
493 pids[count++] = pid;
494 }
495
496 *_pids = pids;
497 DBG("Kernel list tracker pids done (%zd pids)", count);
498end:
499 ret = fclose(fp); /* closes both fp and fd */
500 if (ret) {
501 PERROR("fclose");
502 }
503 return count;
504
505error_fp:
506 ret = close(fd);
507 if (ret) {
508 PERROR("close");
509 }
510error:
511 return -1;
512}
513
aaf26714 514/*
050349bb
DG
515 * Create kernel metadata, open from the kernel tracer and add it to the
516 * kernel session.
aaf26714 517 */
a4b92340 518int kernel_open_metadata(struct ltt_kernel_session *session)
aaf26714
DG
519{
520 int ret;
74024a21 521 struct ltt_kernel_metadata *lkm = NULL;
aaf26714 522
0525e9ae
DG
523 assert(session);
524
54012638 525 /* Allocate kernel metadata */
a4b92340 526 lkm = trace_kernel_create_metadata();
54012638 527 if (lkm == NULL) {
aaf26714
DG
528 goto error;
529 }
530
54012638 531 /* Kernel tracer metadata creation */
f3ed775e 532 ret = kernctl_open_metadata(session->fd, &lkm->conf->attr);
aaf26714 533 if (ret < 0) {
74024a21 534 goto error_open;
aaf26714
DG
535 }
536
8c0faa1d 537 lkm->fd = ret;
7b395890
DG
538 /* Prevent fd duplication after execlp() */
539 ret = fcntl(lkm->fd, F_SETFD, FD_CLOEXEC);
540 if (ret < 0) {
df0f840b 541 PERROR("fcntl session fd");
7b395890
DG
542 }
543
aaf26714 544 session->metadata = lkm;
8c0faa1d 545
00e2e675 546 DBG("Kernel metadata opened (fd: %d)", lkm->fd);
8c0faa1d
DG
547
548 return 0;
549
74024a21
DG
550error_open:
551 trace_kernel_destroy_metadata(lkm);
8c0faa1d 552error:
54012638 553 return -1;
8c0faa1d
DG
554}
555
556/*
050349bb 557 * Start tracing session.
8c0faa1d
DG
558 */
559int kernel_start_session(struct ltt_kernel_session *session)
560{
561 int ret;
562
0525e9ae
DG
563 assert(session);
564
8c0faa1d
DG
565 ret = kernctl_start_session(session->fd);
566 if (ret < 0) {
df0f840b 567 PERROR("ioctl start session");
8c0faa1d
DG
568 goto error;
569 }
570
571 DBG("Kernel session started");
572
573 return 0;
574
575error:
576 return ret;
577}
578
f3ed775e 579/*
050349bb 580 * Make a kernel wait to make sure in-flight probe have completed.
f3ed775e
DG
581 */
582void kernel_wait_quiescent(int fd)
583{
584 int ret;
585
586 DBG("Kernel quiescent wait on %d", fd);
587
588 ret = kernctl_wait_quiescent(fd);
589 if (ret < 0) {
df0f840b 590 PERROR("wait quiescent ioctl");
f3ed775e
DG
591 ERR("Kernel quiescent wait failed");
592 }
593}
594
595/*
f3ed775e
DG
596 * Force flush buffer of metadata.
597 */
598int kernel_metadata_flush_buffer(int fd)
599{
600 int ret;
601
169d2cb7
DG
602 DBG("Kernel flushing metadata buffer on fd %d", fd);
603
f3ed775e
DG
604 ret = kernctl_buffer_flush(fd);
605 if (ret < 0) {
00e2e675 606 ERR("Fail to flush metadata buffers %d (ret: %d)", fd, ret);
f3ed775e
DG
607 }
608
609 return 0;
610}
611
612/*
050349bb 613 * Force flush buffer for channel.
f3ed775e
DG
614 */
615int kernel_flush_buffer(struct ltt_kernel_channel *channel)
616{
617 int ret;
618 struct ltt_kernel_stream *stream;
619
0525e9ae
DG
620 assert(channel);
621
f3ed775e
DG
622 DBG("Flush buffer for channel %s", channel->channel->name);
623
624 cds_list_for_each_entry(stream, &channel->stream_list.head, list) {
625 DBG("Flushing channel stream %d", stream->fd);
626 ret = kernctl_buffer_flush(stream->fd);
627 if (ret < 0) {
df0f840b 628 PERROR("ioctl");
f3ed775e
DG
629 ERR("Fail to flush buffer for stream %d (ret: %d)",
630 stream->fd, ret);
631 }
632 }
633
634 return 0;
635}
636
8c0faa1d 637/*
050349bb 638 * Stop tracing session.
8c0faa1d
DG
639 */
640int kernel_stop_session(struct ltt_kernel_session *session)
641{
642 int ret;
643
0525e9ae
DG
644 assert(session);
645
8c0faa1d
DG
646 ret = kernctl_stop_session(session->fd);
647 if (ret < 0) {
648 goto error;
649 }
650
651 DBG("Kernel session stopped");
652
653 return 0;
654
655error:
656 return ret;
657}
658
659/*
050349bb
DG
660 * Open stream of channel, register it to the kernel tracer and add it
661 * to the stream list of the channel.
8c0faa1d 662 *
1cfb4b98
MD
663 * Note: given that the streams may appear in random order wrt CPU
664 * number (e.g. cpu hotplug), the index value of the stream number in
665 * the stream name is not necessarily linked to the CPU number.
666 *
050349bb 667 * Return the number of created stream. Else, a negative value.
8c0faa1d 668 */
f3ed775e 669int kernel_open_channel_stream(struct ltt_kernel_channel *channel)
8c0faa1d 670{
1cfb4b98 671 int ret;
8c0faa1d
DG
672 struct ltt_kernel_stream *lks;
673
0525e9ae
DG
674 assert(channel);
675
5a47c6a2 676 while ((ret = kernctl_create_stream(channel->fd)) >= 0) {
1cfb4b98
MD
677 lks = trace_kernel_create_stream(channel->channel->name,
678 channel->stream_count);
8c0faa1d 679 if (lks == NULL) {
799e2c4f
MD
680 ret = close(ret);
681 if (ret) {
682 PERROR("close");
683 }
8c0faa1d
DG
684 goto error;
685 }
686
687 lks->fd = ret;
7b395890
DG
688 /* Prevent fd duplication after execlp() */
689 ret = fcntl(lks->fd, F_SETFD, FD_CLOEXEC);
690 if (ret < 0) {
df0f840b 691 PERROR("fcntl session fd");
7b395890
DG
692 }
693
1624d5b7
JD
694 lks->tracefile_size = channel->channel->attr.tracefile_size;
695 lks->tracefile_count = channel->channel->attr.tracefile_count;
696
1cfb4b98 697 /* Add stream to channel stream list */
8c0faa1d
DG
698 cds_list_add(&lks->list, &channel->stream_list.head);
699 channel->stream_count++;
8c0faa1d 700
00e2e675
DG
701 DBG("Kernel stream %s created (fd: %d, state: %d)", lks->name, lks->fd,
702 lks->state);
54012638 703 }
8c0faa1d
DG
704
705 return channel->stream_count;
706
707error:
54012638 708 return -1;
8c0faa1d
DG
709}
710
711/*
050349bb 712 * Open the metadata stream and set it to the kernel session.
8c0faa1d 713 */
f3ed775e 714int kernel_open_metadata_stream(struct ltt_kernel_session *session)
8c0faa1d
DG
715{
716 int ret;
717
0525e9ae
DG
718 assert(session);
719
8c0faa1d
DG
720 ret = kernctl_create_stream(session->metadata->fd);
721 if (ret < 0) {
df0f840b 722 PERROR("kernel create metadata stream");
8c0faa1d
DG
723 goto error;
724 }
725
726 DBG("Kernel metadata stream created (fd: %d)", ret);
727 session->metadata_stream_fd = ret;
7b395890
DG
728 /* Prevent fd duplication after execlp() */
729 ret = fcntl(session->metadata_stream_fd, F_SETFD, FD_CLOEXEC);
730 if (ret < 0) {
df0f840b 731 PERROR("fcntl session fd");
7b395890 732 }
aaf26714
DG
733
734 return 0;
735
736error:
54012638 737 return -1;
aaf26714 738}
2ef84c95
DG
739
740/*
9f19cc17 741 * Get the event list from the kernel tracer and return the number of elements.
2ef84c95 742 */
9f19cc17 743ssize_t kernel_list_events(int tracer_fd, struct lttng_event **events)
2ef84c95 744{
53efb85a 745 int fd, ret;
9f19cc17
DG
746 char *event;
747 size_t nbmem, count = 0;
2ef84c95 748 FILE *fp;
9f19cc17 749 struct lttng_event *elist;
2ef84c95 750
0525e9ae
DG
751 assert(events);
752
2ef84c95
DG
753 fd = kernctl_tracepoint_list(tracer_fd);
754 if (fd < 0) {
df0f840b 755 PERROR("kernel tracepoint list");
2ef84c95
DG
756 goto error;
757 }
758
759 fp = fdopen(fd, "r");
760 if (fp == NULL) {
df0f840b 761 PERROR("kernel tracepoint list fdopen");
61b73b12 762 goto error_fp;
2ef84c95
DG
763 }
764
765 /*
766 * Init memory size counter
767 * See kernel-ctl.h for explanation of this value
768 */
6725fe19 769 nbmem = KERNEL_EVENT_INIT_LIST_SIZE;
ba7f0ae5 770 elist = zmalloc(sizeof(struct lttng_event) * nbmem);
3b870559
MD
771 if (elist == NULL) {
772 PERROR("alloc list events");
773 count = -ENOMEM;
774 goto end;
775 }
2ef84c95 776
53efb85a 777 while (fscanf(fp, "event { name = %m[^;]; };\n", &event) == 1) {
6725fe19 778 if (count >= nbmem) {
3b870559 779 struct lttng_event *new_elist;
53efb85a 780 size_t new_nbmem;
3b870559 781
53efb85a
MD
782 new_nbmem = nbmem << 1;
783 DBG("Reallocating event list from %zu to %zu bytes",
784 nbmem, new_nbmem);
785 new_elist = realloc(elist, new_nbmem * sizeof(struct lttng_event));
3b870559 786 if (new_elist == NULL) {
df0f840b 787 PERROR("realloc list events");
3b870559
MD
788 free(event);
789 free(elist);
61b73b12
MD
790 count = -ENOMEM;
791 goto end;
2ef84c95 792 }
53efb85a
MD
793 /* Zero the new memory */
794 memset(new_elist + nbmem, 0,
795 (new_nbmem - nbmem) * sizeof(struct lttng_event));
796 nbmem = new_nbmem;
3b870559 797 elist = new_elist;
2ef84c95 798 }
99497cd0
MD
799 strncpy(elist[count].name, event, LTTNG_SYMBOL_NAME_LEN);
800 elist[count].name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
67b9d018 801 elist[count].enabled = -1;
9f19cc17 802 count++;
3b870559 803 free(event);
2ef84c95
DG
804 }
805
9f19cc17 806 *events = elist;
ced2f820 807 DBG("Kernel list events done (%zu events)", count);
61b73b12 808end:
799e2c4f
MD
809 ret = fclose(fp); /* closes both fp and fd */
810 if (ret) {
811 PERROR("fclose");
812 }
9f19cc17 813 return count;
2ef84c95 814
61b73b12 815error_fp:
799e2c4f
MD
816 ret = close(fd);
817 if (ret) {
818 PERROR("close");
819 }
2ef84c95
DG
820error:
821 return -1;
822}
096102bd
DG
823
824/*
825 * Get kernel version and validate it.
826 */
88076e89
JD
827int kernel_validate_version(int tracer_fd,
828 struct lttng_kernel_tracer_version *version,
829 struct lttng_kernel_tracer_abi_version *abi_version)
096102bd
DG
830{
831 int ret;
096102bd 832
88076e89 833 ret = kernctl_tracer_version(tracer_fd, version);
096102bd 834 if (ret < 0) {
521dd134 835 ERR("Failed to retrieve the lttng-modules version");
096102bd
DG
836 goto error;
837 }
838
839 /* Validate version */
88076e89 840 if (version->major != VERSION_MAJOR) {
c052142c 841 ERR("Kernel tracer major version (%d) is not compatible with lttng-tools major version (%d)",
88076e89 842 version->major, VERSION_MAJOR);
096102bd 843 goto error_version;
096102bd 844 }
88076e89 845 ret = kernctl_tracer_abi_version(tracer_fd, abi_version);
c052142c 846 if (ret < 0) {
521dd134 847 ERR("Failed to retrieve lttng-modules ABI version");
c052142c
MD
848 goto error;
849 }
88076e89 850 if (abi_version->major != LTTNG_MODULES_ABI_MAJOR_VERSION) {
521dd134 851 ERR("Kernel tracer ABI version (%d.%d) does not match the expected ABI major version (%d.*)",
88076e89 852 abi_version->major, abi_version->minor,
c052142c
MD
853 LTTNG_MODULES_ABI_MAJOR_VERSION);
854 goto error;
855 }
856 DBG2("Kernel tracer version validated (%d.%d, ABI %d.%d)",
88076e89
JD
857 version->major, version->minor,
858 abi_version->major, abi_version->minor);
096102bd
DG
859 return 0;
860
861error_version:
096102bd
DG
862 ret = -1;
863
864error:
521dd134 865 ERR("Kernel tracer version check failed; kernel tracing will not be available");
096102bd
DG
866 return ret;
867}
335a95b7
MD
868
869/*
870 * Kernel work-arounds called at the start of sessiond main().
871 */
872int init_kernel_workarounds(void)
873{
8936c33a 874 int ret;
335a95b7
MD
875 FILE *fp;
876
877 /*
878 * boot_id needs to be read once before being used concurrently
879 * to deal with a Linux kernel race. A fix is proposed for
880 * upstream, but the work-around is needed for older kernels.
881 */
882 fp = fopen("/proc/sys/kernel/random/boot_id", "r");
883 if (!fp) {
884 goto end_boot_id;
885 }
886 while (!feof(fp)) {
887 char buf[37] = "";
888
8936c33a
DG
889 ret = fread(buf, 1, sizeof(buf), fp);
890 if (ret < 0) {
891 /* Ignore error, we don't really care */
892 }
335a95b7 893 }
799e2c4f
MD
894 ret = fclose(fp);
895 if (ret) {
896 PERROR("fclose");
897 }
335a95b7 898end_boot_id:
335a95b7
MD
899 return 0;
900}
2f77fc4b
DG
901
902/*
903 * Complete teardown of a kernel session.
904 */
905void kernel_destroy_session(struct ltt_kernel_session *ksess)
906{
907 if (ksess == NULL) {
908 DBG3("No kernel session when tearing down session");
909 return;
910 }
911
912 DBG("Tearing down kernel session");
913
07b86b52 914 /*
15dc512a
DG
915 * Destroy channels on the consumer if at least one FD has been sent and we
916 * are in no output mode because the streams are in *no* monitor mode so we
917 * have to send a command to clean them up or else they leaked.
07b86b52 918 */
15dc512a 919 if (!ksess->output_traces && ksess->consumer_fds_sent) {
07b86b52
JD
920 int ret;
921 struct consumer_socket *socket;
922 struct lttng_ht_iter iter;
923
924 /* For each consumer socket. */
d069d577 925 rcu_read_lock();
07b86b52
JD
926 cds_lfht_for_each_entry(ksess->consumer->socks->ht, &iter.iter,
927 socket, node.node) {
928 struct ltt_kernel_channel *chan;
929
930 /* For each channel, ask the consumer to destroy it. */
931 cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
932 ret = kernel_consumer_destroy_channel(socket, chan);
933 if (ret < 0) {
934 /* Consumer is probably dead. Use next socket. */
935 continue;
936 }
937 }
938 }
d069d577 939 rcu_read_unlock();
07b86b52
JD
940 }
941
2f77fc4b
DG
942 /* Close any relayd session */
943 consumer_output_send_destroy_relayd(ksess->consumer);
944
945 trace_kernel_destroy_session(ksess);
946}
fb5f35b6
DG
947
948/*
949 * Destroy a kernel channel object. It does not do anything on the tracer side.
950 */
951void kernel_destroy_channel(struct ltt_kernel_channel *kchan)
952{
953 struct ltt_kernel_session *ksess = NULL;
954
955 assert(kchan);
956 assert(kchan->channel);
957
958 DBG3("Kernel destroy channel %s", kchan->channel->name);
959
960 /* Update channel count of associated session. */
961 if (kchan->session) {
962 /* Keep pointer reference so we can update it after the destroy. */
963 ksess = kchan->session;
964 }
965
966 trace_kernel_destroy_channel(kchan);
967
968 /*
969 * At this point the kernel channel is not visible anymore. This is safe
970 * since in order to work on a visible kernel session, the tracing session
971 * lock (ltt_session.lock) MUST be acquired.
972 */
973 if (ksess) {
974 ksess->channel_count--;
975 }
976}
6dc3064a
DG
977
978/*
979 * Take a snapshot for a given kernel session.
980 *
2a06df8d 981 * Return 0 on success or else return a LTTNG_ERR code.
6dc3064a
DG
982 */
983int kernel_snapshot_record(struct ltt_kernel_session *ksess,
d07ceecd
MD
984 struct snapshot_output *output, int wait,
985 uint64_t nb_packets_per_stream)
6dc3064a 986{
2a06df8d 987 int err, ret, saved_metadata_fd;
6dc3064a
DG
988 struct consumer_socket *socket;
989 struct lttng_ht_iter iter;
990 struct ltt_kernel_metadata *saved_metadata;
991
992 assert(ksess);
993 assert(ksess->consumer);
994 assert(output);
995
996 DBG("Kernel snapshot record started");
997
998 /* Save current metadata since the following calls will change it. */
999 saved_metadata = ksess->metadata;
1000 saved_metadata_fd = ksess->metadata_stream_fd;
1001
1002 rcu_read_lock();
1003
1004 ret = kernel_open_metadata(ksess);
1005 if (ret < 0) {
1006 ret = LTTNG_ERR_KERN_META_FAIL;
1007 goto error;
1008 }
1009
1010 ret = kernel_open_metadata_stream(ksess);
1011 if (ret < 0) {
1012 ret = LTTNG_ERR_KERN_META_FAIL;
1013 goto error_open_stream;
1014 }
1015
1016 /* Send metadata to consumer and snapshot everything. */
1017 cds_lfht_for_each_entry(ksess->consumer->socks->ht, &iter.iter,
1018 socket, node.node) {
1019 struct consumer_output *saved_output;
1020 struct ltt_kernel_channel *chan;
6dc3064a
DG
1021
1022 /*
1023 * Temporarly switch consumer output for our snapshot output. As long
1024 * as the session lock is taken, this is safe.
1025 */
1026 saved_output = ksess->consumer;
1027 ksess->consumer = output->consumer;
1028
1029 pthread_mutex_lock(socket->lock);
1030 /* This stream must not be monitored by the consumer. */
07b86b52 1031 ret = kernel_consumer_add_metadata(socket, ksess, 0);
6dc3064a 1032 pthread_mutex_unlock(socket->lock);
07b86b52 1033 /* Put back the saved consumer output into the session. */
6dc3064a
DG
1034 ksess->consumer = saved_output;
1035 if (ret < 0) {
1036 ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
1037 goto error_consumer;
1038 }
1039
1040 /* For each channel, ask the consumer to snapshot it. */
1041 cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
0a28e553 1042 ret = consumer_snapshot_channel(socket, chan->key, output, 0,
5c786ded
JD
1043 ksess->uid, ksess->gid,
1044 DEFAULT_KERNEL_TRACE_DIR, wait,
d07ceecd 1045 nb_packets_per_stream);
6dc3064a
DG
1046 if (ret < 0) {
1047 ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
2a06df8d
DG
1048 (void) kernel_consumer_destroy_metadata(socket,
1049 ksess->metadata);
6dc3064a
DG
1050 goto error_consumer;
1051 }
1052 }
1053
1054 /* Snapshot metadata, */
1055 ret = consumer_snapshot_channel(socket, ksess->metadata->fd, output,
5c786ded 1056 1, ksess->uid, ksess->gid,
d07ceecd 1057 DEFAULT_KERNEL_TRACE_DIR, wait, 0);
6dc3064a
DG
1058 if (ret < 0) {
1059 ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
1060 goto error_consumer;
1061 }
07b86b52
JD
1062
1063 /*
1064 * The metadata snapshot is done, ask the consumer to destroy it since
1065 * it's not monitored on the consumer side.
1066 */
1067 (void) kernel_consumer_destroy_metadata(socket, ksess->metadata);
6dc3064a
DG
1068 }
1069
fac41e72
DG
1070 ret = LTTNG_OK;
1071
6dc3064a
DG
1072error_consumer:
1073 /* Close newly opened metadata stream. It's now on the consumer side. */
2a06df8d
DG
1074 err = close(ksess->metadata_stream_fd);
1075 if (err < 0) {
6dc3064a
DG
1076 PERROR("close snapshot kernel");
1077 }
1078
1079error_open_stream:
1080 trace_kernel_destroy_metadata(ksess->metadata);
1081error:
1082 /* Restore metadata state.*/
1083 ksess->metadata = saved_metadata;
1084 ksess->metadata_stream_fd = saved_metadata_fd;
1085
1086 rcu_read_unlock();
1087 return ret;
1088}
834978fd
DG
1089
1090/*
1091 * Get the syscall mask array from the kernel tracer.
1092 *
1093 * Return 0 on success else a negative value. In both case, syscall_mask should
1094 * be freed.
1095 */
1096int kernel_syscall_mask(int chan_fd, char **syscall_mask, uint32_t *nr_bits)
1097{
1098 assert(syscall_mask);
1099 assert(nr_bits);
1100
1101 return kernctl_syscall_mask(chan_fd, syscall_mask, nr_bits);
1102}
6e21424e
JR
1103
1104/*
1105 * Check for the support of the RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS via abi
1106 * version number.
1107 *
1108 * Return 1 on success, 0 when feature is not supported, negative value in case
1109 * of errors.
1110 */
1111int kernel_supports_ring_buffer_snapshot_sample_positions(int tracer_fd)
1112{
1113 int ret = 0; // Not supported by default
1114 struct lttng_kernel_tracer_abi_version abi;
1115
1116 ret = kernctl_tracer_abi_version(tracer_fd, &abi);
1117 if (ret < 0) {
1118 ERR("Failed to retrieve lttng-modules ABI version");
1119 goto error;
1120 }
1121
1122 /*
1123 * RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS was introduced in 2.3
1124 */
1125 if (abi.major >= 2 && abi.minor >= 3) {
1126 /* Supported */
1127 ret = 1;
1128 } else {
1129 /* Not supported */
1130 ret = 0;
1131 }
1132error:
1133 return ret;
1134}
This page took 0.128511 seconds and 5 git commands to generate.