Fix a zmalloc bug
[ust.git] / libust / tracectl.c
CommitLineData
c39c72ee
PMF
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
1eba9d6b
PMF
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
872037bb 23#define _GNU_SOURCE
68c1021b 24#include <stdio.h>
909bc43f 25#include <stdlib.h>
68c1021b 26#include <stdint.h>
f51d84ea 27#include <pthread.h>
68c1021b 28#include <signal.h>
4723ca09
NC
29#include <sys/epoll.h>
30#include <sys/time.h>
68c1021b
PMF
31#include <sys/types.h>
32#include <sys/socket.h>
a584bc4e 33#include <fcntl.h>
3a7b90de 34#include <poll.h>
ef290fca 35#include <regex.h>
b102c2b0 36#include <urcu/uatomic_arch.h>
4723ca09 37#include <urcu/list.h>
fbd8191b 38
93d0f2ea 39#include <ust/marker.h>
a3adfb05 40#include <ust/tracepoint.h>
616ed36a 41#include <ust/tracectl.h>
c93858f1 42#include "tracer.h"
6af64c43 43#include "usterr.h"
d0b5f2b9 44#include "ustcomm.h"
b73a4c47 45#include "buffers.h"
9160b4e4 46#include "marker-control.h"
fbd8191b 47
68c1021b
PMF
48#define USTSIGNAL SIGIO
49
98963de4
PMF
50#define MAX_MSG_SIZE (100)
51#define MSG_NOTIF 1
52#define MSG_REGISTER_NOTIF 2
53
ed1317e7
PMF
54/* This should only be accessed by the constructor, before the creation
55 * of the listener, and then only by the listener.
56 */
57s64 pidunique = -1LL;
58
4723ca09
NC
59static int epoll_fd;
60static struct ustcomm_sock *listen_sock;
223f2e7c 61
4723ca09 62extern struct chan_info_struct chan_infos[];
3a7b90de 63
4723ca09 64static struct list_head open_buffers_list = LIST_HEAD_INIT(open_buffers_list);
d0b5f2b9 65
4723ca09 66static struct list_head ust_socks = LIST_HEAD_INIT(ust_socks);
68c1021b 67
f293009f 68/* volatile because shared between the listener and the main thread */
8649cd59 69int buffers_to_export = 0;
f293009f 70
ed1317e7
PMF
71static 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
52c51a47 85static void print_markers(FILE *fp)
fbd8191b
PMF
86{
87 struct marker_iter iter;
88
d0b5f2b9 89 lock_markers();
fbd8191b
PMF
90 marker_iter_reset(&iter);
91 marker_iter_start(&iter);
92
e9b58dc0 93 while (iter.marker) {
4723ca09
NC
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);
fbd8191b
PMF
100 marker_iter_next(&iter);
101 }
d0b5f2b9 102 unlock_markers();
fbd8191b
PMF
103}
104
a3adfb05
NC
105static 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
e9b58dc0 113 while (iter.trace_event) {
a3adfb05
NC
114 fprintf(fp, "trace_event: %s\n", iter.trace_event->name);
115 trace_event_iter_next(&iter);
116 }
117 unlock_trace_events();
118}
119
ad45e833
PMF
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
127static void inform_consumer_daemon(const char *trace_name)
d0b5f2b9 128{
204141ee 129 int i,j;
b73a4c47 130 struct ust_trace *trace;
ad45e833
PMF
131 pid_t pid = getpid();
132 int result;
133
134 ltt_lock_traces();
135
136 trace = _ltt_trace_find(trace_name);
e9b58dc0 137 if (trace == NULL) {
ad45e833
PMF
138 WARN("inform_consumer_daemon: could not find trace \"%s\"; it is probably already destroyed", trace_name);
139 goto finish;
140 }
141
e9b58dc0
DS
142 for (i=0; i < trace->nr_channels; i++) {
143 if (trace->channels[i].request_collection) {
8649cd59 144 /* iterate on all cpus */
e9b58dc0 145 for (j=0; j<trace->channels[i].n_cpus; j++) {
8649cd59 146 char *buf;
08b8805e
DG
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 }
8649cd59 152 result = ustcomm_request_consumer(pid, buf);
e9b58dc0 153 if (result == -1) {
4723ca09
NC
154 WARN("Failed to request collection for channel %s. Is the daemon available?",
155 trace->channels[i].channel_name);
8649cd59
PMF
156 /* continue even if fail */
157 }
158 free(buf);
159 STORE_SHARED(buffers_to_export, LOAD_SHARED(buffers_to_export)+1);
204141ee 160 }
ad45e833
PMF
161 }
162 }
163
164 finish:
165 ltt_unlock_traces();
d0b5f2b9 166}
fbd8191b 167
204141ee
PMF
168void seperate_channel_cpu(const char *channel_and_cpu, char **channel, int *cpu)
169{
170 const char *sep;
171
172 sep = rindex(channel_and_cpu, '_');
e9b58dc0 173 if (sep == NULL) {
204141ee
PMF
174 *cpu = -1;
175 sep = channel_and_cpu + strlen(channel_and_cpu);
e9b58dc0 176 } else {
204141ee
PMF
177 *cpu = atoi(sep+1);
178 }
179
08b8805e
DG
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 }
204141ee
PMF
185}
186
4723ca09 187static int do_cmd_get_shmid(const char *recvbuf, int sock)
204141ee
PMF
188{
189 int retval = 0;
b73a4c47 190 struct ust_trace *trace;
204141ee
PMF
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);
e9b58dc0 202 if (channel_and_cpu == NULL) {
27e84572 203 ERR("cannot parse channel");
5624d402 204 retval = -1;
204141ee
PMF
205 goto end;
206 }
207
208 seperate_channel_cpu(channel_and_cpu, &ch_name, &ch_cpu);
e9b58dc0 209 if (ch_cpu == -1) {
27e84572 210 ERR("problem parsing channel name");
5624d402 211 retval = -1;
204141ee
PMF
212 goto free_short_chan_name;
213 }
214
215 ltt_lock_traces();
216 trace = _ltt_trace_find(trace_name);
217 ltt_unlock_traces();
218
e9b58dc0 219 if (trace == NULL) {
204141ee
PMF
220 ERR("cannot find trace!");
221 retval = -1;
222 goto free_short_chan_name;
223 }
224
e9b58dc0 225 for (i=0; i<trace->nr_channels; i++) {
204141ee
PMF
226 struct ust_channel *channel = &trace->channels[i];
227 struct ust_buffer *buf = channel->buf[ch_cpu];
228
e9b58dc0 229 if (!strcmp(trace->channels[i].channel_name, ch_name)) {
204141ee
PMF
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);
08b8805e
DG
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 }
204141ee 240
4723ca09 241 result = ustcomm_send_reply(reply, sock);
e9b58dc0 242 if (result) {
27e84572 243 ERR("ustcomm_send_reply failed");
204141ee
PMF
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
e9b58dc0 256 if (!found) {
27e84572 257 ERR("channel not found (%s)", channel_and_cpu);
204141ee
PMF
258 }
259
260 free_short_chan_name:
261 free(ch_name);
262
263 end:
264 return retval;
265}
266
4723ca09 267static int do_cmd_get_n_subbufs(const char *recvbuf, int sock)
204141ee
PMF
268{
269 int retval = 0;
b73a4c47 270 struct ust_trace *trace;
204141ee
PMF
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);
e9b58dc0 282 if (channel_and_cpu == NULL) {
27e84572 283 ERR("cannot parse channel");
5624d402 284 retval = -1;
204141ee
PMF
285 goto end;
286 }
287
288 seperate_channel_cpu(channel_and_cpu, &ch_name, &ch_cpu);
e9b58dc0 289 if (ch_cpu == -1) {
27e84572 290 ERR("problem parsing channel name");
5624d402 291 retval = -1;
204141ee
PMF
292 goto free_short_chan_name;
293 }
294
295 ltt_lock_traces();
296 trace = _ltt_trace_find(trace_name);
297 ltt_unlock_traces();
298
e9b58dc0 299 if (trace == NULL) {
204141ee
PMF
300 ERR("cannot find trace!");
301 retval = -1;
302 goto free_short_chan_name;
303 }
304
e9b58dc0 305 for (i=0; i<trace->nr_channels; i++) {
204141ee
PMF
306 struct ust_channel *channel = &trace->channels[i];
307
e9b58dc0 308 if (!strcmp(trace->channels[i].channel_name, ch_name)) {
204141ee
PMF
309 char *reply;
310
311 DBG("the n_subbufs for the requested channel is %d", channel->subbuf_cnt);
08b8805e
DG
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 }
204141ee 318
4723ca09 319 result = ustcomm_send_reply(reply, sock);
e9b58dc0 320 if (result) {
27e84572 321 ERR("ustcomm_send_reply failed");
204141ee
PMF
322 free(reply);
323 retval = -1;
324 goto free_short_chan_name;
325 }
326
327 free(reply);
328 found = 1;
329 break;
330 }
331 }
e9b58dc0 332 if (found == 0) {
27e84572 333 ERR("unable to find channel");
204141ee
PMF
334 }
335
336 free_short_chan_name:
337 free(ch_name);
338
339 end:
340 return retval;
341}
342
4723ca09 343static int do_cmd_get_subbuf_size(const char *recvbuf, int sock)
204141ee
PMF
344{
345 int retval = 0;
b73a4c47 346 struct ust_trace *trace;
204141ee
PMF
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);
e9b58dc0 358 if (channel_and_cpu == NULL) {
27e84572 359 ERR("cannot parse channel");
5624d402 360 retval = -1;
204141ee
PMF
361 goto end;
362 }
363
364 seperate_channel_cpu(channel_and_cpu, &ch_name, &ch_cpu);
e9b58dc0 365 if (ch_cpu == -1) {
27e84572 366 ERR("problem parsing channel name");
5624d402 367 retval = -1;
204141ee
PMF
368 goto free_short_chan_name;
369 }
370
371 ltt_lock_traces();
372 trace = _ltt_trace_find(trace_name);
373 ltt_unlock_traces();
374
e9b58dc0 375 if (trace == NULL) {
204141ee
PMF
376 ERR("cannot find trace!");
377 retval = -1;
378 goto free_short_chan_name;
379 }
380
e9b58dc0 381 for (i=0; i<trace->nr_channels; i++) {
204141ee
PMF
382 struct ust_channel *channel = &trace->channels[i];
383
e9b58dc0 384 if (!strcmp(trace->channels[i].channel_name, ch_name)) {
204141ee
PMF
385 char *reply;
386
387 DBG("the subbuf_size for the requested channel is %zd", channel->subbuf_size);
08b8805e
DG
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 }
204141ee 394
4723ca09 395 result = ustcomm_send_reply(reply, sock);
e9b58dc0 396 if (result) {
27e84572 397 ERR("ustcomm_send_reply failed");
204141ee
PMF
398 free(reply);
399 retval = -1;
400 goto free_short_chan_name;
401 }
402
403 free(reply);
404 found = 1;
405 break;
406 }
407 }
e9b58dc0 408 if (found == 0) {
27e84572 409 ERR("unable to find channel");
204141ee
PMF
410 }
411
412 free_short_chan_name:
413 free(ch_name);
414
415 end:
416 return retval;
417}
418
a80e6dd8 419/* Return the power of two which is equal or higher to v */
763f41e5 420
a80e6dd8
PMF
421static unsigned int pow2_higher_or_eq(unsigned int v)
422{
423 int hb = fls(v);
a80e6dd8
PMF
424 int retval = 1<<(hb-1);
425
e9b58dc0 426 if (v-retval == 0)
a80e6dd8
PMF
427 return retval;
428 else
429 return retval<<1;
763f41e5
DS
430}
431
4723ca09 432static int do_cmd_set_subbuf_size(const char *recvbuf, int sock)
763f41e5
DS
433{
434 char *channel_slash_size;
c5ff938a 435 char *ch_name = NULL;
763f41e5
DS
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);
c5ff938a 446 sscanf(channel_slash_size, "%a[^/]/%u", &ch_name, &size);
763f41e5 447
e9b58dc0 448 if (ch_name == NULL) {
763f41e5 449 ERR("cannot parse channel");
5624d402 450 retval = -1;
763f41e5
DS
451 goto end;
452 }
453
a80e6dd8
PMF
454 power = pow2_higher_or_eq(size);
455 power = max_t(unsigned int, 2u, power);
763f41e5 456 if (power != size)
a80e6dd8 457 WARN("using the next power of two for buffer size = %u\n", power);
763f41e5
DS
458
459 ltt_lock_traces();
460 trace = _ltt_trace_find_setup(trace_name);
e9b58dc0 461 if (trace == NULL) {
763f41e5 462 ERR("cannot find trace!");
763f41e5
DS
463 retval = -1;
464 goto end;
465 }
466
e9b58dc0 467 for (i = 0; i < trace->nr_channels; i++) {
763f41e5
DS
468 struct ust_channel *channel = &trace->channels[i];
469
e9b58dc0 470 if (!strcmp(trace->channels[i].channel_name, ch_name)) {
763f41e5
DS
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 }
e9b58dc0 479 if (found == 0) {
763f41e5
DS
480 ERR("unable to find channel");
481 }
482
763f41e5 483 end:
86dd0ebc 484 ltt_unlock_traces();
c5ff938a 485 free(ch_name);
763f41e5
DS
486 return retval;
487}
488
4723ca09 489static int do_cmd_set_subbuf_num(const char *recvbuf, int sock)
763f41e5
DS
490{
491 char *channel_slash_num;
c5ff938a 492 char *ch_name = NULL;
763f41e5
DS
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);
c5ff938a 503 sscanf(channel_slash_num, "%a[^/]/%u", &ch_name, &num);
763f41e5 504
e9b58dc0 505 if (ch_name == NULL) {
763f41e5 506 ERR("cannot parse channel");
5624d402 507 retval = -1;
763f41e5
DS
508 goto end;
509 }
510 if (num < 2) {
511 ERR("subbuffer count should be greater than 2");
5624d402 512 retval = -1;
763f41e5
DS
513 goto end;
514 }
515
516 ltt_lock_traces();
517 trace = _ltt_trace_find_setup(trace_name);
e9b58dc0 518 if (trace == NULL) {
763f41e5 519 ERR("cannot find trace!");
763f41e5
DS
520 retval = -1;
521 goto end;
522 }
523
e9b58dc0 524 for (i = 0; i < trace->nr_channels; i++) {
763f41e5
DS
525 struct ust_channel *channel = &trace->channels[i];
526
e9b58dc0 527 if (!strcmp(trace->channels[i].channel_name, ch_name)) {
763f41e5
DS
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 }
e9b58dc0 536 if (found == 0) {
763f41e5
DS
537 ERR("unable to find channel");
538 }
539
763f41e5 540 end:
86dd0ebc 541 ltt_unlock_traces();
c5ff938a 542 free(ch_name);
763f41e5
DS
543 return retval;
544}
545
4723ca09
NC
546static 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
652static int do_cmd_get_buffer_fd(const char *recvbuf, int sock)
204141ee
PMF
653{
654 int retval = 0;
b73a4c47 655 struct ust_trace *trace;
204141ee
PMF
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;
4723ca09 662 struct ustcomm_header header;
204141ee 663
4723ca09 664 DBG("get_buffer_fd");
204141ee
PMF
665
666 channel_and_cpu = nth_token(recvbuf, 1);
e9b58dc0 667 if (channel_and_cpu == NULL) {
27e84572 668 ERR("cannot parse channel");
5624d402 669 retval = -1;
204141ee
PMF
670 goto end;
671 }
672
673 seperate_channel_cpu(channel_and_cpu, &ch_name, &ch_cpu);
e9b58dc0 674 if (ch_cpu == -1) {
27e84572 675 ERR("problem parsing channel name");
5624d402 676 retval = -1;
204141ee
PMF
677 goto free_short_chan_name;
678 }
679
680 ltt_lock_traces();
681 trace = _ltt_trace_find(trace_name);
204141ee 682
e9b58dc0 683 if (trace == NULL) {
2ddb81a8
PMF
684 int result;
685
753e1b51 686 DBG("Cannot find trace. It was likely destroyed by the user.");
4723ca09 687 result = ustcomm_send_reply("NOTFOUND", sock);
e9b58dc0 688 if (result) {
2ddb81a8 689 ERR("ustcomm_send_reply failed");
2ddb81a8 690 retval = -1;
86dd0ebc 691 goto unlock_traces;
2ddb81a8
PMF
692 }
693
86dd0ebc 694 goto unlock_traces;
204141ee
PMF
695 }
696
e9b58dc0 697 for (i=0; i<trace->nr_channels; i++) {
204141ee
PMF
698 struct ust_channel *channel = &trace->channels[i];
699
e9b58dc0 700 if (!strcmp(trace->channels[i].channel_name, ch_name)) {
204141ee 701 struct ust_buffer *buf = channel->buf[ch_cpu];
204141ee
PMF
702
703 found = 1;
704
4723ca09
NC
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");
86dd0ebc 710 goto unlock_traces;
204141ee 711 }
204141ee 712
d5adede0
PMF
713 /* Being here is the proof the daemon has mapped the buffer in its
714 * memory. We may now decrement buffers_to_export.
715 */
e9b58dc0 716 if (uatomic_read(&buf->consumed) == 0) {
d5adede0 717 DBG("decrementing buffers_to_export");
8649cd59 718 STORE_SHARED(buffers_to_export, LOAD_SHARED(buffers_to_export)-1);
d5adede0
PMF
719 }
720
4723ca09
NC
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);
204141ee
PMF
725 break;
726 }
727 }
e9b58dc0 728 if (found == 0) {
27e84572 729 ERR("unable to find channel");
204141ee
PMF
730 }
731
86dd0ebc
PMF
732 unlock_traces:
733 ltt_unlock_traces();
734
204141ee
PMF
735 free_short_chan_name:
736 free(ch_name);
737
738 end:
739 return retval;
740}
741
4723ca09 742static int do_cmd_put_subbuffer(const char *recvbuf, int sock)
204141ee
PMF
743{
744 int retval = 0;
b73a4c47 745 struct ust_trace *trace;
204141ee
PMF
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;
2ddb81a8 756 char *reply = NULL;
204141ee
PMF
757
758 DBG("put_subbuf");
759
ce2ccc12 760 channel_and_cpu = strdup(nth_token(recvbuf, 1));
e9b58dc0 761 if (channel_and_cpu == NULL) {
27e84572 762 ERR("cannot parse channel");
204141ee
PMF
763 retval = -1;
764 goto end;
765 }
766
ce2ccc12 767 consumed_old_str = strdup(nth_token(recvbuf, 2));
e9b58dc0 768 if (consumed_old_str == NULL) {
27e84572 769 ERR("cannot parse consumed_old");
204141ee
PMF
770 retval = -1;
771 goto free_channel_and_cpu;
772 }
773 consumed_old = strtol(consumed_old_str, &endptr, 10);
e9b58dc0 774 if (*endptr != '\0') {
27e84572 775 ERR("invalid value for consumed_old");
204141ee
PMF
776 retval = -1;
777 goto free_consumed_old_str;
778 }
779
780 seperate_channel_cpu(channel_and_cpu, &ch_name, &ch_cpu);
e9b58dc0 781 if (ch_cpu == -1) {
27e84572 782 ERR("problem parsing channel name");
204141ee
PMF
783 retval = -1;
784 goto free_short_chan_name;
785 }
786
787 ltt_lock_traces();
788 trace = _ltt_trace_find(trace_name);
204141ee 789
e9b58dc0 790 if (trace == NULL) {
753e1b51 791 DBG("Cannot find trace. It was likely destroyed by the user.");
4723ca09 792 result = ustcomm_send_reply("NOTFOUND", sock);
e9b58dc0 793 if (result) {
2ddb81a8 794 ERR("ustcomm_send_reply failed");
2ddb81a8 795 retval = -1;
86dd0ebc 796 goto unlock_traces;
2ddb81a8
PMF
797 }
798
86dd0ebc 799 goto unlock_traces;
204141ee
PMF
800 }
801
e9b58dc0 802 for (i=0; i<trace->nr_channels; i++) {
204141ee
PMF
803 struct ust_channel *channel = &trace->channels[i];
804
e9b58dc0 805 if (!strcmp(trace->channels[i].channel_name, ch_name)) {
204141ee 806 struct ust_buffer *buf = channel->buf[ch_cpu];
204141ee
PMF
807
808 found = 1;
809
b73a4c47 810 result = ust_buffers_put_subbuf(buf, consumed_old);
e9b58dc0 811 if (result < 0) {
b73a4c47 812 WARN("ust_buffers_put_subbuf: error (subbuf=%s)", channel_and_cpu);
08b8805e
DG
813 if (asprintf(&reply, "%s", "ERROR") < 0) {
814 ERR("do_cmd_put_subbuffer : asprintf failed (ERROR)");
815 retval = -1;
816 goto unlock_traces;
817 }
e9b58dc0 818 } else {
b73a4c47 819 DBG("ust_buffers_put_subbuf: success (subbuf=%s)", channel_and_cpu);
08b8805e
DG
820 if (asprintf(&reply, "%s", "OK") < 0) {
821 ERR("do_cmd_put_subbuffer : asprintf failed (OK)");
822 retval = -1;
823 goto unlock_traces;
824 }
204141ee
PMF
825 }
826
4723ca09 827 result = ustcomm_send_reply(reply, sock);
e9b58dc0 828 if (result) {
27e84572 829 ERR("ustcomm_send_reply failed");
204141ee
PMF
830 free(reply);
831 retval = -1;
86dd0ebc 832 goto unlock_traces;
204141ee
PMF
833 }
834
835 free(reply);
836 break;
837 }
838 }
e9b58dc0 839 if (found == 0) {
2ddb81a8 840 ERR("unable to find channel");
204141ee
PMF
841 }
842
86dd0ebc
PMF
843 unlock_traces:
844 ltt_unlock_traces();
204141ee
PMF
845 free_short_chan_name:
846 free(ch_name);
2ddb81a8
PMF
847 free_consumed_old_str:
848 free(consumed_old_str);
849 free_channel_and_cpu:
850 free(channel_and_cpu);
204141ee
PMF
851
852 end:
853 return retval;
854}
855
fc253ce0
PMF
856static void listener_cleanup(void *ptr)
857{
4723ca09 858 ustcomm_del_named_sock(listen_sock, 0);
fc253ce0
PMF
859}
860
b9318b35
AH
861static void do_cmd_force_switch()
862{
4723ca09 863 struct ust_buffer *buf;
b9318b35 864
4723ca09
NC
865 list_for_each_entry(buf, &open_buffers_list,
866 open_buffers_list) {
867 ltt_force_switch(buf, FORCE_FLUSH);
b9318b35
AH
868 }
869}
870
4723ca09 871static int process_client_cmd(char *recvbuf, int sock)
98963de4
PMF
872{
873 int result;
0e4b45ac
PMF
874 char trace_name[] = "auto";
875 char trace_type[] = "ustrelay";
876 int len;
98963de4 877
0e4b45ac 878 len = strlen(recvbuf);
b0540e11 879
e9b58dc0 880 if (!strcmp(recvbuf, "print_markers")) {
0e4b45ac 881 print_markers(stderr);
e9b58dc0 882 } else if (!strcmp(recvbuf, "list_markers")) {
0e4b45ac
PMF
883 char *ptr;
884 size_t size;
885 FILE *fp;
fc253ce0 886
0e4b45ac
PMF
887 fp = open_memstream(&ptr, &size);
888 print_markers(fp);
889 fclose(fp);
98963de4 890
4723ca09 891 result = ustcomm_send_reply(ptr, sock);
3a7b90de 892
0e4b45ac 893 free(ptr);
a3adfb05
NC
894 } else if (!strcmp(recvbuf, "print_trace_events")) {
895 print_trace_events(stderr);
896
e9b58dc0 897 } else if (!strcmp(recvbuf, "list_trace_events")) {
a3adfb05
NC
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
4723ca09 910 result = ustcomm_send_reply(ptr, sock);
a3adfb05
NC
911 if (result < 0) {
912 ERR("list_trace_events failed");
913 return -1;
914 }
915 free(ptr);
e9b58dc0 916 } else if (!strcmp(recvbuf, "start")) {
0e4b45ac
PMF
917 /* start is an operation that setups the trace, allocates it and starts it */
918 result = ltt_trace_setup(trace_name);
e9b58dc0 919 if (result < 0) {
0e4b45ac
PMF
920 ERR("ltt_trace_setup failed");
921 return -1;
3a7b90de 922 }
98963de4 923
0e4b45ac 924 result = ltt_trace_set_type(trace_name, trace_type);
e9b58dc0 925 if (result < 0) {
0e4b45ac
PMF
926 ERR("ltt_trace_set_type failed");
927 return -1;
52c51a47 928 }
52c51a47 929
0e4b45ac 930 result = ltt_trace_alloc(trace_name);
e9b58dc0 931 if (result < 0) {
0e4b45ac
PMF
932 ERR("ltt_trace_alloc failed");
933 return -1;
52c51a47 934 }
52c51a47 935
0e4b45ac 936 inform_consumer_daemon(trace_name);
52c51a47 937
0e4b45ac 938 result = ltt_trace_start(trace_name);
e9b58dc0 939 if (result < 0) {
0e4b45ac
PMF
940 ERR("ltt_trace_start failed");
941 return -1;
d0b5f2b9 942 }
e9b58dc0 943 } else if (!strcmp(recvbuf, "trace_setup")) {
0e4b45ac 944 DBG("trace setup");
d0b5f2b9 945
0e4b45ac 946 result = ltt_trace_setup(trace_name);
e9b58dc0 947 if (result < 0) {
0e4b45ac
PMF
948 ERR("ltt_trace_setup failed");
949 return -1;
d0b5f2b9 950 }
d0b5f2b9 951
0e4b45ac 952 result = ltt_trace_set_type(trace_name, trace_type);
e9b58dc0 953 if (result < 0) {
0e4b45ac
PMF
954 ERR("ltt_trace_set_type failed");
955 return -1;
d0b5f2b9 956 }
e9b58dc0 957 } else if (!strcmp(recvbuf, "trace_alloc")) {
0e4b45ac 958 DBG("trace alloc");
62ec620f 959
0e4b45ac 960 result = ltt_trace_alloc(trace_name);
e9b58dc0 961 if (result < 0) {
0e4b45ac
PMF
962 ERR("ltt_trace_alloc failed");
963 return -1;
763f41e5 964 }
0e4b45ac 965 inform_consumer_daemon(trace_name);
e9b58dc0 966 } else if (!strcmp(recvbuf, "trace_create")) {
0e4b45ac 967 DBG("trace create");
d0b5f2b9 968
0e4b45ac 969 result = ltt_trace_setup(trace_name);
e9b58dc0 970 if (result < 0) {
0e4b45ac
PMF
971 ERR("ltt_trace_setup failed");
972 return -1;
d0b5f2b9 973 }
d0b5f2b9 974
0e4b45ac 975 result = ltt_trace_set_type(trace_name, trace_type);
e9b58dc0 976 if (result < 0) {
0e4b45ac
PMF
977 ERR("ltt_trace_set_type failed");
978 return -1;
d0b5f2b9 979 }
e9b58dc0 980 } else if (!strcmp(recvbuf, "trace_start")) {
0e4b45ac 981 DBG("trace start");
aafb1650 982
0e4b45ac 983 result = ltt_trace_alloc(trace_name);
e9b58dc0 984 if (result < 0) {
0e4b45ac
PMF
985 ERR("ltt_trace_alloc failed");
986 return -1;
811e4b93 987 }
e9b58dc0 988 if (!result) {
0e4b45ac 989 inform_consumer_daemon(trace_name);
811e4b93 990 }
0e4b45ac
PMF
991
992 result = ltt_trace_start(trace_name);
e9b58dc0 993 if (result < 0) {
0e4b45ac
PMF
994 ERR("ltt_trace_start failed");
995 return -1;
3847c3ba 996 }
e9b58dc0 997 } else if (!strcmp(recvbuf, "trace_stop")) {
0e4b45ac 998 DBG("trace stop");
b02e31e5 999
0e4b45ac 1000 result = ltt_trace_stop(trace_name);
e9b58dc0 1001 if (result < 0) {
0e4b45ac
PMF
1002 ERR("ltt_trace_stop failed");
1003 return -1;
1004 }
e9b58dc0 1005 } else if (!strcmp(recvbuf, "trace_destroy")) {
b02e31e5 1006
0e4b45ac 1007 DBG("trace destroy");
204141ee 1008
0e4b45ac 1009 result = ltt_trace_destroy(trace_name, 0);
e9b58dc0 1010 if (result < 0) {
0e4b45ac
PMF
1011 ERR("ltt_trace_destroy failed");
1012 return -1;
763f41e5 1013 }
e9b58dc0 1014 } else if (nth_token_is(recvbuf, "get_shmid", 0) == 1) {
4723ca09 1015 do_cmd_get_shmid(recvbuf, sock);
e9b58dc0 1016 } else if (nth_token_is(recvbuf, "get_n_subbufs", 0) == 1) {
4723ca09 1017 do_cmd_get_n_subbufs(recvbuf, sock);
e9b58dc0 1018 } else if (nth_token_is(recvbuf, "get_subbuf_size", 0) == 1) {
4723ca09 1019 do_cmd_get_subbuf_size(recvbuf, sock);
e9b58dc0 1020 } else if (nth_token_is(recvbuf, "load_probe_lib", 0) == 1) {
0e4b45ac 1021 char *libfile;
52c51a47 1022
0e4b45ac 1023 libfile = nth_token(recvbuf, 1);
52c51a47 1024
0e4b45ac 1025 DBG("load_probe_lib loading %s", libfile);
52c51a47 1026
0e4b45ac 1027 free(libfile);
e9b58dc0 1028 } else if (nth_token_is(recvbuf, "get_subbuffer", 0) == 1) {
4723ca09
NC
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);
e9b58dc0 1036 } else if (nth_token_is(recvbuf, "set_subbuf_size", 0) == 1) {
4723ca09 1037 do_cmd_set_subbuf_size(recvbuf, sock);
e9b58dc0 1038 } else if (nth_token_is(recvbuf, "set_subbuf_num", 0) == 1) {
4723ca09 1039 do_cmd_set_subbuf_num(recvbuf, sock);
e9b58dc0 1040 } else if (nth_token_is(recvbuf, "enable_marker", 0) == 1) {
0e4b45ac 1041 char *channel_slash_name = nth_token(recvbuf, 1);
c5ff938a
DS
1042 char *channel_name = NULL;
1043 char *marker_name = NULL;
0e4b45ac 1044
c5ff938a 1045 result = sscanf(channel_slash_name, "%a[^/]/%as", &channel_name, &marker_name);
0e4b45ac 1046
e9b58dc0 1047 if (channel_name == NULL || marker_name == NULL) {
0e4b45ac 1048 WARN("invalid marker name");
c5ff938a
DS
1049 free(channel_name);
1050 free(marker_name);
0e4b45ac 1051 goto next_cmd;
52c51a47 1052 }
52c51a47 1053
0e4b45ac 1054 result = ltt_marker_connect(channel_name, marker_name, "default");
e9b58dc0 1055 if (result < 0) {
0e4b45ac
PMF
1056 WARN("could not enable marker; channel=%s, name=%s", channel_name, marker_name);
1057 }
c5ff938a
DS
1058
1059 free(channel_name);
1060 free(marker_name);
e9b58dc0 1061 } else if (nth_token_is(recvbuf, "disable_marker", 0) == 1) {
0e4b45ac 1062 char *channel_slash_name = nth_token(recvbuf, 1);
c5ff938a
DS
1063 char *marker_name = NULL;
1064 char *channel_name = NULL;
52c51a47 1065
0e4b45ac 1066 result = sscanf(channel_slash_name, "%a[^/]/%as", &channel_name, &marker_name);
52c51a47 1067
e9b58dc0 1068 if (channel_name == NULL || marker_name == NULL) {
b17081c0 1069 WARN("invalid marker name");
c5ff938a
DS
1070 free(channel_name);
1071 free(marker_name);
b17081c0 1072 goto next_cmd;
52c51a47 1073 }
ed1317e7 1074
0e4b45ac 1075 result = ltt_marker_disconnect(channel_name, marker_name, "default");
e9b58dc0 1076 if (result < 0) {
0e4b45ac
PMF
1077 WARN("could not disable marker; channel=%s, name=%s", channel_name, marker_name);
1078 }
c5ff938a
DS
1079
1080 free(channel_name);
1081 free(marker_name);
e9b58dc0 1082 } else if (nth_token_is(recvbuf, "get_pidunique", 0) == 1) {
0e4b45ac 1083 char *reply;
ed1317e7 1084
08b8805e
DG
1085 if (asprintf(&reply, "%lld", pidunique) < 0) {
1086 ERR("process_client_cmd : asprintf failed (%lld)",
1087 pidunique);
1088 goto next_cmd;
1089 }
ed1317e7 1090
4723ca09 1091 result = ustcomm_send_reply(reply, sock);
e9b58dc0 1092 if (result) {
0e4b45ac
PMF
1093 ERR("listener: get_pidunique: ustcomm_send_reply failed");
1094 goto next_cmd;
ed1317e7 1095 }
0e4b45ac
PMF
1096
1097 free(reply);
e9b58dc0 1098 } else if (nth_token_is(recvbuf, "get_sock_path", 0) == 1) {
b2fb2f91 1099 char *reply = getenv("UST_DAEMON_SOCKET");
e9b58dc0 1100 if (!reply) {
08b8805e
DG
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 }
4723ca09 1106 result = ustcomm_send_reply(reply, sock);
b2fb2f91 1107 free(reply);
e9b58dc0 1108 } else {
4723ca09 1109 result = ustcomm_send_reply(reply, sock);
b2fb2f91 1110 }
e9b58dc0 1111 if (result)
b2fb2f91 1112 ERR("ustcomm_send_reply failed");
e9b58dc0 1113 } else if (nth_token_is(recvbuf, "set_sock_path", 0) == 1) {
b2fb2f91
AH
1114 char *sock_path = nth_token(recvbuf, 1);
1115 result = setenv("UST_DAEMON_SOCKET", sock_path, 1);
e9b58dc0 1116 if (result)
b2fb2f91 1117 ERR("cannot set UST_DAEMON_SOCKET environment variable");
e9b58dc0 1118 } else if (nth_token_is(recvbuf, "force_switch", 0) == 1) {
b9318b35 1119 do_cmd_force_switch();
e9b58dc0 1120 } else {
0e4b45ac
PMF
1121 ERR("unable to parse message: %s", recvbuf);
1122 }
1123
1124next_cmd:
1125
1126 return 0;
1127}
1128
4723ca09
NC
1129#define MAX_EVENTS 10
1130
0e4b45ac
PMF
1131void *listener_main(void *p)
1132{
4723ca09
NC
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;
0e4b45ac
PMF
1137
1138 DBG("LISTENER");
1139
1140 pthread_cleanup_push(listener_cleanup, NULL);
1141
4723ca09
NC
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;
688760ef 1147 }
d0b5f2b9 1148
4723ca09
NC
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 }
98963de4 1173 }
fc253ce0
PMF
1174
1175 pthread_cleanup_pop(1);
98963de4
PMF
1176}
1177
cd03ff7f
PMF
1178/* These should only be accessed in the parent thread,
1179 * not the listener.
1180 */
ce45335c 1181static volatile sig_atomic_t have_listener = 0;
fc253ce0 1182static pthread_t listener_thread;
4440ebcb 1183
98963de4
PMF
1184void create_listener(void)
1185{
c5fdc888 1186 int result;
f51d84ea
PMF
1187 sigset_t sig_all_blocked;
1188 sigset_t orig_parent_mask;
98963de4 1189
e9b58dc0 1190 if (have_listener) {
c5fdc888 1191 WARN("not creating listener because we already had one");
4440ebcb 1192 return;
c5fdc888 1193 }
4440ebcb 1194
f51d84ea
PMF
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);
e9b58dc0 1204 if (result) {
f51d84ea
PMF
1205 PERROR("pthread_sigmask: %s", strerror(result));
1206 }
1207
cd03ff7f 1208 result = pthread_create(&listener_thread, NULL, listener_main, NULL);
e9b58dc0 1209 if (result == -1) {
cd03ff7f 1210 PERROR("pthread_create");
98963de4 1211 }
4440ebcb 1212
f51d84ea
PMF
1213 /* Restore original signal mask in parent */
1214 result = pthread_sigmask(SIG_SETMASK, &orig_parent_mask, NULL);
e9b58dc0 1215 if (result) {
f51d84ea 1216 PERROR("pthread_sigmask: %s", strerror(result));
e9b58dc0 1217 } else {
4267e589
PMF
1218 have_listener = 1;
1219 }
98963de4
PMF
1220}
1221
5de74e51
PMF
1222#define AUTOPROBE_DISABLED 0
1223#define AUTOPROBE_ENABLE_ALL 1
1224#define AUTOPROBE_ENABLE_REGEX 2
1225static int autoprobe_method = AUTOPROBE_DISABLED;
1226static regex_t autoprobe_regex;
ef290fca 1227
20b37a31 1228static void auto_probe_connect(struct marker *m)
68c1021b
PMF
1229{
1230 int result;
1231
5de74e51
PMF
1232 char* concat_name = NULL;
1233 const char *probe_name = "default";
ef290fca 1234
e9b58dc0 1235 if (autoprobe_method == AUTOPROBE_DISABLED) {
ef290fca 1236 return;
e9b58dc0 1237 } else if (autoprobe_method == AUTOPROBE_ENABLE_REGEX) {
5de74e51 1238 result = asprintf(&concat_name, "%s/%s", m->channel, m->name);
e9b58dc0 1239 if (result == -1) {
5de74e51
PMF
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);
ef290fca
PMF
1249 }
1250
5de74e51 1251 result = ltt_marker_connect(m->channel, m->name, probe_name);
e9b58dc0 1252 if (result && result != -EEXIST)
acbf228b 1253 ERR("ltt_marker_connect (marker = %s/%s, errno = %d)", m->channel, m->name, -result);
20b37a31 1254
3ea1e2fc 1255 DBG("auto connected marker %s (addr: %p) %s to probe default", m->channel, m, m->name);
ef290fca 1256
20b37a31
PMF
1257}
1258
4723ca09
NC
1259static 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
1289free_name:
1290 free(name);
1291 return NULL;
1292}
1293
c1083aa8 1294static void __attribute__((constructor)) init()
20b37a31
PMF
1295{
1296 int result;
5de74e51 1297 char* autoprobe_val = NULL;
223f2e7c
AH
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;
20b37a31 1303
ed1317e7
PMF
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
5de74e51 1309 DBG("Tracectl constructor");
20b37a31 1310
4723ca09
NC
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");
3847c3ba
PMF
1323 return;
1324 }
2944a629
PMF
1325
1326 create_listener();
68c1021b 1327
5de74e51 1328 autoprobe_val = getenv("UST_AUTOPROBE");
e9b58dc0 1329 if (autoprobe_val) {
4440ebcb
PMF
1330 struct marker_iter iter;
1331
08230db7 1332 DBG("Autoprobe enabled.");
4440ebcb
PMF
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 */
e9b58dc0 1343 if (autoprobe_val[0] == '/') {
5de74e51
PMF
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 */
e9b58dc0 1351 } else {
5de74e51
PMF
1352 autoprobe_method = AUTOPROBE_ENABLE_REGEX;
1353 }
e9b58dc0 1354 } else {
5de74e51
PMF
1355 /* just enable all instrumentation */
1356 autoprobe_method = AUTOPROBE_ENABLE_ALL;
1357 }
1358
1359 marker_set_new_marker_cb(auto_probe_connect);
1360
4440ebcb
PMF
1361 /* Now, connect the probes that were already registered. */
1362 marker_iter_reset(&iter);
1363 marker_iter_start(&iter);
1364
08230db7 1365 DBG("now iterating on markers already registered");
e9b58dc0 1366 while (iter.marker) {
08230db7 1367 DBG("now iterating on marker %s", iter.marker->name);
4440ebcb
PMF
1368 auto_probe_connect(iter.marker);
1369 marker_iter_next(&iter);
1370 }
1371 }
1372
e9b58dc0 1373 if (getenv("UST_OVERWRITE")) {
8649cd59 1374 int val = atoi(getenv("UST_OVERWRITE"));
e9b58dc0 1375 if (val == 0 || val == 1) {
8649cd59 1376 STORE_SHARED(ust_channels_overwrite_by_default, val);
e9b58dc0 1377 } else {
8649cd59
PMF
1378 WARN("invalid value for UST_OVERWRITE");
1379 }
1380 }
1381
e9b58dc0 1382 if (getenv("UST_AUTOCOLLECT")) {
8649cd59 1383 int val = atoi(getenv("UST_AUTOCOLLECT"));
e9b58dc0 1384 if (val == 0 || val == 1) {
8649cd59 1385 STORE_SHARED(ust_channels_request_collection_by_default, val);
e9b58dc0 1386 } else {
8649cd59
PMF
1387 WARN("invalid value for UST_AUTOCOLLECT");
1388 }
1389 }
1390
223f2e7c 1391 subbuffer_size_val = getenv("UST_SUBBUF_SIZE");
e9b58dc0 1392 if (subbuffer_size_val) {
223f2e7c
AH
1393 sscanf(subbuffer_size_val, "%u", &subbuffer_size);
1394 power = pow2_higher_or_eq(subbuffer_size);
e9b58dc0 1395 if (power != subbuffer_size)
223f2e7c
AH
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");
e9b58dc0 1401 if (subbuffer_count_val) {
223f2e7c 1402 sscanf(subbuffer_count_val, "%u", &subbuffer_count);
e9b58dc0 1403 if (subbuffer_count < 2)
223f2e7c
AH
1404 subbuffer_count = 2;
1405 chan_infos[LTT_CHANNEL_UST].def_subbufcount = subbuffer_count;
1406 }
1407
e9b58dc0 1408 if (getenv("UST_TRACE")) {
4db647c5
PMF
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
4db647c5
PMF
1417 /* Ensure markers are initialized */
1418 init_markers();
1419
e17571a5
PMF
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
027ffc9d
PMF
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 */
20b37a31 1443 ltt_channels_register("ust");
4db647c5
PMF
1444
1445 result = ltt_trace_setup(trace_name);
e9b58dc0 1446 if (result < 0) {
4db647c5
PMF
1447 ERR("ltt_trace_setup failed");
1448 return;
1449 }
1450
1451 result = ltt_trace_set_type(trace_name, trace_type);
e9b58dc0 1452 if (result < 0) {
4db647c5
PMF
1453 ERR("ltt_trace_set_type failed");
1454 return;
1455 }
1456
1457 result = ltt_trace_alloc(trace_name);
e9b58dc0 1458 if (result < 0) {
4db647c5
PMF
1459 ERR("ltt_trace_alloc failed");
1460 return;
1461 }
1462
1463 result = ltt_trace_start(trace_name);
e9b58dc0 1464 if (result < 0) {
4db647c5
PMF
1465 ERR("ltt_trace_start failed");
1466 return;
1467 }
60e57148
PMF
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);
4db647c5
PMF
1472 }
1473
68c1021b
PMF
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,
6d45c11a
PMF
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 */
68c1021b 1490
6d45c11a 1491static void destroy_traces(void)
68c1021b 1492{
6d45c11a 1493 int result;
a584bc4e
PMF
1494
1495 /* if trace running, finish it */
1496
6d45c11a 1497 DBG("destructor stopping traces");
a584bc4e 1498
6d45c11a 1499 result = ltt_trace_stop("auto");
e9b58dc0 1500 if (result == -1) {
6d45c11a
PMF
1501 ERR("ltt_trace_stop error");
1502 }
1503
31d392f1 1504 result = ltt_trace_destroy("auto", 0);
e9b58dc0 1505 if (result == -1) {
6d45c11a
PMF
1506 ERR("ltt_trace_destroy error");
1507 }
68c1021b 1508}
1e2944cb 1509
97d9b88b
PMF
1510static int trace_recording(void)
1511{
1512 int retval = 0;
b73a4c47 1513 struct ust_trace *trace;
97d9b88b
PMF
1514
1515 ltt_lock_traces();
1516
1517 list_for_each_entry(trace, &ltt_traces.head, list) {
e9b58dc0 1518 if (trace->active) {
97d9b88b
PMF
1519 retval = 1;
1520 break;
1521 }
1522 }
1523
1524 ltt_unlock_traces();
1525
1526 return retval;
1527}
1528
f293009f 1529int restarting_usleep(useconds_t usecs)
97d9b88b
PMF
1530{
1531 struct timespec tv;
1532 int result;
1533
f293009f
PMF
1534 tv.tv_sec = 0;
1535 tv.tv_nsec = usecs * 1000;
97d9b88b
PMF
1536
1537 do {
e9b58dc0
DS
1538 result = nanosleep(&tv, &tv);
1539 } while (result == -1 && errno == EINTR);
97d9b88b
PMF
1540
1541 return result;
1542}
1543
4267e589 1544static void stop_listener(void)
fc253ce0
PMF
1545{
1546 int result;
1547
e9b58dc0 1548 if (!have_listener)
4267e589
PMF
1549 return;
1550
fc253ce0 1551 result = pthread_cancel(listener_thread);
e9b58dc0 1552 if (result != 0) {
18cbdbac 1553 ERR("pthread_cancel: %s", strerror(result));
fc253ce0
PMF
1554 }
1555 result = pthread_join(listener_thread, NULL);
e9b58dc0 1556 if (result != 0) {
18cbdbac 1557 ERR("pthread_join: %s", strerror(result));
fc253ce0
PMF
1558 }
1559}
1560
f293009f
PMF
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
97d9b88b
PMF
1571static void __attribute__((destructor)) keepalive()
1572{
e9b58dc0 1573 if (trace_recording() && LOAD_SHARED(buffers_to_export)) {
c472cce0 1574 int total = 0;
f293009f 1575 DBG("Keeping process alive for consumer daemon...");
e9b58dc0 1576 while (LOAD_SHARED(buffers_to_export)) {
f293009f 1577 const int interv = 200000;
c472cce0 1578 restarting_usleep(interv);
f293009f
PMF
1579 total += interv;
1580
e9b58dc0 1581 if (total >= 3000000) {
c472cce0 1582 WARN("non-consumed buffers remaining after wait limit; not waiting anymore");
f293009f
PMF
1583 break;
1584 }
1585 }
1586 DBG("Finally dying...");
1587 }
6d45c11a
PMF
1588
1589 destroy_traces();
1590
fc253ce0
PMF
1591 /* Ask the listener to stop and clean up. */
1592 stop_listener();
97d9b88b 1593}
97d9b88b 1594
775c8a3f 1595void ust_potential_exec(void)
c396a841
PMF
1596{
1597 trace_mark(ust, potential_exec, MARK_NOARGS);
1598
775c8a3f
PMF
1599 DBG("test");
1600
c396a841
PMF
1601 keepalive();
1602}
1603
1e2944cb
PMF
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.
616ed36a
PMF
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.
1e2944cb
PMF
1612 */
1613
616ed36a 1614static void ust_fork(void)
1e2944cb 1615{
4723ca09
NC
1616 struct ust_buffer *buf, *buf_tmp;
1617 struct ustcomm_sock *sock, *sock_tmp;
99b72dc0
PMF
1618 int result;
1619
31d392f1 1620 /* FIXME: technically, the locks could have been taken before the fork */
1e2944cb 1621 DBG("ust: forking");
73850001
PMF
1622
1623 /* break lock if necessary */
1624 ltt_unlock_traces();
1625
1e2944cb 1626 ltt_trace_stop("auto");
31d392f1 1627 ltt_trace_destroy("auto", 1);
4723ca09
NC
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 }
99b72dc0
PMF
1632
1633 /* Delete all blocked consumers */
4723ca09
NC
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) {
2c1ccefa
PMF
1638 PERROR("close");
1639 }
4723ca09
NC
1640 result = close(buf->data_ready_fd_write);
1641 if(result == -1) {
1642 PERROR("close");
1643 }
1644 list_del(&buf->open_buffers_list);
99b72dc0
PMF
1645 }
1646
4723ca09
NC
1647 /* Clean up the listener socket and epoll, keeping the scoket file */
1648 ustcomm_del_named_sock(listen_sock, 1);
1649 close(epoll_fd);
393bc391 1650
4723ca09 1651 /* Re-start the launch sequence */
8649cd59 1652 STORE_SHARED(buffers_to_export, 0);
1e2944cb 1653 have_listener = 0;
4723ca09
NC
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 }
9fb49d0e 1669 create_listener();
99b72dc0
PMF
1670 ltt_trace_setup("auto");
1671 result = ltt_trace_set_type("auto", "ustrelay");
e9b58dc0 1672 if (result < 0) {
99b72dc0 1673 ERR("ltt_trace_set_type failed");
036db133 1674 return;
99b72dc0
PMF
1675 }
1676
1677 ltt_trace_alloc("auto");
1678 ltt_trace_start("auto");
ad45e833 1679 inform_consumer_daemon("auto");
1e2944cb
PMF
1680}
1681
616ed36a
PMF
1682void 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);
e9b58dc0 1699 if (result == -1) {
616ed36a
PMF
1700 PERROR("sigprocmask");
1701 return;
1702 }
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;
616ed36a
PMF
1709
1710 /* Restore signals */
1711 result = sigprocmask(SIG_SETMASK, &fork_info->orig_sigs, NULL);
e9b58dc0 1712 if (result == -1) {
616ed36a
PMF
1713 PERROR("sigprocmask");
1714 return;
1715 }
1716}
1717
1718void ust_after_fork_parent(ust_fork_info_t *fork_info)
1719{
1720 /* Reenable signals */
1721 ust_after_fork_common(fork_info);
1722}
1723
1724void 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.129501 seconds and 4 git commands to generate.