2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <sys/socket.h>
33 #include <sys/types.h>
36 #include <urcu/list.h> /* URCU list library (-lurcu) */
37 #include <ust/ustctl.h> /* UST control lib (-lust) */
38 #include <lttng/lttng.h>
40 #include "liblttsessiondcomm.h"
41 #include "ltt-sessiond.h"
45 #include "traceable-app.h"
48 const char default_home_dir
[] = DEFAULT_HOME_DIR
;
49 const char default_tracing_group
[] = DEFAULT_TRACING_GROUP
;
50 const char default_ust_sock_dir
[] = DEFAULT_UST_SOCK_DIR
;
51 const char default_global_apps_pipe
[] = DEFAULT_GLOBAL_APPS_PIPE
;
53 /* Static functions */
54 static int check_existing_daemon(void);
55 static int ust_connect_app(pid_t pid
);
56 static int init_daemon_socket(void);
57 static int notify_apps(const char* name
);
58 static int process_client_msg(int sock
, struct lttcomm_session_msg
*);
59 static int send_unix_sock(int sock
, void *buf
, size_t len
);
60 static int set_signal_handler(void);
61 static int set_permissions(void);
62 static int setup_data_buffer(char **buf
, size_t size
, struct lttcomm_lttng_header
*llh
);
63 static int create_lttng_rundir(void);
64 static int set_kconsumerd_sockets(void);
65 static void cleanup(void);
66 static void copy_common_data(struct lttcomm_lttng_header
*llh
, struct lttcomm_session_msg
*lsm
);
67 static void sighandler(int sig
);
69 static void *thread_manage_clients(void *data
);
70 static void *thread_manage_apps(void *data
);
71 static void *thread_manage_kconsumerd(void *data
);
77 const char *opt_tracing_group
;
78 static int opt_sig_parent
;
79 static int opt_daemon
;
80 static int is_root
; /* Set to 1 if the daemon is running as root */
83 static char apps_unix_sock_path
[PATH_MAX
]; /* Global application Unix socket path */
84 static char client_unix_sock_path
[PATH_MAX
]; /* Global client Unix socket path */
85 static char kconsumerd_err_unix_sock_path
[PATH_MAX
]; /* kconsumerd error Unix socket path */
86 static char kconsumerd_cmd_unix_sock_path
[PATH_MAX
]; /* kconsumerd command Unix socket path */
88 static int client_sock
;
90 static int kconsumerd_err_sock
;
92 /* Extern in session.h */
93 struct ltt_session
*current_session
;
96 * thread_manage_kconsumerd
98 * This thread manage the kconsumerd error sent
99 * back to the session daemon.
101 static void *thread_manage_kconsumerd(void *data
)
105 DBG("[thread] Manage kconsumerd started");
107 ret
= lttcomm_listen_unix_sock(kconsumerd_err_sock
);
112 sock
= lttcomm_accept_unix_sock(kconsumerd_err_sock
);
118 //ret = lttcomm_recv_unix_sock(sock, &lsm, sizeof(lsm));
120 /* TODO: Consumerd died? */
132 * This thread manage the application socket communication
134 static void *thread_manage_apps(void *data
)
138 /* TODO: Something more elegant is needed but fine for now */
140 int reg
; /* 1:register, 0:unregister */
145 DBG("[thread] Manage apps started");
147 /* Notify all applications to register */
148 notify_apps(default_global_apps_pipe
);
150 ret
= lttcomm_listen_unix_sock(apps_sock
);
156 /* Blocking call, waiting for transmission */
157 sock
= lttcomm_accept_unix_sock(apps_sock
);
162 /* Basic recv here to handle the very simple data
163 * that the libust send to register (reg_msg).
165 ret
= recv(sock
, ®_msg
, sizeof(reg_msg
), 0);
171 /* Add application to the global traceable list */
172 if (reg_msg
.reg
== 1) {
174 ret
= register_traceable_app(reg_msg
.pid
, reg_msg
.uid
);
176 /* register_traceable_app only return an error with
177 * ENOMEM. At this point, we better stop everything.
183 unregister_traceable_app(reg_msg
.pid
);
193 * thread_manage_clients
195 * This thread manage all clients request using the unix
196 * client socket for communication.
198 static void *thread_manage_clients(void *data
)
201 struct lttcomm_session_msg lsm
;
203 DBG("[thread] Manage client started");
205 ret
= lttcomm_listen_unix_sock(client_sock
);
210 /* Notify parent pid that we are ready
211 * to accept command for client side.
213 if (opt_sig_parent
) {
218 /* Blocking call, waiting for transmission */
219 sock
= lttcomm_accept_unix_sock(client_sock
);
225 * Data is received from the lttng client. The struct
226 * lttcomm_session_msg (lsm) contains the command and data
227 * request of the client.
229 ret
= lttcomm_recv_unix_sock(sock
, &lsm
, sizeof(lsm
));
234 /* This function dispatch the work to the LTTng or UST libs
235 * and then sends back the response to the client. This is needed
236 * because there might be more then one lttcomm_lttng_header to
237 * send out so process_client_msg do both jobs.
239 ret
= process_client_msg(sock
, &lsm
);
241 /* Error detected but still accept command */
253 * Send data on a unix socket using the liblttsessiondcomm API.
255 * Return lttcomm error code.
257 static int send_unix_sock(int sock
, void *buf
, size_t len
)
259 /* Check valid length */
264 return lttcomm_send_unix_sock(sock
, buf
, len
);
270 * Return a socket connected to the libust communication socket
271 * of the application identified by the pid.
273 * If the pid is not found in the traceable list,
274 * return -1 to indicate error.
276 static int ust_connect_app(pid_t pid
)
279 struct ltt_traceable_app
*lta
;
281 DBG("Connect to application pid %d", pid
);
283 lta
= find_app_by_pid(pid
);
286 DBG("Application pid %d not found", pid
);
290 sock
= ustctl_connect_pid(lta
->pid
);
292 ERR("Fail connecting to the PID %d\n", pid
);
301 * Notify apps by writing 42 to a named pipe using name.
302 * Every applications waiting for a ltt-sessiond will be notified
303 * and re-register automatically to the session daemon.
305 * Return open or write error value.
307 static int notify_apps(const char *name
)
312 DBG("Notify the global application pipe");
314 /* Try opening the global pipe */
315 fd
= open(name
, O_WRONLY
);
320 /* Notify by writing on the pipe */
321 ret
= write(fd
, "42", 2);
333 * Copy common data between lttcomm_lttng_header and lttcomm_session_msg
335 static void copy_common_data(struct lttcomm_lttng_header
*llh
, struct lttcomm_session_msg
*lsm
)
337 llh
->cmd_type
= lsm
->cmd_type
;
341 if (!uuid_is_null(lsm
->session_id
)) {
342 uuid_copy(llh
->session_id
, lsm
->session_id
);
345 strncpy(llh
->trace_name
, lsm
->trace_name
, strlen(llh
->trace_name
));
346 llh
->trace_name
[strlen(llh
->trace_name
) - 1] = '\0';
352 * Setup the outgoing data buffer for the response
353 * data allocating the right amount of memory.
355 * Return total size of the buffer pointed by buf.
357 static int setup_data_buffer(char **buf
, size_t s_data
, struct lttcomm_lttng_header
*llh
)
362 buf_size
= sizeof(struct lttcomm_lttng_header
) + s_data
;
363 *buf
= malloc(buf_size
);
370 /* Setup lttcomm_lttng_header data and copy
371 * it to the newly allocated buffer.
373 llh
->payload_size
= s_data
;
374 memcpy(*buf
, llh
, sizeof(struct lttcomm_lttng_header
));
385 * This takes the lttcomm_session_msg struct and process the command requested
386 * by the client. It then creates response(s) and send it back to the
387 * given socket (sock).
389 * Return any error encountered or 0 for success.
391 static int process_client_msg(int sock
, struct lttcomm_session_msg
*lsm
)
393 int ust_sock
, ret
, buf_size
;
395 char *send_buf
= NULL
;
396 struct lttcomm_lttng_header llh
;
398 DBG("Processing client message");
400 /* Copy common data to identify the response
401 * on the lttng client side.
403 copy_common_data(&llh
, lsm
);
405 /* Check command that needs a session */
406 if (lsm
->cmd_type
!= LTTNG_CREATE_SESSION
&&
407 lsm
->cmd_type
!= LTTNG_LIST_SESSIONS
&&
408 lsm
->cmd_type
!= UST_LIST_APPS
)
410 current_session
= find_session_by_uuid(lsm
->session_id
);
411 if (current_session
== NULL
) {
412 ret
= LTTCOMM_SELECT_SESS
;
417 /* Default return code.
418 * In our world, everything is OK... right? ;)
420 llh
.ret_code
= LTTCOMM_OK
;
422 header_size
= sizeof(struct lttcomm_lttng_header
);
424 /* Connect to ust apps if available pid */
426 /* Connect to app using ustctl API */
427 ust_sock
= ust_connect_app(lsm
->pid
);
429 ret
= LTTCOMM_NO_TRACEABLE
;
434 /* Process by command type */
435 switch (lsm
->cmd_type
) {
436 case LTTNG_CREATE_SESSION
:
438 ret
= create_session(lsm
->session_name
, &llh
.session_id
);
441 ret
= LTTCOMM_EXIST_SESS
;
448 buf_size
= setup_data_buffer(&send_buf
, 0, &llh
);
456 case LTTNG_DESTROY_SESSION
:
458 ret
= destroy_session(&lsm
->session_id
);
460 ret
= LTTCOMM_NO_SESS
;
465 /* No auxiliary data so only send the llh struct. */
468 case LTTNG_LIST_TRACES
:
470 unsigned int trace_count
= get_trace_count_per_session(current_session
);
472 if (trace_count
== 0) {
473 ret
= LTTCOMM_NO_TRACE
;
477 buf_size
= setup_data_buffer(&send_buf
,
478 sizeof(struct lttng_trace
) * trace_count
, &llh
);
484 get_traces_per_session(current_session
, (struct lttng_trace
*)(send_buf
+ header_size
));
487 case UST_CREATE_TRACE
:
489 ret
= ust_create_trace(ust_sock
, lsm
->pid
);
491 /* If -1 is returned from ust_create_trace, malloc
492 * failed so it's pretty much a fatal error.
498 /* No auxiliary data so only send the llh struct. */
503 unsigned int app_count
= get_app_count();
504 /* Stop right now if no apps */
505 if (app_count
== 0) {
506 ret
= LTTCOMM_NO_APPS
;
510 /* Setup data buffer and details for transmission */
511 buf_size
= setup_data_buffer(&send_buf
,
512 sizeof(pid_t
) * app_count
, &llh
);
518 get_app_list_pids((pid_t
*)(send_buf
+ header_size
));
522 case UST_START_TRACE
:
524 ret
= ust_start_trace(ust_sock
, lsm
->pid
);
526 /* No auxiliary data so only send the llh struct. */
531 ret
= ust_stop_trace(ust_sock
, lsm
->pid
);
533 /* No auxiliary data so only send the llh struct. */
536 case LTTNG_LIST_SESSIONS
:
538 unsigned int session_count
= get_session_count();
539 /* Stop right now if no session */
540 if (session_count
== 0) {
541 ret
= LTTCOMM_NO_SESS
;
545 /* Setup data buffer and details for transmission */
546 buf_size
= setup_data_buffer(&send_buf
,
547 (sizeof(struct lttng_session
) * session_count
), &llh
);
553 get_lttng_session((struct lttng_session
*)(send_buf
+ header_size
));
559 /* Undefined command */
565 ret
= send_unix_sock(sock
, send_buf
, buf_size
);
567 if (send_buf
!= NULL
) {
574 DBG("Return code to client %d", ret
);
575 /* Notify client of error */
577 llh
.payload_size
= 0;
578 send_unix_sock(sock
, (void*) &llh
, sizeof(llh
));
584 * usage function on stderr
586 static void usage(void)
588 fprintf(stderr
, "Usage: %s OPTIONS\n\nOptions:\n", progname
);
589 fprintf(stderr
, " -h, --help Display this usage.\n");
590 fprintf(stderr
, " -c, --client-sock PATH Specify path for the client unix socket\n");
591 fprintf(stderr
, " -a, --apps-sock PATH Specify path for apps unix socket\n");
592 fprintf(stderr
, " --kconsumerd-err-sock PATH Specify path for the kernel consumer error socket\n");
593 fprintf(stderr
, " --kconsumerd-cmd-sock PATH Specify path for the kernel consumer command socket\n");
594 fprintf(stderr
, " -d, --daemonize Start as a daemon.\n");
595 fprintf(stderr
, " -g, --group NAME Specify the tracing group name. (default: tracing)\n");
596 fprintf(stderr
, " -V, --version Show version number.\n");
597 fprintf(stderr
, " -S, --sig-parent Send SIGCHLD to parent pid to notify readiness.\n");
598 fprintf(stderr
, " -q, --quiet No output at all.\n");
599 fprintf(stderr
, " -v, --verbose Verbose mode. Activate DBG() macro.\n");
603 * daemon argument parsing
605 static int parse_args(int argc
, char **argv
)
609 static struct option long_options
[] = {
610 { "client-sock", 1, 0, 'c' },
611 { "apps-sock", 1, 0, 'a' },
612 { "kconsumerd-cmd-sock", 1, 0, 0 },
613 { "kconsumerd-err-sock", 1, 0, 0 },
614 { "daemonize", 0, 0, 'd' },
615 { "sig-parent", 0, 0, 'S' },
616 { "help", 0, 0, 'h' },
617 { "group", 1, 0, 'g' },
618 { "version", 0, 0, 'V' },
619 { "quiet", 0, 0, 'q' },
620 { "verbose", 0, 0, 'v' },
625 int option_index
= 0;
626 c
= getopt_long(argc
, argv
, "dhqvVS" "a:c:g:s:E:C:", long_options
, &option_index
);
633 fprintf(stderr
, "option %s", long_options
[option_index
].name
);
635 fprintf(stderr
, " with arg %s\n", optarg
);
639 snprintf(client_unix_sock_path
, PATH_MAX
, "%s", optarg
);
642 snprintf(apps_unix_sock_path
, PATH_MAX
, "%s", optarg
);
648 opt_tracing_group
= strdup(optarg
);
654 fprintf(stdout
, "%s\n", VERSION
);
660 snprintf(kconsumerd_err_unix_sock_path
, PATH_MAX
, "%s", optarg
);
663 snprintf(kconsumerd_cmd_unix_sock_path
, PATH_MAX
, "%s", optarg
);
672 /* Unknown option or other error.
673 * Error is printed by getopt, just return */
684 * Creates the two needed socket by the daemon.
685 * apps_sock - The communication socket for all UST apps.
686 * client_sock - The communication of the cli tool (lttng).
688 static int init_daemon_socket()
693 old_umask
= umask(0);
695 /* Create client tool unix socket */
696 client_sock
= lttcomm_create_unix_sock(client_unix_sock_path
);
697 if (client_sock
< 0) {
698 ERR("Create unix sock failed: %s", client_unix_sock_path
);
703 /* File permission MUST be 660 */
704 ret
= chmod(client_unix_sock_path
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
);
706 ERR("Set file permissions failed: %s", client_unix_sock_path
);
711 /* Create the application unix socket */
712 apps_sock
= lttcomm_create_unix_sock(apps_unix_sock_path
);
714 ERR("Create unix sock failed: %s", apps_unix_sock_path
);
719 /* File permission MUST be 666 */
720 ret
= chmod(apps_unix_sock_path
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
| S_IWOTH
);
722 ERR("Set file permissions failed: %s", apps_unix_sock_path
);
733 * check_existing_daemon
735 * Check if the global socket is available.
736 * If yes, error is returned.
738 static int check_existing_daemon()
742 ret
= access(client_unix_sock_path
, F_OK
);
744 ret
= access(apps_unix_sock_path
, F_OK
);
753 * Return pointer to home directory path using
754 * the env variable HOME.
758 static const char *get_home_dir(void)
760 const char *home_path
;
762 if ((home_path
= (const char *) getenv("HOME")) == NULL
) {
763 home_path
= default_home_dir
;
772 * Set the tracing group gid onto the client socket.
774 static int set_permissions(void)
779 /* Decide which group name to use */
780 (opt_tracing_group
!= NULL
) ?
781 (grp
= getgrnam(opt_tracing_group
)) :
782 (grp
= getgrnam(default_tracing_group
));
785 ERR("Missing tracing group. Aborting execution.\n");
790 /* Set lttng run dir */
791 ret
= chown(LTTNG_RUNDIR
, 0, grp
->gr_gid
);
793 ERR("Unable to set group on " LTTNG_RUNDIR
);
797 /* lttng client socket path */
798 ret
= chown(client_unix_sock_path
, 0, grp
->gr_gid
);
800 ERR("Unable to set group on %s", client_unix_sock_path
);
804 /* kconsumerd error socket path */
805 ret
= chown(kconsumerd_err_unix_sock_path
, 0, grp
->gr_gid
);
807 ERR("Unable to set group on %s", kconsumerd_err_unix_sock_path
);
811 DBG("All permissions are set");
818 * create_lttng_rundir
820 * Create the lttng run directory needed for all
821 * global sockets and pipe.
823 static int create_lttng_rundir(void)
827 ret
= mkdir(LTTNG_RUNDIR
, S_IRWXU
| S_IRWXG
);
829 ERR("Unable to create " LTTNG_RUNDIR
);
838 * set_kconsumerd_sockets
840 * Setup sockets and directory needed by the kconsumerd
841 * communication with the session daemon.
843 static int set_kconsumerd_sockets(void)
847 if (strlen(kconsumerd_err_unix_sock_path
) == 0) {
848 snprintf(kconsumerd_err_unix_sock_path
, PATH_MAX
, KCONSUMERD_ERR_SOCK_PATH
);
851 if (strlen(kconsumerd_cmd_unix_sock_path
) == 0) {
852 snprintf(kconsumerd_cmd_unix_sock_path
, PATH_MAX
, KCONSUMERD_CMD_SOCK_PATH
);
855 ret
= mkdir(KCONSUMERD_PATH
, S_IRWXU
| S_IRWXG
);
857 ERR("Failed to create " KCONSUMERD_PATH
);
861 /* Create the kconsumerd error unix socket */
862 kconsumerd_err_sock
= lttcomm_create_unix_sock(kconsumerd_err_unix_sock_path
);
863 if (kconsumerd_err_sock
< 0) {
864 ERR("Create unix sock failed: %s", kconsumerd_err_unix_sock_path
);
869 /* File permission MUST be 660 */
870 ret
= chmod(kconsumerd_err_unix_sock_path
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
);
872 ERR("Set file permissions failed: %s", kconsumerd_err_unix_sock_path
);
884 * Setup signal handler for :
885 * SIGINT, SIGTERM, SIGPIPE
887 static int set_signal_handler(void)
893 if ((ret
= sigemptyset(&sigset
)) < 0) {
894 perror("sigemptyset");
898 sa
.sa_handler
= sighandler
;
901 if ((ret
= sigaction(SIGTERM
, &sa
, NULL
)) < 0) {
906 if ((ret
= sigaction(SIGINT
, &sa
, NULL
)) < 0) {
911 if ((ret
= sigaction(SIGPIPE
, &sa
, NULL
)) < 0) {
916 DBG("Signal handler set for SIGTERM, SIGPIPE and SIGINT");
924 * Signal handler for the daemon
926 static void sighandler(int sig
)
930 DBG("SIGPIPE catched");
933 DBG("SIGINT catched");
937 DBG("SIGTERM catched");
950 * Cleanup the daemon on exit
952 static void cleanup()
960 MSG("\n%c[%d;%dm*** assert failed *** ==> %c[%dm", 27,1,31,27,0);
961 MSG("%c[%d;%dmMatthew, BEET driven development works!%c[%dm",27,1,33,27,0);
964 unlink(client_unix_sock_path
);
965 unlink(apps_unix_sock_path
);
966 unlink(kconsumerd_err_unix_sock_path
);
968 ret
= asprintf(&cmd
, "rm -rf " LTTNG_RUNDIR
);
970 ERR("asprintf failed. Something is really wrong!");
973 /* Remove lttng run directory */
976 ERR("Unable to clean " LTTNG_RUNDIR
);
983 int main(int argc
, char **argv
)
988 pthread_t threads
[2];
990 /* Parse arguments */
992 if ((ret
= parse_args(argc
, argv
) < 0)) {
1005 /* Check if daemon is UID = 0 */
1006 is_root
= !getuid();
1008 /* Set all sockets path */
1010 ret
= create_lttng_rundir();
1015 if (strlen(apps_unix_sock_path
) == 0) {
1016 snprintf(apps_unix_sock_path
, PATH_MAX
,
1017 DEFAULT_GLOBAL_APPS_UNIX_SOCK
);
1020 if (strlen(client_unix_sock_path
) == 0) {
1021 snprintf(client_unix_sock_path
, PATH_MAX
,
1022 DEFAULT_GLOBAL_CLIENT_UNIX_SOCK
);
1025 ret
= set_kconsumerd_sockets();
1030 if (strlen(apps_unix_sock_path
) == 0) {
1031 snprintf(apps_unix_sock_path
, PATH_MAX
,
1032 DEFAULT_HOME_APPS_UNIX_SOCK
, get_home_dir());
1035 /* Set the cli tool unix socket path */
1036 if (strlen(client_unix_sock_path
) == 0) {
1037 snprintf(client_unix_sock_path
, PATH_MAX
,
1038 DEFAULT_HOME_CLIENT_UNIX_SOCK
, get_home_dir());
1042 /* See if daemon already exist. If any of the two
1043 * socket needed by the daemon are present, this test fails
1045 if ((ret
= check_existing_daemon()) == 0) {
1046 ERR("Already running daemon.\n");
1047 /* We do not goto error because we must not
1048 * cleanup() because a daemon is already running.
1050 return EXIT_FAILURE
;
1053 if (set_signal_handler() < 0) {
1057 /* Setup the needed unix socket */
1058 if (init_daemon_socket() < 0) {
1062 /* Set credentials to socket */
1063 if (is_root
&& (set_permissions() < 0)) {
1067 /* Get parent pid if -S, --sig-parent is specified. */
1068 if (opt_sig_parent
) {
1073 /* Create thread to manage the client socket */
1074 ret
= pthread_create(&threads
[0], NULL
, thread_manage_clients
, (void *) NULL
);
1076 perror("pthread_create");
1080 /* Create thread to manage application socket */
1081 ret
= pthread_create(&threads
[1], NULL
, thread_manage_apps
, (void *) NULL
);
1083 perror("pthread_create");
1087 for (i
= 0; i
< 2; i
++) {
1088 ret
= pthread_join(threads
[i
], &status
);
1090 perror("pthread_join");
1102 return EXIT_FAILURE
;