Contexts for RT debugging
[lttng-tools.git] / src / bin / lttng-sessiond / kernel.c
1 /*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
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.
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 *
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.
16 */
17
18 #define _LGPL_SOURCE
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <inttypes.h>
26
27 #include <common/common.h>
28 #include <common/kernel-ctl/kernel-ctl.h>
29 #include <common/kernel-ctl/kernel-ioctl.h>
30 #include <common/sessiond-comm/sessiond-comm.h>
31
32 #include "consumer.h"
33 #include "kernel.h"
34 #include "kernel-consumer.h"
35 #include "kern-modules.h"
36 #include "utils.h"
37
38 /*
39 * Add context on a kernel channel.
40 */
41 int kernel_add_channel_context(struct ltt_kernel_channel *chan,
42 struct ltt_kernel_context *ctx)
43 {
44 int ret;
45
46 assert(chan);
47 assert(ctx);
48
49 DBG("Adding context to channel %s", chan->channel->name);
50 ret = kernctl_add_context(chan->fd, &ctx->ctx);
51 if (ret < 0) {
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:
58 /* If EEXIST, we just ignore the error */
59 ret = 0;
60 goto end;
61 default:
62 PERROR("add context ioctl");
63 ret = LTTNG_ERR_KERN_CONTEXT_FAIL;
64 goto error;
65 }
66 }
67
68 end:
69 cds_list_add_tail(&ctx->list, &chan->ctx_list);
70 return 0;
71
72 error:
73 return ret;
74 }
75
76 /*
77 * Create a new kernel session, register it to the kernel tracer and add it to
78 * the session daemon session.
79 */
80 int kernel_create_session(struct ltt_session *session, int tracer_fd)
81 {
82 int ret;
83 struct ltt_kernel_session *lks;
84
85 assert(session);
86
87 /* Allocate data structure */
88 lks = trace_kernel_create_session();
89 if (lks == NULL) {
90 ret = -1;
91 goto error;
92 }
93
94 /* Kernel tracer session creation */
95 ret = kernctl_create_session(tracer_fd);
96 if (ret < 0) {
97 PERROR("ioctl kernel create session");
98 goto error;
99 }
100
101 lks->fd = ret;
102 /* Prevent fd duplication after execlp() */
103 ret = fcntl(lks->fd, F_SETFD, FD_CLOEXEC);
104 if (ret < 0) {
105 PERROR("fcntl session fd");
106 }
107
108 lks->id = session->id;
109 lks->consumer_fds_sent = 0;
110 session->kernel_session = lks;
111
112 DBG("Kernel session created (fd: %d)", lks->fd);
113
114 return 0;
115
116 error:
117 if (lks) {
118 trace_kernel_destroy_session(lks);
119 }
120 return ret;
121 }
122
123 /*
124 * Create a kernel channel, register it to the kernel tracer and add it to the
125 * kernel session.
126 */
127 int kernel_create_channel(struct ltt_kernel_session *session,
128 struct lttng_channel *chan)
129 {
130 int ret;
131 struct ltt_kernel_channel *lkc;
132
133 assert(session);
134 assert(chan);
135
136 /* Allocate kernel channel */
137 lkc = trace_kernel_create_channel(chan);
138 if (lkc == NULL) {
139 goto error;
140 }
141
142 DBG3("Kernel create channel %s with attr: %d, %" PRIu64 ", %" PRIu64 ", %u, %u, %d, %d",
143 chan->name, lkc->channel->attr.overwrite,
144 lkc->channel->attr.subbuf_size, lkc->channel->attr.num_subbuf,
145 lkc->channel->attr.switch_timer_interval, lkc->channel->attr.read_timer_interval,
146 lkc->channel->attr.live_timer_interval, lkc->channel->attr.output);
147
148 /* Kernel tracer channel creation */
149 ret = kernctl_create_channel(session->fd, &lkc->channel->attr);
150 if (ret < 0) {
151 PERROR("ioctl kernel create channel");
152 goto error;
153 }
154
155 /* Setup the channel fd */
156 lkc->fd = ret;
157 /* Prevent fd duplication after execlp() */
158 ret = fcntl(lkc->fd, F_SETFD, FD_CLOEXEC);
159 if (ret < 0) {
160 PERROR("fcntl session fd");
161 }
162
163 /* Add channel to session */
164 cds_list_add(&lkc->list, &session->channel_list.head);
165 session->channel_count++;
166 lkc->session = session;
167
168 DBG("Kernel channel %s created (fd: %d)", lkc->channel->name, lkc->fd);
169
170 return 0;
171
172 error:
173 if (lkc) {
174 free(lkc->channel);
175 free(lkc);
176 }
177 return -1;
178 }
179
180 /*
181 * Create a kernel event, enable it to the kernel tracer and add it to the
182 * channel event list of the kernel session.
183 * We own filter_expression and filter.
184 */
185 int kernel_create_event(struct lttng_event *ev,
186 struct ltt_kernel_channel *channel,
187 char *filter_expression,
188 struct lttng_filter_bytecode *filter)
189 {
190 int ret;
191 struct ltt_kernel_event *event;
192
193 assert(ev);
194 assert(channel);
195
196 /* We pass ownership of filter_expression and filter */
197 event = trace_kernel_create_event(ev, filter_expression,
198 filter);
199 if (event == NULL) {
200 ret = -1;
201 goto error;
202 }
203
204 ret = kernctl_create_event(channel->fd, event->event);
205 if (ret < 0) {
206 switch (errno) {
207 case EEXIST:
208 break;
209 case ENOSYS:
210 WARN("Event type not implemented");
211 break;
212 case ENOENT:
213 WARN("Event %s not found!", ev->name);
214 break;
215 default:
216 PERROR("create event ioctl");
217 }
218 ret = -errno;
219 goto free_event;
220 }
221
222 event->type = ev->type;
223 event->fd = ret;
224 /* Prevent fd duplication after execlp() */
225 ret = fcntl(event->fd, F_SETFD, FD_CLOEXEC);
226 if (ret < 0) {
227 PERROR("fcntl session fd");
228 }
229
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
250 /* Add event to event list */
251 cds_list_add(&event->list, &channel->events_list.head);
252 channel->event_count++;
253
254 DBG("Event %s created (fd: %d)", ev->name, event->fd);
255
256 return 0;
257
258 enable_error:
259 filter_error:
260 {
261 int closeret;
262
263 closeret = close(event->fd);
264 if (closeret) {
265 PERROR("close event fd");
266 }
267 }
268 free_event:
269 free(event);
270 error:
271 return ret;
272 }
273
274 /*
275 * Disable a kernel channel.
276 */
277 int kernel_disable_channel(struct ltt_kernel_channel *chan)
278 {
279 int ret;
280
281 assert(chan);
282
283 ret = kernctl_disable(chan->fd);
284 if (ret < 0) {
285 PERROR("disable chan ioctl");
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
295 error:
296 return ret;
297 }
298
299 /*
300 * Enable a kernel channel.
301 */
302 int kernel_enable_channel(struct ltt_kernel_channel *chan)
303 {
304 int ret;
305
306 assert(chan);
307
308 ret = kernctl_enable(chan->fd);
309 if (ret < 0 && errno != EEXIST) {
310 PERROR("Enable kernel chan");
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
319 error:
320 return ret;
321 }
322
323 /*
324 * Enable a kernel event.
325 */
326 int kernel_enable_event(struct ltt_kernel_event *event)
327 {
328 int ret;
329
330 assert(event);
331
332 ret = kernctl_enable(event->fd);
333 if (ret < 0) {
334 switch (errno) {
335 case EEXIST:
336 ret = LTTNG_ERR_KERN_EVENT_EXIST;
337 break;
338 default:
339 PERROR("enable kernel event");
340 break;
341 }
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
350 error:
351 return ret;
352 }
353
354 /*
355 * Disable a kernel event.
356 */
357 int kernel_disable_event(struct ltt_kernel_event *event)
358 {
359 int ret;
360
361 assert(event);
362
363 ret = kernctl_disable(event->fd);
364 if (ret < 0) {
365 switch (errno) {
366 case EEXIST:
367 ret = LTTNG_ERR_KERN_EVENT_EXIST;
368 break;
369 default:
370 PERROR("disable kernel event");
371 break;
372 }
373 goto error;
374 }
375
376 event->enabled = 0;
377 DBG("Kernel event %s disabled (fd: %d)", event->event->name, event->fd);
378
379 return 0;
380
381 error:
382 return ret;
383 }
384
385
386 int kernel_track_pid(struct ltt_kernel_session *session, int pid)
387 {
388 int ret;
389
390 DBG("Kernel track PID %d for session id %" PRIu64 ".",
391 pid, session->id);
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 }
406 }
407
408 int kernel_untrack_pid(struct ltt_kernel_session *session, int pid)
409 {
410 int ret;
411
412 DBG("Kernel untrack PID %d for session id %" PRIu64 ".",
413 pid, session->id);
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 }
428 }
429
430 ssize_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);
485 end:
486 ret = fclose(fp); /* closes both fp and fd */
487 if (ret) {
488 PERROR("fclose");
489 }
490 return count;
491
492 error_fp:
493 ret = close(fd);
494 if (ret) {
495 PERROR("close");
496 }
497 error:
498 return -1;
499 }
500
501 /*
502 * Create kernel metadata, open from the kernel tracer and add it to the
503 * kernel session.
504 */
505 int kernel_open_metadata(struct ltt_kernel_session *session)
506 {
507 int ret;
508 struct ltt_kernel_metadata *lkm = NULL;
509
510 assert(session);
511
512 /* Allocate kernel metadata */
513 lkm = trace_kernel_create_metadata();
514 if (lkm == NULL) {
515 goto error;
516 }
517
518 /* Kernel tracer metadata creation */
519 ret = kernctl_open_metadata(session->fd, &lkm->conf->attr);
520 if (ret < 0) {
521 goto error_open;
522 }
523
524 lkm->fd = ret;
525 /* Prevent fd duplication after execlp() */
526 ret = fcntl(lkm->fd, F_SETFD, FD_CLOEXEC);
527 if (ret < 0) {
528 PERROR("fcntl session fd");
529 }
530
531 session->metadata = lkm;
532
533 DBG("Kernel metadata opened (fd: %d)", lkm->fd);
534
535 return 0;
536
537 error_open:
538 trace_kernel_destroy_metadata(lkm);
539 error:
540 return -1;
541 }
542
543 /*
544 * Start tracing session.
545 */
546 int kernel_start_session(struct ltt_kernel_session *session)
547 {
548 int ret;
549
550 assert(session);
551
552 ret = kernctl_start_session(session->fd);
553 if (ret < 0) {
554 PERROR("ioctl start session");
555 goto error;
556 }
557
558 DBG("Kernel session started");
559
560 return 0;
561
562 error:
563 return ret;
564 }
565
566 /*
567 * Make a kernel wait to make sure in-flight probe have completed.
568 */
569 void 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) {
577 PERROR("wait quiescent ioctl");
578 ERR("Kernel quiescent wait failed");
579 }
580 }
581
582 /*
583 * Kernel calibrate
584 */
585 int kernel_calibrate(int fd, struct lttng_kernel_calibrate *calibrate)
586 {
587 int ret;
588
589 assert(calibrate);
590
591 ret = kernctl_calibrate(fd, calibrate);
592 if (ret < 0) {
593 PERROR("calibrate ioctl");
594 return -1;
595 }
596
597 return 0;
598 }
599
600
601 /*
602 * Force flush buffer of metadata.
603 */
604 int kernel_metadata_flush_buffer(int fd)
605 {
606 int ret;
607
608 DBG("Kernel flushing metadata buffer on fd %d", fd);
609
610 ret = kernctl_buffer_flush(fd);
611 if (ret < 0) {
612 ERR("Fail to flush metadata buffers %d (ret: %d)", fd, ret);
613 }
614
615 return 0;
616 }
617
618 /*
619 * Force flush buffer for channel.
620 */
621 int kernel_flush_buffer(struct ltt_kernel_channel *channel)
622 {
623 int ret;
624 struct ltt_kernel_stream *stream;
625
626 assert(channel);
627
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) {
634 PERROR("ioctl");
635 ERR("Fail to flush buffer for stream %d (ret: %d)",
636 stream->fd, ret);
637 }
638 }
639
640 return 0;
641 }
642
643 /*
644 * Stop tracing session.
645 */
646 int kernel_stop_session(struct ltt_kernel_session *session)
647 {
648 int ret;
649
650 assert(session);
651
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
661 error:
662 return ret;
663 }
664
665 /*
666 * Open stream of channel, register it to the kernel tracer and add it
667 * to the stream list of the channel.
668 *
669 * Return the number of created stream. Else, a negative value.
670 */
671 int kernel_open_channel_stream(struct ltt_kernel_channel *channel)
672 {
673 int ret, count = 0;
674 struct ltt_kernel_stream *lks;
675
676 assert(channel);
677
678 while ((ret = kernctl_create_stream(channel->fd)) >= 0) {
679 lks = trace_kernel_create_stream(channel->channel->name, count);
680 if (lks == NULL) {
681 ret = close(ret);
682 if (ret) {
683 PERROR("close");
684 }
685 goto error;
686 }
687
688 lks->fd = ret;
689 /* Prevent fd duplication after execlp() */
690 ret = fcntl(lks->fd, F_SETFD, FD_CLOEXEC);
691 if (ret < 0) {
692 PERROR("fcntl session fd");
693 }
694
695 lks->tracefile_size = channel->channel->attr.tracefile_size;
696 lks->tracefile_count = channel->channel->attr.tracefile_count;
697
698 /* Add stream to channe stream list */
699 cds_list_add(&lks->list, &channel->stream_list.head);
700 channel->stream_count++;
701
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);
707 }
708
709 return channel->stream_count;
710
711 error:
712 return -1;
713 }
714
715 /*
716 * Open the metadata stream and set it to the kernel session.
717 */
718 int kernel_open_metadata_stream(struct ltt_kernel_session *session)
719 {
720 int ret;
721
722 assert(session);
723
724 ret = kernctl_create_stream(session->metadata->fd);
725 if (ret < 0) {
726 PERROR("kernel create metadata stream");
727 goto error;
728 }
729
730 DBG("Kernel metadata stream created (fd: %d)", ret);
731 session->metadata_stream_fd = ret;
732 /* Prevent fd duplication after execlp() */
733 ret = fcntl(session->metadata_stream_fd, F_SETFD, FD_CLOEXEC);
734 if (ret < 0) {
735 PERROR("fcntl session fd");
736 }
737
738 return 0;
739
740 error:
741 return -1;
742 }
743
744 /*
745 * Get the event list from the kernel tracer and return the number of elements.
746 */
747 ssize_t kernel_list_events(int tracer_fd, struct lttng_event **events)
748 {
749 int fd, ret;
750 char *event;
751 size_t nbmem, count = 0;
752 FILE *fp;
753 struct lttng_event *elist;
754
755 assert(events);
756
757 fd = kernctl_tracepoint_list(tracer_fd);
758 if (fd < 0) {
759 PERROR("kernel tracepoint list");
760 goto error;
761 }
762
763 fp = fdopen(fd, "r");
764 if (fp == NULL) {
765 PERROR("kernel tracepoint list fdopen");
766 goto error_fp;
767 }
768
769 /*
770 * Init memory size counter
771 * See kernel-ctl.h for explanation of this value
772 */
773 nbmem = KERNEL_EVENT_INIT_LIST_SIZE;
774 elist = zmalloc(sizeof(struct lttng_event) * nbmem);
775 if (elist == NULL) {
776 PERROR("alloc list events");
777 count = -ENOMEM;
778 goto end;
779 }
780
781 while (fscanf(fp, "event { name = %m[^;]; };\n", &event) == 1) {
782 if (count >= nbmem) {
783 struct lttng_event *new_elist;
784 size_t new_nbmem;
785
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));
790 if (new_elist == NULL) {
791 PERROR("realloc list events");
792 free(event);
793 free(elist);
794 count = -ENOMEM;
795 goto end;
796 }
797 /* Zero the new memory */
798 memset(new_elist + nbmem, 0,
799 (new_nbmem - nbmem) * sizeof(struct lttng_event));
800 nbmem = new_nbmem;
801 elist = new_elist;
802 }
803 strncpy(elist[count].name, event, LTTNG_SYMBOL_NAME_LEN);
804 elist[count].name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
805 elist[count].enabled = -1;
806 count++;
807 free(event);
808 }
809
810 *events = elist;
811 DBG("Kernel list events done (%zu events)", count);
812 end:
813 ret = fclose(fp); /* closes both fp and fd */
814 if (ret) {
815 PERROR("fclose");
816 }
817 return count;
818
819 error_fp:
820 ret = close(fd);
821 if (ret) {
822 PERROR("close");
823 }
824 error:
825 return -1;
826 }
827
828 /*
829 * Get kernel version and validate it.
830 */
831 int kernel_validate_version(int tracer_fd)
832 {
833 int ret;
834 struct lttng_kernel_tracer_version version;
835 struct lttng_kernel_tracer_abi_version abi_version;
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 */
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);
847 goto error_version;
848 }
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);
863 return 0;
864
865 error_version:
866 ret = -1;
867
868 error:
869 return ret;
870 }
871
872 /*
873 * Kernel work-arounds called at the start of sessiond main().
874 */
875 int init_kernel_workarounds(void)
876 {
877 int ret;
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
892 ret = fread(buf, 1, sizeof(buf), fp);
893 if (ret < 0) {
894 /* Ignore error, we don't really care */
895 }
896 }
897 ret = fclose(fp);
898 if (ret) {
899 PERROR("fclose");
900 }
901 end_boot_id:
902 return 0;
903 }
904
905 /*
906 * Complete teardown of a kernel session.
907 */
908 void 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
917 /*
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.
921 */
922 if (!ksess->output_traces && ksess->consumer_fds_sent) {
923 int ret;
924 struct consumer_socket *socket;
925 struct lttng_ht_iter iter;
926
927 /* For each consumer socket. */
928 rcu_read_lock();
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 }
942 rcu_read_unlock();
943 }
944
945 /* Close any relayd session */
946 consumer_output_send_destroy_relayd(ksess->consumer);
947
948 trace_kernel_destroy_session(ksess);
949 }
950
951 /*
952 * Destroy a kernel channel object. It does not do anything on the tracer side.
953 */
954 void 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 }
980
981 /*
982 * Take a snapshot for a given kernel session.
983 *
984 * Return 0 on success or else return a LTTNG_ERR code.
985 */
986 int kernel_snapshot_record(struct ltt_kernel_session *ksess,
987 struct snapshot_output *output, int wait,
988 uint64_t nb_packets_per_stream)
989 {
990 int err, ret, saved_metadata_fd;
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;
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. */
1034 ret = kernel_consumer_add_metadata(socket, ksess, 0);
1035 pthread_mutex_unlock(socket->lock);
1036 /* Put back the saved consumer output into the session. */
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) {
1045 pthread_mutex_lock(socket->lock);
1046 ret = consumer_snapshot_channel(socket, chan->fd, output, 0,
1047 ksess->uid, ksess->gid,
1048 DEFAULT_KERNEL_TRACE_DIR, wait,
1049 nb_packets_per_stream);
1050 pthread_mutex_unlock(socket->lock);
1051 if (ret < 0) {
1052 ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
1053 (void) kernel_consumer_destroy_metadata(socket,
1054 ksess->metadata);
1055 goto error_consumer;
1056 }
1057 }
1058
1059 /* Snapshot metadata, */
1060 pthread_mutex_lock(socket->lock);
1061 ret = consumer_snapshot_channel(socket, ksess->metadata->fd, output,
1062 1, ksess->uid, ksess->gid,
1063 DEFAULT_KERNEL_TRACE_DIR, wait, 0);
1064 pthread_mutex_unlock(socket->lock);
1065 if (ret < 0) {
1066 ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
1067 goto error_consumer;
1068 }
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);
1075 }
1076
1077 ret = LTTNG_OK;
1078
1079 error_consumer:
1080 /* Close newly opened metadata stream. It's now on the consumer side. */
1081 err = close(ksess->metadata_stream_fd);
1082 if (err < 0) {
1083 PERROR("close snapshot kernel");
1084 }
1085
1086 error_open_stream:
1087 trace_kernel_destroy_metadata(ksess->metadata);
1088 error:
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 }
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 */
1103 int 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.088323 seconds and 4 git commands to generate.