Update version to 0.16
[ust.git] / libust / tracectl.c
... / ...
CommitLineData
1/* Copyright (C) 2009 Pierre-Marc Fournier
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library 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 GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18/* This file contains the implementation of the UST listener thread, which
19 * receives trace control commands. It also coordinates the initialization of
20 * libust.
21 */
22
23#define _GNU_SOURCE
24#define _LGPL_SOURCE
25#include <stdio.h>
26#include <stdlib.h>
27#include <stdint.h>
28#include <pthread.h>
29#include <signal.h>
30#include <sys/epoll.h>
31#include <sys/time.h>
32#include <sys/types.h>
33#include <sys/socket.h>
34#include <fcntl.h>
35#include <poll.h>
36#include <regex.h>
37#include <urcu/uatomic.h>
38#include <urcu/list.h>
39
40#include <ust/marker.h>
41#include <ust/tracepoint.h>
42#include <ust/tracepoint-internal.h>
43#include <ust/tracectl.h>
44#include <ust/clock.h>
45#include "tracer.h"
46#include "usterr_signal_safe.h"
47#include "ustcomm.h"
48#include "buffers.h"
49#include "marker-control.h"
50
51/* This should only be accessed by the constructor, before the creation
52 * of the listener, and then only by the listener.
53 */
54s64 pidunique = -1LL;
55
56/* The process pid is used to detect a non-traceable fork
57 * and allow the non-traceable fork to be ignored
58 * by destructor sequences in libust
59 */
60static pid_t processpid = 0;
61
62static struct ustcomm_header _receive_header;
63static struct ustcomm_header *receive_header = &_receive_header;
64static char receive_buffer[USTCOMM_BUFFER_SIZE];
65static char send_buffer[USTCOMM_BUFFER_SIZE];
66
67static int epoll_fd;
68
69/*
70 * Listener thread data vs fork() protection mechanism. Ensures that no listener
71 * thread mutexes and data structures are being concurrently modified or held by
72 * other threads when fork() is executed.
73 */
74static pthread_mutex_t listener_thread_data_mutex = PTHREAD_MUTEX_INITIALIZER;
75
76/* Mutex protecting listen_sock. Nests inside listener_thread_data_mutex. */
77static pthread_mutex_t listen_sock_mutex = PTHREAD_MUTEX_INITIALIZER;
78static struct ustcomm_sock *listen_sock;
79
80extern struct chan_info_struct chan_infos[];
81
82static struct cds_list_head ust_socks = CDS_LIST_HEAD_INIT(ust_socks);
83
84/* volatile because shared between the listener and the main thread */
85int buffers_to_export = 0;
86
87int ust_clock_source;
88
89static long long make_pidunique(void)
90{
91 s64 retval;
92 struct timeval tv;
93
94 gettimeofday(&tv, NULL);
95
96 retval = tv.tv_sec;
97 retval <<= 32;
98 retval |= tv.tv_usec;
99
100 return retval;
101}
102
103static void print_ust_marker(FILE *fp)
104{
105 struct ust_marker_iter iter;
106
107 ust_marker_iter_reset(&iter);
108 ust_marker_iter_start(&iter);
109
110 while (iter.ust_marker) {
111 fprintf(fp, "ust_marker: %s/%s %d \"%s\" %p\n",
112 (*iter.ust_marker)->channel,
113 (*iter.ust_marker)->name,
114 (int)(*iter.ust_marker)->state,
115 (*iter.ust_marker)->format,
116 NULL); /*
117 * location is null for now, will be added
118 * to a different table.
119 */
120 ust_marker_iter_next(&iter);
121 }
122 ust_marker_iter_stop(&iter);
123}
124
125static void print_trace_events(FILE *fp)
126{
127 struct trace_event_iter iter;
128
129 trace_event_iter_reset(&iter);
130 trace_event_iter_start(&iter);
131
132 while (iter.trace_event) {
133 fprintf(fp, "trace_event: %s\n", (*iter.trace_event)->name);
134 trace_event_iter_next(&iter);
135 }
136 trace_event_iter_stop(&iter);
137}
138
139static int connect_ustconsumer(void)
140{
141 int result, fd;
142 char default_daemon_path[] = SOCK_DIR "/ustconsumer";
143 char *explicit_daemon_path, *daemon_path;
144
145 explicit_daemon_path = getenv("UST_DAEMON_SOCKET");
146 if (explicit_daemon_path) {
147 daemon_path = explicit_daemon_path;
148 } else {
149 daemon_path = default_daemon_path;
150 }
151
152 DBG("Connecting to daemon_path %s", daemon_path);
153
154 result = ustcomm_connect_path(daemon_path, &fd);
155 if (result < 0) {
156 WARN("connect_ustconsumer failed, daemon_path: %s",
157 daemon_path);
158 return result;
159 }
160
161 return fd;
162}
163
164
165static void request_buffer_consumer(int sock,
166 const char *trace,
167 const char *channel,
168 int cpu)
169{
170 struct ustcomm_header send_header, recv_header;
171 struct ustcomm_buffer_info buf_inf;
172 int result = 0;
173
174 result = ustcomm_pack_buffer_info(&send_header,
175 &buf_inf,
176 trace,
177 channel,
178 cpu);
179
180 if (result < 0) {
181 ERR("failed to pack buffer info message %s_%d",
182 channel, cpu);
183 return;
184 }
185
186 buf_inf.pid = getpid();
187 send_header.command = CONSUME_BUFFER;
188
189 result = ustcomm_req(sock, &send_header, (char *) &buf_inf,
190 &recv_header, NULL);
191 if (result <= 0) {
192 PERROR("request for buffer consumer failed, is the daemon online?");
193 }
194
195 return;
196}
197
198/* Ask the daemon to collect a trace called trace_name and being
199 * produced by this pid.
200 *
201 * The trace must be at least allocated. (It can also be started.)
202 * This is because _ltt_trace_find is used.
203 */
204
205static void inform_consumer_daemon(const char *trace_name)
206{
207 int sock, i,j;
208 struct ust_trace *trace;
209 const char *ch_name;
210
211 sock = connect_ustconsumer();
212 if (sock < 0) {
213 return;
214 }
215
216 DBG("Connected to ustconsumer");
217
218 ltt_lock_traces();
219
220 trace = _ltt_trace_find(trace_name);
221 if (trace == NULL) {
222 WARN("inform_consumer_daemon: could not find trace \"%s\"; it is probably already destroyed", trace_name);
223 goto unlock_traces;
224 }
225
226 for (i=0; i < trace->nr_channels; i++) {
227 if (trace->channels[i].request_collection) {
228 /* iterate on all cpus */
229 for (j=0; j<trace->channels[i].n_cpus; j++) {
230 ch_name = trace->channels[i].channel_name;
231 request_buffer_consumer(sock, trace_name,
232 ch_name, j);
233 CMM_STORE_SHARED(buffers_to_export,
234 CMM_LOAD_SHARED(buffers_to_export)+1);
235 }
236 }
237 }
238
239unlock_traces:
240 ltt_unlock_traces();
241
242 close(sock);
243}
244
245static struct ust_channel *find_channel(const char *ch_name,
246 struct ust_trace *trace)
247{
248 int i;
249
250 for (i=0; i<trace->nr_channels; i++) {
251 if (!strcmp(trace->channels[i].channel_name, ch_name)) {
252 return &trace->channels[i];
253 }
254 }
255
256 return NULL;
257}
258
259static int get_buffer_shmid_pipe_fd(const char *trace_name, const char *ch_name,
260 int ch_cpu,
261 int *buf_shmid,
262 int *buf_struct_shmid,
263 int *buf_pipe_fd)
264{
265 struct ust_trace *trace;
266 struct ust_channel *channel;
267 struct ust_buffer *buf;
268
269 DBG("get_buffer_shmid_pipe_fd");
270
271 ltt_lock_traces();
272 trace = _ltt_trace_find(trace_name);
273 ltt_unlock_traces();
274
275 if (trace == NULL) {
276 ERR("cannot find trace!");
277 return -ENODATA;
278 }
279
280 channel = find_channel(ch_name, trace);
281 if (!channel) {
282 ERR("cannot find channel %s!", ch_name);
283 return -ENODATA;
284 }
285
286 buf = channel->buf[ch_cpu];
287
288 *buf_shmid = buf->shmid;
289 *buf_struct_shmid = channel->buf_struct_shmids[ch_cpu];
290 *buf_pipe_fd = buf->data_ready_fd_read;
291
292 return 0;
293}
294
295static int get_subbuf_num_size(const char *trace_name, const char *ch_name,
296 int *num, int *size)
297{
298 struct ust_trace *trace;
299 struct ust_channel *channel;
300
301 DBG("get_subbuf_size");
302
303 ltt_lock_traces();
304 trace = _ltt_trace_find(trace_name);
305 ltt_unlock_traces();
306
307 if (!trace) {
308 ERR("cannot find trace!");
309 return -ENODATA;
310 }
311
312 channel = find_channel(ch_name, trace);
313 if (!channel) {
314 ERR("unable to find channel");
315 return -ENODATA;
316 }
317
318 *num = channel->subbuf_cnt;
319 *size = channel->subbuf_size;
320
321 return 0;
322}
323
324/* Return the power of two which is equal or higher to v */
325
326static unsigned int pow2_higher_or_eq(unsigned int v)
327{
328 int hb = fls(v);
329 int retval = 1<<(hb-1);
330
331 if (v-retval == 0)
332 return retval;
333 else
334 return retval<<1;
335}
336
337static int set_subbuf_size(const char *trace_name, const char *ch_name,
338 unsigned int size)
339{
340 unsigned int power;
341 int retval = 0;
342 struct ust_trace *trace;
343 struct ust_channel *channel;
344
345 DBG("set_subbuf_size");
346
347 power = pow2_higher_or_eq(size);
348 power = max_t(unsigned int, 2u, power);
349 if (power != size) {
350 WARN("using the next power of two for buffer size = %u\n", power);
351 }
352
353 ltt_lock_traces();
354 trace = _ltt_trace_find_setup(trace_name);
355 if (trace == NULL) {
356 ERR("cannot find trace!");
357 retval = -ENODATA;
358 goto unlock_traces;
359 }
360
361 channel = find_channel(ch_name, trace);
362 if (!channel) {
363 ERR("unable to find channel");
364 retval = -ENODATA;
365 goto unlock_traces;
366 }
367
368 channel->subbuf_size = power;
369 DBG("the set_subbuf_size for the requested channel is %zu", channel->subbuf_size);
370
371unlock_traces:
372 ltt_unlock_traces();
373
374 return retval;
375}
376
377static int set_subbuf_num(const char *trace_name, const char *ch_name,
378 unsigned int num)
379{
380 struct ust_trace *trace;
381 struct ust_channel *channel;
382 int retval = 0;
383
384 DBG("set_subbuf_num");
385
386 if (num < 2) {
387 ERR("subbuffer count should be greater than 2");
388 return -EINVAL;
389 }
390
391 ltt_lock_traces();
392 trace = _ltt_trace_find_setup(trace_name);
393 if (trace == NULL) {
394 ERR("cannot find trace!");
395 retval = -ENODATA;
396 goto unlock_traces;
397 }
398
399 channel = find_channel(ch_name, trace);
400 if (!channel) {
401 ERR("unable to find channel");
402 retval = -ENODATA;
403 goto unlock_traces;
404 }
405
406 channel->subbuf_cnt = num;
407 DBG("the set_subbuf_cnt for the requested channel is %u", channel->subbuf_cnt);
408
409unlock_traces:
410 ltt_unlock_traces();
411 return retval;
412}
413
414static int get_subbuffer(const char *trace_name, const char *ch_name,
415 int ch_cpu, long *consumed_old)
416{
417 int retval = 0;
418 struct ust_trace *trace;
419 struct ust_channel *channel;
420 struct ust_buffer *buf;
421
422 DBG("get_subbuf");
423
424 *consumed_old = 0;
425
426 ltt_lock_traces();
427 trace = _ltt_trace_find(trace_name);
428
429 if (!trace) {
430 DBG("Cannot find trace. It was likely destroyed by the user.");
431 retval = -ENODATA;
432 goto unlock_traces;
433 }
434
435 channel = find_channel(ch_name, trace);
436 if (!channel) {
437 ERR("unable to find channel");
438 retval = -ENODATA;
439 goto unlock_traces;
440 }
441
442 buf = channel->buf[ch_cpu];
443
444 retval = ust_buffers_get_subbuf(buf, consumed_old);
445 if (retval < 0) {
446 WARN("missed buffer?");
447 }
448
449unlock_traces:
450 ltt_unlock_traces();
451
452 return retval;
453}
454
455
456static int notify_buffer_mapped(const char *trace_name,
457 const char *ch_name,
458 int ch_cpu)
459{
460 int retval = 0;
461 struct ust_trace *trace;
462 struct ust_channel *channel;
463 struct ust_buffer *buf;
464
465 DBG("get_buffer_fd");
466
467 ltt_lock_traces();
468 trace = _ltt_trace_find(trace_name);
469
470 if (!trace) {
471 retval = -ENODATA;
472 DBG("Cannot find trace. It was likely destroyed by the user.");
473 goto unlock_traces;
474 }
475
476 channel = find_channel(ch_name, trace);
477 if (!channel) {
478 retval = -ENODATA;
479 ERR("unable to find channel");
480 goto unlock_traces;
481 }
482
483 buf = channel->buf[ch_cpu];
484
485 /* Being here is the proof the daemon has mapped the buffer in its
486 * memory. We may now decrement buffers_to_export.
487 */
488 if (uatomic_read(&buf->consumed) == 0) {
489 DBG("decrementing buffers_to_export");
490 CMM_STORE_SHARED(buffers_to_export, CMM_LOAD_SHARED(buffers_to_export)-1);
491 }
492
493unlock_traces:
494 ltt_unlock_traces();
495
496 return retval;
497}
498
499static int put_subbuffer(const char *trace_name, const char *ch_name,
500 int ch_cpu, long consumed_old)
501{
502 int retval = 0;
503 struct ust_trace *trace;
504 struct ust_channel *channel;
505 struct ust_buffer *buf;
506
507 DBG("put_subbuf");
508
509 ltt_lock_traces();
510 trace = _ltt_trace_find(trace_name);
511
512 if (!trace) {
513 retval = -ENODATA;
514 DBG("Cannot find trace. It was likely destroyed by the user.");
515 goto unlock_traces;
516 }
517
518 channel = find_channel(ch_name, trace);
519 if (!channel) {
520 retval = -ENODATA;
521 ERR("unable to find channel");
522 goto unlock_traces;
523 }
524
525 buf = channel->buf[ch_cpu];
526
527 retval = ust_buffers_put_subbuf(buf, consumed_old);
528 if (retval < 0) {
529 WARN("ust_buffers_put_subbuf: error (subbuf=%s_%d)",
530 ch_name, ch_cpu);
531 } else {
532 DBG("ust_buffers_put_subbuf: success (subbuf=%s_%d)",
533 ch_name, ch_cpu);
534 }
535
536unlock_traces:
537 ltt_unlock_traces();
538
539 return retval;
540}
541
542static void release_listener_mutex(void *ptr)
543{
544 pthread_mutex_unlock(&listener_thread_data_mutex);
545}
546
547static void listener_cleanup(void *ptr)
548{
549 pthread_mutex_lock(&listen_sock_mutex);
550 if (listen_sock) {
551 ustcomm_del_named_sock(listen_sock, 0);
552 listen_sock = NULL;
553 }
554 pthread_mutex_unlock(&listen_sock_mutex);
555}
556
557static int force_subbuf_switch(const char *trace_name)
558{
559 struct ust_trace *trace;
560 int i, j, retval = 0;
561
562 ltt_lock_traces();
563 trace = _ltt_trace_find(trace_name);
564 if (!trace) {
565 retval = -ENODATA;
566 DBG("Cannot find trace. It was likely destroyed by the user.");
567 goto unlock_traces;
568 }
569
570 for (i = 0; i < trace->nr_channels; i++) {
571 for (j = 0; j < trace->channels[i].n_cpus; j++) {
572 ltt_force_switch(trace->channels[i].buf[j],
573 FORCE_FLUSH);
574 }
575 }
576
577unlock_traces:
578 ltt_unlock_traces();
579
580 return retval;
581}
582
583static int process_trace_cmd(int command, char *trace_name)
584{
585 int result;
586 char trace_type[] = "ustrelay";
587
588 switch(command) {
589 case START:
590 /* start is an operation that setups the trace, allocates it and starts it */
591 result = ltt_trace_setup(trace_name);
592 if (result < 0) {
593 ERR("ltt_trace_setup failed");
594 return result;
595 }
596
597 result = ltt_trace_set_type(trace_name, trace_type);
598 if (result < 0) {
599 ERR("ltt_trace_set_type failed");
600 return result;
601 }
602
603 result = ltt_trace_alloc(trace_name);
604 if (result < 0) {
605 ERR("ltt_trace_alloc failed");
606 return result;
607 }
608
609 inform_consumer_daemon(trace_name);
610
611 result = ltt_trace_start(trace_name);
612 if (result < 0) {
613 ERR("ltt_trace_start failed");
614 return result;
615 }
616
617 return 0;
618 case SETUP_TRACE:
619 DBG("trace setup");
620
621 result = ltt_trace_setup(trace_name);
622 if (result < 0) {
623 ERR("ltt_trace_setup failed");
624 return result;
625 }
626
627 result = ltt_trace_set_type(trace_name, trace_type);
628 if (result < 0) {
629 ERR("ltt_trace_set_type failed");
630 return result;
631 }
632
633 return 0;
634 case ALLOC_TRACE:
635 DBG("trace alloc");
636
637 result = ltt_trace_alloc(trace_name);
638 if (result < 0) {
639 ERR("ltt_trace_alloc failed");
640 return result;
641 }
642 inform_consumer_daemon(trace_name);
643
644 return 0;
645
646 case CREATE_TRACE:
647 DBG("trace create");
648
649 result = ltt_trace_setup(trace_name);
650 if (result < 0) {
651 ERR("ltt_trace_setup failed");
652 return result;
653 }
654
655 result = ltt_trace_set_type(trace_name, trace_type);
656 if (result < 0) {
657 ERR("ltt_trace_set_type failed");
658 return result;
659 }
660
661 return 0;
662 case START_TRACE:
663 DBG("trace start");
664
665 result = ltt_trace_alloc(trace_name);
666 if (result < 0) {
667 ERR("ltt_trace_alloc failed");
668 return result;
669 }
670 if (!result) {
671 inform_consumer_daemon(trace_name);
672 }
673
674 result = ltt_trace_start(trace_name);
675 if (result < 0) {
676 ERR("ltt_trace_start failed");
677 return result;
678 }
679
680 return 0;
681 case STOP_TRACE:
682 DBG("trace stop");
683
684 result = ltt_trace_stop(trace_name);
685 if (result < 0) {
686 ERR("ltt_trace_stop failed");
687 return result;
688 }
689
690 return 0;
691 case DESTROY_TRACE:
692 DBG("trace destroy");
693
694 result = ltt_trace_destroy(trace_name, 0);
695 if (result < 0) {
696 ERR("ltt_trace_destroy failed");
697 return result;
698 }
699 return 0;
700 case FORCE_SUBBUF_SWITCH:
701 DBG("force switch");
702
703 result = force_subbuf_switch(trace_name);
704 if (result < 0) {
705 ERR("force_subbuf_switch failed");
706 return result;
707 }
708 return 0;
709 }
710
711 return 0;
712}
713
714
715static void process_channel_cmd(int sock, int command,
716 struct ustcomm_channel_info *ch_inf)
717{
718 struct ustcomm_header _reply_header;
719 struct ustcomm_header *reply_header = &_reply_header;
720 struct ustcomm_channel_info *reply_msg =
721 (struct ustcomm_channel_info *)send_buffer;
722 int result, offset = 0, num, size;
723
724 memset(reply_header, 0, sizeof(*reply_header));
725
726 switch (command) {
727 case GET_SUBBUF_NUM_SIZE:
728 result = get_subbuf_num_size(ch_inf->trace,
729 ch_inf->channel,
730 &num, &size);
731 if (result < 0) {
732 reply_header->result = result;
733 break;
734 }
735
736 reply_msg->channel = USTCOMM_POISON_PTR;
737 reply_msg->subbuf_num = num;
738 reply_msg->subbuf_size = size;
739
740
741 reply_header->size = COMPUTE_MSG_SIZE(reply_msg, offset);
742
743 break;
744 case SET_SUBBUF_NUM:
745 reply_header->result = set_subbuf_num(ch_inf->trace,
746 ch_inf->channel,
747 ch_inf->subbuf_num);
748
749 break;
750 case SET_SUBBUF_SIZE:
751 reply_header->result = set_subbuf_size(ch_inf->trace,
752 ch_inf->channel,
753 ch_inf->subbuf_size);
754
755
756 break;
757 }
758 if (ustcomm_send(sock, reply_header, (char *)reply_msg) < 0) {
759 ERR("ustcomm_send failed");
760 }
761}
762
763static void process_buffer_cmd(int sock, int command,
764 struct ustcomm_buffer_info *buf_inf)
765{
766 struct ustcomm_header _reply_header;
767 struct ustcomm_header *reply_header = &_reply_header;
768 struct ustcomm_buffer_info *reply_msg =
769 (struct ustcomm_buffer_info *)send_buffer;
770 int result, offset = 0, buf_shmid, buf_struct_shmid, buf_pipe_fd;
771 long consumed_old;
772
773 memset(reply_header, 0, sizeof(*reply_header));
774
775 switch (command) {
776 case GET_BUF_SHMID_PIPE_FD:
777 result = get_buffer_shmid_pipe_fd(buf_inf->trace,
778 buf_inf->channel,
779 buf_inf->ch_cpu,
780 &buf_shmid,
781 &buf_struct_shmid,
782 &buf_pipe_fd);
783 if (result < 0) {
784 reply_header->result = result;
785 break;
786 }
787
788 reply_msg->channel = USTCOMM_POISON_PTR;
789 reply_msg->buf_shmid = buf_shmid;
790 reply_msg->buf_struct_shmid = buf_struct_shmid;
791
792 reply_header->size = COMPUTE_MSG_SIZE(reply_msg, offset);
793 reply_header->fd_included = 1;
794
795 if (ustcomm_send_fd(sock, reply_header, (char *)reply_msg,
796 &buf_pipe_fd) < 0) {
797 ERR("ustcomm_send failed");
798 }
799 return;
800
801 case NOTIFY_BUF_MAPPED:
802 reply_header->result =
803 notify_buffer_mapped(buf_inf->trace,
804 buf_inf->channel,
805 buf_inf->ch_cpu);
806 break;
807 case GET_SUBBUFFER:
808 result = get_subbuffer(buf_inf->trace, buf_inf->channel,
809 buf_inf->ch_cpu, &consumed_old);
810 if (result < 0) {
811 reply_header->result = result;
812 break;
813 }
814
815 reply_msg->channel = USTCOMM_POISON_PTR;
816 reply_msg->consumed_old = consumed_old;
817
818 reply_header->size = COMPUTE_MSG_SIZE(reply_msg, offset);
819
820 break;
821 case PUT_SUBBUFFER:
822 result = put_subbuffer(buf_inf->trace, buf_inf->channel,
823 buf_inf->ch_cpu,
824 buf_inf->consumed_old);
825 reply_header->result = result;
826
827 break;
828 }
829
830 if (ustcomm_send(sock, reply_header, (char *)reply_msg) < 0) {
831 ERR("ustcomm_send failed");
832 }
833
834}
835
836static void process_ust_marker_cmd(int sock, int command,
837 struct ustcomm_ust_marker_info *ust_marker_inf)
838{
839 struct ustcomm_header _reply_header;
840 struct ustcomm_header *reply_header = &_reply_header;
841 int result = 0;
842
843 memset(reply_header, 0, sizeof(*reply_header));
844
845 switch(command) {
846 case ENABLE_MARKER:
847
848 result = ltt_ust_marker_connect(ust_marker_inf->channel,
849 ust_marker_inf->ust_marker,
850 "default");
851 if (result < 0) {
852 WARN("could not enable ust_marker; channel=%s,"
853 " name=%s",
854 ust_marker_inf->channel,
855 ust_marker_inf->ust_marker);
856
857 }
858 break;
859 case DISABLE_MARKER:
860 result = ltt_ust_marker_disconnect(ust_marker_inf->channel,
861 ust_marker_inf->ust_marker,
862 "default");
863 if (result < 0) {
864 WARN("could not disable ust_marker; channel=%s,"
865 " name=%s",
866 ust_marker_inf->channel,
867 ust_marker_inf->ust_marker);
868 }
869 break;
870 }
871
872 reply_header->result = result;
873
874 if (ustcomm_send(sock, reply_header, NULL) < 0) {
875 ERR("ustcomm_send failed");
876 }
877
878}
879static void process_client_cmd(struct ustcomm_header *recv_header,
880 char *recv_buf, int sock)
881{
882 int result;
883 struct ustcomm_header _reply_header;
884 struct ustcomm_header *reply_header = &_reply_header;
885 char *send_buf = send_buffer;
886
887 memset(reply_header, 0, sizeof(*reply_header));
888 memset(send_buf, 0, sizeof(send_buffer));
889
890 switch(recv_header->command) {
891 case GET_SUBBUF_NUM_SIZE:
892 case SET_SUBBUF_NUM:
893 case SET_SUBBUF_SIZE:
894 {
895 struct ustcomm_channel_info *ch_inf;
896 ch_inf = (struct ustcomm_channel_info *)recv_buf;
897 result = ustcomm_unpack_channel_info(ch_inf);
898 if (result < 0) {
899 ERR("couldn't unpack channel info");
900 reply_header->result = -EINVAL;
901 goto send_response;
902 }
903 process_channel_cmd(sock, recv_header->command, ch_inf);
904 return;
905 }
906 case GET_BUF_SHMID_PIPE_FD:
907 case NOTIFY_BUF_MAPPED:
908 case GET_SUBBUFFER:
909 case PUT_SUBBUFFER:
910 {
911 struct ustcomm_buffer_info *buf_inf;
912 buf_inf = (struct ustcomm_buffer_info *)recv_buf;
913 result = ustcomm_unpack_buffer_info(buf_inf);
914 if (result < 0) {
915 ERR("couldn't unpack buffer info");
916 reply_header->result = -EINVAL;
917 goto send_response;
918 }
919 process_buffer_cmd(sock, recv_header->command, buf_inf);
920 return;
921 }
922 case ENABLE_MARKER:
923 case DISABLE_MARKER:
924 {
925 struct ustcomm_ust_marker_info *ust_marker_inf;
926 ust_marker_inf = (struct ustcomm_ust_marker_info *)recv_buf;
927 result = ustcomm_unpack_ust_marker_info(ust_marker_inf);
928 if (result < 0) {
929 ERR("couldn't unpack ust_marker info");
930 reply_header->result = -EINVAL;
931 goto send_response;
932 }
933 process_ust_marker_cmd(sock, recv_header->command, ust_marker_inf);
934 return;
935 }
936 case LIST_MARKERS:
937 {
938 char *ptr;
939 size_t size;
940 FILE *fp;
941
942 fp = open_memstream(&ptr, &size);
943 if (fp == NULL) {
944 ERR("opening memstream failed");
945 return;
946 }
947 print_ust_marker(fp);
948 fclose(fp);
949
950 reply_header->size = size + 1; /* Include final \0 */
951
952 result = ustcomm_send(sock, reply_header, ptr);
953
954 free(ptr);
955
956 if (result < 0) {
957 PERROR("failed to send ust_marker list");
958 }
959
960 break;
961 }
962 case LIST_TRACE_EVENTS:
963 {
964 char *ptr;
965 size_t size;
966 FILE *fp;
967
968 fp = open_memstream(&ptr, &size);
969 if (fp == NULL) {
970 ERR("opening memstream failed");
971 return;
972 }
973 print_trace_events(fp);
974 fclose(fp);
975
976 reply_header->size = size + 1; /* Include final \0 */
977
978 result = ustcomm_send(sock, reply_header, ptr);
979
980 free(ptr);
981
982 if (result < 0) {
983 ERR("list_trace_events failed");
984 return;
985 }
986
987 break;
988 }
989 case LOAD_PROBE_LIB:
990 {
991 char *libfile;
992
993 /* FIXME: No functionality at all... */
994 libfile = recv_buf;
995
996 DBG("load_probe_lib loading %s", libfile);
997
998 break;
999 }
1000 case GET_PIDUNIQUE:
1001 {
1002 struct ustcomm_pidunique *pid_msg;
1003 pid_msg = (struct ustcomm_pidunique *)send_buf;
1004
1005 pid_msg->pidunique = pidunique;
1006 reply_header->size = sizeof(pid_msg);
1007
1008 goto send_response;
1009
1010 }
1011 case GET_SOCK_PATH:
1012 {
1013 struct ustcomm_single_field *sock_msg;
1014 char *sock_path_env;
1015
1016 sock_msg = (struct ustcomm_single_field *)send_buf;
1017
1018 sock_path_env = getenv("UST_DAEMON_SOCKET");
1019
1020 if (!sock_path_env) {
1021 result = ustcomm_pack_single_field(reply_header,
1022 sock_msg,
1023 SOCK_DIR "/ustconsumer");
1024
1025 } else {
1026 result = ustcomm_pack_single_field(reply_header,
1027 sock_msg,
1028 sock_path_env);
1029 }
1030 reply_header->result = result;
1031
1032 goto send_response;
1033 }
1034 case SET_SOCK_PATH:
1035 {
1036 struct ustcomm_single_field *sock_msg;
1037 sock_msg = (struct ustcomm_single_field *)recv_buf;
1038 result = ustcomm_unpack_single_field(sock_msg);
1039 if (result < 0) {
1040 reply_header->result = -EINVAL;
1041 goto send_response;
1042 }
1043
1044 reply_header->result = setenv("UST_DAEMON_SOCKET",
1045 sock_msg->field, 1);
1046
1047 goto send_response;
1048 }
1049 case START:
1050 case SETUP_TRACE:
1051 case ALLOC_TRACE:
1052 case CREATE_TRACE:
1053 case START_TRACE:
1054 case STOP_TRACE:
1055 case DESTROY_TRACE:
1056 case FORCE_SUBBUF_SWITCH:
1057 {
1058 struct ustcomm_single_field *trace_inf =
1059 (struct ustcomm_single_field *)recv_buf;
1060
1061 result = ustcomm_unpack_single_field(trace_inf);
1062 if (result < 0) {
1063 ERR("couldn't unpack trace info");
1064 reply_header->result = -EINVAL;
1065 goto send_response;
1066 }
1067
1068 reply_header->result =
1069 process_trace_cmd(recv_header->command,
1070 trace_inf->field);
1071 goto send_response;
1072
1073 }
1074 default:
1075 reply_header->result = -EINVAL;
1076
1077 goto send_response;
1078 }
1079
1080 return;
1081
1082send_response:
1083 ustcomm_send(sock, reply_header, send_buf);
1084}
1085
1086#define MAX_EVENTS 10
1087
1088void *listener_main(void *p)
1089{
1090 struct ustcomm_sock *epoll_sock;
1091 struct epoll_event events[MAX_EVENTS];
1092 struct sockaddr addr;
1093 int accept_fd, nfds, result, i, addr_size;
1094
1095 DBG("LISTENER");
1096
1097 pthread_cleanup_push(listener_cleanup, NULL);
1098
1099 for(;;) {
1100 nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
1101 if (nfds == -1) {
1102 PERROR("listener_main: epoll_wait failed");
1103 continue;
1104 }
1105
1106 for (i = 0; i < nfds; i++) {
1107 pthread_mutex_lock(&listener_thread_data_mutex);
1108 pthread_cleanup_push(release_listener_mutex, NULL);
1109 epoll_sock = (struct ustcomm_sock *)events[i].data.ptr;
1110 if (epoll_sock == listen_sock) {
1111 addr_size = sizeof(struct sockaddr);
1112 accept_fd = accept(epoll_sock->fd,
1113 &addr,
1114 (socklen_t *)&addr_size);
1115 if (accept_fd == -1) {
1116 PERROR("listener_main: accept failed");
1117 continue;
1118 }
1119 ustcomm_init_sock(accept_fd, epoll_fd,
1120 &ust_socks);
1121 } else {
1122 memset(receive_header, 0,
1123 sizeof(*receive_header));
1124 memset(receive_buffer, 0,
1125 sizeof(receive_buffer));
1126 result = ustcomm_recv(epoll_sock->fd,
1127 receive_header,
1128 receive_buffer);
1129 if (result == 0) {
1130 ustcomm_del_sock(epoll_sock, 0);
1131 } else {
1132 process_client_cmd(receive_header,
1133 receive_buffer,
1134 epoll_sock->fd);
1135 }
1136 }
1137 pthread_cleanup_pop(1); /* release listener mutex */
1138 }
1139 }
1140
1141 pthread_cleanup_pop(1);
1142}
1143
1144/* These should only be accessed in the parent thread,
1145 * not the listener.
1146 */
1147static volatile sig_atomic_t have_listener = 0;
1148static pthread_t listener_thread;
1149
1150void create_listener(void)
1151{
1152 int result;
1153 sigset_t sig_all_blocked;
1154 sigset_t orig_parent_mask;
1155
1156 if (have_listener) {
1157 WARN("not creating listener because we already had one");
1158 return;
1159 }
1160
1161 /* A new thread created by pthread_create inherits the signal mask
1162 * from the parent. To avoid any signal being received by the
1163 * listener thread, we block all signals temporarily in the parent,
1164 * while we create the listener thread.
1165 */
1166
1167 sigfillset(&sig_all_blocked);
1168
1169 result = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_parent_mask);
1170 if (result) {
1171 PERROR("pthread_sigmask: %s", strerror(result));
1172 }
1173
1174 result = pthread_create(&listener_thread, NULL, listener_main, NULL);
1175 if (result == -1) {
1176 PERROR("pthread_create");
1177 }
1178
1179 /* Restore original signal mask in parent */
1180 result = pthread_sigmask(SIG_SETMASK, &orig_parent_mask, NULL);
1181 if (result) {
1182 PERROR("pthread_sigmask: %s", strerror(result));
1183 } else {
1184 have_listener = 1;
1185 }
1186}
1187
1188#define AUTOPROBE_DISABLED 0
1189#define AUTOPROBE_ENABLE_ALL 1
1190#define AUTOPROBE_ENABLE_REGEX 2
1191static int autoprobe_method = AUTOPROBE_DISABLED;
1192static regex_t autoprobe_regex;
1193
1194static void auto_probe_connect(struct ust_marker *m)
1195{
1196 int result;
1197
1198 char* concat_name = NULL;
1199 const char *probe_name = "default";
1200
1201 if (autoprobe_method == AUTOPROBE_DISABLED) {
1202 return;
1203 } else if (autoprobe_method == AUTOPROBE_ENABLE_REGEX) {
1204 result = asprintf(&concat_name, "%s/%s", m->channel, m->name);
1205 if (result == -1) {
1206 ERR("auto_probe_connect: asprintf failed (ust_marker %s/%s)",
1207 m->channel, m->name);
1208 return;
1209 }
1210 if (regexec(&autoprobe_regex, concat_name, 0, NULL, 0)) {
1211 free(concat_name);
1212 return;
1213 }
1214 free(concat_name);
1215 }
1216
1217 result = ltt_ust_marker_connect(m->channel, m->name, probe_name);
1218 if (result && result != -EEXIST)
1219 ERR("ltt_ust_marker_connect (ust_marker = %s/%s, errno = %d)", m->channel, m->name, -result);
1220
1221 DBG("auto connected ust_marker %s (addr: %p) %s to probe default", m->channel, m, m->name);
1222
1223}
1224
1225static struct ustcomm_sock * init_app_socket(int epoll_fd)
1226{
1227 char *dir_name, *sock_name;
1228 int result;
1229 struct ustcomm_sock *sock = NULL;
1230 time_t mtime;
1231
1232 dir_name = ustcomm_user_sock_dir();
1233 if (!dir_name)
1234 return NULL;
1235
1236 mtime = ustcomm_pid_st_mtime(getpid());
1237 if (!mtime) {
1238 goto free_dir_name;
1239 }
1240
1241 result = asprintf(&sock_name, "%s/%d.%ld", dir_name,
1242 (int) getpid(), (long) mtime);
1243 if (result < 0) {
1244 ERR("string overflow allocating socket name, "
1245 "UST thread bailing");
1246 goto free_dir_name;
1247 }
1248
1249 result = ensure_dir_exists(dir_name, S_IRWXU);
1250 if (result == -1) {
1251 ERR("Unable to create socket directory %s, UST thread bailing",
1252 dir_name);
1253 goto free_sock_name;
1254 }
1255
1256 sock = ustcomm_init_named_socket(sock_name, epoll_fd);
1257 if (!sock) {
1258 ERR("Error initializing named socket (%s). Check that directory"
1259 "exists and that it is writable. UST thread bailing", sock_name);
1260 goto free_sock_name;
1261 }
1262
1263free_sock_name:
1264 free(sock_name);
1265free_dir_name:
1266 free(dir_name);
1267
1268 return sock;
1269}
1270
1271static void __attribute__((constructor)) init()
1272{
1273 struct timespec ts;
1274 int result;
1275 char* autoprobe_val = NULL;
1276 char* subbuffer_size_val = NULL;
1277 char* subbuffer_count_val = NULL;
1278 unsigned int subbuffer_size;
1279 unsigned int subbuffer_count;
1280 unsigned int power;
1281
1282 /* Assign the pidunique, to be able to differentiate the processes with same
1283 * pid, (before and after an exec).
1284 */
1285 pidunique = make_pidunique();
1286 processpid = getpid();
1287
1288 DBG("Tracectl constructor");
1289
1290 /* Set up epoll */
1291 epoll_fd = epoll_create(MAX_EVENTS);
1292 if (epoll_fd == -1) {
1293 ERR("epoll_create failed, tracing shutting down");
1294 return;
1295 }
1296
1297 /* Create the socket */
1298 listen_sock = init_app_socket(epoll_fd);
1299 if (!listen_sock) {
1300 ERR("failed to create application socket,"
1301 " tracing shutting down");
1302 return;
1303 }
1304
1305 create_listener();
1306
1307 /* Get clock the clock source type */
1308
1309 /* Default clock source */
1310 ust_clock_source = CLOCK_TRACE;
1311 if (clock_gettime(ust_clock_source, &ts) != 0) {
1312 ust_clock_source = CLOCK_MONOTONIC;
1313 DBG("UST traces will not be synchronized with LTTng traces");
1314 }
1315
1316 if (getenv("UST_TRACE") || getenv("UST_AUTOPROBE")) {
1317 /* Ensure ust_marker control is initialized */
1318 init_ust_marker_control();
1319 }
1320
1321 autoprobe_val = getenv("UST_AUTOPROBE");
1322 if (autoprobe_val) {
1323 struct ust_marker_iter iter;
1324
1325 DBG("Autoprobe enabled.");
1326
1327 /* first, set the callback that will connect the
1328 * probe on new ust_marker
1329 */
1330 if (autoprobe_val[0] == '/') {
1331 result = regcomp(&autoprobe_regex, autoprobe_val+1, 0);
1332 if (result) {
1333 char regexerr[150];
1334
1335 regerror(result, &autoprobe_regex, regexerr, sizeof(regexerr));
1336 ERR("cannot parse regex %s (%s), will ignore UST_AUTOPROBE", autoprobe_val, regexerr);
1337 /* don't crash the application just for this */
1338 } else {
1339 autoprobe_method = AUTOPROBE_ENABLE_REGEX;
1340 }
1341 } else {
1342 /* just enable all instrumentation */
1343 autoprobe_method = AUTOPROBE_ENABLE_ALL;
1344 }
1345
1346 ust_marker_set_new_ust_marker_cb(auto_probe_connect);
1347
1348 /* Now, connect the probes that were already registered. */
1349 ust_marker_iter_reset(&iter);
1350 ust_marker_iter_start(&iter);
1351
1352 DBG("now iterating on ust_marker already registered");
1353 while (iter.ust_marker) {
1354 DBG("now iterating on ust_marker %s", (*iter.ust_marker)->name);
1355 auto_probe_connect(*iter.ust_marker);
1356 ust_marker_iter_next(&iter);
1357 }
1358 ust_marker_iter_stop(&iter);
1359 }
1360
1361 if (getenv("UST_OVERWRITE")) {
1362 int val = atoi(getenv("UST_OVERWRITE"));
1363 if (val == 0 || val == 1) {
1364 CMM_STORE_SHARED(ust_channels_overwrite_by_default, val);
1365 } else {
1366 WARN("invalid value for UST_OVERWRITE");
1367 }
1368 }
1369
1370 if (getenv("UST_AUTOCOLLECT")) {
1371 int val = atoi(getenv("UST_AUTOCOLLECT"));
1372 if (val == 0 || val == 1) {
1373 CMM_STORE_SHARED(ust_channels_request_collection_by_default, val);
1374 } else {
1375 WARN("invalid value for UST_AUTOCOLLECT");
1376 }
1377 }
1378
1379 subbuffer_size_val = getenv("UST_SUBBUF_SIZE");
1380 if (subbuffer_size_val) {
1381 sscanf(subbuffer_size_val, "%u", &subbuffer_size);
1382 power = pow2_higher_or_eq(subbuffer_size);
1383 if (power != subbuffer_size)
1384 WARN("using the next power of two for buffer size = %u\n", power);
1385 chan_infos[LTT_CHANNEL_UST].def_subbufsize = power;
1386 }
1387
1388 subbuffer_count_val = getenv("UST_SUBBUF_NUM");
1389 if (subbuffer_count_val) {
1390 sscanf(subbuffer_count_val, "%u", &subbuffer_count);
1391 if (subbuffer_count < 2)
1392 subbuffer_count = 2;
1393 chan_infos[LTT_CHANNEL_UST].def_subbufcount = subbuffer_count;
1394 }
1395
1396 if (getenv("UST_TRACE")) {
1397 char trace_name[] = "auto";
1398 char trace_type[] = "ustrelay";
1399
1400 DBG("starting early tracing");
1401
1402 /* Ensure buffers are initialized, for the transport to be available.
1403 * We are about to set a trace type and it will fail without this.
1404 */
1405 init_ustrelay_transport();
1406
1407 /* FIXME: When starting early tracing (here), depending on the
1408 * order of constructors, it is very well possible some ust_marker
1409 * sections are not yet registered. Because of this, some
1410 * channels may not be registered. Yet, we are about to ask the
1411 * daemon to collect the channels. Channels which are not yet
1412 * registered will not be collected.
1413 *
1414 * Currently, in LTTng, there is no way to add a channel after
1415 * trace start. The reason for this is that it induces complex
1416 * concurrency issues on the trace structures, which can only
1417 * be resolved using RCU. This has not been done yet. As a
1418 * workaround, we are forcing the registration of the "ust"
1419 * channel here. This is the only channel (apart from metadata)
1420 * that can be reliably used in early tracing.
1421 *
1422 * Non-early tracing does not have this problem and can use
1423 * arbitrary channel names.
1424 */
1425 ltt_channels_register("ust");
1426
1427 result = ltt_trace_setup(trace_name);
1428 if (result < 0) {
1429 ERR("ltt_trace_setup failed");
1430 return;
1431 }
1432
1433 result = ltt_trace_set_type(trace_name, trace_type);
1434 if (result < 0) {
1435 ERR("ltt_trace_set_type failed");
1436 return;
1437 }
1438
1439 result = ltt_trace_alloc(trace_name);
1440 if (result < 0) {
1441 ERR("ltt_trace_alloc failed");
1442 return;
1443 }
1444
1445 result = ltt_trace_start(trace_name);
1446 if (result < 0) {
1447 ERR("ltt_trace_start failed");
1448 return;
1449 }
1450
1451 /* Do this after the trace is started in order to avoid creating confusion
1452 * if the trace fails to start. */
1453 inform_consumer_daemon(trace_name);
1454 }
1455
1456 return;
1457
1458 /* should decrementally destroy stuff if error */
1459
1460}
1461
1462/* This is only called if we terminate normally, not with an unhandled signal,
1463 * so we cannot rely on it. However, for now, LTTV requires that the header of
1464 * the last sub-buffer contain a valid end time for the trace. This is done
1465 * automatically only when the trace is properly stopped.
1466 *
1467 * If the traced program crashed, it is always possible to manually add the
1468 * right value in the header, or to open the trace in text mode.
1469 *
1470 * FIXME: Fix LTTV so it doesn't need this.
1471 */
1472
1473static void destroy_traces(void)
1474{
1475 int result;
1476
1477 /* if trace running, finish it */
1478
1479 DBG("destructor stopping traces");
1480
1481 result = ltt_trace_stop("auto");
1482 if (result == -1) {
1483 ERR("ltt_trace_stop error");
1484 }
1485
1486 result = ltt_trace_destroy("auto", 0);
1487 if (result == -1) {
1488 ERR("ltt_trace_destroy error");
1489 }
1490}
1491
1492static int trace_recording(void)
1493{
1494 int retval = 0;
1495 struct ust_trace *trace;
1496
1497 ltt_lock_traces();
1498
1499 cds_list_for_each_entry(trace, &ltt_traces.head, list) {
1500 if (trace->active) {
1501 retval = 1;
1502 break;
1503 }
1504 }
1505
1506 ltt_unlock_traces();
1507
1508 return retval;
1509}
1510
1511int restarting_usleep(useconds_t usecs)
1512{
1513 struct timespec tv;
1514 int result;
1515
1516 tv.tv_sec = 0;
1517 tv.tv_nsec = usecs * 1000;
1518
1519 do {
1520 result = nanosleep(&tv, &tv);
1521 } while (result == -1 && errno == EINTR);
1522
1523 return result;
1524}
1525
1526static void stop_listener(void)
1527{
1528 int result;
1529
1530 if (!have_listener)
1531 return;
1532
1533 result = pthread_cancel(listener_thread);
1534 if (result != 0) {
1535 ERR("pthread_cancel: %s", strerror(result));
1536 }
1537 result = pthread_join(listener_thread, NULL);
1538 if (result != 0) {
1539 ERR("pthread_join: %s", strerror(result));
1540 }
1541}
1542
1543/* This destructor keeps the process alive for a few seconds in order
1544 * to leave time for ustconsumer to connect to its buffers. This is necessary
1545 * for programs whose execution is very short. It is also useful in all
1546 * programs when tracing is started close to the end of the program
1547 * execution.
1548 *
1549 * FIXME: For now, this only works for the first trace created in a
1550 * process.
1551 */
1552
1553static void __attribute__((destructor)) keepalive()
1554{
1555 if (processpid != getpid()) {
1556 return;
1557 }
1558
1559 if (trace_recording() && CMM_LOAD_SHARED(buffers_to_export)) {
1560 int total = 0;
1561 DBG("Keeping process alive for consumer daemon...");
1562 while (CMM_LOAD_SHARED(buffers_to_export)) {
1563 const int interv = 200000;
1564 restarting_usleep(interv);
1565 total += interv;
1566
1567 if (total >= 3000000) {
1568 WARN("non-consumed buffers remaining after wait limit; not waiting anymore");
1569 break;
1570 }
1571 }
1572 DBG("Finally dying...");
1573 }
1574
1575 destroy_traces();
1576
1577 /* Ask the listener to stop and clean up. */
1578 stop_listener();
1579}
1580
1581void ust_potential_exec(void)
1582{
1583 ust_marker(potential_exec, UST_MARKER_NOARGS);
1584
1585 DBG("test");
1586
1587 keepalive();
1588}
1589
1590/* Notify ust that there was a fork. This needs to be called inside
1591 * the new process, anytime a process whose memory is not shared with
1592 * the parent is created. If this function is not called, the events
1593 * of the new process will not be collected.
1594 *
1595 * Signals should be disabled before the fork and reenabled only after
1596 * this call in order to guarantee tracing is not started before ust_fork()
1597 * sanitizes the new process.
1598 */
1599
1600static void ust_fork(void)
1601{
1602 struct ustcomm_sock *sock, *sock_tmp;
1603 struct ust_trace *trace, *trace_tmp;
1604 int result;
1605
1606 /* FIXME: technically, the locks could have been taken before the fork */
1607 DBG("ust: forking");
1608
1609 /* Get the pid of the new process */
1610 processpid = getpid();
1611
1612 /*
1613 * FIXME: This could be prettier, we loop over the list twice and
1614 * following good locking practice should lock around the loop
1615 */
1616 cds_list_for_each_entry_safe(trace, trace_tmp, &ltt_traces.head, list) {
1617 ltt_trace_stop(trace->trace_name);
1618 }
1619
1620 /* Delete all active connections, but leave them in the epoll set */
1621 cds_list_for_each_entry_safe(sock, sock_tmp, &ust_socks, list) {
1622 ustcomm_del_sock(sock, 1);
1623 }
1624
1625 /*
1626 * FIXME: This could be prettier, we loop over the list twice and
1627 * following good locking practice should lock around the loop
1628 */
1629 cds_list_for_each_entry_safe(trace, trace_tmp, &ltt_traces.head, list) {
1630 ltt_trace_destroy(trace->trace_name, 1);
1631 }
1632
1633 /* Clean up the listener socket and epoll, keeping the socket file */
1634 if (listen_sock) {
1635 ustcomm_del_named_sock(listen_sock, 1);
1636 listen_sock = NULL;
1637 }
1638 close(epoll_fd);
1639
1640 /* Re-start the launch sequence */
1641 CMM_STORE_SHARED(buffers_to_export, 0);
1642 have_listener = 0;
1643
1644 /* Set up epoll */
1645 epoll_fd = epoll_create(MAX_EVENTS);
1646 if (epoll_fd == -1) {
1647 ERR("epoll_create failed, tracing shutting down");
1648 return;
1649 }
1650
1651 /* Create the socket */
1652 listen_sock = init_app_socket(epoll_fd);
1653 if (!listen_sock) {
1654 ERR("failed to create application socket,"
1655 " tracing shutting down");
1656 return;
1657 }
1658 create_listener();
1659 ltt_trace_setup("auto");
1660 result = ltt_trace_set_type("auto", "ustrelay");
1661 if (result < 0) {
1662 ERR("ltt_trace_set_type failed");
1663 return;
1664 }
1665
1666 ltt_trace_alloc("auto");
1667 ltt_trace_start("auto");
1668 inform_consumer_daemon("auto");
1669}
1670
1671void ust_before_fork(ust_fork_info_t *fork_info)
1672{
1673 /* Disable signals. This is to avoid that the child
1674 * intervenes before it is properly setup for tracing. It is
1675 * safer to disable all signals, because then we know we are not
1676 * breaking anything by restoring the original mask.
1677 */
1678 sigset_t all_sigs;
1679 int result;
1680
1681 /* FIXME:
1682 - only do this if tracing is active
1683 */
1684
1685 /* Disable signals */
1686 sigfillset(&all_sigs);
1687 result = sigprocmask(SIG_BLOCK, &all_sigs, &fork_info->orig_sigs);
1688 if (result == -1) {
1689 PERROR("sigprocmask");
1690 return;
1691 }
1692
1693 /*
1694 * Take the fork lock to make sure we are not in the middle of
1695 * something in the listener thread.
1696 */
1697 pthread_mutex_lock(&listener_thread_data_mutex);
1698 /*
1699 * Hold listen_sock_mutex to protect from listen_sock teardown.
1700 */
1701 pthread_mutex_lock(&listen_sock_mutex);
1702 rcu_bp_before_fork();
1703}
1704
1705/* Don't call this function directly in a traced program */
1706static void ust_after_fork_common(ust_fork_info_t *fork_info)
1707{
1708 int result;
1709
1710 pthread_mutex_unlock(&listen_sock_mutex);
1711 pthread_mutex_unlock(&listener_thread_data_mutex);
1712 /* Restore signals */
1713 result = sigprocmask(SIG_SETMASK, &fork_info->orig_sigs, NULL);
1714 if (result == -1) {
1715 PERROR("sigprocmask");
1716 return;
1717 }
1718}
1719
1720void ust_after_fork_parent(ust_fork_info_t *fork_info)
1721{
1722 rcu_bp_after_fork_parent();
1723 /* Release mutexes and reenable signals */
1724 ust_after_fork_common(fork_info);
1725}
1726
1727void ust_after_fork_child(ust_fork_info_t *fork_info)
1728{
1729 /* Release urcu mutexes */
1730 rcu_bp_after_fork_child();
1731
1732 /* Sanitize the child */
1733 ust_fork();
1734
1735 /* Release mutexes and reenable signals */
1736 ust_after_fork_common(fork_info);
1737}
1738
This page took 0.029061 seconds and 5 git commands to generate.