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