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