X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=2714aa966d110e3bd58a1e698d09691d4810cc54;hb=449935a10fad850b3a0378ffca982f601592997c;hp=d15effdabfecb70a0c9c739cbe61faf762d6fd4b;hpb=882ef83557ba5d5abd408eabd13a3e644b69737e;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index d15effdab..2714aa966 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "lttng-sessiond.h" #include "buffer-registry.h" @@ -243,6 +244,38 @@ struct health_app *health_sessiond; /* JUL TCP port for registration. Used by the JUL thread. */ unsigned int jul_tcp_port = DEFAULT_JUL_TCP_PORT; +/* + * Whether sessiond is ready for commands/health check requests. + * NR_LTTNG_SESSIOND_READY must match the number of calls to + * lttng_sessiond_notify_ready(). + */ +#define NR_LTTNG_SESSIOND_READY 2 +int lttng_sessiond_ready = NR_LTTNG_SESSIOND_READY; + +/* Notify parents that we are ready for cmd and health check */ +static +void lttng_sessiond_notify_ready(void) +{ + if (uatomic_sub_return(<tng_sessiond_ready, 1) == 0) { + /* + * Notify parent pid that we are ready to accept command + * for client side. This ppid is the one from the + * external process that spawned us. + */ + if (opt_sig_parent) { + kill(ppid, SIGUSR1); + } + + /* + * Notify the parent of the fork() process that we are + * ready. + */ + if (opt_daemon) { + kill(child_ppid, SIGUSR1); + } + } +} + static void setup_consumerd_path(void) { @@ -801,13 +834,13 @@ static void *thread_manage_kernel(void *data) */ lttng_poll_init(&events); - if (testpoint(thread_manage_kernel)) { + if (testpoint(sessiond_thread_manage_kernel)) { goto error_testpoint; } health_code_update(); - if (testpoint(thread_manage_kernel_before_loop)) { + if (testpoint(sessiond_thread_manage_kernel_before_loop)) { goto error_testpoint; } @@ -987,7 +1020,7 @@ static void *thread_manage_consumer(void *data) restart: health_poll_entry(); - if (testpoint(thread_manage_consumer)) { + if (testpoint(sessiond_thread_manage_consumer)) { goto error; } @@ -1260,7 +1293,7 @@ static void *thread_manage_apps(void *data) health_register(health_sessiond, HEALTH_SESSIOND_TYPE_APP_MANAGE); - if (testpoint(thread_manage_apps)) { + if (testpoint(sessiond_thread_manage_apps)) { goto error_testpoint; } @@ -1276,7 +1309,7 @@ static void *thread_manage_apps(void *data) goto error; } - if (testpoint(thread_manage_apps_before_loop)) { + if (testpoint(sessiond_thread_manage_apps_before_loop)) { goto error; } @@ -1345,10 +1378,6 @@ static void *thread_manage_apps(void *data) } DBG("Apps with sock %d added to poll set", sock); - - health_code_update(); - - break; } } else { /* @@ -1364,7 +1393,6 @@ static void *thread_manage_apps(void *data) /* Socket closed on remote end. */ ust_app_unregister(pollfd); - break; } } @@ -1767,7 +1795,7 @@ static void *thread_registration_apps(void *data) health_register(health_sessiond, HEALTH_SESSIOND_TYPE_APP_REG); - if (testpoint(thread_registration_apps)) { + if (testpoint(sessiond_thread_registration_apps)) { goto error_testpoint; } @@ -2936,73 +2964,75 @@ skip_domain: break; } case LTTNG_ENABLE_EVENT: - case LTTNG_ENABLE_EVENT_WITH_EXCLUSION: { struct lttng_event_exclusion *exclusion = NULL; struct lttng_filter_bytecode *bytecode = NULL; - if (cmd_ctx->lsm->cmd_type == LTTNG_ENABLE_EVENT || - (cmd_ctx->lsm->u.enable.exclusion_count == 0 && cmd_ctx->lsm->u.enable.bytecode_len == 0)) { - ret = cmd_enable_event(cmd_ctx->session, &cmd_ctx->lsm->domain, - cmd_ctx->lsm->u.enable.channel_name, - &cmd_ctx->lsm->u.enable.event, NULL, NULL, kernel_poll_pipe[1]); - } else { - if (cmd_ctx->lsm->u.enable.exclusion_count != 0) { - exclusion = zmalloc(sizeof(struct lttng_event_exclusion) + - cmd_ctx->lsm->u.enable.exclusion_count * LTTNG_SYMBOL_NAME_LEN); - if (!exclusion) { - ret = LTTNG_ERR_EXCLUSION_NOMEM; - goto error; - } - DBG("Receiving var len data from client ..."); - exclusion->count = cmd_ctx->lsm->u.enable.exclusion_count; - ret = lttcomm_recv_unix_sock(sock, exclusion->names, - cmd_ctx->lsm->u.enable.exclusion_count * LTTNG_SYMBOL_NAME_LEN); - if (ret <= 0) { - DBG("Nothing recv() from client var len data... continuing"); - *sock_error = 1; - ret = LTTNG_ERR_EXCLUSION_INVAL; - goto error; - } + /* Handle exclusion events and receive it from the client. */ + if (cmd_ctx->lsm->u.enable.exclusion_count > 0) { + size_t count = cmd_ctx->lsm->u.enable.exclusion_count; + + exclusion = zmalloc(sizeof(struct lttng_event_exclusion) + + (count * LTTNG_SYMBOL_NAME_LEN)); + if (!exclusion) { + ret = LTTNG_ERR_EXCLUSION_NOMEM; + goto error; } - if (cmd_ctx->lsm->u.enable.bytecode_len != 0) { - bytecode = zmalloc(cmd_ctx->lsm->u.enable.bytecode_len); - if (!bytecode) { - if (!exclusion) - free(exclusion); - ret = LTTNG_ERR_FILTER_NOMEM; - goto error; - } - /* Receive var. len. data */ - DBG("Receiving var len data from client ..."); - ret = lttcomm_recv_unix_sock(sock, bytecode, - cmd_ctx->lsm->u.enable.bytecode_len); - if (ret <= 0) { - DBG("Nothing recv() from client car len data... continuing"); - *sock_error = 1; - if (!exclusion) - free(exclusion); - ret = LTTNG_ERR_FILTER_INVAL; - goto error; - } - if (bytecode->len + sizeof(*bytecode) - != cmd_ctx->lsm->u.enable.bytecode_len) { - free(bytecode); - if (!exclusion) - free(exclusion); - ret = LTTNG_ERR_FILTER_INVAL; - goto error; - } + DBG("Receiving var len exclusion event list from client ..."); + exclusion->count = count; + ret = lttcomm_recv_unix_sock(sock, exclusion->names, + count * LTTNG_SYMBOL_NAME_LEN); + if (ret <= 0) { + DBG("Nothing recv() from client var len data... continuing"); + *sock_error = 1; + free(exclusion); + ret = LTTNG_ERR_EXCLUSION_INVAL; + goto error; + } + } + + /* Handle filter and get bytecode from client. */ + if (cmd_ctx->lsm->u.enable.bytecode_len > 0) { + size_t bytecode_len = cmd_ctx->lsm->u.enable.bytecode_len; + + if (bytecode_len > LTTNG_FILTER_MAX_LEN) { + ret = LTTNG_ERR_FILTER_INVAL; + free(exclusion); + goto error; + } + + bytecode = zmalloc(bytecode_len); + if (!bytecode) { + free(exclusion); + ret = LTTNG_ERR_FILTER_NOMEM; + goto error; + } + + /* Receive var. len. data */ + DBG("Receiving var len filter's bytecode from client ..."); + ret = lttcomm_recv_unix_sock(sock, bytecode, bytecode_len); + if (ret <= 0) { + DBG("Nothing recv() from client car len data... continuing"); + *sock_error = 1; + free(bytecode); + free(exclusion); + ret = LTTNG_ERR_FILTER_INVAL; + goto error; } - ret = cmd_enable_event(cmd_ctx->session, - &cmd_ctx->lsm->domain, - cmd_ctx->lsm->u.enable.channel_name, - &cmd_ctx->lsm->u.enable.event, bytecode, - exclusion, - kernel_poll_pipe[1]); + if ((bytecode->len + sizeof(*bytecode)) != bytecode_len) { + free(bytecode); + free(exclusion); + ret = LTTNG_ERR_FILTER_INVAL; + goto error; + } } + + ret = cmd_enable_event(cmd_ctx->session, &cmd_ctx->lsm->domain, + cmd_ctx->lsm->u.enable.channel_name, + &cmd_ctx->lsm->u.enable.event, bytecode, exclusion, + kernel_poll_pipe[1]); break; } case LTTNG_ENABLE_ALL_EVENT: @@ -3326,46 +3356,6 @@ skip_domain: cmd_ctx->lsm->u.reg.path, cdata); break; } - case LTTNG_ENABLE_EVENT_WITH_FILTER: - { - struct lttng_filter_bytecode *bytecode; - - if (cmd_ctx->lsm->u.enable.bytecode_len > LTTNG_FILTER_MAX_LEN) { - ret = LTTNG_ERR_FILTER_INVAL; - goto error; - } - if (cmd_ctx->lsm->u.enable.bytecode_len == 0) { - ret = LTTNG_ERR_FILTER_INVAL; - goto error; - } - bytecode = zmalloc(cmd_ctx->lsm->u.enable.bytecode_len); - if (!bytecode) { - ret = LTTNG_ERR_FILTER_NOMEM; - goto error; - } - /* Receive var. len. data */ - DBG("Receiving var len data from client ..."); - ret = lttcomm_recv_unix_sock(sock, bytecode, - cmd_ctx->lsm->u.enable.bytecode_len); - if (ret <= 0) { - DBG("Nothing recv() from client var len data... continuing"); - *sock_error = 1; - ret = LTTNG_ERR_FILTER_INVAL; - goto error; - } - - if (bytecode->len + sizeof(*bytecode) - != cmd_ctx->lsm->u.enable.bytecode_len) { - free(bytecode); - ret = LTTNG_ERR_FILTER_INVAL; - goto error; - } - - ret = cmd_enable_event(cmd_ctx->session, &cmd_ctx->lsm->domain, - cmd_ctx->lsm->u.enable.channel_name, - &cmd_ctx->lsm->u.enable.event, bytecode, NULL, kernel_poll_pipe[1]); - break; - } case LTTNG_DATA_PENDING: { ret = cmd_data_pending(cmd_ctx->session); @@ -3608,6 +3598,8 @@ static void *thread_manage_health(void *data) goto error; } + lttng_sessiond_notify_ready(); + while (1) { DBG("Health check ready"); @@ -3736,10 +3728,6 @@ static void *thread_manage_clients(void *data) health_register(health_sessiond, HEALTH_SESSIOND_TYPE_CMD); - if (testpoint(thread_manage_clients)) { - goto error_testpoint; - } - health_code_update(); ret = lttcomm_listen_unix_sock(client_sock); @@ -3762,20 +3750,14 @@ static void *thread_manage_clients(void *data) goto error; } - /* - * Notify parent pid that we are ready to accept command for client side. - * This ppid is the one from the external process that spawned us. - */ - if (opt_sig_parent) { - kill(ppid, SIGUSR1); - } + lttng_sessiond_notify_ready(); - /* Notify the parent of the fork() process that we are ready. */ - if (opt_daemon) { - kill(child_ppid, SIGUSR1); + /* This testpoint is after we signal readiness to the parent. */ + if (testpoint(sessiond_thread_manage_clients)) { + goto error; } - if (testpoint(thread_manage_clients_before_loop)) { + if (testpoint(sessiond_thread_manage_clients_before_loop)) { goto error; } @@ -3950,7 +3932,6 @@ error: error_listen: error_create_poll: -error_testpoint: unlink(client_unix_sock_path); if (client_sock >= 0) { ret = close(client_sock); @@ -4546,95 +4527,6 @@ error: return; } -/* - * Daemonize this process by forking and making the parent wait for the child - * to signal it indicating readiness. Once received, the parent successfully - * quits. - * - * The child process undergoes the same action that daemon(3) does meaning - * setsid, chdir, and dup /dev/null into 0, 1 and 2. - * - * Return 0 on success else -1 on error. - */ -static int daemonize(void) -{ - int ret; - pid_t pid; - - /* Get parent pid of this process. */ - child_ppid = getppid(); - - pid = fork(); - if (pid < 0) { - PERROR("fork"); - goto error; - } else if (pid == 0) { - int fd; - pid_t sid; - - /* Child */ - - /* - * Get the newly created parent pid so we can signal that process when - * we are ready to operate. - */ - child_ppid = getppid(); - - sid = setsid(); - if (sid < 0) { - PERROR("setsid"); - goto error; - } - - /* Try to change directory to /. If we can't well at least notify. */ - ret = chdir("/"); - if (ret < 0) { - PERROR("chdir"); - } - - fd = open(_PATH_DEVNULL, O_RDWR, 0); - if (fd < 0) { - PERROR("open %s", _PATH_DEVNULL); - /* Let 0, 1 and 2 open since we can't bind them to /dev/null. */ - } else { - (void) dup2(fd, STDIN_FILENO); - (void) dup2(fd, STDOUT_FILENO); - (void) dup2(fd, STDERR_FILENO); - if (fd > 2) { - ret = close(fd); - if (ret < 0) { - PERROR("close"); - } - } - } - goto end; - } else { - /* Parent */ - - /* - * Waiting for child to notify this parent that it can exit. Note that - * sleep() is interrupted before the 1 second delay as soon as the - * signal is received, so it will not cause visible delay for the - * user. - */ - while (!CMM_LOAD_SHARED(recv_child_signal)) { - sleep(1); - } - - /* - * From this point on, the parent can exit and the child is now an - * operationnal session daemon ready to serve clients and applications. - */ - exit(EXIT_SUCCESS); - } - -end: - return 0; - -error: - return -1; -} - /* * main */ @@ -4671,7 +4563,7 @@ int main(int argc, char **argv) if (opt_daemon) { int i; - ret = daemonize(); + ret = lttng_daemonize(&child_ppid, &recv_child_signal, 1); if (ret < 0) { goto error; }