X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=052e32e0c32ec2fb8bfe2a17e71afa0487ebf868;hp=37c7354ef0827f22fd23a1f53c2a71464fb18c1a;hb=4421f712a81faad99bb5f20369c276803aeba381;hpb=72dd74910ee17be5d82c6b2286f454942bf19d24 diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 37c7354ef..052e32e0c 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -68,6 +68,7 @@ #include "testpoint.h" #include "ust-thread.h" #include "jul-thread.h" +#include "save.h" #define CONSUMERD_FILE "lttng-consumerd" @@ -79,7 +80,6 @@ static int opt_sig_parent; static int opt_verbose_consumer; static int opt_daemon, opt_background; static int opt_no_kernel; -static int is_root; /* Set to 1 if the daemon is running as root */ static pid_t ppid; /* Parent PID for --sig-parent option */ static pid_t child_ppid; /* Internal parent PID use with daemonize. */ static char *rundir; @@ -205,8 +205,10 @@ static pthread_t jul_reg_thread; * UST registration command queue. This queue is tied with a futex and uses a N * wakers / 1 waiter implemented and detailed in futex.c/.h * - * The thread_manage_apps and thread_dispatch_ust_registration interact with - * this queue and the wait/wake scheme. + * The thread_registration_apps and thread_dispatch_ust_registration uses this + * queue along with the wait/wake scheme. The thread_manage_apps receives down + * the line new application socket and monitors it for any I/O error or clean + * close that triggers an unregistration of the application. */ static struct ust_cmd_queue ust_cmd_queue; @@ -284,6 +286,9 @@ struct health_app *health_sessiond; /* JUL TCP port for registration. Used by the JUL thread. */ unsigned int jul_tcp_port = DEFAULT_JUL_TCP_PORT; +/* Am I root or not. */ +int is_root; /* Set to 1 if the daemon is running as root */ + const char * const config_section_name = "sessiond"; /* @@ -1150,7 +1155,6 @@ restart: } health_code_update(); - if (code == LTTCOMM_CONSUMERD_COMMAND_SOCK_READY) { /* Connect both socket, command and metadata. */ consumer_data->cmd_sock = @@ -1307,13 +1311,13 @@ error: } consumer_data->cmd_sock = -1; } - if (*consumer_data->metadata_sock.fd_ptr >= 0) { + if (consumer_data->metadata_sock.fd_ptr && + *consumer_data->metadata_sock.fd_ptr >= 0) { ret = close(*consumer_data->metadata_sock.fd_ptr); if (ret) { PERROR("close"); } } - if (sock >= 0) { ret = close(sock); if (ret) { @@ -1327,9 +1331,10 @@ error: pthread_mutex_unlock(&consumer_data->lock); /* Cleanup metadata socket mutex. */ - pthread_mutex_destroy(consumer_data->metadata_sock.lock); - free(consumer_data->metadata_sock.lock); - + if (consumer_data->metadata_sock.lock) { + pthread_mutex_destroy(consumer_data->metadata_sock.lock); + free(consumer_data->metadata_sock.lock); + } lttng_poll_clean(&events); error_poll: if (err) { @@ -1630,6 +1635,10 @@ static void *thread_dispatch_ust_registration(void *data) health_register(health_sessiond, HEALTH_SESSIOND_TYPE_APP_REG_DISPATCH); + if (testpoint(sessiond_thread_app_reg_dispatch)) { + goto error_testpoint; + } + health_code_update(); CDS_INIT_LIST_HEAD(&wait_queue.head); @@ -1834,6 +1843,7 @@ error: free(wait_node); } +error_testpoint: DBG("Dispatch thread dying"); if (err) { health_error(); @@ -2022,11 +2032,6 @@ static void *thread_registration_apps(void *data) exit: error: - if (err) { - health_error(); - ERR("Health error occurred in %s", __func__); - } - /* Notify that the registration thread is gone */ notify_ust_apps(0); @@ -2051,6 +2056,10 @@ error_listen: error_create_poll: error_testpoint: DBG("UST Registration thread cleanup complete"); + if (err) { + health_error(); + ERR("Health error occurred in %s", __func__); + } health_unregister(health_sessiond); return NULL; @@ -2147,19 +2156,23 @@ static int spawn_consumer_thread(struct consumer_data *consumer_data) if (ret != 0) { errno = ret; if (ret == ETIMEDOUT) { + int pth_ret; + /* * Call has timed out so we kill the kconsumerd_thread and return * an error. */ ERR("Condition timed out. The consumer thread was never ready." " Killing it"); - ret = pthread_cancel(consumer_data->thread); - if (ret < 0) { + pth_ret = pthread_cancel(consumer_data->thread); + if (pth_ret < 0) { PERROR("pthread_cancel consumer thread"); } } else { PERROR("pthread_cond_wait failed consumer thread"); } + /* Caller is expecting a negative value on failure. */ + ret = -1; goto error; } @@ -2220,9 +2233,12 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) */ if (opt_verbose_consumer) { verbosity = "--verbose"; - } else { + } else if (lttng_opt_quiet) { verbosity = "--quiet"; + } else { + verbosity = ""; } + switch (consumer_data->type) { case LTTNG_CONSUMER_KERNEL: /* @@ -2245,10 +2261,11 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) consumer_to_use = consumerd32_bin; } else { DBG("Could not find any valid consumerd executable"); + ret = -EINVAL; break; } DBG("Using kernel consumer at: %s", consumer_to_use); - execl(consumer_to_use, + ret = execl(consumer_to_use, "lttng-consumerd", verbosity, "-k", "--consumerd-cmd-sock", consumer_data->cmd_unix_sock_path, "--consumerd-err-sock", consumer_data->err_unix_sock_path, @@ -2296,9 +2313,6 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) if (consumerd64_libdir[0] != '\0') { free(tmpnew); } - if (ret) { - goto error; - } break; } case LTTNG_CONSUMER32_UST: @@ -2342,9 +2356,6 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) if (consumerd32_libdir[0] != '\0') { free(tmpnew); } - if (ret) { - goto error; - } break; } default: @@ -2352,8 +2363,9 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) exit(EXIT_FAILURE); } if (errno != 0) { - PERROR("kernel start consumer exec"); + PERROR("Consumer execl()"); } + /* Reaching this point, we got a failure on our execl(). */ exit(EXIT_FAILURE); } else if (pid > 0) { ret = pid; @@ -2712,6 +2724,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_SNAPSHOT_DEL_OUTPUT: case LTTNG_SNAPSHOT_LIST_OUTPUT: case LTTNG_SNAPSHOT_RECORD: + case LTTNG_SAVE_SESSION: need_domain = 0; break; default: @@ -2770,6 +2783,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_LIST_SESSIONS: case LTTNG_LIST_TRACEPOINTS: case LTTNG_LIST_TRACEPOINT_FIELDS: + case LTTNG_SAVE_SESSION: need_tracing_session = 0; break; default: @@ -3033,6 +3047,7 @@ skip_domain: { struct lttng_event_exclusion *exclusion = NULL; struct lttng_filter_bytecode *bytecode = NULL; + char *filter_expression = NULL; /* Handle exclusion events and receive it from the client. */ if (cmd_ctx->lsm->u.enable.exclusion_count > 0) { @@ -3058,6 +3073,38 @@ skip_domain: } } + /* Get filter expression from client. */ + if (cmd_ctx->lsm->u.enable.expression_len > 0) { + size_t expression_len = + cmd_ctx->lsm->u.enable.expression_len; + + if (expression_len > LTTNG_FILTER_MAX_LEN) { + ret = LTTNG_ERR_FILTER_INVAL; + free(exclusion); + goto error; + } + + filter_expression = zmalloc(expression_len); + if (!filter_expression) { + free(exclusion); + ret = LTTNG_ERR_FILTER_NOMEM; + goto error; + } + + /* Receive var. len. data */ + DBG("Receiving var len filter's expression from client ..."); + ret = lttcomm_recv_unix_sock(sock, filter_expression, + expression_len); + if (ret <= 0) { + DBG("Nothing recv() from client car len data... continuing"); + *sock_error = 1; + free(filter_expression); + free(exclusion); + ret = LTTNG_ERR_FILTER_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; @@ -3097,7 +3144,8 @@ skip_domain: 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, + &cmd_ctx->lsm->u.enable.event, + filter_expression, bytecode, exclusion, kernel_poll_pipe[1]); break; } @@ -3107,7 +3155,8 @@ skip_domain: ret = cmd_enable_event_all(cmd_ctx->session, &cmd_ctx->lsm->domain, cmd_ctx->lsm->u.enable.channel_name, - cmd_ctx->lsm->u.enable.event.type, NULL, kernel_poll_pipe[1]); + cmd_ctx->lsm->u.enable.event.type, NULL, NULL, + kernel_poll_pipe[1]); break; } case LTTNG_LIST_TRACEPOINTS: @@ -3115,7 +3164,9 @@ skip_domain: struct lttng_event *events; ssize_t nb_events; + session_lock_list(); nb_events = cmd_list_tracepoints(cmd_ctx->lsm->domain.type, &events); + session_unlock_list(); if (nb_events < 0) { /* Return value is a negative lttng_error_code. */ ret = -nb_events; @@ -3146,8 +3197,10 @@ skip_domain: struct lttng_event_field *fields; ssize_t nb_fields; + session_lock_list(); nb_fields = cmd_list_tracepoint_fields(cmd_ctx->lsm->domain.type, &fields); + session_unlock_list(); if (nb_fields < 0) { /* Return value is a negative lttng_error_code. */ ret = -nb_fields; @@ -3566,6 +3619,12 @@ skip_domain: free(uris); break; } + case LTTNG_SAVE_SESSION: + { + ret = cmd_save_sessions(&cmd_ctx->lsm->u.save_session.attr, + &cmd_ctx->creds); + break; + } default: ret = LTTNG_ERR_UND; break; @@ -3730,7 +3789,7 @@ restart: rcu_thread_online(); - reply.ret_code = 0; + memset(&reply, 0, sizeof(reply)); for (i = 0; i < NR_HEALTH_SESSIOND_TYPES; i++) { /* * health_check_state returns 0 if health is