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