Major changes on the lttng command line tool
[lttng-tools.git] / ltt-sessiond / main.c
CommitLineData
826d496d
MD
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
fac6795d
DG
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.
91d76f53 8 *
fac6795d
DG
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.
91d76f53 13 *
fac6795d
DG
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.
fac6795d
DG
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) */
5b97ec60 38#include <lttng/lttng.h>
fac6795d
DG
39
40#include "liblttsessiondcomm.h"
41#include "ltt-sessiond.h"
75462a81 42#include "lttngerr.h"
5b74c7b1 43#include "session.h"
fda89c9b 44#include "trace.h"
91d76f53 45#include "traceable-app.h"
fac6795d 46
5e16da05
MD
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
75462a81 54/* Const values */
686204ab
MD
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
fac6795d 60/* Static functions */
fac6795d 61static int check_existing_daemon(void);
471d1693 62static int ust_connect_app(pid_t pid);
fac6795d 63static int init_daemon_socket(void);
62bd06d8 64static int notify_apps(const char* name);
5461b305 65static int process_client_msg(struct command_ctx *cmd_ctx);
e065084a 66static int send_unix_sock(int sock, void *buf, size_t len);
62bd06d8 67static int set_signal_handler(void);
d6f42150 68static int set_permissions(void);
5461b305 69static int setup_lttng_msg(struct command_ctx *cmd_ctx, size_t size);
d6f42150
DG
70static int create_lttng_rundir(void);
71static int set_kconsumerd_sockets(void);
62bd06d8 72static void cleanup(void);
62bd06d8 73static void sighandler(int sig);
5461b305 74static void clean_command_ctx(struct command_ctx *cmd_ctx);
fac6795d 75
1fd70b72
DG
76static void *thread_manage_clients(void *data);
77static void *thread_manage_apps(void *data);
d6f42150 78static void *thread_manage_kconsumerd(void *data);
fac6795d 79
fac6795d 80/* Variables */
62bd06d8
DG
81int opt_verbose;
82int opt_quiet;
fac6795d
DG
83const char *progname;
84const char *opt_tracing_group;
5b8719f5 85static int opt_sig_parent;
fac6795d
DG
86static int opt_daemon;
87static int is_root; /* Set to 1 if the daemon is running as root */
5b8719f5 88static pid_t ppid;
fac6795d 89
d6f42150
DG
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 */
fac6795d 94
d6f42150
DG
95static int client_sock;
96static int apps_sock;
97static int kconsumerd_err_sock;
fac6795d 98
d6f42150
DG
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
fac6795d
DG
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;
fac6795d
DG
141
142 /* TODO: Something more elegant is needed but fine for now */
5e16da05
MD
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 */
686204ab 146 struct {
fac6795d 147 int reg; /* 1:register, 0:unregister */
686204ab
MD
148 pid_t pid;
149 uid_t uid;
150 } reg_msg;
fac6795d 151
e07ae692
DG
152 DBG("[thread] Manage apps started");
153
d6f42150 154 ret = lttcomm_listen_unix_sock(apps_sock);
fac6795d
DG
155 if (ret < 0) {
156 goto error;
157 }
158
5e16da05
MD
159 /* Notify all applications to register */
160 notify_apps(default_global_apps_pipe);
161
fac6795d 162 while (1) {
894be886 163 DBG("Accepting application registration");
fac6795d 164 /* Blocking call, waiting for transmission */
d6f42150 165 sock = lttcomm_accept_unix_sock(apps_sock);
fac6795d
DG
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 */
91d76f53
DG
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 }
fac6795d
DG
189 } else {
190 /* Unregistering */
91d76f53 191 unregister_traceable_app(reg_msg.pid);
fac6795d
DG
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;
5461b305 209 struct command_ctx *cmd_ctx;
fac6795d 210
e07ae692
DG
211 DBG("[thread] Manage client started");
212
d6f42150 213 ret = lttcomm_listen_unix_sock(client_sock);
fac6795d
DG
214 if (ret < 0) {
215 goto error;
216 }
217
5b8719f5
DG
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
fac6795d
DG
225 while (1) {
226 /* Blocking call, waiting for transmission */
5461b305 227 DBG("Accepting client command ...");
d6f42150 228 sock = lttcomm_accept_unix_sock(client_sock);
fac6795d
DG
229 if (sock < 0) {
230 goto error;
231 }
232
5461b305
DG
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
fac6795d
DG
241 /*
242 * Data is received from the lttng client. The struct
5461b305
DG
243 * lttcomm_session_msg (lsm) contains the command and data request of
244 * the client.
fac6795d 245 */
5461b305
DG
246 DBG("Receiving data from client ...");
247 ret = lttcomm_recv_unix_sock(sock, cmd_ctx->lsm, sizeof(struct lttcomm_session_msg));
87378cf5 248 if (ret <= 0) {
fac6795d
DG
249 continue;
250 }
251
5461b305
DG
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.
fac6795d 257 */
5461b305 258 ret = process_client_msg(cmd_ctx);
e065084a 259 if (ret < 0) {
5461b305
DG
260 /* TODO: Inform client somehow of the fatal error. At this point,
261 * ret < 0 means that a malloc failed (ENOMEM). */
e065084a 262 /* Error detected but still accept command */
5461b305 263 clean_command_ctx(cmd_ctx);
e065084a 264 continue;
fac6795d 265 }
5461b305 266
894be886
DG
267 DBG("Sending response (size: %d, retcode: %d)",
268 cmd_ctx->lttng_msg_size, cmd_ctx->llm->ret_code);
5461b305
DG
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);
fac6795d
DG
275 }
276
277error:
278 return NULL;
279}
280
e065084a
DG
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
5461b305
DG
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
fac6795d 318/*
471d1693 319 * ust_connect_app
fac6795d
DG
320 *
321 * Return a socket connected to the libust communication socket
322 * of the application identified by the pid.
379473d2
DG
323 *
324 * If the pid is not found in the traceable list,
325 * return -1 to indicate error.
fac6795d 326 */
471d1693 327static int ust_connect_app(pid_t pid)
fac6795d 328{
91d76f53
DG
329 int sock;
330 struct ltt_traceable_app *lta;
379473d2 331
e07ae692
DG
332 DBG("Connect to application pid %d", pid);
333
91d76f53
DG
334 lta = find_app_by_pid(pid);
335 if (lta == NULL) {
336 /* App not found */
7442b2ba 337 DBG("Application pid %d not found", pid);
379473d2
DG
338 return -1;
339 }
fac6795d 340
91d76f53 341 sock = ustctl_connect_pid(lta->pid);
fac6795d 342 if (sock < 0) {
75462a81 343 ERR("Fail connecting to the PID %d\n", pid);
fac6795d
DG
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
e07ae692
DG
363 DBG("Notify the global application pipe");
364
fac6795d
DG
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
e065084a 381/*
5461b305 382 * setup_lttng_msg
ca95a216 383 *
5461b305
DG
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.
ca95a216
DG
387 *
388 * Return total size of the buffer pointed by buf.
389 */
5461b305 390static int setup_lttng_msg(struct command_ctx *cmd_ctx, size_t size)
ca95a216 391{
5461b305 392 int ret, buf_size, trace_name_size;
ca95a216 393
5461b305
DG
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) {
ca95a216 403 perror("malloc");
5461b305 404 ret = -ENOMEM;
ca95a216
DG
405 goto error;
406 }
407
5461b305
DG
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);
ca95a216
DG
421
422 return buf_size;
423
424error:
425 return ret;
426}
427
fac6795d
DG
428/*
429 * process_client_msg
430 *
5461b305
DG
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.
fac6795d 434 *
e065084a 435 * Return any error encountered or 0 for success.
fac6795d 436 */
5461b305 437static int process_client_msg(struct command_ctx *cmd_ctx)
fac6795d 438{
5461b305 439 int ret;
fac6795d 440
5461b305 441 DBG("Processing client command %d", cmd_ctx->lsm->cmd_type);
fac6795d 442
379473d2 443 /* Check command that needs a session */
5461b305 444 switch (cmd_ctx->lsm->cmd_type) {
5e16da05
MD
445 case LTTNG_CREATE_SESSION:
446 case LTTNG_LIST_SESSIONS:
447 case UST_LIST_APPS:
448 break;
449 default:
5461b305
DG
450 cmd_ctx->session = find_session_by_uuid(cmd_ctx->lsm->session_uuid);
451 if (cmd_ctx->session == NULL) {
379473d2 452 ret = LTTCOMM_SELECT_SESS;
5461b305 453 goto error;
379473d2 454 }
5e16da05 455 break;
379473d2
DG
456 }
457
471d1693 458 /* Connect to ust apps if available pid */
5461b305 459 if (cmd_ctx->lsm->pid > 0) {
471d1693 460 /* Connect to app using ustctl API */
5461b305
DG
461 cmd_ctx->ust_sock = ust_connect_app(cmd_ctx->lsm->pid);
462 if (cmd_ctx->ust_sock < 0) {
471d1693 463 ret = LTTCOMM_NO_TRACEABLE;
5461b305 464 goto error;
471d1693
DG
465 }
466 }
467
fac6795d 468 /* Process by command type */
5461b305 469 switch (cmd_ctx->lsm->cmd_type) {
894be886
DG
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 }
5e16da05
MD
483 case LTTNG_CREATE_SESSION:
484 {
5461b305
DG
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);
5e16da05
MD
492 if (ret < 0) {
493 if (ret == -1) {
494 ret = LTTCOMM_EXIST_SESS;
495 } else {
aaf97519 496 ret = LTTCOMM_FATAL;
aaf97519 497 }
5461b305 498 goto error;
8028d920 499 }
1657e9bb 500
5461b305 501 ret = LTTCOMM_OK;
5e16da05
MD
502 break;
503 }
504 case LTTNG_DESTROY_SESSION:
505 {
5461b305
DG
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);
5e16da05
MD
513 if (ret < 0) {
514 ret = LTTCOMM_NO_SESS;
5461b305 515 goto error;
5e16da05 516 }
1657e9bb 517
5461b305
DG
518 ret = LTTCOMM_OK;
519 break;
5e16da05
MD
520 }
521 case LTTNG_LIST_TRACES:
522 {
5461b305 523 unsigned int trace_count;
1657e9bb 524
5461b305 525 trace_count = get_trace_count_per_session(cmd_ctx->session);
5e16da05
MD
526 if (trace_count == 0) {
527 ret = LTTCOMM_NO_TRACE;
5461b305 528 goto error;
1657e9bb 529 }
df0da139 530
5461b305
DG
531 ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_trace) * trace_count);
532 if (ret < 0) {
533 goto setup_error;
df0da139 534 }
ca95a216 535
5461b305
DG
536 get_traces_per_session(cmd_ctx->session,
537 (struct lttng_trace *)(cmd_ctx->llm->payload));
538
539 ret = LTTCOMM_OK;
5e16da05
MD
540 break;
541 }
542 case UST_CREATE_TRACE:
543 {
5461b305
DG
544 /* Setup lttng message with no payload */
545 ret = setup_lttng_msg(cmd_ctx, 0);
5e16da05 546 if (ret < 0) {
5461b305 547 goto setup_error;
fac6795d 548 }
ce3d728c 549
5461b305
DG
550 ret = ust_create_trace(cmd_ctx);
551 if (ret < 0) {
552 goto setup_error;
553 }
554 break;
5e16da05
MD
555 }
556 case UST_LIST_APPS:
557 {
5461b305
DG
558 unsigned int app_count;
559
560 app_count = get_app_count();
561 DBG("Traceable application count : %d", app_count);
5e16da05
MD
562 if (app_count == 0) {
563 ret = LTTCOMM_NO_APPS;
5461b305 564 goto error;
ce3d728c 565 }
520ff687 566
5461b305
DG
567 ret = setup_lttng_msg(cmd_ctx, sizeof(pid_t) * app_count);
568 if (ret < 0) {
569 goto setup_error;
520ff687 570 }
57167058 571
5461b305 572 get_app_list_pids((pid_t *)(cmd_ctx->llm->payload));
5e16da05 573
5461b305 574 ret = LTTCOMM_OK;
5e16da05
MD
575 break;
576 }
577 case UST_START_TRACE:
578 {
5461b305
DG
579 /* Setup lttng message with no payload */
580 ret = setup_lttng_msg(cmd_ctx, 0);
581 if (ret < 0) {
582 goto setup_error;
583 }
ca95a216 584
5461b305
DG
585 ret = ust_start_trace(cmd_ctx);
586 if (ret < 0) {
587 goto setup_error;
588 }
589 break;
5e16da05
MD
590 }
591 case UST_STOP_TRACE:
592 {
5461b305
DG
593 /* Setup lttng message with no payload */
594 ret = setup_lttng_msg(cmd_ctx, 0);
595 if (ret < 0) {
596 goto setup_error;
597 }
ca95a216 598
5461b305
DG
599 ret = ust_stop_trace(cmd_ctx);
600 if (ret < 0) {
601 goto setup_error;
602 }
603 break;
5e16da05
MD
604 }
605 case LTTNG_LIST_SESSIONS:
606 {
5461b305
DG
607 unsigned int session_count;
608
609 session_count = get_session_count();
5e16da05
MD
610 if (session_count == 0) {
611 ret = LTTCOMM_NO_SESS;
5461b305 612 goto error;
57167058 613 }
5e16da05 614
5461b305
DG
615 ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) * session_count);
616 if (ret < 0) {
617 goto setup_error;
e065084a 618 }
5e16da05 619
5461b305 620 get_lttng_session((struct lttng_session *)(cmd_ctx->llm->payload));
5e16da05 621
5461b305 622 ret = LTTCOMM_OK;
5e16da05
MD
623 break;
624 }
625 default:
626 /* Undefined command */
5461b305
DG
627 ret = setup_lttng_msg(cmd_ctx, 0);
628 if (ret < 0) {
629 goto setup_error;
630 }
631
5e16da05 632 ret = LTTCOMM_UND;
5461b305 633 break;
fac6795d
DG
634 }
635
5461b305
DG
636 /* Set return code */
637 cmd_ctx->llm->ret_code = ret;
ca95a216 638
e065084a
DG
639 return ret;
640
5461b305 641error:
5461b305
DG
642 if (cmd_ctx->llm == NULL) {
643 DBG("Missing llm structure. Allocating one.");
894be886 644 if (setup_lttng_msg(cmd_ctx, 0) < 0) {
5461b305
DG
645 goto setup_error;
646 }
647 }
e065084a 648 /* Notify client of error */
5461b305 649 cmd_ctx->llm->ret_code = ret;
e065084a 650
5461b305 651setup_error:
8028d920 652 return ret;
fac6795d
DG
653}
654
655/*
656 * usage function on stderr
657 */
658static void usage(void)
659{
b716ce68 660 fprintf(stderr, "Usage: %s OPTIONS\n\nOptions:\n", progname);
d6f42150
DG
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");
fac6795d
DG
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' },
d6f42150
DG
684 { "kconsumerd-cmd-sock", 1, 0, 0 },
685 { "kconsumerd-err-sock", 1, 0, 0 },
fac6795d 686 { "daemonize", 0, 0, 'd' },
5b8719f5 687 { "sig-parent", 0, 0, 'S' },
fac6795d
DG
688 { "help", 0, 0, 'h' },
689 { "group", 1, 0, 'g' },
690 { "version", 0, 0, 'V' },
75462a81 691 { "quiet", 0, 0, 'q' },
3f9947db 692 { "verbose", 0, 0, 'v' },
fac6795d
DG
693 { NULL, 0, 0, 0 }
694 };
695
696 while (1) {
697 int option_index = 0;
d6f42150 698 c = getopt_long(argc, argv, "dhqvVS" "a:c:g:s:E:C:", long_options, &option_index);
fac6795d
DG
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;
b716ce68 710 case 'c':
fac6795d
DG
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);
5b8719f5
DG
728 case 'S':
729 opt_sig_parent = 1;
730 break;
d6f42150
DG
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;
75462a81
DG
737 case 'q':
738 opt_quiet = 1;
739 break;
3f9947db
DG
740 case 'v':
741 opt_verbose = 1;
742 break;
fac6795d
DG
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.
d6f42150
DG
757 * apps_sock - The communication socket for all UST apps.
758 * client_sock - The communication of the cli tool (lttng).
fac6795d
DG
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 */
d6f42150
DG
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);
fac6795d
DG
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) {
d6f42150 778 ERR("Set file permissions failed: %s", client_unix_sock_path);
fac6795d
DG
779 perror("chmod");
780 goto end;
781 }
782
783 /* Create the application unix socket */
d6f42150
DG
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);
fac6795d
DG
787 ret = -1;
788 goto end;
789 }
790
d6f42150 791 /* File permission MUST be 666 */
fac6795d
DG
792 ret = chmod(apps_unix_sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
793 if (ret < 0) {
d6f42150 794 ERR("Set file permissions failed: %s", apps_unix_sock_path);
fac6795d
DG
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.
62bd06d8 808 * If yes, error is returned.
fac6795d
DG
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/*
62bd06d8 823 * get_home_dir
fac6795d 824 *
62bd06d8
DG
825 * Return pointer to home directory path using
826 * the env variable HOME.
fac6795d 827 *
62bd06d8 828 * Default : /tmp
fac6795d
DG
829 */
830static const char *get_home_dir(void)
831{
832 const char *home_path;
833
686204ab 834 if ((home_path = (const char *) getenv("HOME")) == NULL) {
fac6795d
DG
835 home_path = default_home_dir;
836 }
837
838 return home_path;
839}
840
841/*
d6f42150 842 * set_permissions
fac6795d 843 *
5e16da05
MD
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).
fac6795d 848 */
d6f42150 849static int set_permissions(void)
fac6795d
DG
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) {
75462a81 860 ERR("Missing tracing group. Aborting execution.\n");
fac6795d
DG
861 ret = -1;
862 goto end;
863 }
864
d6f42150
DG
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 */
fac6795d
DG
873 ret = chown(client_unix_sock_path, 0, grp->gr_gid);
874 if (ret < 0) {
d6f42150
DG
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);
fac6795d
DG
883 perror("chown");
884 }
885
d6f42150 886 DBG("All permissions are set");
e07ae692 887
fac6795d
DG
888end:
889 return ret;
890}
891
d6f42150
DG
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
fac6795d 956/*
62bd06d8 957 * set_signal_handler
fac6795d 958 *
62bd06d8 959 * Setup signal handler for :
fac6795d
DG
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
e07ae692
DG
991 DBG("Signal handler set for SIGTERM, SIGPIPE and SIGINT");
992
fac6795d
DG
993 return ret;
994}
995
996/**
62bd06d8 997 * sighandler
fac6795d 998 *
62bd06d8 999 * Signal handler for the daemon
fac6795d
DG
1000 */
1001static void sighandler(int sig)
1002{
1003 switch (sig) {
1004 case SIGPIPE:
e07ae692 1005 DBG("SIGPIPE catched");
87378cf5 1006 return;
fac6795d 1007 case SIGINT:
e07ae692
DG
1008 DBG("SIGINT catched");
1009 cleanup();
1010 break;
fac6795d 1011 case SIGTERM:
e07ae692 1012 DBG("SIGTERM catched");
fac6795d 1013 cleanup();
686204ab 1014 break;
fac6795d
DG
1015 default:
1016 break;
1017 }
1018
1019 exit(EXIT_SUCCESS);
1020}
1021
1022/*
62bd06d8 1023 * cleanup
fac6795d 1024 *
62bd06d8 1025 * Cleanup the daemon on exit
fac6795d
DG
1026 */
1027static void cleanup()
1028{
d6f42150
DG
1029 int ret;
1030 char *cmd;
1031
e07ae692
DG
1032 DBG("Cleaning up");
1033
fac6795d 1034 /* <fun> */
b716ce68
DG
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);
fac6795d
DG
1037 /* </fun> */
1038
1039 unlink(client_unix_sock_path);
1040 unlink(apps_unix_sock_path);
d6f42150
DG
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 }
fac6795d
DG
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) {
53094c05
DG
1073 ret = daemon(0, 0);
1074 if (ret < 0) {
1075 perror("daemon");
1076 goto error;
1077 }
fac6795d
DG
1078 }
1079
1080 /* Check if daemon is UID = 0 */
1081 is_root = !getuid();
1082
1083 /* Set all sockets path */
1084 if (is_root) {
d6f42150
DG
1085 ret = create_lttng_rundir();
1086 if (ret < 0) {
1087 goto error;
1088 }
1089
fac6795d 1090 if (strlen(apps_unix_sock_path) == 0) {
d6f42150
DG
1091 snprintf(apps_unix_sock_path, PATH_MAX,
1092 DEFAULT_GLOBAL_APPS_UNIX_SOCK);
fac6795d
DG
1093 }
1094
1095 if (strlen(client_unix_sock_path) == 0) {
d6f42150
DG
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;
fac6795d
DG
1103 }
1104 } else {
1105 if (strlen(apps_unix_sock_path) == 0) {
d6f42150
DG
1106 snprintf(apps_unix_sock_path, PATH_MAX,
1107 DEFAULT_HOME_APPS_UNIX_SOCK, get_home_dir());
fac6795d
DG
1108 }
1109
1110 /* Set the cli tool unix socket path */
1111 if (strlen(client_unix_sock_path) == 0) {
d6f42150
DG
1112 snprintf(client_unix_sock_path, PATH_MAX,
1113 DEFAULT_HOME_CLIENT_UNIX_SOCK, get_home_dir());
fac6795d
DG
1114 }
1115 }
1116
847177cd
DG
1117 DBG("Client socket path %s", client_unix_sock_path);
1118 DBG("Application socket path %s", apps_unix_sock_path);
1119
fac6795d
DG
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) {
75462a81 1124 ERR("Already running daemon.\n");
ab118b20 1125 /* We do not goto error because we must not
d6f42150 1126 * cleanup() because a daemon is already running.
ab118b20 1127 */
5e16da05 1128 exit(EXIT_FAILURE);
fac6795d
DG
1129 }
1130
1131 if (set_signal_handler() < 0) {
1132 goto error;
1133 }
1134
d6f42150 1135 /* Setup the needed unix socket */
fac6795d
DG
1136 if (init_daemon_socket() < 0) {
1137 goto error;
1138 }
1139
1140 /* Set credentials to socket */
d6f42150 1141 if (is_root && (set_permissions() < 0)) {
fac6795d
DG
1142 goto error;
1143 }
1144
5b8719f5
DG
1145 /* Get parent pid if -S, --sig-parent is specified. */
1146 if (opt_sig_parent) {
1147 ppid = getppid();
1148 }
1149
fac6795d
DG
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();
5e16da05 1175 exit(EXIT_SUCCESS);
fac6795d
DG
1176
1177error:
1178 cleanup();
5e16da05 1179 exit(EXIT_FAILURE);
fac6795d 1180}
This page took 0.079203 seconds and 4 git commands to generate.