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