2 * ust-basic-tracing.c - Basic single-session, single-channel, single-process UST tracing
4 * Copyright (C) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; only version 2 of the License.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place - Suite 330, Boston, MA 02111-1307, USA.
21 #define _LARGEFILE64_SOURCE
29 #include <sys/types.h>
34 #include <urcu/futex.h>
35 #include <urcu/uatomic.h>
37 #include <sys/socket.h>
39 #include "lttng-ust-comm.h"
40 #include "../../libringbuffer/backend.h"
41 #include "../../libringbuffer/frontend.h"
43 #define MAX_NR_STREAMS 64
44 #define MAX_NR_EVENTS 128
50 uint64_t memory_map_size
;
53 static int session_handle
;
54 static struct object_data metadata_stream_data
;
55 static struct object_data metadata_data
;
56 static struct object_data channel_data
;
57 static struct object_data stream_data
[MAX_NR_STREAMS
];
58 static int event_handle
[MAX_NR_EVENTS
];
59 static int context_handle
;
61 static int apps_socket
= -1;
62 static char apps_sock_path
[PATH_MAX
];
63 static char local_apps_wait_shm_path
[PATH_MAX
];
65 static volatile int quit_program
;
67 static void handle_signals(int signo
)
73 int open_streams(int sock
, int channel_handle
, struct object_data
*stream_datas
,
79 struct ustcomm_ust_msg lum
;
80 struct ustcomm_ust_reply lur
;
82 memset(&lum
, 0, sizeof(lum
));
83 lum
.handle
= channel_handle
;
84 lum
.cmd
= LTTNG_UST_STREAM
;
85 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
88 stream_datas
[k
].handle
= lur
.ret_val
;
89 printf("received stream handle %u\n",
90 stream_datas
[k
].handle
);
91 if (lur
.ret_code
== USTCOMM_OK
) {
94 stream_datas
[k
].memory_map_size
= lur
.u
.stream
.memory_map_size
;
96 len
= ustcomm_recv_fd(sock
);
99 stream_datas
[k
].shm_fd
= len
;
101 len
= ustcomm_recv_fd(sock
);
104 stream_datas
[k
].wait_fd
= len
;
117 int close_streams(int sock
, struct object_data
*stream_datas
, int nr_check
)
121 for (k
= 0; k
< nr_check
; k
++) {
122 struct ustcomm_ust_msg lum
;
123 struct ustcomm_ust_reply lur
;
125 if (!stream_datas
[k
].handle
)
127 memset(&lum
, 0, sizeof(lum
));
128 lum
.handle
= stream_datas
[k
].handle
;
129 lum
.cmd
= LTTNG_UST_RELEASE
;
130 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
132 printf("Error closing stream\n");
135 if (stream_datas
[k
].shm_fd
>= 0) {
136 ret
= close(stream_datas
[k
].shm_fd
);
138 printf("Error closing stream shm_fd\n");
142 if (stream_datas
[k
].wait_fd
>= 0) {
143 ret
= close(stream_datas
[k
].wait_fd
);
145 printf("Error closing stream wait_fd\n");
154 struct shm_handle
*map_channel(struct object_data
*chan_data
,
155 struct object_data
*stream_datas
, int nr_check
)
157 struct shm_handle
*handle
;
158 struct channel
*chan
;
161 /* map metadata channel */
162 handle
= channel_handle_create(chan_data
->shm_fd
,
164 chan_data
->memory_map_size
);
166 printf("create handle error\n");
169 chan_data
->shm_fd
= -1;
170 chan_data
->wait_fd
= -1;
171 chan
= shmp(handle
, handle
->chan
);
173 for (k
= 0; k
< nr_check
; k
++) {
174 struct object_data
*stream_data
= &stream_datas
[k
];
176 if (!stream_data
->handle
)
179 ret
= channel_handle_add_stream(handle
,
181 stream_data
->wait_fd
,
182 stream_data
->memory_map_size
);
184 printf("add stream error\n");
187 stream_data
->shm_fd
= -1;
188 stream_data
->wait_fd
= -1;
193 channel_destroy(chan
, handle
, 1);
198 void unmap_channel(struct shm_handle
*handle
)
200 struct channel
*chan
;
202 chan
= shmp(handle
, handle
->chan
);
204 channel_destroy(chan
, handle
, 1);
208 int consume_stream(struct shm_handle
*handle
, int cpu
, char *outfile
)
210 struct channel
*chan
;
211 struct lib_ring_buffer
*buf
;
214 uint64_t memory_map_size
;
216 chan
= shmp(handle
, handle
->chan
);
219 buf
= channel_get_ring_buffer(&chan
->backend
.config
,
220 chan
, cpu
, handle
, &shm_fd
, &wait_fd
, &memory_map_size
);
223 ret
= lib_ring_buffer_open_read(buf
, handle
, 1);
229 outfd
= open(outfile
, O_WRONLY
| O_CREAT
| O_LARGEFILE
| O_TRUNC
,
230 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
);
232 perror("open output");
236 printf("Waiting for buffer data for %s\n", outfile
);
238 unsigned long read_size
;
239 unsigned long copy_size
;
242 ret
= lib_ring_buffer_get_next_subbuf(buf
, handle
);
243 printf("get next ret %d\n", ret
);
246 if (ret
== -EAGAIN
) {
251 printf("Error %d in lib_ring_buffer_get_next_subbuf\n", ret
);
254 read_size
= lib_ring_buffer_get_read_data_size(
255 &chan
->backend
.config
, buf
, handle
);
256 read_size
= PAGE_ALIGN(read_size
);
257 ptr
= lib_ring_buffer_read_offset_address(
258 &buf
->backend
, 0, handle
);
259 printf("WRITE: copy %lu bytes\n", read_size
);
260 copy_size
= write(outfd
, ptr
, read_size
);
261 if (copy_size
< read_size
) {
262 printf("write issue: copied %zd, expected %lu\n", copy_size
, read_size
);
264 lib_ring_buffer_put_next_subbuf(buf
, handle
);
274 lib_ring_buffer_release_read(buf
, handle
, 1);
279 int consume_buffers(const char *outputpath
)
283 char pathname
[PATH_MAX
];
284 struct shm_handle
*handle
;
286 snprintf(pathname
, PATH_MAX
- 1, "%s", outputpath
);
287 old_umask
= umask(0);
288 ret
= mkdir(pathname
, S_IRWXU
| S_IRWXG
);
289 if (ret
&& errno
!= EEXIST
) {
297 handle
= map_channel(&metadata_data
,
298 &metadata_stream_data
, 1);
301 snprintf(pathname
, PATH_MAX
- 1,
302 "%s/metadata", outputpath
);
303 ret
= consume_stream(handle
, -1, pathname
);
304 if (ret
&& ret
!= -ENOENT
) {
305 printf("Error in consume_stream\n");
308 unmap_channel(handle
);
310 /* copy binary data */
311 handle
= map_channel(&channel_data
,
312 stream_data
, MAX_NR_STREAMS
);
315 for (k
= 0; k
< MAX_NR_STREAMS
; k
++) {
316 snprintf(pathname
, PATH_MAX
- 1,
317 "%s/data_%u", outputpath
, k
);
318 ret
= consume_stream(handle
, k
, pathname
);
319 if (ret
&& ret
!= -ENOENT
) {
320 printf("Error in consume_stream\n");
324 unmap_channel(handle
);
330 int send_app_msgs(int sock
, const char *outputpath
,
331 unsigned int nr_events
, const char **event_names
)
333 struct ustcomm_ust_msg lum
;
334 struct ustcomm_ust_reply lur
;
338 memset(&lum
, 0, sizeof(lum
));
339 lum
.handle
= LTTNG_UST_ROOT_HANDLE
;
340 lum
.cmd
= LTTNG_UST_SESSION
;
341 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
344 session_handle
= lur
.ret_val
;
345 printf("received session handle %u\n", session_handle
);
347 /* Create metadata channel */
348 memset(&lum
, 0, sizeof(lum
));
349 lum
.handle
= session_handle
;
350 lum
.cmd
= LTTNG_UST_METADATA
;
351 lum
.u
.channel
.overwrite
= 0;
352 lum
.u
.channel
.subbuf_size
= 32768;
353 lum
.u
.channel
.num_subbuf
= 4;
354 lum
.u
.channel
.switch_timer_interval
= 0;
355 lum
.u
.channel
.read_timer_interval
= 0;
356 lum
.u
.channel
.output
= LTTNG_UST_MMAP
;
357 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
360 metadata_data
.handle
= lur
.ret_val
;
361 printf("received metadata handle %u\n", metadata_data
.handle
);
362 if (lur
.ret_code
== USTCOMM_OK
) {
365 metadata_data
.memory_map_size
= lur
.u
.channel
.memory_map_size
;
367 len
= ustcomm_recv_fd(sock
);
370 metadata_data
.shm_fd
= len
;
372 len
= ustcomm_recv_fd(sock
);
375 metadata_data
.wait_fd
= len
;
378 ret
= open_streams(sock
, metadata_data
.handle
,
379 &metadata_stream_data
, 1);
381 printf("Error in open_streams\n");
385 /* Create data channel */
386 memset(&lum
, 0, sizeof(lum
));
387 lum
.handle
= session_handle
;
388 lum
.cmd
= LTTNG_UST_CHANNEL
;
389 //lum.u.channel.overwrite = 0;
390 lum
.u
.channel
.overwrite
= 1;
391 lum
.u
.channel
.subbuf_size
= 32768;
392 lum
.u
.channel
.num_subbuf
= 8;
393 //lum.u.channel.num_subbuf = 4;
394 //lum.u.channel.num_subbuf = 2;
395 lum
.u
.channel
.switch_timer_interval
= 0;
396 lum
.u
.channel
.read_timer_interval
= 0;
397 lum
.u
.channel
.output
= LTTNG_UST_MMAP
;
398 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
401 channel_data
.handle
= lur
.ret_val
;
402 printf("received channel handle %u\n", channel_data
.handle
);
403 if (lur
.ret_code
== USTCOMM_OK
) {
406 channel_data
.memory_map_size
= lur
.u
.channel
.memory_map_size
;
408 len
= ustcomm_recv_fd(sock
);
411 channel_data
.shm_fd
= len
;
413 len
= ustcomm_recv_fd(sock
);
416 channel_data
.wait_fd
= len
;
420 for (k
= 0; k
< nr_events
; k
++) {
421 memset(&lum
, 0, sizeof(lum
));
422 lum
.handle
= channel_data
.handle
;
423 lum
.cmd
= LTTNG_UST_EVENT
;
424 strncpy(lum
.u
.event
.name
, event_names
[k
],
425 LTTNG_UST_SYM_NAME_LEN
);
426 lum
.u
.event
.instrumentation
= LTTNG_UST_TRACEPOINT
;
427 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
430 event_handle
[k
] = lur
.ret_val
;
431 printf("received event handle %u\n", event_handle
[k
]);
434 /* Attach vtid context */
435 memset(&lum
, 0, sizeof(lum
));
436 lum
.handle
= channel_data
.handle
;
437 lum
.cmd
= LTTNG_UST_CONTEXT
;
438 lum
.u
.context
.ctx
= LTTNG_UST_CONTEXT_VTID
;
439 //lum.u.context.ctx = LTTNG_UST_CONTEXT_PTHREAD_ID;
440 //lum.u.context.ctx = LTTNG_UST_CONTEXT_VPID;
441 //lum.u.context.ctx = LTTNG_UST_CONTEXT_PROCNAME;
442 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
445 context_handle
= lur
.ret_val
;
446 printf("received context handle %u\n", context_handle
);
448 /* Get references to channel streams */
449 ret
= open_streams(sock
, channel_data
.handle
,
450 stream_data
, MAX_NR_STREAMS
);
452 printf("Error in open_streams\n");
456 memset(&lum
, 0, sizeof(lum
));
457 lum
.handle
= session_handle
;
458 lum
.cmd
= LTTNG_UST_SESSION_START
;
459 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
462 printf("Session handle %u started.\n", session_handle
);
464 /* Tell application registration is done */
465 memset(&lum
, 0, sizeof(lum
));
466 lum
.handle
= LTTNG_UST_ROOT_HANDLE
;
467 lum
.cmd
= LTTNG_UST_REGISTER_DONE
;
468 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
471 printf("Registration done acknowledged.\n");
475 ret
= consume_buffers(outputpath
);
477 printf("Error in consume_buffers\n");
481 /* Release data channel */
482 /* Release streams */
483 ret
= close_streams(sock
, stream_data
,
488 /* Release context */
489 memset(&lum
, 0, sizeof(lum
));
490 lum
.handle
= context_handle
;
491 lum
.cmd
= LTTNG_UST_RELEASE
;
492 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
497 for (k
= 0; k
< nr_events
; k
++) {
498 memset(&lum
, 0, sizeof(lum
));
499 lum
.handle
= event_handle
[k
];
500 lum
.cmd
= LTTNG_UST_RELEASE
;
501 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
505 memset(&lum
, 0, sizeof(lum
));
506 lum
.handle
= channel_data
.handle
;
507 lum
.cmd
= LTTNG_UST_RELEASE
;
508 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
511 if (channel_data
.shm_fd
>= 0) {
512 ret
= close(channel_data
.shm_fd
);
516 if (channel_data
.wait_fd
>= 0) {
517 ret
= close(channel_data
.wait_fd
);
522 /* Release metadata channel */
523 ret
= close_streams(sock
, &metadata_stream_data
, 1);
527 memset(&lum
, 0, sizeof(lum
));
528 lum
.handle
= metadata_data
.handle
;
529 lum
.cmd
= LTTNG_UST_RELEASE
;
530 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
533 if (metadata_data
.shm_fd
>= 0) {
534 ret
= close(metadata_data
.shm_fd
);
538 if (metadata_data
.wait_fd
>= 0) {
539 ret
= close(metadata_data
.wait_fd
);
544 /* Release session */
545 memset(&lum
, 0, sizeof(lum
));
546 lum
.handle
= session_handle
;
547 lum
.cmd
= LTTNG_UST_RELEASE
;
548 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
556 * Using fork to set umask in the child process (not multi-thread safe). We
557 * deal with the shm_open vs ftruncate race (happening when the sessiond owns
558 * the shm and does not let everybody modify it, to ensure safety against
559 * shm_unlink) by simply letting the mmap fail and retrying after a few
560 * seconds. For global shm, everybody has rw access to it until the sessiond
563 static int get_wait_shm(char *shm_path
, size_t mmap_size
, int global
)
565 int wait_shm_fd
, ret
;
568 /* Default permissions */
569 mode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
;
571 /* Change owner of the shm path */
573 ret
= chown(shm_path
, 0, 0);
575 if (errno
!= ENOENT
) {
576 perror("chown wait shm");
582 * If global session daemon, any application can register so the shm
583 * needs to be set in read-only mode for others.
587 ret
= chown(shm_path
, getuid(), getgid());
589 if (errno
!= ENOENT
) {
590 perror("chown wait shm");
597 * Set permissions to the shm even if we did not create the shm.
599 ret
= chmod(shm_path
, mode
);
601 if (errno
!= ENOENT
) {
602 perror("chmod wait shm");
608 * We're alone in a child process, so we can modify the process-wide
614 * Try creating shm (or get rw access). We don't do an exclusive open,
615 * because we allow other processes to create+ftruncate it concurrently.
617 wait_shm_fd
= shm_open(shm_path
, O_RDWR
| O_CREAT
, mode
);
618 if (wait_shm_fd
< 0) {
619 perror("shm_open wait shm");
623 ret
= ftruncate(wait_shm_fd
, mmap_size
);
625 perror("ftruncate wait shm");
629 ret
= fchmod(wait_shm_fd
, mode
);
635 printf("Got the wait shm fd %d\n", wait_shm_fd
);
640 printf("Failing to get the wait shm fd\n");
645 int update_futex(int fd
, int active
)
647 size_t mmap_size
= sysconf(_SC_PAGE_SIZE
);
651 wait_shm_mmap
= mmap(NULL
, mmap_size
, PROT_READ
| PROT_WRITE
,
653 if (wait_shm_mmap
== MAP_FAILED
) {
659 uatomic_set((int32_t *) wait_shm_mmap
, 1);
660 futex_async((int32_t *) wait_shm_mmap
, FUTEX_WAKE
,
661 INT_MAX
, NULL
, NULL
, 0);
663 uatomic_set((int32_t *) wait_shm_mmap
, 0);
665 ret
= munmap(wait_shm_mmap
, mmap_size
);
667 perror("Error unmapping wait shm");
676 * Set open files limit to unlimited. This daemon can open a large number of
677 * file descriptors in order to consumer multiple kernel traces.
679 static void set_ulimit(void)
685 * If not root, we cannot increase our max open files. But our
686 * scope is then limited to processes from a single user.
690 /* The kernel does not allowed an infinite limit for open files */
691 lim
.rlim_cur
= 65535;
692 lim
.rlim_max
= 65535;
694 ret
= setrlimit(RLIMIT_NOFILE
, &lim
);
696 perror("failed to set open files limit");
702 * ./ust-basic-tracing outputpath event_name1 event_name2 ....
704 int main(int argc
, const char **argv
)
706 const char *home_dir
;
707 int ret
, wait_shm_fd
;
708 struct sigaction act
;
709 mode_t old_umask
= 0;
710 const char *outputpath
;
711 const char **event_names
;
712 unsigned int nr_events
;
716 printf("%s outputpath event_name1 event_name2 ...\n",
720 outputpath
= argv
[1];
721 event_names
= &argv
[2];
722 nr_events
= argc
- 2;
727 memset(&act
, 0, sizeof(act
));
728 ret
= sigemptyset(&act
.sa_mask
);
730 perror("sigemptyset");
734 act
.sa_handler
= SIG_IGN
;
735 ret
= sigaction(SIGPIPE
, &act
, NULL
);
742 act
.sa_handler
= handle_signals
;
743 ret
= sigaction(SIGTERM
, &act
, NULL
);
749 ret
= sigaction(SIGINT
, &act
, NULL
);
755 if (geteuid() == 0) {
756 ret
= mkdir(LTTNG_RUNDIR
, S_IRWXU
| S_IRWXG
| S_IROTH
| S_IXOTH
);
757 if (ret
&& errno
!= EEXIST
) {
761 wait_shm_fd
= get_wait_shm(DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH
,
762 sysconf(_SC_PAGE_SIZE
), 1);
763 if (wait_shm_fd
< 0) {
764 perror("global wait shm error");
767 strcpy(apps_sock_path
, DEFAULT_GLOBAL_APPS_UNIX_SOCK
);
768 old_umask
= umask(0);
770 snprintf(local_apps_wait_shm_path
, PATH_MAX
,
771 DEFAULT_HOME_APPS_WAIT_SHM_PATH
, getuid());
772 wait_shm_fd
= get_wait_shm(local_apps_wait_shm_path
,
773 sysconf(_SC_PAGE_SIZE
), 0);
774 if (wait_shm_fd
< 0) {
775 perror("local wait shm error");
778 home_dir
= (const char *) getenv("HOME");
780 perror("getenv error");
783 snprintf(apps_sock_path
, PATH_MAX
,
784 DEFAULT_HOME_APPS_UNIX_SOCK
, home_dir
);
787 ret
= ustcomm_create_unix_sock(apps_sock_path
);
789 perror("create error");
795 /* File permission MUST be 666 */
796 ret
= chmod(apps_sock_path
,
797 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
| S_IWOTH
);
799 printf("Set file permissions failed: %s\n", apps_sock_path
);
805 ret
= ustcomm_listen_unix_sock(apps_socket
);
807 perror("listen error");
811 /* wake up futexes */
812 ret
= update_futex(wait_shm_fd
, 1);
814 fprintf(stderr
, "Error wakeup futex\n");
828 char name
[16]; /* Process name */
835 printf("Accepting application registration\n");
836 sock
= ustcomm_accept_unix_sock(apps_socket
);
838 perror("accept error");
843 * Basic recv here to handle the very simple data
844 * that the libust send to register (reg_msg).
846 len
= ustcomm_recv_unix_sock(sock
, ®_msg
, sizeof(reg_msg
));
847 if (len
< 0 || len
!= sizeof(reg_msg
)) {
848 perror("ustcomm_recv_unix_sock");
851 memcpy(bufname
, reg_msg
.name
, 16);
853 printf("Application %s pid %u ppid %u uid %u gid %u has registered (version : %u.%u)\n",
854 bufname
, reg_msg
.pid
, reg_msg
.ppid
, reg_msg
.uid
,
855 reg_msg
.gid
, reg_msg
.major
, reg_msg
.minor
);
856 ret
= send_app_msgs(sock
, outputpath
, nr_events
, event_names
);
858 printf("Error in send_app_msgs.\n");
865 printf("quitting.\n");
866 /* Let applications know we are not responding anymore */
867 ret
= update_futex(wait_shm_fd
, 0);
869 fprintf(stderr
, "Error wakeup futex\n");