Major changes on the lttng command line tool
[lttng-tools.git] / ltt-sessiond / main.c
... / ...
CommitLineData
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
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.
8 *
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.
13 *
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.
17 */
18
19#define _GNU_SOURCE
20#include <fcntl.h>
21#include <getopt.h>
22#include <grp.h>
23#include <limits.h>
24#include <pthread.h>
25#include <signal.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/ipc.h>
30#include <sys/shm.h>
31#include <sys/socket.h>
32#include <sys/stat.h>
33#include <sys/types.h>
34#include <unistd.h>
35
36#include <urcu/list.h> /* URCU list library (-lurcu) */
37#include <ust/ustctl.h> /* UST control lib (-lust) */
38#include <lttng/lttng.h>
39
40#include "liblttsessiondcomm.h"
41#include "ltt-sessiond.h"
42#include "lttngerr.h"
43#include "session.h"
44#include "trace.h"
45#include "traceable-app.h"
46
47/*
48 * TODO:
49 * teardown: signal SIGTERM handler -> write into pipe. Threads waits
50 * with epoll on pipe and on other pipes/sockets for commands. Main
51 * simply waits on pthread join.
52 */
53
54/* Const values */
55const char default_home_dir[] = DEFAULT_HOME_DIR;
56const char default_tracing_group[] = DEFAULT_TRACING_GROUP;
57const char default_ust_sock_dir[] = DEFAULT_UST_SOCK_DIR;
58const char default_global_apps_pipe[] = DEFAULT_GLOBAL_APPS_PIPE;
59
60/* Static functions */
61static int check_existing_daemon(void);
62static int ust_connect_app(pid_t pid);
63static int init_daemon_socket(void);
64static int notify_apps(const char* name);
65static int process_client_msg(struct command_ctx *cmd_ctx);
66static int send_unix_sock(int sock, void *buf, size_t len);
67static int set_signal_handler(void);
68static int set_permissions(void);
69static int setup_lttng_msg(struct command_ctx *cmd_ctx, size_t size);
70static int create_lttng_rundir(void);
71static int set_kconsumerd_sockets(void);
72static void cleanup(void);
73static void sighandler(int sig);
74static void clean_command_ctx(struct command_ctx *cmd_ctx);
75
76static void *thread_manage_clients(void *data);
77static void *thread_manage_apps(void *data);
78static void *thread_manage_kconsumerd(void *data);
79
80/* Variables */
81int opt_verbose;
82int opt_quiet;
83const char *progname;
84const char *opt_tracing_group;
85static int opt_sig_parent;
86static int opt_daemon;
87static int is_root; /* Set to 1 if the daemon is running as root */
88static pid_t ppid;
89
90static char apps_unix_sock_path[PATH_MAX]; /* Global application Unix socket path */
91static char client_unix_sock_path[PATH_MAX]; /* Global client Unix socket path */
92static char kconsumerd_err_unix_sock_path[PATH_MAX]; /* kconsumerd error Unix socket path */
93static char kconsumerd_cmd_unix_sock_path[PATH_MAX]; /* kconsumerd command Unix socket path */
94
95static int client_sock;
96static int apps_sock;
97static int kconsumerd_err_sock;
98
99/*
100 * thread_manage_kconsumerd
101 *
102 * This thread manage the kconsumerd error sent
103 * back to the session daemon.
104 */
105static void *thread_manage_kconsumerd(void *data)
106{
107 int sock, ret;
108
109 DBG("[thread] Manage kconsumerd started");
110
111 ret = lttcomm_listen_unix_sock(kconsumerd_err_sock);
112 if (ret < 0) {
113 goto error;
114 }
115
116 sock = lttcomm_accept_unix_sock(kconsumerd_err_sock);
117 if (sock < 0) {
118 goto error;
119 }
120
121 while (1) {
122 //ret = lttcomm_recv_unix_sock(sock, &lsm, sizeof(lsm));
123 if (ret <= 0) {
124 /* TODO: Consumerd died? */
125 continue;
126 }
127 }
128
129error:
130 return NULL;
131}
132
133/*
134 * thread_manage_apps
135 *
136 * This thread manage the application socket communication
137 */
138static void *thread_manage_apps(void *data)
139{
140 int sock, ret;
141
142 /* TODO: Something more elegant is needed but fine for now */
143 /* FIXME: change all types to either uint8_t, uint32_t, uint64_t
144 * for 32-bit vs 64-bit compat processes. */
145 /* replicate in ust with version number */
146 struct {
147 int reg; /* 1:register, 0:unregister */
148 pid_t pid;
149 uid_t uid;
150 } reg_msg;
151
152 DBG("[thread] Manage apps started");
153
154 ret = lttcomm_listen_unix_sock(apps_sock);
155 if (ret < 0) {
156 goto error;
157 }
158
159 /* Notify all applications to register */
160 notify_apps(default_global_apps_pipe);
161
162 while (1) {
163 DBG("Accepting application registration");
164 /* Blocking call, waiting for transmission */
165 sock = lttcomm_accept_unix_sock(apps_sock);
166 if (sock < 0) {
167 goto error;
168 }
169
170 /* Basic recv here to handle the very simple data
171 * that the libust send to register (reg_msg).
172 */
173 ret = recv(sock, &reg_msg, sizeof(reg_msg), 0);
174 if (ret < 0) {
175 perror("recv");
176 continue;
177 }
178
179 /* Add application to the global traceable list */
180 if (reg_msg.reg == 1) {
181 /* Registering */
182 ret = register_traceable_app(reg_msg.pid, reg_msg.uid);
183 if (ret < 0) {
184 /* register_traceable_app only return an error with
185 * ENOMEM. At this point, we better stop everything.
186 */
187 goto error;
188 }
189 } else {
190 /* Unregistering */
191 unregister_traceable_app(reg_msg.pid);
192 }
193 }
194
195error:
196
197 return NULL;
198}
199
200/*
201 * thread_manage_clients
202 *
203 * This thread manage all clients request using the unix
204 * client socket for communication.
205 */
206static void *thread_manage_clients(void *data)
207{
208 int sock, ret;
209 struct command_ctx *cmd_ctx;
210
211 DBG("[thread] Manage client started");
212
213 ret = lttcomm_listen_unix_sock(client_sock);
214 if (ret < 0) {
215 goto error;
216 }
217
218 /* Notify parent pid that we are ready
219 * to accept command for client side.
220 */
221 if (opt_sig_parent) {
222 kill(ppid, SIGCHLD);
223 }
224
225 while (1) {
226 /* Blocking call, waiting for transmission */
227 DBG("Accepting client command ...");
228 sock = lttcomm_accept_unix_sock(client_sock);
229 if (sock < 0) {
230 goto error;
231 }
232
233 /* Allocate context command to process the client request */
234 cmd_ctx = malloc(sizeof(struct command_ctx));
235
236 /* Allocate data buffer for reception */
237 cmd_ctx->lsm = malloc(sizeof(struct lttcomm_session_msg));
238 cmd_ctx->llm = NULL;
239 cmd_ctx->session = NULL;
240
241 /*
242 * Data is received from the lttng client. The struct
243 * lttcomm_session_msg (lsm) contains the command and data request of
244 * the client.
245 */
246 DBG("Receiving data from client ...");
247 ret = lttcomm_recv_unix_sock(sock, cmd_ctx->lsm, sizeof(struct lttcomm_session_msg));
248 if (ret <= 0) {
249 continue;
250 }
251
252 /*
253 * This function dispatch the work to the kernel or userspace tracer
254 * libs and fill the lttcomm_lttng_msg data structure of all the needed
255 * informations for the client. The command context struct contains
256 * everything this function may needs.
257 */
258 ret = process_client_msg(cmd_ctx);
259 if (ret < 0) {
260 /* TODO: Inform client somehow of the fatal error. At this point,
261 * ret < 0 means that a malloc failed (ENOMEM). */
262 /* Error detected but still accept command */
263 clean_command_ctx(cmd_ctx);
264 continue;
265 }
266
267 DBG("Sending response (size: %d, retcode: %d)",
268 cmd_ctx->lttng_msg_size, cmd_ctx->llm->ret_code);
269 ret = send_unix_sock(sock, cmd_ctx->llm, cmd_ctx->lttng_msg_size);
270 if (ret < 0) {
271 ERR("Failed to send data back to client");
272 }
273
274 clean_command_ctx(cmd_ctx);
275 }
276
277error:
278 return NULL;
279}
280
281/*
282 * send_unix_sock
283 *
284 * Send data on a unix socket using the liblttsessiondcomm API.
285 *
286 * Return lttcomm error code.
287 */
288static int send_unix_sock(int sock, void *buf, size_t len)
289{
290 /* Check valid length */
291 if (len <= 0) {
292 return -1;
293 }
294
295 return lttcomm_send_unix_sock(sock, buf, len);
296}
297
298/*
299 * clean_command_ctx
300 *
301 * Free memory of a command context structure.
302 */
303static void clean_command_ctx(struct command_ctx *cmd_ctx)
304{
305 DBG("Clean command context structure %p", cmd_ctx);
306 if (cmd_ctx) {
307 if (cmd_ctx->llm) {
308 free(cmd_ctx->llm);
309 }
310 if (cmd_ctx->lsm) {
311 free(cmd_ctx->lsm);
312 }
313 free(cmd_ctx);
314 cmd_ctx = NULL;
315 }
316}
317
318/*
319 * ust_connect_app
320 *
321 * Return a socket connected to the libust communication socket
322 * of the application identified by the pid.
323 *
324 * If the pid is not found in the traceable list,
325 * return -1 to indicate error.
326 */
327static int ust_connect_app(pid_t pid)
328{
329 int sock;
330 struct ltt_traceable_app *lta;
331
332 DBG("Connect to application pid %d", pid);
333
334 lta = find_app_by_pid(pid);
335 if (lta == NULL) {
336 /* App not found */
337 DBG("Application pid %d not found", pid);
338 return -1;
339 }
340
341 sock = ustctl_connect_pid(lta->pid);
342 if (sock < 0) {
343 ERR("Fail connecting to the PID %d\n", pid);
344 }
345
346 return sock;
347}
348
349/*
350 * notify_apps
351 *
352 * Notify apps by writing 42 to a named pipe using name.
353 * Every applications waiting for a ltt-sessiond will be notified
354 * and re-register automatically to the session daemon.
355 *
356 * Return open or write error value.
357 */
358static int notify_apps(const char *name)
359{
360 int fd;
361 int ret = -1;
362
363 DBG("Notify the global application pipe");
364
365 /* Try opening the global pipe */
366 fd = open(name, O_WRONLY);
367 if (fd < 0) {
368 goto error;
369 }
370
371 /* Notify by writing on the pipe */
372 ret = write(fd, "42", 2);
373 if (ret < 0) {
374 perror("write");
375 }
376
377error:
378 return ret;
379}
380
381/*
382 * setup_lttng_msg
383 *
384 * Setup the outgoing data buffer for the response (llm) by allocating the
385 * right amount of memory and copying the original information from the lsm
386 * structure.
387 *
388 * Return total size of the buffer pointed by buf.
389 */
390static int setup_lttng_msg(struct command_ctx *cmd_ctx, size_t size)
391{
392 int ret, buf_size, trace_name_size;
393
394 /*
395 * Check for the trace_name. If defined, it's part of the payload data of
396 * the llm structure.
397 */
398 trace_name_size = strlen(cmd_ctx->lsm->trace_name);
399 buf_size = trace_name_size + size;
400
401 cmd_ctx->llm = malloc(sizeof(struct lttcomm_lttng_msg) + buf_size);
402 if (cmd_ctx->llm == NULL) {
403 perror("malloc");
404 ret = -ENOMEM;
405 goto error;
406 }
407
408 /* Copy common data */
409 cmd_ctx->llm->cmd_type = cmd_ctx->lsm->cmd_type;
410 cmd_ctx->llm->pid = cmd_ctx->lsm->pid;
411 if (!uuid_is_null(cmd_ctx->lsm->session_uuid)) {
412 uuid_copy(cmd_ctx->llm->session_uuid, cmd_ctx->lsm->session_uuid);
413 }
414
415 cmd_ctx->llm->trace_name_offset = trace_name_size;
416 cmd_ctx->llm->data_size = size;
417 cmd_ctx->lttng_msg_size = sizeof(struct lttcomm_lttng_msg) + buf_size;
418
419 /* Copy trace name to the llm structure. Begining of the payload. */
420 memcpy(cmd_ctx->llm->payload, cmd_ctx->lsm->trace_name, trace_name_size);
421
422 return buf_size;
423
424error:
425 return ret;
426}
427
428/*
429 * process_client_msg
430 *
431 * Process the command requested by the lttng client within the command
432 * context structure. This function make sure that the return structure (llm)
433 * is set and ready for transmission before returning.
434 *
435 * Return any error encountered or 0 for success.
436 */
437static int process_client_msg(struct command_ctx *cmd_ctx)
438{
439 int ret;
440
441 DBG("Processing client command %d", cmd_ctx->lsm->cmd_type);
442
443 /* Check command that needs a session */
444 switch (cmd_ctx->lsm->cmd_type) {
445 case LTTNG_CREATE_SESSION:
446 case LTTNG_LIST_SESSIONS:
447 case UST_LIST_APPS:
448 break;
449 default:
450 cmd_ctx->session = find_session_by_uuid(cmd_ctx->lsm->session_uuid);
451 if (cmd_ctx->session == NULL) {
452 ret = LTTCOMM_SELECT_SESS;
453 goto error;
454 }
455 break;
456 }
457
458 /* Connect to ust apps if available pid */
459 if (cmd_ctx->lsm->pid > 0) {
460 /* Connect to app using ustctl API */
461 cmd_ctx->ust_sock = ust_connect_app(cmd_ctx->lsm->pid);
462 if (cmd_ctx->ust_sock < 0) {
463 ret = LTTCOMM_NO_TRACEABLE;
464 goto error;
465 }
466 }
467
468 /* Process by command type */
469 switch (cmd_ctx->lsm->cmd_type) {
470 case KERNEL_ENABLE_EVENT:
471 {
472 /* Setup lttng message with no payload */
473 ret = setup_lttng_msg(cmd_ctx, 0);
474 if (ret < 0) {
475 goto setup_error;
476 }
477
478 DBG("Enabling kernel event %s", cmd_ctx->lsm->u.event.event_name);
479
480 ret = LTTCOMM_OK;
481 break;
482 }
483 case LTTNG_CREATE_SESSION:
484 {
485 /* Setup lttng message with no payload */
486 ret = setup_lttng_msg(cmd_ctx, 0);
487 if (ret < 0) {
488 goto setup_error;
489 }
490
491 ret = create_session(cmd_ctx->lsm->session_name, &cmd_ctx->llm->session_uuid);
492 if (ret < 0) {
493 if (ret == -1) {
494 ret = LTTCOMM_EXIST_SESS;
495 } else {
496 ret = LTTCOMM_FATAL;
497 }
498 goto error;
499 }
500
501 ret = LTTCOMM_OK;
502 break;
503 }
504 case LTTNG_DESTROY_SESSION:
505 {
506 /* Setup lttng message with no payload */
507 ret = setup_lttng_msg(cmd_ctx, 0);
508 if (ret < 0) {
509 goto setup_error;
510 }
511
512 ret = destroy_session(&cmd_ctx->lsm->session_uuid);
513 if (ret < 0) {
514 ret = LTTCOMM_NO_SESS;
515 goto error;
516 }
517
518 ret = LTTCOMM_OK;
519 break;
520 }
521 case LTTNG_LIST_TRACES:
522 {
523 unsigned int trace_count;
524
525 trace_count = get_trace_count_per_session(cmd_ctx->session);
526 if (trace_count == 0) {
527 ret = LTTCOMM_NO_TRACE;
528 goto error;
529 }
530
531 ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_trace) * trace_count);
532 if (ret < 0) {
533 goto setup_error;
534 }
535
536 get_traces_per_session(cmd_ctx->session,
537 (struct lttng_trace *)(cmd_ctx->llm->payload));
538
539 ret = LTTCOMM_OK;
540 break;
541 }
542 case UST_CREATE_TRACE:
543 {
544 /* Setup lttng message with no payload */
545 ret = setup_lttng_msg(cmd_ctx, 0);
546 if (ret < 0) {
547 goto setup_error;
548 }
549
550 ret = ust_create_trace(cmd_ctx);
551 if (ret < 0) {
552 goto setup_error;
553 }
554 break;
555 }
556 case UST_LIST_APPS:
557 {
558 unsigned int app_count;
559
560 app_count = get_app_count();
561 DBG("Traceable application count : %d", app_count);
562 if (app_count == 0) {
563 ret = LTTCOMM_NO_APPS;
564 goto error;
565 }
566
567 ret = setup_lttng_msg(cmd_ctx, sizeof(pid_t) * app_count);
568 if (ret < 0) {
569 goto setup_error;
570 }
571
572 get_app_list_pids((pid_t *)(cmd_ctx->llm->payload));
573
574 ret = LTTCOMM_OK;
575 break;
576 }
577 case UST_START_TRACE:
578 {
579 /* Setup lttng message with no payload */
580 ret = setup_lttng_msg(cmd_ctx, 0);
581 if (ret < 0) {
582 goto setup_error;
583 }
584
585 ret = ust_start_trace(cmd_ctx);
586 if (ret < 0) {
587 goto setup_error;
588 }
589 break;
590 }
591 case UST_STOP_TRACE:
592 {
593 /* Setup lttng message with no payload */
594 ret = setup_lttng_msg(cmd_ctx, 0);
595 if (ret < 0) {
596 goto setup_error;
597 }
598
599 ret = ust_stop_trace(cmd_ctx);
600 if (ret < 0) {
601 goto setup_error;
602 }
603 break;
604 }
605 case LTTNG_LIST_SESSIONS:
606 {
607 unsigned int session_count;
608
609 session_count = get_session_count();
610 if (session_count == 0) {
611 ret = LTTCOMM_NO_SESS;
612 goto error;
613 }
614
615 ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) * session_count);
616 if (ret < 0) {
617 goto setup_error;
618 }
619
620 get_lttng_session((struct lttng_session *)(cmd_ctx->llm->payload));
621
622 ret = LTTCOMM_OK;
623 break;
624 }
625 default:
626 /* Undefined command */
627 ret = setup_lttng_msg(cmd_ctx, 0);
628 if (ret < 0) {
629 goto setup_error;
630 }
631
632 ret = LTTCOMM_UND;
633 break;
634 }
635
636 /* Set return code */
637 cmd_ctx->llm->ret_code = ret;
638
639 return ret;
640
641error:
642 if (cmd_ctx->llm == NULL) {
643 DBG("Missing llm structure. Allocating one.");
644 if (setup_lttng_msg(cmd_ctx, 0) < 0) {
645 goto setup_error;
646 }
647 }
648 /* Notify client of error */
649 cmd_ctx->llm->ret_code = ret;
650
651setup_error:
652 return ret;
653}
654
655/*
656 * usage function on stderr
657 */
658static void usage(void)
659{
660 fprintf(stderr, "Usage: %s OPTIONS\n\nOptions:\n", progname);
661 fprintf(stderr, " -h, --help Display this usage.\n");
662 fprintf(stderr, " -c, --client-sock PATH Specify path for the client unix socket\n");
663 fprintf(stderr, " -a, --apps-sock PATH Specify path for apps unix socket\n");
664 fprintf(stderr, " --kconsumerd-err-sock PATH Specify path for the kernel consumer error socket\n");
665 fprintf(stderr, " --kconsumerd-cmd-sock PATH Specify path for the kernel consumer command socket\n");
666 fprintf(stderr, " -d, --daemonize Start as a daemon.\n");
667 fprintf(stderr, " -g, --group NAME Specify the tracing group name. (default: tracing)\n");
668 fprintf(stderr, " -V, --version Show version number.\n");
669 fprintf(stderr, " -S, --sig-parent Send SIGCHLD to parent pid to notify readiness.\n");
670 fprintf(stderr, " -q, --quiet No output at all.\n");
671 fprintf(stderr, " -v, --verbose Verbose mode. Activate DBG() macro.\n");
672}
673
674/*
675 * daemon argument parsing
676 */
677static int parse_args(int argc, char **argv)
678{
679 int c;
680
681 static struct option long_options[] = {
682 { "client-sock", 1, 0, 'c' },
683 { "apps-sock", 1, 0, 'a' },
684 { "kconsumerd-cmd-sock", 1, 0, 0 },
685 { "kconsumerd-err-sock", 1, 0, 0 },
686 { "daemonize", 0, 0, 'd' },
687 { "sig-parent", 0, 0, 'S' },
688 { "help", 0, 0, 'h' },
689 { "group", 1, 0, 'g' },
690 { "version", 0, 0, 'V' },
691 { "quiet", 0, 0, 'q' },
692 { "verbose", 0, 0, 'v' },
693 { NULL, 0, 0, 0 }
694 };
695
696 while (1) {
697 int option_index = 0;
698 c = getopt_long(argc, argv, "dhqvVS" "a:c:g:s:E:C:", long_options, &option_index);
699 if (c == -1) {
700 break;
701 }
702
703 switch (c) {
704 case 0:
705 fprintf(stderr, "option %s", long_options[option_index].name);
706 if (optarg) {
707 fprintf(stderr, " with arg %s\n", optarg);
708 }
709 break;
710 case 'c':
711 snprintf(client_unix_sock_path, PATH_MAX, "%s", optarg);
712 break;
713 case 'a':
714 snprintf(apps_unix_sock_path, PATH_MAX, "%s", optarg);
715 break;
716 case 'd':
717 opt_daemon = 1;
718 break;
719 case 'g':
720 opt_tracing_group = strdup(optarg);
721 break;
722 case 'h':
723 usage();
724 exit(EXIT_FAILURE);
725 case 'V':
726 fprintf(stdout, "%s\n", VERSION);
727 exit(EXIT_SUCCESS);
728 case 'S':
729 opt_sig_parent = 1;
730 break;
731 case 'E':
732 snprintf(kconsumerd_err_unix_sock_path, PATH_MAX, "%s", optarg);
733 break;
734 case 'C':
735 snprintf(kconsumerd_cmd_unix_sock_path, PATH_MAX, "%s", optarg);
736 break;
737 case 'q':
738 opt_quiet = 1;
739 break;
740 case 'v':
741 opt_verbose = 1;
742 break;
743 default:
744 /* Unknown option or other error.
745 * Error is printed by getopt, just return */
746 return -1;
747 }
748 }
749
750 return 0;
751}
752
753/*
754 * init_daemon_socket
755 *
756 * Creates the two needed socket by the daemon.
757 * apps_sock - The communication socket for all UST apps.
758 * client_sock - The communication of the cli tool (lttng).
759 */
760static int init_daemon_socket()
761{
762 int ret = 0;
763 mode_t old_umask;
764
765 old_umask = umask(0);
766
767 /* Create client tool unix socket */
768 client_sock = lttcomm_create_unix_sock(client_unix_sock_path);
769 if (client_sock < 0) {
770 ERR("Create unix sock failed: %s", client_unix_sock_path);
771 ret = -1;
772 goto end;
773 }
774
775 /* File permission MUST be 660 */
776 ret = chmod(client_unix_sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
777 if (ret < 0) {
778 ERR("Set file permissions failed: %s", client_unix_sock_path);
779 perror("chmod");
780 goto end;
781 }
782
783 /* Create the application unix socket */
784 apps_sock = lttcomm_create_unix_sock(apps_unix_sock_path);
785 if (apps_sock < 0) {
786 ERR("Create unix sock failed: %s", apps_unix_sock_path);
787 ret = -1;
788 goto end;
789 }
790
791 /* File permission MUST be 666 */
792 ret = chmod(apps_unix_sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
793 if (ret < 0) {
794 ERR("Set file permissions failed: %s", apps_unix_sock_path);
795 perror("chmod");
796 goto end;
797 }
798
799end:
800 umask(old_umask);
801 return ret;
802}
803
804/*
805 * check_existing_daemon
806 *
807 * Check if the global socket is available.
808 * If yes, error is returned.
809 */
810static int check_existing_daemon()
811{
812 int ret;
813
814 ret = access(client_unix_sock_path, F_OK);
815 if (ret == 0) {
816 ret = access(apps_unix_sock_path, F_OK);
817 }
818
819 return ret;
820}
821
822/*
823 * get_home_dir
824 *
825 * Return pointer to home directory path using
826 * the env variable HOME.
827 *
828 * Default : /tmp
829 */
830static const char *get_home_dir(void)
831{
832 const char *home_path;
833
834 if ((home_path = (const char *) getenv("HOME")) == NULL) {
835 home_path = default_home_dir;
836 }
837
838 return home_path;
839}
840
841/*
842 * set_permissions
843 *
844 * Set the tracing group gid onto the client socket.
845 *
846 * Race window between mkdir and chown is OK because we are going from
847 * less permissive (root.root) to more permissive (root.tracing).
848 */
849static int set_permissions(void)
850{
851 int ret;
852 struct group *grp;
853
854 /* Decide which group name to use */
855 (opt_tracing_group != NULL) ?
856 (grp = getgrnam(opt_tracing_group)) :
857 (grp = getgrnam(default_tracing_group));
858
859 if (grp == NULL) {
860 ERR("Missing tracing group. Aborting execution.\n");
861 ret = -1;
862 goto end;
863 }
864
865 /* Set lttng run dir */
866 ret = chown(LTTNG_RUNDIR, 0, grp->gr_gid);
867 if (ret < 0) {
868 ERR("Unable to set group on " LTTNG_RUNDIR);
869 perror("chown");
870 }
871
872 /* lttng client socket path */
873 ret = chown(client_unix_sock_path, 0, grp->gr_gid);
874 if (ret < 0) {
875 ERR("Unable to set group on %s", client_unix_sock_path);
876 perror("chown");
877 }
878
879 /* kconsumerd error socket path */
880 ret = chown(kconsumerd_err_unix_sock_path, 0, grp->gr_gid);
881 if (ret < 0) {
882 ERR("Unable to set group on %s", kconsumerd_err_unix_sock_path);
883 perror("chown");
884 }
885
886 DBG("All permissions are set");
887
888end:
889 return ret;
890}
891
892/*
893 * create_lttng_rundir
894 *
895 * Create the lttng run directory needed for all
896 * global sockets and pipe.
897 */
898static int create_lttng_rundir(void)
899{
900 int ret;
901
902 ret = mkdir(LTTNG_RUNDIR, S_IRWXU | S_IRWXG );
903 if (ret < 0) {
904 ERR("Unable to create " LTTNG_RUNDIR);
905 goto error;
906 }
907
908error:
909 return ret;
910}
911
912/*
913 * set_kconsumerd_sockets
914 *
915 * Setup sockets and directory needed by the kconsumerd
916 * communication with the session daemon.
917 */
918static int set_kconsumerd_sockets(void)
919{
920 int ret;
921
922 if (strlen(kconsumerd_err_unix_sock_path) == 0) {
923 snprintf(kconsumerd_err_unix_sock_path, PATH_MAX, KCONSUMERD_ERR_SOCK_PATH);
924 }
925
926 if (strlen(kconsumerd_cmd_unix_sock_path) == 0) {
927 snprintf(kconsumerd_cmd_unix_sock_path, PATH_MAX, KCONSUMERD_CMD_SOCK_PATH);
928 }
929
930 ret = mkdir(KCONSUMERD_PATH, S_IRWXU | S_IRWXG);
931 if (ret < 0) {
932 ERR("Failed to create " KCONSUMERD_PATH);
933 goto error;
934 }
935
936 /* Create the kconsumerd error unix socket */
937 kconsumerd_err_sock = lttcomm_create_unix_sock(kconsumerd_err_unix_sock_path);
938 if (kconsumerd_err_sock < 0) {
939 ERR("Create unix sock failed: %s", kconsumerd_err_unix_sock_path);
940 ret = -1;
941 goto error;
942 }
943
944 /* File permission MUST be 660 */
945 ret = chmod(kconsumerd_err_unix_sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
946 if (ret < 0) {
947 ERR("Set file permissions failed: %s", kconsumerd_err_unix_sock_path);
948 perror("chmod");
949 goto error;
950 }
951
952error:
953 return ret;
954}
955
956/*
957 * set_signal_handler
958 *
959 * Setup signal handler for :
960 * SIGINT, SIGTERM, SIGPIPE
961 */
962static int set_signal_handler(void)
963{
964 int ret = 0;
965 struct sigaction sa;
966 sigset_t sigset;
967
968 if ((ret = sigemptyset(&sigset)) < 0) {
969 perror("sigemptyset");
970 return ret;
971 }
972
973 sa.sa_handler = sighandler;
974 sa.sa_mask = sigset;
975 sa.sa_flags = 0;
976 if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) {
977 perror("sigaction");
978 return ret;
979 }
980
981 if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) {
982 perror("sigaction");
983 return ret;
984 }
985
986 if ((ret = sigaction(SIGPIPE, &sa, NULL)) < 0) {
987 perror("sigaction");
988 return ret;
989 }
990
991 DBG("Signal handler set for SIGTERM, SIGPIPE and SIGINT");
992
993 return ret;
994}
995
996/**
997 * sighandler
998 *
999 * Signal handler for the daemon
1000 */
1001static void sighandler(int sig)
1002{
1003 switch (sig) {
1004 case SIGPIPE:
1005 DBG("SIGPIPE catched");
1006 return;
1007 case SIGINT:
1008 DBG("SIGINT catched");
1009 cleanup();
1010 break;
1011 case SIGTERM:
1012 DBG("SIGTERM catched");
1013 cleanup();
1014 break;
1015 default:
1016 break;
1017 }
1018
1019 exit(EXIT_SUCCESS);
1020}
1021
1022/*
1023 * cleanup
1024 *
1025 * Cleanup the daemon on exit
1026 */
1027static void cleanup()
1028{
1029 int ret;
1030 char *cmd;
1031
1032 DBG("Cleaning up");
1033
1034 /* <fun> */
1035 MSG("\n%c[%d;%dm*** assert failed *** ==> %c[%dm", 27,1,31,27,0);
1036 MSG("%c[%d;%dmMatthew, BEET driven development works!%c[%dm",27,1,33,27,0);
1037 /* </fun> */
1038
1039 unlink(client_unix_sock_path);
1040 unlink(apps_unix_sock_path);
1041 unlink(kconsumerd_err_unix_sock_path);
1042
1043 ret = asprintf(&cmd, "rm -rf " LTTNG_RUNDIR);
1044 if (ret < 0) {
1045 ERR("asprintf failed. Something is really wrong!");
1046 }
1047
1048 /* Remove lttng run directory */
1049 ret = system(cmd);
1050 if (ret < 0) {
1051 ERR("Unable to clean " LTTNG_RUNDIR);
1052 }
1053}
1054
1055/*
1056 * main
1057 */
1058int main(int argc, char **argv)
1059{
1060 int i;
1061 int ret = 0;
1062 void *status;
1063 pthread_t threads[2];
1064
1065 /* Parse arguments */
1066 progname = argv[0];
1067 if ((ret = parse_args(argc, argv) < 0)) {
1068 goto error;
1069 }
1070
1071 /* Daemonize */
1072 if (opt_daemon) {
1073 ret = daemon(0, 0);
1074 if (ret < 0) {
1075 perror("daemon");
1076 goto error;
1077 }
1078 }
1079
1080 /* Check if daemon is UID = 0 */
1081 is_root = !getuid();
1082
1083 /* Set all sockets path */
1084 if (is_root) {
1085 ret = create_lttng_rundir();
1086 if (ret < 0) {
1087 goto error;
1088 }
1089
1090 if (strlen(apps_unix_sock_path) == 0) {
1091 snprintf(apps_unix_sock_path, PATH_MAX,
1092 DEFAULT_GLOBAL_APPS_UNIX_SOCK);
1093 }
1094
1095 if (strlen(client_unix_sock_path) == 0) {
1096 snprintf(client_unix_sock_path, PATH_MAX,
1097 DEFAULT_GLOBAL_CLIENT_UNIX_SOCK);
1098 }
1099
1100 ret = set_kconsumerd_sockets();
1101 if (ret < 0) {
1102 goto error;
1103 }
1104 } else {
1105 if (strlen(apps_unix_sock_path) == 0) {
1106 snprintf(apps_unix_sock_path, PATH_MAX,
1107 DEFAULT_HOME_APPS_UNIX_SOCK, get_home_dir());
1108 }
1109
1110 /* Set the cli tool unix socket path */
1111 if (strlen(client_unix_sock_path) == 0) {
1112 snprintf(client_unix_sock_path, PATH_MAX,
1113 DEFAULT_HOME_CLIENT_UNIX_SOCK, get_home_dir());
1114 }
1115 }
1116
1117 DBG("Client socket path %s", client_unix_sock_path);
1118 DBG("Application socket path %s", apps_unix_sock_path);
1119
1120 /* See if daemon already exist. If any of the two
1121 * socket needed by the daemon are present, this test fails
1122 */
1123 if ((ret = check_existing_daemon()) == 0) {
1124 ERR("Already running daemon.\n");
1125 /* We do not goto error because we must not
1126 * cleanup() because a daemon is already running.
1127 */
1128 exit(EXIT_FAILURE);
1129 }
1130
1131 if (set_signal_handler() < 0) {
1132 goto error;
1133 }
1134
1135 /* Setup the needed unix socket */
1136 if (init_daemon_socket() < 0) {
1137 goto error;
1138 }
1139
1140 /* Set credentials to socket */
1141 if (is_root && (set_permissions() < 0)) {
1142 goto error;
1143 }
1144
1145 /* Get parent pid if -S, --sig-parent is specified. */
1146 if (opt_sig_parent) {
1147 ppid = getppid();
1148 }
1149
1150 while (1) {
1151 /* Create thread to manage the client socket */
1152 ret = pthread_create(&threads[0], NULL, thread_manage_clients, (void *) NULL);
1153 if (ret != 0) {
1154 perror("pthread_create");
1155 goto error;
1156 }
1157
1158 /* Create thread to manage application socket */
1159 ret = pthread_create(&threads[1], NULL, thread_manage_apps, (void *) NULL);
1160 if (ret != 0) {
1161 perror("pthread_create");
1162 goto error;
1163 }
1164
1165 for (i = 0; i < 2; i++) {
1166 ret = pthread_join(threads[i], &status);
1167 if (ret != 0) {
1168 perror("pthread_join");
1169 goto error;
1170 }
1171 }
1172 }
1173
1174 cleanup();
1175 exit(EXIT_SUCCESS);
1176
1177error:
1178 cleanup();
1179 exit(EXIT_FAILURE);
1180}
This page took 0.026581 seconds and 4 git commands to generate.