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