Distribute all necessary files for building
[lttng-ust.git] / libust / tracectl.c
CommitLineData
68c1021b
PMF
1#include <stdio.h>
2#include <stdint.h>
3#include <signal.h>
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <sys/un.h>
98963de4 7#include <sched.h>
a584bc4e 8#include <fcntl.h>
3a7b90de 9#include <poll.h>
fbd8191b
PMF
10
11#include "marker.h"
a584bc4e 12#include "tracer.h"
d0b5f2b9
PMF
13#include "localerr.h"
14#include "ustcomm.h"
46ef48cd 15#include "relay.h" /* FIXME: remove */
fbd8191b 16
b02e31e5 17//#define USE_CLONE
3847c3ba 18
68c1021b
PMF
19#define USTSIGNAL SIGIO
20
98963de4
PMF
21#define MAX_MSG_SIZE (100)
22#define MSG_NOTIF 1
23#define MSG_REGISTER_NOTIF 2
24
a584bc4e
PMF
25char consumer_stack[10000];
26
3a7b90de
PMF
27struct list_head blocked_consumers = LIST_HEAD_INIT(blocked_consumers);
28
d0b5f2b9
PMF
29static struct ustcomm_app ustcomm_app;
30
68c1021b
PMF
31struct tracecmd { /* no padding */
32 uint32_t size;
33 uint16_t command;
34};
35
98963de4
PMF
36//struct listener_arg {
37// int pipe_fd;
38//};
39
40struct trctl_msg {
41 /* size: the size of all the fields except size itself */
42 uint32_t size;
43 uint16_t type;
44 /* Only the necessary part of the payload is transferred. It
45 * may even be none of it.
46 */
47 char payload[94];
48};
68c1021b 49
a584bc4e
PMF
50struct consumer_channel {
51 int fd;
52 struct ltt_channel_struct *chan;
53};
54
3a7b90de
PMF
55struct blocked_consumer {
56 int fd_consumer;
57 int fd_producer;
58 int tmp_poll_idx;
59
60 /* args to ustcomm_send_reply */
61 struct ustcomm_server server;
62 struct ustcomm_source src;
63
64 /* args to ltt_do_get_subbuf */
65 struct rchan_buf *rbuf;
66 struct ltt_channel_buf_struct *lttbuf;
67
68 struct list_head list;
69};
70
52c51a47 71static void print_markers(FILE *fp)
fbd8191b
PMF
72{
73 struct marker_iter iter;
74
d0b5f2b9 75 lock_markers();
fbd8191b
PMF
76 marker_iter_reset(&iter);
77 marker_iter_start(&iter);
78
79 while(iter.marker) {
52c51a47 80 fprintf(fp, "marker: %s_%s %d \"%s\"\n", iter.marker->channel, iter.marker->name, (int)imv_read(iter.marker->state), iter.marker->format);
fbd8191b
PMF
81 marker_iter_next(&iter);
82 }
d0b5f2b9 83 unlock_markers();
fbd8191b
PMF
84}
85
68c1021b
PMF
86void do_command(struct tracecmd *cmd)
87{
88}
89
90void receive_commands()
91{
92}
93
98963de4
PMF
94int fd_notif = -1;
95void notif_cb(void)
96{
97 int result;
98 struct trctl_msg msg;
99
100 /* FIXME: fd_notif should probably be protected by a spinlock */
101
102 if(fd_notif == -1)
103 return;
104
105 msg.type = MSG_NOTIF;
106 msg.size = sizeof(msg.type);
107
108 /* FIXME: don't block here */
109 result = write(fd_notif, &msg, msg.size+sizeof(msg.size));
110 if(result == -1) {
111 PERROR("write");
112 return;
113 }
114}
115
d0b5f2b9
PMF
116static int inform_consumer_daemon(void)
117{
3847c3ba
PMF
118 ustcomm_request_consumer(getpid(), "metadata");
119 ustcomm_request_consumer(getpid(), "ust");
d0b5f2b9 120}
fbd8191b 121
3a7b90de
PMF
122void process_blocked_consumers(void)
123{
124 int n_fds = 0;
125 struct pollfd *fds;
126 struct blocked_consumer *bc;
127 int idx = 0;
128 char inbuf;
129 int result;
130
131 list_for_each_entry(bc, &blocked_consumers, list) {
132 n_fds++;
133 }
134
135 fds = (struct pollfd *) malloc(n_fds * sizeof(struct pollfd));
136 if(fds == NULL) {
137 ERR("malloc returned NULL");
138 return;
139 }
140
141 list_for_each_entry(bc, &blocked_consumers, list) {
142 fds[idx].fd = bc->fd_producer;
143 fds[idx].events = POLLIN;
144 bc->tmp_poll_idx = idx;
145 idx++;
146 }
147
148 result = poll(fds, n_fds, 0);
149 if(result == -1) {
150 PERROR("poll");
151 return -1;
152 }
153
154 list_for_each_entry(bc, &blocked_consumers, list) {
155 if(fds[bc->tmp_poll_idx].revents) {
156 long consumed_old = 0;
157 char *reply;
158
159 result = read(bc->fd_producer, &inbuf, 1);
160 if(result == -1) {
161 PERROR("read");
162 continue;
163 }
164 if(result == 0) {
165 DBG("PRODUCER END");
166
167 close(bc->fd_producer);
168
769d0157 169 list_del(&bc->list);
3a7b90de
PMF
170
171 result = ustcomm_send_reply(&bc->server, "END", &bc->src);
172 if(result < 0) {
173 ERR("ustcomm_send_reply failed");
174 continue;
175 }
176
177 continue;
178 }
179
180 result = ltt_do_get_subbuf(bc->rbuf, bc->lttbuf, &consumed_old);
181 if(result == -EAGAIN) {
182 WARN("missed buffer?");
183 continue;
184 }
185 else if(result < 0) {
186 DBG("ltt_do_get_subbuf: error: %s", strerror(-result));
187 }
188 asprintf(&reply, "%s %ld", "OK", consumed_old);
189 result = ustcomm_send_reply(&bc->server, reply, &bc->src);
190 if(result < 0) {
191 ERR("ustcomm_send_reply failed");
192 free(reply);
193 continue;
194 }
195 free(reply);
196
769d0157 197 list_del(&bc->list);
3a7b90de
PMF
198 }
199 }
200
201}
202
98963de4
PMF
203int listener_main(void *p)
204{
205 int result;
206
b0540e11
PMF
207 DBG("LISTENER");
208
98963de4 209 for(;;) {
98963de4 210 uint32_t size;
98963de4
PMF
211 struct sockaddr_un addr;
212 socklen_t addrlen = sizeof(addr);
aafb1650
PMF
213 char trace_name[] = "auto";
214 char trace_type[] = "ustrelay";
d0b5f2b9
PMF
215 char *recvbuf;
216 int len;
b02e31e5 217 struct ustcomm_source src;
98963de4 218
3a7b90de
PMF
219 process_blocked_consumers();
220
221 result = ustcomm_app_recv_message(&ustcomm_app, &recvbuf, &src, 5);
222 if(result < 0) {
d0b5f2b9
PMF
223 WARN("error in ustcomm_app_recv_message");
224 continue;
225 }
3a7b90de
PMF
226 else if(result == 0) {
227 /* no message */
228 continue;
229 }
98963de4 230
d0b5f2b9
PMF
231 DBG("received a message! it's: %s\n", recvbuf);
232 len = strlen(recvbuf);
98963de4 233
d0b5f2b9 234 if(!strcmp(recvbuf, "print_markers")) {
52c51a47
PMF
235 print_markers(stderr);
236 }
237 else if(!strcmp(recvbuf, "list_markers")) {
238 char *ptr;
239 size_t size;
240 FILE *fp;
241
242 fp = open_memstream(&ptr, &size);
243 print_markers(fp);
244 fclose(fp);
245
246 result = ustcomm_send_reply(&ustcomm_app.server, ptr, &src);
247
248 free(ptr);
249 }
250 else if(!strcmp(recvbuf, "start")) {
251 /* start is an operation that setups the trace, allocates it and starts it */
252 result = ltt_trace_setup(trace_name);
253 if(result < 0) {
254 ERR("ltt_trace_setup failed");
255 return;
256 }
257
258 result = ltt_trace_set_type(trace_name, trace_type);
259 if(result < 0) {
260 ERR("ltt_trace_set_type failed");
261 return;
262 }
263
264 result = ltt_trace_alloc(trace_name);
265 if(result < 0) {
266 ERR("ltt_trace_alloc failed");
267 return;
268 }
269
270 inform_consumer_daemon();
271
272 result = ltt_trace_start(trace_name);
273 if(result < 0) {
274 ERR("ltt_trace_start failed");
275 continue;
276 }
d0b5f2b9
PMF
277 }
278 else if(!strcmp(recvbuf, "trace_setup")) {
279 DBG("trace setup");
fbd8191b 280
d0b5f2b9
PMF
281 result = ltt_trace_setup(trace_name);
282 if(result < 0) {
283 ERR("ltt_trace_setup failed");
284 return;
fbd8191b 285 }
d0b5f2b9
PMF
286
287 result = ltt_trace_set_type(trace_name, trace_type);
288 if(result < 0) {
289 ERR("ltt_trace_set_type failed");
290 return;
fbd8191b 291 }
d0b5f2b9
PMF
292 }
293 else if(!strcmp(recvbuf, "trace_alloc")) {
294 DBG("trace alloc");
295
296 result = ltt_trace_alloc(trace_name);
297 if(result < 0) {
298 ERR("ltt_trace_alloc failed");
299 return;
fbd8191b 300 }
d0b5f2b9
PMF
301 }
302 else if(!strcmp(recvbuf, "trace_start")) {
303 DBG("trace start");
304
305 result = ltt_trace_start(trace_name);
306 if(result < 0) {
307 ERR("ltt_trace_start failed");
308 continue;
fbd8191b 309 }
d0b5f2b9
PMF
310 }
311 else if(!strcmp(recvbuf, "trace_stop")) {
312 DBG("trace stop");
313
314 result = ltt_trace_stop(trace_name);
315 if(result < 0) {
316 ERR("ltt_trace_stop failed");
317 return;
aafb1650 318 }
d0b5f2b9
PMF
319 }
320 else if(!strcmp(recvbuf, "trace_destroy")) {
aafb1650 321
d0b5f2b9 322 DBG("trace destroy");
aafb1650 323
d0b5f2b9
PMF
324 result = ltt_trace_destroy(trace_name);
325 if(result < 0) {
326 ERR("ltt_trace_destroy failed");
327 return;
fbd8191b 328 }
98963de4 329 }
b02e31e5 330 else if(nth_token_is(recvbuf, "get_shmid", 0) == 1) {
3847c3ba
PMF
331 struct ltt_trace_struct *trace;
332 char trace_name[] = "auto";
333 int i;
811e4b93 334 char *channel_name;
3847c3ba
PMF
335
336 DBG("get_shmid");
337
811e4b93
PMF
338 channel_name = nth_token(recvbuf, 1);
339 if(channel_name == NULL) {
340 ERR("get_shmid: cannot parse channel");
341 goto next_cmd;
342 }
343
3847c3ba
PMF
344 ltt_lock_traces();
345 trace = _ltt_trace_find(trace_name);
346 ltt_unlock_traces();
347
348 if(trace == NULL) {
349 CPRINTF("cannot find trace!");
350 return 1;
351 }
352
353 for(i=0; i<trace->nr_channels; i++) {
354 struct rchan *rchan = trace->channels[i].trans_channel_data;
355 struct rchan_buf *rbuf = rchan->buf;
8cefc145
PMF
356 struct ltt_channel_struct *ltt_channel = (struct ltt_channel_struct *)rchan->private_data;
357 struct ltt_channel_buf_struct *ltt_buf = ltt_channel->buf;
3847c3ba 358
811e4b93
PMF
359 if(!strcmp(trace->channels[i].channel_name, channel_name)) {
360 char *reply;
361
362 DBG("the shmid for the requested channel is %d", rbuf->shmid);
8cefc145
PMF
363 DBG("the shmid for its buffer structure is %d", ltt_channel->buf_shmid);
364 asprintf(&reply, "%d %d", rbuf->shmid, ltt_channel->buf_shmid);
811e4b93
PMF
365
366 result = ustcomm_send_reply(&ustcomm_app.server, reply, &src);
367 if(result) {
368 ERR("listener: get_shmid: ustcomm_send_reply failed");
369 goto next_cmd;
370 }
371
372 free(reply);
373
374 break;
375 }
376 }
377 }
378 else if(nth_token_is(recvbuf, "get_n_subbufs", 0) == 1) {
379 struct ltt_trace_struct *trace;
380 char trace_name[] = "auto";
381 int i;
382 char *channel_name;
383
384 DBG("get_n_subbufs");
385
386 channel_name = nth_token(recvbuf, 1);
387 if(channel_name == NULL) {
388 ERR("get_n_subbufs: cannot parse channel");
389 goto next_cmd;
390 }
391
392 ltt_lock_traces();
393 trace = _ltt_trace_find(trace_name);
394 ltt_unlock_traces();
395
396 if(trace == NULL) {
397 CPRINTF("cannot find trace!");
398 return 1;
399 }
400
401 for(i=0; i<trace->nr_channels; i++) {
402 struct rchan *rchan = trace->channels[i].trans_channel_data;
403
404 if(!strcmp(trace->channels[i].channel_name, channel_name)) {
405 char *reply;
406
407 DBG("the n_subbufs for the requested channel is %d", rchan->n_subbufs);
408 asprintf(&reply, "%d", rchan->n_subbufs);
409
410 result = ustcomm_send_reply(&ustcomm_app.server, reply, &src);
411 if(result) {
412 ERR("listener: get_n_subbufs: ustcomm_send_reply failed");
413 goto next_cmd;
414 }
415
416 free(reply);
417
418 break;
419 }
420 }
421 }
422 else if(nth_token_is(recvbuf, "get_subbuf_size", 0) == 1) {
423 struct ltt_trace_struct *trace;
424 char trace_name[] = "auto";
425 int i;
426 char *channel_name;
427
428 DBG("get_subbuf_size");
429
430 channel_name = nth_token(recvbuf, 1);
431 if(channel_name == NULL) {
432 ERR("get_subbuf_size: cannot parse channel");
433 goto next_cmd;
434 }
435
436 ltt_lock_traces();
437 trace = _ltt_trace_find(trace_name);
438 ltt_unlock_traces();
439
440 if(trace == NULL) {
441 CPRINTF("cannot find trace!");
442 return 1;
443 }
444
445 for(i=0; i<trace->nr_channels; i++) {
446 struct rchan *rchan = trace->channels[i].trans_channel_data;
447
448 if(!strcmp(trace->channels[i].channel_name, channel_name)) {
449 char *reply;
450
451 DBG("the subbuf_size for the requested channel is %d", rchan->subbuf_size);
452 asprintf(&reply, "%d", rchan->subbuf_size);
453
454 result = ustcomm_send_reply(&ustcomm_app.server, reply, &src);
455 if(result) {
456 ERR("listener: get_subbuf_size: ustcomm_send_reply failed");
457 goto next_cmd;
458 }
459
460 free(reply);
3847c3ba 461
811e4b93
PMF
462 break;
463 }
3847c3ba
PMF
464 }
465 }
b02e31e5
PMF
466 else if(nth_token_is(recvbuf, "load_probe_lib", 0) == 1) {
467 char *libfile;
468
469 libfile = nth_token(recvbuf, 1);
470
471 DBG("load_probe_lib loading %s", libfile);
472 }
688760ef
PMF
473 else if(nth_token_is(recvbuf, "get_subbuffer", 0) == 1) {
474 struct ltt_trace_struct *trace;
475 char trace_name[] = "auto";
476 int i;
477 char *channel_name;
478
479 DBG("get_subbuf");
480
481 channel_name = nth_token(recvbuf, 1);
482 if(channel_name == NULL) {
483 ERR("get_subbuf: cannot parse channel");
484 goto next_cmd;
485 }
486
487 ltt_lock_traces();
488 trace = _ltt_trace_find(trace_name);
489 ltt_unlock_traces();
490
491 if(trace == NULL) {
492 CPRINTF("cannot find trace!");
493 return 1;
494 }
495
496 for(i=0; i<trace->nr_channels; i++) {
497 struct rchan *rchan = trace->channels[i].trans_channel_data;
498
499 if(!strcmp(trace->channels[i].channel_name, channel_name)) {
500 struct rchan_buf *rbuf = rchan->buf;
501 struct ltt_channel_buf_struct *lttbuf = trace->channels[i].buf;
502 char *reply;
503 long consumed_old=0;
3a7b90de
PMF
504 int fd;
505 struct blocked_consumer *bc;
688760ef 506
3a7b90de
PMF
507 bc = (struct blocked_consumer *) malloc(sizeof(struct blocked_consumer));
508 if(bc == NULL) {
509 ERR("malloc returned NULL");
688760ef
PMF
510 goto next_cmd;
511 }
3a7b90de
PMF
512 bc->fd_consumer = src.fd;
513 bc->fd_producer = lttbuf->data_ready_fd_read;
514 bc->rbuf = rbuf;
515 bc->lttbuf = lttbuf;
516 bc->src = src;
517 bc->server = ustcomm_app.server;
688760ef 518
3a7b90de 519 list_add(&bc->list, &blocked_consumers);
688760ef
PMF
520
521 break;
522 }
523 }
524 }
525 else if(nth_token_is(recvbuf, "put_subbuffer", 0) == 1) {
526 struct ltt_trace_struct *trace;
527 char trace_name[] = "auto";
528 int i;
529 char *channel_name;
530 long consumed_old;
531 char *consumed_old_str;
532 char *endptr;
533
534 DBG("put_subbuf");
535
536 channel_name = strdup_malloc(nth_token(recvbuf, 1));
537 if(channel_name == NULL) {
538 ERR("put_subbuf_size: cannot parse channel");
539 goto next_cmd;
540 }
541
542 consumed_old_str = strdup_malloc(nth_token(recvbuf, 2));
543 if(consumed_old_str == NULL) {
544 ERR("put_subbuf: cannot parse consumed_old");
545 goto next_cmd;
546 }
547 consumed_old = strtol(consumed_old_str, &endptr, 10);
548 if(*endptr != '\0') {
549 ERR("put_subbuf: invalid value for consumed_old");
550 goto next_cmd;
551 }
552
553 ltt_lock_traces();
554 trace = _ltt_trace_find(trace_name);
555 ltt_unlock_traces();
556
557 if(trace == NULL) {
558 CPRINTF("cannot find trace!");
559 return 1;
560 }
561
562 for(i=0; i<trace->nr_channels; i++) {
563 struct rchan *rchan = trace->channels[i].trans_channel_data;
564
565 if(!strcmp(trace->channels[i].channel_name, channel_name)) {
566 struct rchan_buf *rbuf = rchan->buf;
567 struct ltt_channel_buf_struct *lttbuf = trace->channels[i].buf;
568 char *reply;
569 long consumed_old=0;
570
571 result = ltt_do_put_subbuf(rbuf, lttbuf, consumed_old);
572 if(result < 0) {
0a58610f
PMF
573 WARN("ltt_do_put_subbuf: error (subbuf=%s)", channel_name);
574 asprintf(&reply, "%s", "ERROR", consumed_old);
688760ef
PMF
575 }
576 else {
0a58610f
PMF
577 DBG("ltt_do_put_subbuf: success (subbuf=%s)", channel_name);
578 asprintf(&reply, "%s", "OK", consumed_old);
688760ef 579 }
688760ef
PMF
580
581 result = ustcomm_send_reply(&ustcomm_app.server, reply, &src);
582 if(result) {
583 ERR("listener: put_subbuf: ustcomm_send_reply failed");
584 goto next_cmd;
585 }
586
587 free(reply);
588
589 break;
590 }
591 }
592
593 free(channel_name);
594 free(consumed_old_str);
595 }
52c51a47
PMF
596 else if(nth_token_is(recvbuf, "enable_marker", 0) == 1) {
597 char *channel_slash_name = nth_token(recvbuf, 1);
598 char channel_name[256]="";
599 char marker_name[256]="";
600 struct marker_iter iter;
601
602 result = sscanf(channel_slash_name, "%255[^/]/%255s", channel_name, marker_name);
603
604 if(channel_name == NULL || marker_name == NULL) {
605 WARN("invalid marker name");
606 goto next_cmd;
607 }
608 printf("%s %s\n", channel_name, marker_name);
609
610 result = ltt_marker_connect(channel_name, marker_name, "default");
611 if(result < 0) {
612 WARN("could not enable marker; channel=%s, name=%s", channel_name, marker_name);
613 }
614 }
615 else if(nth_token_is(recvbuf, "disable_marker", 0) == 1) {
616 char *channel_slash_name = nth_token(recvbuf, 1);
617 char *marker_name;
618 char *channel_name;
619 struct marker_iter iter;
620
621 result = sscanf(channel_slash_name, "%a[^/]/%as", &channel_name, &marker_name);
622
623 if(marker_name == NULL) {
624 }
625 printf("%s %s\n", channel_name, marker_name);
626
627 result = ltt_marker_disconnect(channel_name, marker_name, "default");
628 if(result < 0) {
629 WARN("could not disable marker; channel=%s, name=%s", channel_name, marker_name);
630 }
631 }
3a7b90de
PMF
632// else if(nth_token_is(recvbuf, "get_notifications", 0) == 1) {
633// struct ltt_trace_struct *trace;
634// char trace_name[] = "auto";
635// int i;
636// char *channel_name;
637//
638// DBG("get_notifications");
639//
640// channel_name = strdup_malloc(nth_token(recvbuf, 1));
641// if(channel_name == NULL) {
642// ERR("put_subbuf_size: cannot parse channel");
643// goto next_cmd;
644// }
645//
646// ltt_lock_traces();
647// trace = _ltt_trace_find(trace_name);
648// ltt_unlock_traces();
649//
650// if(trace == NULL) {
651// CPRINTF("cannot find trace!");
652// return 1;
653// }
654//
655// for(i=0; i<trace->nr_channels; i++) {
656// struct rchan *rchan = trace->channels[i].trans_channel_data;
657// int fd;
658//
659// if(!strcmp(trace->channels[i].channel_name, channel_name)) {
660// struct rchan_buf *rbuf = rchan->buf;
661// struct ltt_channel_buf_struct *lttbuf = trace->channels[i].buf;
662//
663// result = fd = ustcomm_app_detach_client(&ustcomm_app, &src);
664// if(result == -1) {
665// ERR("ustcomm_app_detach_client failed");
666// goto next_cmd;
667// }
668//
669// lttbuf->wake_consumer_arg = (void *) fd;
670//
671// smp_wmb();
672//
673// lttbuf->call_wake_consumer = 1;
674//
675// break;
676// }
677// }
678//
679// free(channel_name);
680// }
688760ef
PMF
681 else {
682 ERR("unable to parse message: %s", recvbuf);
683 }
d0b5f2b9 684
811e4b93 685 next_cmd:
d0b5f2b9 686 free(recvbuf);
98963de4
PMF
687 }
688}
689
b0540e11
PMF
690static char listener_stack[16384];
691
98963de4
PMF
692void create_listener(void)
693{
694 int result;
695 static char listener_stack[16384];
b0540e11 696 //char *listener_stack = malloc(16384);
98963de4 697
3847c3ba 698#ifdef USE_CLONE
fbd8191b 699 result = clone(listener_main, listener_stack+sizeof(listener_stack)-1, CLONE_FS | CLONE_FILES | CLONE_VM | CLONE_SIGHAND | CLONE_THREAD, NULL);
98963de4
PMF
700 if(result == -1) {
701 perror("clone");
702 }
3847c3ba
PMF
703#else
704 pthread_t thread;
b0540e11 705
3847c3ba
PMF
706 pthread_create(&thread, NULL, listener_main, NULL);
707#endif
98963de4
PMF
708}
709
d0b5f2b9
PMF
710/* The signal handler itself. Signals must be setup so there cannot be
711 nested signals. */
68c1021b
PMF
712
713void sighandler(int sig)
714{
d0b5f2b9 715 static char have_listener = 0;
68c1021b 716 DBG("sighandler");
d0b5f2b9
PMF
717
718 if(!have_listener) {
719 create_listener();
720 have_listener = 1;
721 }
68c1021b
PMF
722}
723
724/* Called by the app signal handler to chain it to us. */
725
98963de4 726void chain_signal(void)
68c1021b
PMF
727{
728 sighandler(USTSIGNAL);
729}
730
98963de4 731static int init_socket(void)
68c1021b 732{
d0b5f2b9 733 return ustcomm_init_app(getpid(), &ustcomm_app);
68c1021b
PMF
734}
735
98963de4 736static void destroy_socket(void)
68c1021b 737{
46ef48cd
PMF
738// int result;
739//
740// if(mysocketfile[0] == '\0')
741// return;
742//
743// result = unlink(mysocketfile);
744// if(result == -1) {
745// PERROR("unlink");
746// }
68c1021b
PMF
747}
748
98963de4 749static int init_signal_handler(void)
68c1021b
PMF
750{
751 /* Attempt to handler SIGIO. If the main program wants to
752 * handle it, fine, it'll override us. They it'll have to
753 * use the chaining function.
754 */
755
756 int result;
757 struct sigaction act;
758
759 result = sigemptyset(&act.sa_mask);
760 if(result == -1) {
761 PERROR("sigemptyset");
762 return -1;
763 }
764
765 act.sa_handler = sighandler;
766 act.sa_flags = SA_RESTART;
767
768 /* Only defer ourselves. Also, try to restart interrupted
769 * syscalls to disturb the traced program as little as possible.
770 */
771 result = sigaction(SIGIO, &act, NULL);
772 if(result == -1) {
773 PERROR("sigaction");
774 return -1;
775 }
776
777 return 0;
778}
779
20b37a31 780static void auto_probe_connect(struct marker *m)
68c1021b
PMF
781{
782 int result;
783
20b37a31
PMF
784 result = ltt_marker_connect(m->channel, m->name, "default");
785 if(result)
786 ERR("ltt_marker_connect");
787
788 DBG("just auto connected marker %s %s to probe default", m->channel, m->name);
789}
790
791static void __attribute__((constructor(101))) init0()
792{
793 DBG("UST_AUTOPROBE constructor");
794 if(getenv("UST_AUTOPROBE")) {
795 marker_set_new_marker_cb(auto_probe_connect);
796 }
797}
798
a584bc4e
PMF
799static void fini(void);
800
20b37a31
PMF
801static void __attribute__((constructor(1000))) init()
802{
803 int result;
804
805 DBG("UST_TRACE constructor");
806
3847c3ba
PMF
807 /* Must create socket before signal handler to prevent races.
808 */
809 result = init_socket();
810 if(result == -1) {
811 ERR("init_socket error");
812 return;
813 }
814 result = init_signal_handler();
815 if(result == -1) {
816 ERR("init_signal_handler error");
817 return;
818 }
68c1021b 819
4db647c5
PMF
820 if(getenv("UST_TRACE")) {
821 char trace_name[] = "auto";
822 char trace_type[] = "ustrelay";
823
824 DBG("starting early tracing");
825
826 /* Ensure marker control is initialized */
827 init_marker_control();
828
829 /* Ensure relay is initialized */
830 init_ustrelay_transport();
831
832 /* Ensure markers are initialized */
833 init_markers();
834
20b37a31
PMF
835 /* In case. */
836 ltt_channels_register("ust");
4db647c5
PMF
837
838 result = ltt_trace_setup(trace_name);
839 if(result < 0) {
840 ERR("ltt_trace_setup failed");
841 return;
842 }
843
844 result = ltt_trace_set_type(trace_name, trace_type);
845 if(result < 0) {
846 ERR("ltt_trace_set_type failed");
847 return;
848 }
849
850 result = ltt_trace_alloc(trace_name);
851 if(result < 0) {
852 ERR("ltt_trace_alloc failed");
853 return;
854 }
855
856 result = ltt_trace_start(trace_name);
857 if(result < 0) {
858 ERR("ltt_trace_start failed");
859 return;
860 }
3847c3ba 861 inform_consumer_daemon();
4db647c5
PMF
862 }
863
68c1021b
PMF
864
865 return;
866
867 /* should decrementally destroy stuff if error */
868
869}
870
871/* This is only called if we terminate normally, not with an unhandled signal,
872 * so we cannot rely on it. */
873
899b5967
PMF
874/* This destructor probably isn't needed, because ustd can do crash recovery. */
875#if 0
98963de4 876static void __attribute__((destructor)) fini()
68c1021b 877{
a584bc4e
PMF
878 int result;
879
880 /* if trace running, finish it */
881
882 DBG("destructor stopping traces");
883
884 result = ltt_trace_stop("auto");
885 if(result == -1) {
886 ERR("ltt_trace_stop error");
887 }
888
889 result = ltt_trace_destroy("auto");
890 if(result == -1) {
891 ERR("ltt_trace_destroy error");
892 }
893
68c1021b
PMF
894 destroy_socket();
895}
899b5967 896#endif
This page took 0.064534 seconds and 5 git commands to generate.