Sessiond timer thread
[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;
d40f0359 538 lkm->key = ++next_kernel_channel_key;
7b395890
DG
539 /* Prevent fd duplication after execlp() */
540 ret = fcntl(lkm->fd, F_SETFD, FD_CLOEXEC);
541 if (ret < 0) {
df0f840b 542 PERROR("fcntl session fd");
7b395890
DG
543 }
544
aaf26714 545 session->metadata = lkm;
8c0faa1d 546
00e2e675 547 DBG("Kernel metadata opened (fd: %d)", lkm->fd);
8c0faa1d
DG
548
549 return 0;
550
74024a21
DG
551error_open:
552 trace_kernel_destroy_metadata(lkm);
8c0faa1d 553error:
54012638 554 return -1;
8c0faa1d
DG
555}
556
557/*
050349bb 558 * Start tracing session.
8c0faa1d
DG
559 */
560int kernel_start_session(struct ltt_kernel_session *session)
561{
562 int ret;
563
0525e9ae
DG
564 assert(session);
565
8c0faa1d
DG
566 ret = kernctl_start_session(session->fd);
567 if (ret < 0) {
df0f840b 568 PERROR("ioctl start session");
8c0faa1d
DG
569 goto error;
570 }
571
572 DBG("Kernel session started");
573
574 return 0;
575
576error:
577 return ret;
578}
579
f3ed775e 580/*
050349bb 581 * Make a kernel wait to make sure in-flight probe have completed.
f3ed775e
DG
582 */
583void kernel_wait_quiescent(int fd)
584{
585 int ret;
586
587 DBG("Kernel quiescent wait on %d", fd);
588
589 ret = kernctl_wait_quiescent(fd);
590 if (ret < 0) {
df0f840b 591 PERROR("wait quiescent ioctl");
f3ed775e
DG
592 ERR("Kernel quiescent wait failed");
593 }
594}
595
596/*
f3ed775e
DG
597 * Force flush buffer of metadata.
598 */
599int kernel_metadata_flush_buffer(int fd)
600{
601 int ret;
602
169d2cb7
DG
603 DBG("Kernel flushing metadata buffer on fd %d", fd);
604
f3ed775e
DG
605 ret = kernctl_buffer_flush(fd);
606 if (ret < 0) {
00e2e675 607 ERR("Fail to flush metadata buffers %d (ret: %d)", fd, ret);
f3ed775e
DG
608 }
609
610 return 0;
611}
612
613/*
050349bb 614 * Force flush buffer for channel.
f3ed775e
DG
615 */
616int kernel_flush_buffer(struct ltt_kernel_channel *channel)
617{
618 int ret;
619 struct ltt_kernel_stream *stream;
620
0525e9ae
DG
621 assert(channel);
622
f3ed775e
DG
623 DBG("Flush buffer for channel %s", channel->channel->name);
624
625 cds_list_for_each_entry(stream, &channel->stream_list.head, list) {
626 DBG("Flushing channel stream %d", stream->fd);
627 ret = kernctl_buffer_flush(stream->fd);
628 if (ret < 0) {
df0f840b 629 PERROR("ioctl");
f3ed775e
DG
630 ERR("Fail to flush buffer for stream %d (ret: %d)",
631 stream->fd, ret);
632 }
633 }
634
635 return 0;
636}
637
8c0faa1d 638/*
050349bb 639 * Stop tracing session.
8c0faa1d
DG
640 */
641int kernel_stop_session(struct ltt_kernel_session *session)
642{
643 int ret;
644
0525e9ae
DG
645 assert(session);
646
8c0faa1d
DG
647 ret = kernctl_stop_session(session->fd);
648 if (ret < 0) {
649 goto error;
650 }
651
652 DBG("Kernel session stopped");
653
654 return 0;
655
656error:
657 return ret;
658}
659
660/*
050349bb
DG
661 * Open stream of channel, register it to the kernel tracer and add it
662 * to the stream list of the channel.
8c0faa1d 663 *
1cfb4b98
MD
664 * Note: given that the streams may appear in random order wrt CPU
665 * number (e.g. cpu hotplug), the index value of the stream number in
666 * the stream name is not necessarily linked to the CPU number.
667 *
050349bb 668 * Return the number of created stream. Else, a negative value.
8c0faa1d 669 */
f3ed775e 670int kernel_open_channel_stream(struct ltt_kernel_channel *channel)
8c0faa1d 671{
1cfb4b98 672 int ret;
8c0faa1d
DG
673 struct ltt_kernel_stream *lks;
674
0525e9ae
DG
675 assert(channel);
676
5a47c6a2 677 while ((ret = kernctl_create_stream(channel->fd)) >= 0) {
1cfb4b98
MD
678 lks = trace_kernel_create_stream(channel->channel->name,
679 channel->stream_count);
8c0faa1d 680 if (lks == NULL) {
799e2c4f
MD
681 ret = close(ret);
682 if (ret) {
683 PERROR("close");
684 }
8c0faa1d
DG
685 goto error;
686 }
687
688 lks->fd = ret;
7b395890
DG
689 /* Prevent fd duplication after execlp() */
690 ret = fcntl(lks->fd, F_SETFD, FD_CLOEXEC);
691 if (ret < 0) {
df0f840b 692 PERROR("fcntl session fd");
7b395890
DG
693 }
694
1624d5b7
JD
695 lks->tracefile_size = channel->channel->attr.tracefile_size;
696 lks->tracefile_count = channel->channel->attr.tracefile_count;
697
1cfb4b98 698 /* Add stream to channel stream list */
8c0faa1d
DG
699 cds_list_add(&lks->list, &channel->stream_list.head);
700 channel->stream_count++;
8c0faa1d 701
00e2e675
DG
702 DBG("Kernel stream %s created (fd: %d, state: %d)", lks->name, lks->fd,
703 lks->state);
54012638 704 }
8c0faa1d
DG
705
706 return channel->stream_count;
707
708error:
54012638 709 return -1;
8c0faa1d
DG
710}
711
712/*
050349bb 713 * Open the metadata stream and set it to the kernel session.
8c0faa1d 714 */
f3ed775e 715int kernel_open_metadata_stream(struct ltt_kernel_session *session)
8c0faa1d
DG
716{
717 int ret;
718
0525e9ae
DG
719 assert(session);
720
8c0faa1d
DG
721 ret = kernctl_create_stream(session->metadata->fd);
722 if (ret < 0) {
df0f840b 723 PERROR("kernel create metadata stream");
8c0faa1d
DG
724 goto error;
725 }
726
727 DBG("Kernel metadata stream created (fd: %d)", ret);
728 session->metadata_stream_fd = ret;
7b395890
DG
729 /* Prevent fd duplication after execlp() */
730 ret = fcntl(session->metadata_stream_fd, F_SETFD, FD_CLOEXEC);
731 if (ret < 0) {
df0f840b 732 PERROR("fcntl session fd");
7b395890 733 }
aaf26714
DG
734
735 return 0;
736
737error:
54012638 738 return -1;
aaf26714 739}
2ef84c95
DG
740
741/*
9f19cc17 742 * Get the event list from the kernel tracer and return the number of elements.
2ef84c95 743 */
9f19cc17 744ssize_t kernel_list_events(int tracer_fd, struct lttng_event **events)
2ef84c95 745{
53efb85a 746 int fd, ret;
9f19cc17
DG
747 char *event;
748 size_t nbmem, count = 0;
2ef84c95 749 FILE *fp;
9f19cc17 750 struct lttng_event *elist;
2ef84c95 751
0525e9ae
DG
752 assert(events);
753
2ef84c95
DG
754 fd = kernctl_tracepoint_list(tracer_fd);
755 if (fd < 0) {
df0f840b 756 PERROR("kernel tracepoint list");
2ef84c95
DG
757 goto error;
758 }
759
760 fp = fdopen(fd, "r");
761 if (fp == NULL) {
df0f840b 762 PERROR("kernel tracepoint list fdopen");
61b73b12 763 goto error_fp;
2ef84c95
DG
764 }
765
766 /*
767 * Init memory size counter
768 * See kernel-ctl.h for explanation of this value
769 */
6725fe19 770 nbmem = KERNEL_EVENT_INIT_LIST_SIZE;
ba7f0ae5 771 elist = zmalloc(sizeof(struct lttng_event) * nbmem);
3b870559
MD
772 if (elist == NULL) {
773 PERROR("alloc list events");
774 count = -ENOMEM;
775 goto end;
776 }
2ef84c95 777
53efb85a 778 while (fscanf(fp, "event { name = %m[^;]; };\n", &event) == 1) {
6725fe19 779 if (count >= nbmem) {
3b870559 780 struct lttng_event *new_elist;
53efb85a 781 size_t new_nbmem;
3b870559 782
53efb85a
MD
783 new_nbmem = nbmem << 1;
784 DBG("Reallocating event list from %zu to %zu bytes",
785 nbmem, new_nbmem);
786 new_elist = realloc(elist, new_nbmem * sizeof(struct lttng_event));
3b870559 787 if (new_elist == NULL) {
df0f840b 788 PERROR("realloc list events");
3b870559
MD
789 free(event);
790 free(elist);
61b73b12
MD
791 count = -ENOMEM;
792 goto end;
2ef84c95 793 }
53efb85a
MD
794 /* Zero the new memory */
795 memset(new_elist + nbmem, 0,
796 (new_nbmem - nbmem) * sizeof(struct lttng_event));
797 nbmem = new_nbmem;
3b870559 798 elist = new_elist;
2ef84c95 799 }
99497cd0
MD
800 strncpy(elist[count].name, event, LTTNG_SYMBOL_NAME_LEN);
801 elist[count].name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
67b9d018 802 elist[count].enabled = -1;
9f19cc17 803 count++;
3b870559 804 free(event);
2ef84c95
DG
805 }
806
9f19cc17 807 *events = elist;
ced2f820 808 DBG("Kernel list events done (%zu events)", count);
61b73b12 809end:
799e2c4f
MD
810 ret = fclose(fp); /* closes both fp and fd */
811 if (ret) {
812 PERROR("fclose");
813 }
9f19cc17 814 return count;
2ef84c95 815
61b73b12 816error_fp:
799e2c4f
MD
817 ret = close(fd);
818 if (ret) {
819 PERROR("close");
820 }
2ef84c95
DG
821error:
822 return -1;
823}
096102bd
DG
824
825/*
826 * Get kernel version and validate it.
827 */
88076e89
JD
828int kernel_validate_version(int tracer_fd,
829 struct lttng_kernel_tracer_version *version,
830 struct lttng_kernel_tracer_abi_version *abi_version)
096102bd
DG
831{
832 int ret;
096102bd 833
88076e89 834 ret = kernctl_tracer_version(tracer_fd, version);
096102bd 835 if (ret < 0) {
521dd134 836 ERR("Failed to retrieve the lttng-modules version");
096102bd
DG
837 goto error;
838 }
839
840 /* Validate version */
88076e89 841 if (version->major != VERSION_MAJOR) {
c052142c 842 ERR("Kernel tracer major version (%d) is not compatible with lttng-tools major version (%d)",
88076e89 843 version->major, VERSION_MAJOR);
096102bd 844 goto error_version;
096102bd 845 }
88076e89 846 ret = kernctl_tracer_abi_version(tracer_fd, abi_version);
c052142c 847 if (ret < 0) {
521dd134 848 ERR("Failed to retrieve lttng-modules ABI version");
c052142c
MD
849 goto error;
850 }
88076e89 851 if (abi_version->major != LTTNG_MODULES_ABI_MAJOR_VERSION) {
521dd134 852 ERR("Kernel tracer ABI version (%d.%d) does not match the expected ABI major version (%d.*)",
88076e89 853 abi_version->major, abi_version->minor,
c052142c
MD
854 LTTNG_MODULES_ABI_MAJOR_VERSION);
855 goto error;
856 }
857 DBG2("Kernel tracer version validated (%d.%d, ABI %d.%d)",
88076e89
JD
858 version->major, version->minor,
859 abi_version->major, abi_version->minor);
096102bd
DG
860 return 0;
861
862error_version:
096102bd
DG
863 ret = -1;
864
865error:
521dd134 866 ERR("Kernel tracer version check failed; kernel tracing will not be available");
096102bd
DG
867 return ret;
868}
335a95b7
MD
869
870/*
871 * Kernel work-arounds called at the start of sessiond main().
872 */
873int init_kernel_workarounds(void)
874{
8936c33a 875 int ret;
335a95b7
MD
876 FILE *fp;
877
878 /*
879 * boot_id needs to be read once before being used concurrently
880 * to deal with a Linux kernel race. A fix is proposed for
881 * upstream, but the work-around is needed for older kernels.
882 */
883 fp = fopen("/proc/sys/kernel/random/boot_id", "r");
884 if (!fp) {
885 goto end_boot_id;
886 }
887 while (!feof(fp)) {
888 char buf[37] = "";
889
8936c33a
DG
890 ret = fread(buf, 1, sizeof(buf), fp);
891 if (ret < 0) {
892 /* Ignore error, we don't really care */
893 }
335a95b7 894 }
799e2c4f
MD
895 ret = fclose(fp);
896 if (ret) {
897 PERROR("fclose");
898 }
335a95b7 899end_boot_id:
335a95b7
MD
900 return 0;
901}
2f77fc4b
DG
902
903/*
904 * Complete teardown of a kernel session.
905 */
906void kernel_destroy_session(struct ltt_kernel_session *ksess)
907{
908 if (ksess == NULL) {
909 DBG3("No kernel session when tearing down session");
910 return;
911 }
912
913 DBG("Tearing down kernel session");
914
07b86b52 915 /*
15dc512a
DG
916 * Destroy channels on the consumer if at least one FD has been sent and we
917 * are in no output mode because the streams are in *no* monitor mode so we
918 * have to send a command to clean them up or else they leaked.
07b86b52 919 */
15dc512a 920 if (!ksess->output_traces && ksess->consumer_fds_sent) {
07b86b52
JD
921 int ret;
922 struct consumer_socket *socket;
923 struct lttng_ht_iter iter;
924
925 /* For each consumer socket. */
d069d577 926 rcu_read_lock();
07b86b52
JD
927 cds_lfht_for_each_entry(ksess->consumer->socks->ht, &iter.iter,
928 socket, node.node) {
929 struct ltt_kernel_channel *chan;
930
931 /* For each channel, ask the consumer to destroy it. */
932 cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
933 ret = kernel_consumer_destroy_channel(socket, chan);
934 if (ret < 0) {
935 /* Consumer is probably dead. Use next socket. */
936 continue;
937 }
938 }
939 }
d069d577 940 rcu_read_unlock();
07b86b52
JD
941 }
942
2f77fc4b
DG
943 /* Close any relayd session */
944 consumer_output_send_destroy_relayd(ksess->consumer);
945
946 trace_kernel_destroy_session(ksess);
947}
fb5f35b6
DG
948
949/*
950 * Destroy a kernel channel object. It does not do anything on the tracer side.
951 */
952void kernel_destroy_channel(struct ltt_kernel_channel *kchan)
953{
954 struct ltt_kernel_session *ksess = NULL;
955
956 assert(kchan);
957 assert(kchan->channel);
958
959 DBG3("Kernel destroy channel %s", kchan->channel->name);
960
961 /* Update channel count of associated session. */
962 if (kchan->session) {
963 /* Keep pointer reference so we can update it after the destroy. */
964 ksess = kchan->session;
965 }
966
967 trace_kernel_destroy_channel(kchan);
968
969 /*
970 * At this point the kernel channel is not visible anymore. This is safe
971 * since in order to work on a visible kernel session, the tracing session
972 * lock (ltt_session.lock) MUST be acquired.
973 */
974 if (ksess) {
975 ksess->channel_count--;
976 }
977}
6dc3064a
DG
978
979/*
980 * Take a snapshot for a given kernel session.
981 *
2a06df8d 982 * Return 0 on success or else return a LTTNG_ERR code.
6dc3064a
DG
983 */
984int kernel_snapshot_record(struct ltt_kernel_session *ksess,
d07ceecd
MD
985 struct snapshot_output *output, int wait,
986 uint64_t nb_packets_per_stream)
6dc3064a 987{
2a06df8d 988 int err, ret, saved_metadata_fd;
6dc3064a
DG
989 struct consumer_socket *socket;
990 struct lttng_ht_iter iter;
991 struct ltt_kernel_metadata *saved_metadata;
992
993 assert(ksess);
994 assert(ksess->consumer);
995 assert(output);
996
997 DBG("Kernel snapshot record started");
998
999 /* Save current metadata since the following calls will change it. */
1000 saved_metadata = ksess->metadata;
1001 saved_metadata_fd = ksess->metadata_stream_fd;
1002
1003 rcu_read_lock();
1004
1005 ret = kernel_open_metadata(ksess);
1006 if (ret < 0) {
1007 ret = LTTNG_ERR_KERN_META_FAIL;
1008 goto error;
1009 }
1010
1011 ret = kernel_open_metadata_stream(ksess);
1012 if (ret < 0) {
1013 ret = LTTNG_ERR_KERN_META_FAIL;
1014 goto error_open_stream;
1015 }
1016
1017 /* Send metadata to consumer and snapshot everything. */
1018 cds_lfht_for_each_entry(ksess->consumer->socks->ht, &iter.iter,
1019 socket, node.node) {
1020 struct consumer_output *saved_output;
1021 struct ltt_kernel_channel *chan;
6dc3064a
DG
1022
1023 /*
1024 * Temporarly switch consumer output for our snapshot output. As long
1025 * as the session lock is taken, this is safe.
1026 */
1027 saved_output = ksess->consumer;
1028 ksess->consumer = output->consumer;
1029
1030 pthread_mutex_lock(socket->lock);
1031 /* This stream must not be monitored by the consumer. */
07b86b52 1032 ret = kernel_consumer_add_metadata(socket, ksess, 0);
6dc3064a 1033 pthread_mutex_unlock(socket->lock);
07b86b52 1034 /* Put back the saved consumer output into the session. */
6dc3064a
DG
1035 ksess->consumer = saved_output;
1036 if (ret < 0) {
1037 ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
1038 goto error_consumer;
1039 }
1040
1041 /* For each channel, ask the consumer to snapshot it. */
1042 cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
0a28e553 1043 ret = consumer_snapshot_channel(socket, chan->key, output, 0,
5c786ded
JD
1044 ksess->uid, ksess->gid,
1045 DEFAULT_KERNEL_TRACE_DIR, wait,
d07ceecd 1046 nb_packets_per_stream);
6dc3064a
DG
1047 if (ret < 0) {
1048 ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
2a06df8d
DG
1049 (void) kernel_consumer_destroy_metadata(socket,
1050 ksess->metadata);
6dc3064a
DG
1051 goto error_consumer;
1052 }
1053 }
1054
1055 /* Snapshot metadata, */
d40f0359 1056 ret = consumer_snapshot_channel(socket, ksess->metadata->key, output,
5c786ded 1057 1, ksess->uid, ksess->gid,
d07ceecd 1058 DEFAULT_KERNEL_TRACE_DIR, wait, 0);
6dc3064a
DG
1059 if (ret < 0) {
1060 ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
1061 goto error_consumer;
1062 }
07b86b52
JD
1063
1064 /*
1065 * The metadata snapshot is done, ask the consumer to destroy it since
1066 * it's not monitored on the consumer side.
1067 */
1068 (void) kernel_consumer_destroy_metadata(socket, ksess->metadata);
6dc3064a
DG
1069 }
1070
fac41e72
DG
1071 ret = LTTNG_OK;
1072
6dc3064a
DG
1073error_consumer:
1074 /* Close newly opened metadata stream. It's now on the consumer side. */
2a06df8d
DG
1075 err = close(ksess->metadata_stream_fd);
1076 if (err < 0) {
6dc3064a
DG
1077 PERROR("close snapshot kernel");
1078 }
1079
1080error_open_stream:
1081 trace_kernel_destroy_metadata(ksess->metadata);
1082error:
1083 /* Restore metadata state.*/
1084 ksess->metadata = saved_metadata;
1085 ksess->metadata_stream_fd = saved_metadata_fd;
1086
1087 rcu_read_unlock();
1088 return ret;
1089}
834978fd
DG
1090
1091/*
1092 * Get the syscall mask array from the kernel tracer.
1093 *
1094 * Return 0 on success else a negative value. In both case, syscall_mask should
1095 * be freed.
1096 */
1097int kernel_syscall_mask(int chan_fd, char **syscall_mask, uint32_t *nr_bits)
1098{
1099 assert(syscall_mask);
1100 assert(nr_bits);
1101
1102 return kernctl_syscall_mask(chan_fd, syscall_mask, nr_bits);
1103}
6e21424e
JR
1104
1105/*
1106 * Check for the support of the RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS via abi
1107 * version number.
1108 *
1109 * Return 1 on success, 0 when feature is not supported, negative value in case
1110 * of errors.
1111 */
1112int kernel_supports_ring_buffer_snapshot_sample_positions(int tracer_fd)
1113{
1114 int ret = 0; // Not supported by default
1115 struct lttng_kernel_tracer_abi_version abi;
1116
1117 ret = kernctl_tracer_abi_version(tracer_fd, &abi);
1118 if (ret < 0) {
1119 ERR("Failed to retrieve lttng-modules ABI version");
1120 goto error;
1121 }
1122
1123 /*
1124 * RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS was introduced in 2.3
1125 */
1126 if (abi.major >= 2 && abi.minor >= 3) {
1127 /* Supported */
1128 ret = 1;
1129 } else {
1130 /* Not supported */
1131 ret = 0;
1132 }
1133error:
1134 return ret;
1135}
This page took 0.114106 seconds and 4 git commands to generate.