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