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