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