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