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
];
60 static int apps_socket
= -1;
61 static char apps_sock_path
[PATH_MAX
];
62 static char local_apps_wait_shm_path
[PATH_MAX
];
64 static volatile int quit_program
;
66 static void handle_signals(int signo
)
71 static int send_app_msg(int sock
, struct lttcomm_ust_msg
*lum
)
75 len
= lttcomm_send_unix_sock(sock
, lum
, sizeof(*lum
));
78 printf("message successfully sent\n");
81 if (errno
== ECONNRESET
) {
82 printf("remote end closed connection\n");
87 printf("incorrect message size: %zd\n", len
);
93 static int recv_app_reply(int sock
, struct lttcomm_ust_reply
*lur
,
94 uint32_t expected_handle
, uint32_t expected_cmd
)
98 memset(lur
, 0, sizeof(*lur
));
99 len
= lttcomm_recv_unix_sock(sock
, lur
, sizeof(*lur
));
101 case 0: /* orderly shutdown */
102 printf("Application has performed an orderly shutdown\n");
105 printf("result message received\n");
106 if (lur
->handle
!= expected_handle
) {
107 printf("Unexpected result message handle\n");
111 if (lur
->cmd
!= expected_cmd
) {
112 printf("Unexpected result message command\n");
115 if (lur
->ret_code
!= LTTCOMM_OK
) {
116 printf("remote operation failed with code %d.\n",
118 return lur
->ret_code
;
122 if (errno
== ECONNRESET
) {
123 printf("remote end closed connection\n");
128 printf("incorrect message size: %zd\n", len
);
129 return len
> 0 ? -1 : len
;
133 static int send_app_cmd(int sock
,
134 struct lttcomm_ust_msg
*lum
,
135 struct lttcomm_ust_reply
*lur
)
139 ret
= send_app_msg(sock
, lum
);
142 ret
= recv_app_reply(sock
, lur
, lum
->handle
, lum
->cmd
);
150 * Receives a single fd from socket.
152 * Returns the size of received data
154 static int lttcomm_recv_fd(int sock
)
159 struct cmsghdr
*cmsg
;
160 char recv_fd
[CMSG_SPACE(sizeof(int))];
161 struct msghdr msg
= { 0 };
168 /* Prepare to receive the structures */
169 iov
[0].iov_base
= &data_fd
;
170 iov
[0].iov_len
= sizeof(data_fd
);
173 msg
.msg_control
= recv_fd
;
174 msg
.msg_controllen
= sizeof(recv_fd
);
176 printf("Waiting to receive fd\n");
177 if ((ret
= recvmsg(sock
, &msg
, 0)) < 0) {
181 if (ret
!= sizeof(data_fd
)) {
182 printf("Received %d bytes, expected %ld", ret
, sizeof(data_fd
));
185 cmsg
= CMSG_FIRSTHDR(&msg
);
187 printf("Invalid control message header\n");
191 if (cmsg
->cmsg_level
!= SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
192 printf("Didn't received any fd\n");
197 for (i
= 0; i
< sizeof(int); i
++)
198 tmp
.vc
[i
] = CMSG_DATA(cmsg
)[i
];
200 printf("received fd %d\n", ret
);
207 int open_streams(int sock
, int channel_handle
, struct object_data
*stream_datas
,
213 struct lttcomm_ust_msg lum
;
214 struct lttcomm_ust_reply lur
;
216 memset(&lum
, 0, sizeof(lum
));
217 lum
.handle
= channel_handle
;
218 lum
.cmd
= LTTNG_UST_STREAM
;
219 ret
= send_app_cmd(sock
, &lum
, &lur
);
221 assert(k
< nr_check
);
222 stream_datas
[k
].handle
= lur
.ret_val
;
223 printf("received stream handle %u\n",
224 stream_datas
[k
].handle
);
225 if (lur
.ret_code
== LTTCOMM_OK
) {
228 stream_datas
[k
].memory_map_size
= lur
.u
.stream
.memory_map_size
;
230 len
= lttcomm_recv_fd(sock
);
233 stream_datas
[k
].shm_fd
= len
;
235 len
= lttcomm_recv_fd(sock
);
238 stream_datas
[k
].wait_fd
= len
;
251 int close_streams(int sock
, struct object_data
*stream_datas
, int nr_check
)
255 for (k
= 0; k
< nr_check
; k
++) {
256 struct lttcomm_ust_msg lum
;
257 struct lttcomm_ust_reply lur
;
259 if (!stream_datas
[k
].handle
)
261 memset(&lum
, 0, sizeof(lum
));
262 lum
.handle
= stream_datas
[k
].handle
;
263 lum
.cmd
= LTTNG_UST_RELEASE
;
264 ret
= send_app_cmd(sock
, &lum
, &lur
);
266 printf("Error closing stream\n");
269 if (stream_datas
[k
].shm_fd
>= 0) {
270 ret
= close(stream_datas
[k
].shm_fd
);
272 printf("Error closing stream shm_fd\n");
276 if (stream_datas
[k
].wait_fd
>= 0) {
277 ret
= close(stream_datas
[k
].wait_fd
);
279 printf("Error closing stream wait_fd\n");
288 struct shm_handle
*map_channel(struct object_data
*chan_data
,
289 struct object_data
*stream_datas
, int nr_check
)
291 struct shm_handle
*handle
;
292 struct channel
*chan
;
295 /* map metadata channel */
296 handle
= channel_handle_create(chan_data
->shm_fd
,
298 chan_data
->memory_map_size
);
300 printf("create handle error\n");
303 chan_data
->shm_fd
= -1;
304 chan_data
->wait_fd
= -1;
305 chan
= shmp(handle
, handle
->chan
);
307 for (k
= 0; k
< nr_check
; k
++) {
308 struct object_data
*stream_data
= &stream_datas
[k
];
310 if (!stream_data
->handle
)
313 ret
= channel_handle_add_stream(handle
,
315 stream_data
->wait_fd
,
316 stream_data
->memory_map_size
);
318 printf("add stream error\n");
321 stream_data
->shm_fd
= -1;
322 stream_data
->wait_fd
= -1;
327 channel_destroy(chan
, handle
, 1);
332 void unmap_channel(struct shm_handle
*handle
)
334 struct channel
*chan
;
336 chan
= shmp(handle
, handle
->chan
);
338 channel_destroy(chan
, handle
, 1);
342 int consume_stream(struct shm_handle
*handle
, int cpu
, char *outfile
)
344 struct channel
*chan
;
345 struct lib_ring_buffer
*buf
;
348 uint64_t memory_map_size
;
350 chan
= shmp(handle
, handle
->chan
);
353 buf
= channel_get_ring_buffer(&chan
->backend
.config
,
354 chan
, cpu
, handle
, &shm_fd
, &wait_fd
, &memory_map_size
);
357 ret
= lib_ring_buffer_open_read(buf
, handle
, 1);
363 outfd
= open(outfile
, O_WRONLY
| O_CREAT
| O_LARGEFILE
| O_TRUNC
,
364 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
);
366 perror("open output");
370 printf("Waiting for buffer data for %s\n", outfile
);
372 unsigned long read_size
;
373 unsigned long copy_size
;
376 ret
= lib_ring_buffer_get_next_subbuf(buf
, handle
);
377 printf("get next ret %d\n", ret
);
380 if (ret
== -EAGAIN
) {
385 printf("Error %d in lib_ring_buffer_get_next_subbuf\n", ret
);
388 read_size
= lib_ring_buffer_get_read_data_size(
389 &chan
->backend
.config
, buf
, handle
);
390 read_size
= PAGE_ALIGN(read_size
);
391 ptr
= lib_ring_buffer_read_offset_address(
392 &buf
->backend
, 0, handle
);
393 printf("WRITE: copy %lu bytes\n", read_size
);
394 copy_size
= write(outfd
, ptr
, read_size
);
395 if (copy_size
< read_size
) {
396 printf("write issue: copied %zd, expected %lu\n", copy_size
, read_size
);
398 lib_ring_buffer_put_next_subbuf(buf
, handle
);
408 lib_ring_buffer_release_read(buf
, handle
, 1);
413 int consume_buffers(const char *outputpath
)
417 char pathname
[PATH_MAX
];
418 struct shm_handle
*handle
;
420 snprintf(pathname
, PATH_MAX
- 1, "%s", outputpath
);
421 old_umask
= umask(0);
422 ret
= mkdir(pathname
, S_IRWXU
| S_IRWXG
);
423 if (ret
&& errno
!= EEXIST
) {
431 handle
= map_channel(&metadata_data
,
432 &metadata_stream_data
, 1);
435 snprintf(pathname
, PATH_MAX
- 1,
436 "%s/metadata", outputpath
);
437 ret
= consume_stream(handle
, -1, pathname
);
438 if (ret
&& ret
!= -ENOENT
) {
439 printf("Error in consume_stream\n");
442 unmap_channel(handle
);
444 /* copy binary data */
445 handle
= map_channel(&channel_data
,
446 stream_data
, MAX_NR_STREAMS
);
449 for (k
= 0; k
< MAX_NR_STREAMS
; k
++) {
450 snprintf(pathname
, PATH_MAX
- 1,
451 "%s/data_%u", outputpath
, k
);
452 ret
= consume_stream(handle
, k
, pathname
);
453 if (ret
&& ret
!= -ENOENT
) {
454 printf("Error in consume_stream\n");
458 unmap_channel(handle
);
463 int send_app_msgs(int sock
, const char *outputpath
,
464 unsigned int nr_events
, const char **event_names
)
466 struct lttcomm_ust_msg lum
;
467 struct lttcomm_ust_reply lur
;
471 memset(&lum
, 0, sizeof(lum
));
472 lum
.handle
= LTTNG_UST_ROOT_HANDLE
;
473 lum
.cmd
= LTTNG_UST_SESSION
;
474 ret
= send_app_cmd(sock
, &lum
, &lur
);
477 session_handle
= lur
.ret_val
;
478 printf("received session handle %u\n", session_handle
);
480 /* Create metadata channel */
481 memset(&lum
, 0, sizeof(lum
));
482 lum
.handle
= session_handle
;
483 lum
.cmd
= LTTNG_UST_METADATA
;
484 lum
.u
.channel
.overwrite
= 0;
485 lum
.u
.channel
.subbuf_size
= 32768;
486 lum
.u
.channel
.num_subbuf
= 4;
487 lum
.u
.channel
.switch_timer_interval
= 0;
488 lum
.u
.channel
.read_timer_interval
= 0;
489 lum
.u
.channel
.output
= LTTNG_UST_MMAP
;
490 ret
= send_app_cmd(sock
, &lum
, &lur
);
493 metadata_data
.handle
= lur
.ret_val
;
494 printf("received metadata handle %u\n", metadata_data
.handle
);
495 if (lur
.ret_code
== LTTCOMM_OK
) {
498 metadata_data
.memory_map_size
= lur
.u
.channel
.memory_map_size
;
500 len
= lttcomm_recv_fd(sock
);
503 metadata_data
.shm_fd
= len
;
505 len
= lttcomm_recv_fd(sock
);
508 metadata_data
.wait_fd
= len
;
511 ret
= open_streams(sock
, metadata_data
.handle
,
512 &metadata_stream_data
, 1);
514 printf("Error in open_streams\n");
518 /* Create data channel */
519 memset(&lum
, 0, sizeof(lum
));
520 lum
.handle
= session_handle
;
521 lum
.cmd
= LTTNG_UST_CHANNEL
;
522 //lum.u.channel.overwrite = 0;
523 lum
.u
.channel
.overwrite
= 1;
524 lum
.u
.channel
.subbuf_size
= 32768;
525 lum
.u
.channel
.num_subbuf
= 8;
526 //lum.u.channel.num_subbuf = 4;
527 //lum.u.channel.num_subbuf = 2;
528 lum
.u
.channel
.switch_timer_interval
= 0;
529 lum
.u
.channel
.read_timer_interval
= 0;
530 lum
.u
.channel
.output
= LTTNG_UST_MMAP
;
531 ret
= send_app_cmd(sock
, &lum
, &lur
);
534 channel_data
.handle
= lur
.ret_val
;
535 printf("received channel handle %u\n", channel_data
.handle
);
536 if (lur
.ret_code
== LTTCOMM_OK
) {
539 channel_data
.memory_map_size
= lur
.u
.channel
.memory_map_size
;
541 len
= lttcomm_recv_fd(sock
);
544 channel_data
.shm_fd
= len
;
546 len
= lttcomm_recv_fd(sock
);
549 channel_data
.wait_fd
= len
;
553 for (k
= 0; k
< nr_events
; k
++) {
554 memset(&lum
, 0, sizeof(lum
));
555 lum
.handle
= channel_data
.handle
;
556 lum
.cmd
= LTTNG_UST_EVENT
;
557 strncpy(lum
.u
.event
.name
, event_names
[k
],
558 LTTNG_UST_SYM_NAME_LEN
);
559 lum
.u
.event
.instrumentation
= LTTNG_UST_TRACEPOINT
;
560 ret
= send_app_cmd(sock
, &lum
, &lur
);
563 event_handle
[k
] = lur
.ret_val
;
564 printf("received event handle %u\n", event_handle
[k
]);
567 /* Get references to channel streams */
568 ret
= open_streams(sock
, channel_data
.handle
,
569 stream_data
, MAX_NR_STREAMS
);
571 printf("Error in open_streams\n");
575 memset(&lum
, 0, sizeof(lum
));
576 lum
.handle
= session_handle
;
577 lum
.cmd
= LTTNG_UST_SESSION_START
;
578 ret
= send_app_cmd(sock
, &lum
, &lur
);
581 printf("Session handle %u started.\n", session_handle
);
583 /* Tell application registration is done */
584 memset(&lum
, 0, sizeof(lum
));
585 lum
.handle
= LTTNG_UST_ROOT_HANDLE
;
586 lum
.cmd
= LTTNG_UST_REGISTER_DONE
;
587 ret
= send_app_cmd(sock
, &lum
, &lur
);
590 printf("Registration done acknowledged.\n");
594 ret
= consume_buffers(outputpath
);
596 printf("Error in consume_buffers\n");
600 /* Release data channel */
601 /* Release streams */
602 ret
= close_streams(sock
, stream_data
,
608 for (k
= 0; k
< nr_events
; k
++) {
609 memset(&lum
, 0, sizeof(lum
));
610 lum
.handle
= event_handle
[k
];
611 lum
.cmd
= LTTNG_UST_RELEASE
;
612 ret
= send_app_cmd(sock
, &lum
, &lur
);
616 memset(&lum
, 0, sizeof(lum
));
617 lum
.handle
= channel_data
.handle
;
618 lum
.cmd
= LTTNG_UST_RELEASE
;
619 ret
= send_app_cmd(sock
, &lum
, &lur
);
622 if (channel_data
.shm_fd
>= 0) {
623 ret
= close(channel_data
.shm_fd
);
627 if (channel_data
.wait_fd
>= 0) {
628 ret
= close(channel_data
.wait_fd
);
633 /* Release metadata channel */
634 ret
= close_streams(sock
, &metadata_stream_data
, 1);
638 memset(&lum
, 0, sizeof(lum
));
639 lum
.handle
= metadata_data
.handle
;
640 lum
.cmd
= LTTNG_UST_RELEASE
;
641 ret
= send_app_cmd(sock
, &lum
, &lur
);
644 if (metadata_data
.shm_fd
>= 0) {
645 ret
= close(metadata_data
.shm_fd
);
649 if (metadata_data
.wait_fd
>= 0) {
650 ret
= close(metadata_data
.wait_fd
);
655 /* Release session */
656 memset(&lum
, 0, sizeof(lum
));
657 lum
.handle
= session_handle
;
658 lum
.cmd
= LTTNG_UST_RELEASE
;
659 ret
= send_app_cmd(sock
, &lum
, &lur
);
667 * Using fork to set umask in the child process (not multi-thread safe). We
668 * deal with the shm_open vs ftruncate race (happening when the sessiond owns
669 * the shm and does not let everybody modify it, to ensure safety against
670 * shm_unlink) by simply letting the mmap fail and retrying after a few
671 * seconds. For global shm, everybody has rw access to it until the sessiond
674 static int get_wait_shm(char *shm_path
, size_t mmap_size
, int global
)
676 int wait_shm_fd
, ret
;
679 /* Default permissions */
680 mode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
;
682 /* Change owner of the shm path */
684 ret
= chown(shm_path
, 0, 0);
686 if (errno
!= ENOENT
) {
687 perror("chown wait shm");
693 * If global session daemon, any application can register so the shm
694 * needs to be set in read-only mode for others.
698 ret
= chown(shm_path
, getuid(), getgid());
700 if (errno
!= ENOENT
) {
701 perror("chown wait shm");
708 * Set permissions to the shm even if we did not create the shm.
710 ret
= chmod(shm_path
, mode
);
712 if (errno
!= ENOENT
) {
713 perror("chmod wait shm");
719 * We're alone in a child process, so we can modify the process-wide
725 * Try creating shm (or get rw access). We don't do an exclusive open,
726 * because we allow other processes to create+ftruncate it concurrently.
728 wait_shm_fd
= shm_open(shm_path
, O_RDWR
| O_CREAT
, mode
);
729 if (wait_shm_fd
< 0) {
730 perror("shm_open wait shm");
734 ret
= ftruncate(wait_shm_fd
, mmap_size
);
736 perror("ftruncate wait shm");
740 ret
= fchmod(wait_shm_fd
, mode
);
746 printf("Got the wait shm fd %d\n", wait_shm_fd
);
751 printf("Failing to get the wait shm fd\n");
756 int update_futex(int fd
, int active
)
758 size_t mmap_size
= sysconf(_SC_PAGE_SIZE
);
762 wait_shm_mmap
= mmap(NULL
, mmap_size
, PROT_READ
| PROT_WRITE
,
764 if (wait_shm_mmap
== MAP_FAILED
) {
770 uatomic_set((int32_t *) wait_shm_mmap
, 1);
771 futex_async((int32_t *) wait_shm_mmap
, FUTEX_WAKE
,
772 INT_MAX
, NULL
, NULL
, 0);
774 uatomic_set((int32_t *) wait_shm_mmap
, 0);
776 ret
= munmap(wait_shm_mmap
, mmap_size
);
778 perror("Error unmapping wait shm");
787 * Set open files limit to unlimited. This daemon can open a large number of
788 * file descriptors in order to consumer multiple kernel traces.
790 static void set_ulimit(void)
796 * If not root, we cannot increase our max open files. But our
797 * scope is then limited to processes from a single user.
801 /* The kernel does not allowed an infinite limit for open files */
802 lim
.rlim_cur
= 65535;
803 lim
.rlim_max
= 65535;
805 ret
= setrlimit(RLIMIT_NOFILE
, &lim
);
807 perror("failed to set open files limit");
813 * ./ust-basic-tracing outputpath event_name1 event_name2 ....
815 int main(int argc
, const char **argv
)
817 const char *home_dir
;
818 int ret
, wait_shm_fd
;
819 struct sigaction act
;
820 mode_t old_umask
= 0;
821 const char *outputpath
;
822 const char **event_names
;
823 unsigned int nr_events
;
827 printf("%s outputpath event_name1 event_name2 ...\n",
831 outputpath
= argv
[1];
832 event_names
= &argv
[2];
833 nr_events
= argc
- 2;
838 memset(&act
, 0, sizeof(act
));
839 ret
= sigemptyset(&act
.sa_mask
);
841 perror("sigemptyset");
845 act
.sa_handler
= SIG_IGN
;
846 ret
= sigaction(SIGPIPE
, &act
, NULL
);
853 act
.sa_handler
= handle_signals
;
854 ret
= sigaction(SIGTERM
, &act
, NULL
);
860 ret
= sigaction(SIGINT
, &act
, NULL
);
866 if (geteuid() == 0) {
867 ret
= mkdir(LTTNG_RUNDIR
, S_IRWXU
| S_IRWXG
| S_IROTH
| S_IXOTH
);
868 if (ret
&& errno
!= EEXIST
) {
872 wait_shm_fd
= get_wait_shm(DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH
,
873 sysconf(_SC_PAGE_SIZE
), 1);
874 if (wait_shm_fd
< 0) {
875 perror("global wait shm error");
878 strcpy(apps_sock_path
, DEFAULT_GLOBAL_APPS_UNIX_SOCK
);
879 old_umask
= umask(0);
881 snprintf(local_apps_wait_shm_path
, PATH_MAX
,
882 DEFAULT_HOME_APPS_WAIT_SHM_PATH
, getuid());
883 wait_shm_fd
= get_wait_shm(local_apps_wait_shm_path
,
884 sysconf(_SC_PAGE_SIZE
), 0);
885 if (wait_shm_fd
< 0) {
886 perror("local wait shm error");
889 home_dir
= (const char *) getenv("HOME");
891 perror("getenv error");
894 snprintf(apps_sock_path
, PATH_MAX
,
895 DEFAULT_HOME_APPS_UNIX_SOCK
, home_dir
);
898 ret
= lttcomm_create_unix_sock(apps_sock_path
);
900 perror("create error");
906 /* File permission MUST be 666 */
907 ret
= chmod(apps_sock_path
,
908 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
| S_IWOTH
);
910 printf("Set file permissions failed: %s\n", apps_sock_path
);
916 ret
= lttcomm_listen_unix_sock(apps_socket
);
918 perror("listen error");
922 /* wake up futexes */
923 ret
= update_futex(wait_shm_fd
, 1);
925 fprintf(stderr
, "Error wakeup futex\n");
939 char name
[16]; /* Process name */
946 printf("Accepting application registration\n");
947 sock
= lttcomm_accept_unix_sock(apps_socket
);
949 perror("accept error");
954 * Basic recv here to handle the very simple data
955 * that the libust send to register (reg_msg).
957 len
= lttcomm_recv_unix_sock(sock
, ®_msg
, sizeof(reg_msg
));
958 if (len
< 0 || len
!= sizeof(reg_msg
)) {
959 perror("lttcomm_recv_unix_sock");
962 memcpy(bufname
, reg_msg
.name
, 16);
964 printf("Application %s pid %u ppid %u uid %u gid %u has registered (version : %u.%u)\n",
965 bufname
, reg_msg
.pid
, reg_msg
.ppid
, reg_msg
.uid
,
966 reg_msg
.gid
, reg_msg
.major
, reg_msg
.minor
);
967 ret
= send_app_msgs(sock
, outputpath
, nr_events
, event_names
);
969 printf("Error in send_app_msgs.\n");
976 printf("quitting.\n");
977 /* Let applications know we are not responding anymore */
978 ret
= update_futex(wait_shm_fd
, 0);
980 fprintf(stderr
, "Error wakeup futex\n");