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
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License only.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #define _LARGEFILE64_SOURCE
33 #include <sys/resource.h>
34 #include <sys/socket.h>
37 #include <sys/types.h>
40 #include <urcu/futex.h>
41 #include <urcu/uatomic.h>
44 #include <lttng/ust-error.h>
45 #include "../../libringbuffer/backend.h"
46 #include "../../libringbuffer/frontend.h"
47 #include "../../liblttng-ust/compat.h" /* For ENODATA */
49 #define MAX_NR_STREAMS 64
50 #define MAX_NR_EVENTS 128
52 static int session_handle
;
53 static struct lttng_ust_object_data metadata_stream_data
;
54 static struct lttng_ust_object_data metadata_data
;
55 static struct lttng_ust_object_data channel_data
;
56 static struct lttng_ust_object_data stream_data
[MAX_NR_STREAMS
];
57 static int event_handle
[MAX_NR_EVENTS
];
58 static int context_handle
;
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
)
72 int open_streams(int sock
, int channel_handle
, struct lttng_ust_object_data
*stream_datas
,
78 struct ustcomm_ust_msg lum
;
79 struct ustcomm_ust_reply lur
;
81 memset(&lum
, 0, sizeof(lum
));
82 lum
.handle
= channel_handle
;
83 lum
.cmd
= LTTNG_UST_STREAM
;
84 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
87 stream_datas
[k
].handle
= lur
.ret_val
;
88 printf("received stream handle %u\n",
89 stream_datas
[k
].handle
);
90 if (lur
.ret_code
== LTTNG_UST_OK
) {
93 stream_datas
[k
].memory_map_size
= lur
.u
.stream
.memory_map_size
;
95 len
= ustcomm_recv_fd(sock
);
98 stream_datas
[k
].shm_fd
= len
;
100 len
= ustcomm_recv_fd(sock
);
103 stream_datas
[k
].wait_fd
= len
;
107 if (ret
== -LTTNG_UST_ERR_NOENT
)
116 int close_streams(int sock
, struct lttng_ust_object_data
*stream_datas
, int nr_check
)
120 for (k
= 0; k
< nr_check
; k
++) {
121 struct ustcomm_ust_msg lum
;
122 struct ustcomm_ust_reply lur
;
124 if (!stream_datas
[k
].handle
)
126 memset(&lum
, 0, sizeof(lum
));
127 lum
.handle
= stream_datas
[k
].handle
;
128 lum
.cmd
= LTTNG_UST_RELEASE
;
129 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
131 printf("Error closing stream\n");
134 if (stream_datas
[k
].shm_fd
>= 0) {
135 ret
= close(stream_datas
[k
].shm_fd
);
137 printf("Error closing stream shm_fd\n");
141 if (stream_datas
[k
].wait_fd
>= 0) {
142 ret
= close(stream_datas
[k
].wait_fd
);
144 printf("Error closing stream wait_fd\n");
153 struct lttng_ust_shm_handle
*map_channel(struct lttng_ust_object_data
*chan_data
,
154 struct lttng_ust_object_data
*stream_datas
, int nr_check
)
156 struct lttng_ust_shm_handle
*handle
;
157 struct channel
*chan
;
160 /* map metadata channel */
161 handle
= channel_handle_create(chan_data
->shm_fd
,
163 chan_data
->memory_map_size
);
165 printf("create handle error\n");
168 chan_data
->shm_fd
= -1;
169 chan_data
->wait_fd
= -1;
170 chan
= shmp(handle
, handle
->chan
);
172 for (k
= 0; k
< nr_check
; k
++) {
173 struct lttng_ust_object_data
*stream_data
= &stream_datas
[k
];
175 if (!stream_data
->handle
)
178 ret
= channel_handle_add_stream(handle
,
180 stream_data
->wait_fd
,
181 stream_data
->memory_map_size
);
183 printf("add stream error\n");
186 stream_data
->shm_fd
= -1;
187 stream_data
->wait_fd
= -1;
192 channel_destroy(chan
, handle
, 1);
197 void unmap_channel(struct lttng_ust_shm_handle
*handle
)
199 struct channel
*chan
;
201 chan
= shmp(handle
, handle
->chan
);
203 channel_destroy(chan
, handle
, 1);
207 int consume_stream(struct lttng_ust_shm_handle
*handle
, int cpu
, char *outfile
)
209 struct channel
*chan
;
210 struct lttng_ust_lib_ring_buffer
*buf
;
212 int *shm_fd
, *wait_fd
;
213 uint64_t *memory_map_size
;
215 chan
= shmp(handle
, handle
->chan
);
218 buf
= channel_get_ring_buffer(&chan
->backend
.config
,
219 chan
, cpu
, handle
, &shm_fd
, &wait_fd
, &memory_map_size
);
222 ret
= lib_ring_buffer_open_read(buf
, handle
, 1);
228 outfd
= open(outfile
, O_WRONLY
| O_CREAT
| O_TRUNC
,
229 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
);
231 perror("open output");
235 printf("Waiting for buffer data for %s\n", outfile
);
237 unsigned long read_size
;
238 unsigned long copy_size
;
241 ret
= lib_ring_buffer_get_next_subbuf(buf
, handle
);
242 printf("get next ret %d\n", ret
);
245 if (ret
== -EAGAIN
) {
250 printf("Error %d in lib_ring_buffer_get_next_subbuf\n", ret
);
253 read_size
= lib_ring_buffer_get_read_data_size(
254 &chan
->backend
.config
, buf
, handle
);
255 read_size
= PAGE_ALIGN(read_size
);
256 ptr
= lib_ring_buffer_read_offset_address(
257 &buf
->backend
, 0, handle
);
258 printf("WRITE: copy %lu bytes\n", read_size
);
259 copy_size
= write(outfd
, ptr
, read_size
);
260 if (copy_size
< read_size
) {
261 printf("write issue: copied %lu, expected %lu\n", copy_size
, read_size
);
263 lib_ring_buffer_put_next_subbuf(buf
, handle
);
273 lib_ring_buffer_release_read(buf
, handle
, 1);
278 int consume_buffers(const char *outputpath
)
282 char pathname
[PATH_MAX
];
283 struct lttng_ust_shm_handle
*handle
;
285 snprintf(pathname
, PATH_MAX
- 1, "%s", outputpath
);
286 old_umask
= umask(0);
287 ret
= mkdir(pathname
, S_IRWXU
| S_IRWXG
);
288 if (ret
&& errno
!= EEXIST
) {
296 handle
= map_channel(&metadata_data
,
297 &metadata_stream_data
, 1);
300 snprintf(pathname
, PATH_MAX
- 1,
301 "%s/metadata", outputpath
);
302 ret
= consume_stream(handle
, -1, pathname
);
303 if (ret
&& ret
!= -ENOENT
) {
304 printf("Error in consume_stream\n");
307 unmap_channel(handle
);
309 /* copy binary data */
310 handle
= map_channel(&channel_data
,
311 stream_data
, MAX_NR_STREAMS
);
314 for (k
= 0; k
< MAX_NR_STREAMS
; k
++) {
315 snprintf(pathname
, PATH_MAX
- 1,
316 "%s/data_%u", outputpath
, k
);
317 ret
= consume_stream(handle
, k
, pathname
);
318 if (ret
&& ret
!= -ENOENT
) {
319 printf("Error in consume_stream\n");
323 unmap_channel(handle
);
329 int send_app_msgs(int sock
, const char *outputpath
,
330 unsigned int nr_events
, const char **event_names
)
332 struct ustcomm_ust_msg lum
;
333 struct ustcomm_ust_reply lur
;
337 memset(&lum
, 0, sizeof(lum
));
338 lum
.handle
= LTTNG_UST_ROOT_HANDLE
;
339 lum
.cmd
= LTTNG_UST_SESSION
;
340 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
343 session_handle
= lur
.ret_val
;
344 printf("received session handle %u\n", session_handle
);
346 /* Create metadata channel */
347 memset(&lum
, 0, sizeof(lum
));
348 lum
.handle
= session_handle
;
349 lum
.cmd
= LTTNG_UST_METADATA
;
350 lum
.u
.channel
.overwrite
= 0;
351 lum
.u
.channel
.subbuf_size
= 32768;
352 lum
.u
.channel
.num_subbuf
= 4;
353 lum
.u
.channel
.switch_timer_interval
= 0;
354 lum
.u
.channel
.read_timer_interval
= 0;
355 lum
.u
.channel
.output
= LTTNG_UST_MMAP
;
356 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
359 metadata_data
.handle
= lur
.ret_val
;
360 printf("received metadata handle %u\n", metadata_data
.handle
);
361 if (lur
.ret_code
== LTTNG_UST_OK
) {
364 metadata_data
.memory_map_size
= lur
.u
.channel
.memory_map_size
;
366 len
= ustcomm_recv_fd(sock
);
369 metadata_data
.shm_fd
= len
;
371 len
= ustcomm_recv_fd(sock
);
374 metadata_data
.wait_fd
= len
;
377 ret
= open_streams(sock
, metadata_data
.handle
,
378 &metadata_stream_data
, 1);
380 printf("Error in open_streams\n");
384 /* Create data channel */
385 memset(&lum
, 0, sizeof(lum
));
386 lum
.handle
= session_handle
;
387 lum
.cmd
= LTTNG_UST_CHANNEL
;
388 //lum.u.channel.overwrite = 0;
389 lum
.u
.channel
.overwrite
= 1;
390 lum
.u
.channel
.subbuf_size
= 32768;
391 lum
.u
.channel
.num_subbuf
= 8;
392 //lum.u.channel.num_subbuf = 4;
393 //lum.u.channel.num_subbuf = 2;
394 lum
.u
.channel
.switch_timer_interval
= 0;
395 lum
.u
.channel
.read_timer_interval
= 0;
396 lum
.u
.channel
.output
= LTTNG_UST_MMAP
;
397 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
400 channel_data
.handle
= lur
.ret_val
;
401 printf("received channel handle %u\n", channel_data
.handle
);
402 if (lur
.ret_code
== LTTNG_UST_OK
) {
405 channel_data
.memory_map_size
= lur
.u
.channel
.memory_map_size
;
407 len
= ustcomm_recv_fd(sock
);
410 channel_data
.shm_fd
= len
;
412 len
= ustcomm_recv_fd(sock
);
415 channel_data
.wait_fd
= len
;
419 for (k
= 0; k
< nr_events
; k
++) {
420 memset(&lum
, 0, sizeof(lum
));
421 lum
.handle
= channel_data
.handle
;
422 lum
.cmd
= LTTNG_UST_EVENT
;
423 strncpy(lum
.u
.event
.name
, event_names
[k
],
424 LTTNG_UST_SYM_NAME_LEN
);
425 lum
.u
.event
.instrumentation
= LTTNG_UST_TRACEPOINT
;
426 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
429 event_handle
[k
] = lur
.ret_val
;
430 printf("received event handle %u\n", event_handle
[k
]);
433 /* Attach vtid context */
434 memset(&lum
, 0, sizeof(lum
));
435 lum
.handle
= channel_data
.handle
;
436 lum
.cmd
= LTTNG_UST_CONTEXT
;
437 lum
.u
.context
.ctx
= LTTNG_UST_CONTEXT_VTID
;
438 //lum.u.context.ctx = LTTNG_UST_CONTEXT_PTHREAD_ID;
439 //lum.u.context.ctx = LTTNG_UST_CONTEXT_VPID;
440 //lum.u.context.ctx = LTTNG_UST_CONTEXT_PROCNAME;
441 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
444 context_handle
= lur
.ret_val
;
445 printf("received context handle %u\n", context_handle
);
447 /* Get references to channel streams */
448 ret
= open_streams(sock
, channel_data
.handle
,
449 stream_data
, MAX_NR_STREAMS
);
451 printf("Error in open_streams\n");
455 memset(&lum
, 0, sizeof(lum
));
456 lum
.handle
= session_handle
;
457 lum
.cmd
= LTTNG_UST_SESSION_START
;
458 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
461 printf("Session handle %u started.\n", session_handle
);
463 /* Tell application registration is done */
464 memset(&lum
, 0, sizeof(lum
));
465 lum
.handle
= LTTNG_UST_ROOT_HANDLE
;
466 lum
.cmd
= LTTNG_UST_REGISTER_DONE
;
467 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
470 printf("Registration done acknowledged.\n");
474 ret
= consume_buffers(outputpath
);
476 printf("Error in consume_buffers\n");
480 /* Release data channel */
481 /* Release streams */
482 ret
= close_streams(sock
, stream_data
,
487 /* Release context */
488 memset(&lum
, 0, sizeof(lum
));
489 lum
.handle
= context_handle
;
490 lum
.cmd
= LTTNG_UST_RELEASE
;
491 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
496 for (k
= 0; k
< nr_events
; k
++) {
497 memset(&lum
, 0, sizeof(lum
));
498 lum
.handle
= event_handle
[k
];
499 lum
.cmd
= LTTNG_UST_RELEASE
;
500 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
504 memset(&lum
, 0, sizeof(lum
));
505 lum
.handle
= channel_data
.handle
;
506 lum
.cmd
= LTTNG_UST_RELEASE
;
507 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
510 if (channel_data
.shm_fd
>= 0) {
511 ret
= close(channel_data
.shm_fd
);
515 if (channel_data
.wait_fd
>= 0) {
516 ret
= close(channel_data
.wait_fd
);
521 /* Release metadata channel */
522 ret
= close_streams(sock
, &metadata_stream_data
, 1);
526 memset(&lum
, 0, sizeof(lum
));
527 lum
.handle
= metadata_data
.handle
;
528 lum
.cmd
= LTTNG_UST_RELEASE
;
529 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
532 if (metadata_data
.shm_fd
>= 0) {
533 ret
= close(metadata_data
.shm_fd
);
537 if (metadata_data
.wait_fd
>= 0) {
538 ret
= close(metadata_data
.wait_fd
);
543 /* Release session */
544 memset(&lum
, 0, sizeof(lum
));
545 lum
.handle
= session_handle
;
546 lum
.cmd
= LTTNG_UST_RELEASE
;
547 ret
= ustcomm_send_app_cmd(sock
, &lum
, &lur
);
555 * Using fork to set umask in the child process (not multi-thread safe). We
556 * deal with the shm_open vs ftruncate race (happening when the sessiond owns
557 * the shm and does not let everybody modify it, to ensure safety against
558 * shm_unlink) by simply letting the mmap fail and retrying after a few
559 * seconds. For global shm, everybody has rw access to it until the sessiond
562 static int get_wait_shm(char *shm_path
, size_t mmap_size
, int global
)
564 int wait_shm_fd
, ret
;
567 /* Default permissions */
568 mode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
;
570 /* Change owner of the shm path */
572 ret
= chown(shm_path
, 0, 0);
574 if (errno
!= ENOENT
) {
575 perror("chown wait shm");
581 * If global session daemon, any application can register so the shm
582 * needs to be set in read-only mode for others.
586 ret
= chown(shm_path
, getuid(), getgid());
588 if (errno
!= ENOENT
) {
589 perror("chown wait shm");
596 * Set permissions to the shm even if we did not create the shm.
598 ret
= chmod(shm_path
, mode
);
600 if (errno
!= ENOENT
) {
601 perror("chmod wait shm");
607 * We're alone in a child process, so we can modify the process-wide
613 * Try creating shm (or get rw access). We don't do an exclusive open,
614 * because we allow other processes to create+ftruncate it concurrently.
616 wait_shm_fd
= shm_open(shm_path
, O_RDWR
| O_CREAT
, mode
);
617 if (wait_shm_fd
< 0) {
618 perror("shm_open wait shm");
622 ret
= ftruncate(wait_shm_fd
, mmap_size
);
624 perror("ftruncate wait shm");
628 ret
= fchmod(wait_shm_fd
, mode
);
634 printf("Got the wait shm fd %d\n", wait_shm_fd
);
639 printf("Failing to get the wait shm fd\n");
644 int update_futex(int fd
, int active
)
650 page_size
= sysconf(_SC_PAGE_SIZE
);
651 if (page_size
<= 0) {
655 perror("Error in sysconf(_SC_PAGE_SIZE)");
658 wait_shm_mmap
= mmap(NULL
, page_size
, PROT_READ
| PROT_WRITE
,
660 if (wait_shm_mmap
== MAP_FAILED
) {
666 uatomic_set((int32_t *) wait_shm_mmap
, 1);
667 if (futex_async((int32_t *) wait_shm_mmap
, FUTEX_WAKE
,
668 INT_MAX
, NULL
, NULL
, 0) < 0) {
669 perror("futex_async");
673 uatomic_set((int32_t *) wait_shm_mmap
, 0);
675 ret
= munmap(wait_shm_mmap
, page_size
);
677 perror("Error unmapping wait shm");
686 * Set open files limit to unlimited. This daemon can open a large number of
687 * file descriptors in order to consumer multiple kernel traces.
689 static void set_ulimit(void)
695 * If not root, we cannot increase our max open files. But our
696 * scope is then limited to processes from a single user.
700 /* The kernel does not allowed an infinite limit for open files */
701 lim
.rlim_cur
= 65535;
702 lim
.rlim_max
= 65535;
704 ret
= setrlimit(RLIMIT_NOFILE
, &lim
);
706 perror("failed to set open files limit");
712 * ./ust-basic-tracing outputpath event_name1 event_name2 ....
714 int main(int argc
, const char **argv
)
716 const char *home_dir
;
717 char home_rundir
[PATH_MAX
];
719 int ret
, wait_shm_fd
;
720 struct sigaction act
;
721 mode_t old_umask
= 0;
722 const char *outputpath
;
723 const char **event_names
;
724 unsigned int nr_events
;
729 printf("%s outputpath event_name1 event_name2 ...\n",
733 outputpath
= argv
[1];
734 event_names
= &argv
[2];
735 nr_events
= argc
- 2;
740 memset(&act
, 0, sizeof(act
));
741 ret
= sigemptyset(&act
.sa_mask
);
743 perror("sigemptyset");
747 act
.sa_handler
= SIG_IGN
;
748 ret
= sigaction(SIGPIPE
, &act
, NULL
);
755 act
.sa_handler
= handle_signals
;
756 ret
= sigaction(SIGTERM
, &act
, NULL
);
762 ret
= sigaction(SIGINT
, &act
, NULL
);
768 page_size
= sysconf(_SC_PAGE_SIZE
);
769 if (page_size
<= 0) {
773 perror("Error in sysconf(_SC_PAGE_SIZE)");
777 if (geteuid() == 0) {
778 ret
= mkdir(LTTNG_RUNDIR
, S_IRWXU
| S_IRWXG
| S_IROTH
| S_IXOTH
);
779 if (ret
&& errno
!= EEXIST
) {
783 wait_shm_fd
= get_wait_shm(DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH
,
785 if (wait_shm_fd
< 0) {
786 perror("global wait shm error");
789 strcpy(apps_sock_path
, DEFAULT_GLOBAL_APPS_UNIX_SOCK
);
790 old_umask
= umask(0);
792 home_dir
= (const char *) getenv("HOME");
794 perror("getenv error");
798 snprintf(home_rundir
, PATH_MAX
,
799 LTTNG_HOME_RUNDIR
, home_dir
);
801 ret
= mkdir(home_rundir
, S_IRWXU
| S_IRWXG
| S_IROTH
| S_IXOTH
);
802 if (ret
&& errno
!= EEXIST
) {
807 snprintf(local_apps_wait_shm_path
, PATH_MAX
,
808 DEFAULT_HOME_APPS_WAIT_SHM_PATH
, getuid());
809 wait_shm_fd
= get_wait_shm(local_apps_wait_shm_path
,
811 if (wait_shm_fd
< 0) {
812 perror("local wait shm error");
815 snprintf(apps_sock_path
, PATH_MAX
,
816 DEFAULT_HOME_APPS_UNIX_SOCK
, home_dir
);
819 ret
= ustcomm_create_unix_sock(apps_sock_path
);
821 perror("create error");
827 /* File permission MUST be 666 */
828 ret
= chmod(apps_sock_path
,
829 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
| S_IWOTH
);
831 printf("Set file permissions failed: %s\n", apps_sock_path
);
837 ret
= ustcomm_listen_unix_sock(apps_socket
);
839 perror("listen error");
843 /* wake up futexes */
844 ret
= update_futex(wait_shm_fd
, 1);
846 fprintf(stderr
, "Error wakeup futex\n");
860 uint32_t bits_per_long
;
861 char name
[16]; /* Process name */
868 printf("Accepting application registration\n");
869 sock
= ustcomm_accept_unix_sock(apps_socket
);
871 perror("accept error");
876 * Basic recv here to handle the very simple data
877 * that the libust send to register (reg_msg).
879 len
= ustcomm_recv_unix_sock(sock
, ®_msg
, sizeof(reg_msg
));
880 if (len
< 0 || len
!= sizeof(reg_msg
)) {
881 perror("ustcomm_recv_unix_sock");
884 memcpy(bufname
, reg_msg
.name
, 16);
886 printf("Application %s pid %u ppid %u uid %u gid %u has registered (version : %u.%u)\n",
887 bufname
, reg_msg
.pid
, reg_msg
.ppid
, reg_msg
.uid
,
888 reg_msg
.gid
, reg_msg
.major
, reg_msg
.minor
);
889 ret
= send_app_msgs(sock
, outputpath
, nr_events
, event_names
);
891 printf("Error in send_app_msgs.\n");
898 printf("quitting.\n");
899 /* Let applications know we are not responding anymore */
900 ret
= update_futex(wait_shm_fd
, 0);
902 fprintf(stderr
, "Error wakeup futex\n");
907 printf("Removing %s directory\n", home_rundir
);
908 ret
= asprintf(&cmd
, "rm -rf %s", home_rundir
);
910 printf("asprintf failed. Something is really wrong!\n");
914 /* Remove lttng run directory */
917 printf("Unable to clean %s\n", home_rundir
);