X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=36d154e1fff0cd5ebe46afa6b74700110c969b61;hb=df09ff2e14eeef441e1031cbfcea0114cab9bc2d;hp=e5054735efd6279aec0fe5648a122dca3f366943;hpb=834978fd9e2392f20867351ca99bf7bdf31b4f56;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index e5054735e..36d154e1f 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -629,6 +629,9 @@ static void cleanup(void) } } + DBG("Cleaning up all agent apps"); + agent_app_ht_clean(); + DBG("Closing all UST sockets"); ust_app_clean_list(); buffer_reg_destroy_registries(); @@ -1002,12 +1005,14 @@ static void *thread_manage_kernel(void *data) update_poll_flag = 0; } - DBG("Thread kernel polling on %d fds", LTTNG_POLL_GETNB(&events)); + DBG("Thread kernel polling"); /* Poll infinite value of time */ restart: health_poll_entry(); ret = lttng_poll_wait(&events, -1); + DBG("Thread kernel return from poll on %d fds", + LTTNG_POLL_GETNB(&events)); health_poll_exit(); if (ret < 0) { /* @@ -1033,6 +1038,11 @@ static void *thread_manage_kernel(void *data) health_code_update(); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -1116,7 +1126,7 @@ static void signal_consumer_condition(struct consumer_data *data, int state) */ static void *thread_manage_consumer(void *data) { - int sock = -1, i, ret, pollfd, err = -1; + int sock = -1, i, ret, pollfd, err = -1, should_quit = 0; uint32_t revents, nb_fd; enum lttcomm_return_code code; struct lttng_poll_event events; @@ -1178,6 +1188,11 @@ restart: health_code_update(); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -1274,6 +1289,15 @@ restart: /* Infinite blocking call, waiting for transmission */ restart_poll: while (1) { + health_code_update(); + + /* Exit the thread because the thread quit pipe has been triggered. */ + if (should_quit) { + /* Not a health error. */ + err = 0; + goto exit; + } + health_poll_entry(); ret = lttng_poll_wait(&events, -1); health_poll_exit(); @@ -1296,13 +1320,18 @@ restart_poll: health_code_update(); - /* Thread quit pipe has been closed. Killing thread. */ - ret = sessiond_check_thread_quit_pipe(pollfd, revents); - if (ret) { - err = 0; - goto exit; + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; } + /* + * Thread quit pipe has been triggered, flag that we should stop + * but continue the current loop to handle potential data from + * consumer. + */ + should_quit = sessiond_check_thread_quit_pipe(pollfd, revents); + if (pollfd == sock) { /* Event on the consumerd socket */ if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) { @@ -1330,11 +1359,8 @@ restart_poll: ERR("Handling metadata request"); goto error; } - break; - } else { - ERR("Unknown pollfd"); - goto error; } + /* No need for an else branch all FDs are tested prior. */ } health_code_update(); } @@ -1449,12 +1475,14 @@ static void *thread_manage_apps(void *data) health_code_update(); while (1) { - DBG("Apps thread polling on %d fds", LTTNG_POLL_GETNB(&events)); + DBG("Apps thread polling"); /* Inifinite blocking call, waiting for transmission */ restart: health_poll_entry(); ret = lttng_poll_wait(&events, -1); + DBG("Apps thread return from poll on %d fds", + LTTNG_POLL_GETNB(&events)); health_poll_exit(); if (ret < 0) { /* @@ -1475,6 +1503,11 @@ static void *thread_manage_apps(void *data) health_code_update(); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -1653,6 +1686,11 @@ static void sanitize_wait_queue(struct ust_reg_wait_queue *wait_queue) uint32_t revents = LTTNG_POLL_GETEV(&events, i); int pollfd = LTTNG_POLL_GETFD(&events, i); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + cds_list_for_each_entry_safe(wait_node, tmp_wait_node, &wait_queue->head, head) { if (pollfd == wait_node->app->sock && @@ -1992,6 +2030,11 @@ static void *thread_registration_apps(void *data) revents = LTTNG_POLL_GETEV(&events, i); pollfd = LTTNG_POLL_GETFD(&events, i); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -3206,12 +3249,14 @@ skip_domain: if (bytecode_len > LTTNG_FILTER_MAX_LEN) { ret = LTTNG_ERR_FILTER_INVAL; + free(filter_expression); free(exclusion); goto error; } bytecode = zmalloc(bytecode_len); if (!bytecode) { + free(filter_expression); free(exclusion); ret = LTTNG_ERR_FILTER_NOMEM; goto error; @@ -3223,6 +3268,7 @@ skip_domain: if (ret <= 0) { DBG("Nothing recv() from client car len data... continuing"); *sock_error = 1; + free(filter_expression); free(bytecode); free(exclusion); ret = LTTNG_ERR_FILTER_INVAL; @@ -3230,6 +3276,7 @@ skip_domain: } if ((bytecode->len + sizeof(*bytecode)) != bytecode_len) { + free(filter_expression); free(bytecode); free(exclusion); ret = LTTNG_ERR_FILTER_INVAL; @@ -3373,31 +3420,12 @@ skip_domain: goto error; } - ret = cmd_set_consumer_uri(cmd_ctx->lsm->domain.type, cmd_ctx->session, - nb_uri, uris); + ret = cmd_set_consumer_uri(cmd_ctx->session, nb_uri, uris); + free(uris); if (ret != LTTNG_OK) { - free(uris); goto error; } - /* - * XXX: 0 means that this URI should be applied on the session. Should - * be a DOMAIN enuam. - */ - if (cmd_ctx->lsm->domain.type == 0) { - /* Add the URI for the UST session if a consumer is present. */ - if (cmd_ctx->session->ust_session && - cmd_ctx->session->ust_session->consumer) { - ret = cmd_set_consumer_uri(LTTNG_DOMAIN_UST, cmd_ctx->session, - nb_uri, uris); - } else if (cmd_ctx->session->kernel_session && - cmd_ctx->session->kernel_session->consumer) { - ret = cmd_set_consumer_uri(LTTNG_DOMAIN_KERNEL, - cmd_ctx->session, nb_uri, uris); - } - } - - free(uris); break; } @@ -3490,7 +3518,7 @@ skip_domain: case LTTNG_LIST_CHANNELS: { int nb_chan; - struct lttng_channel *channels; + struct lttng_channel *channels = NULL; nb_chan = cmd_list_channels(cmd_ctx->lsm->domain.type, cmd_ctx->session, &channels); @@ -3864,6 +3892,11 @@ restart: revents = LTTNG_POLL_GETEV(&events, i); pollfd = LTTNG_POLL_GETFD(&events, i); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -4036,6 +4069,11 @@ static void *thread_manage_clients(void *data) health_code_update(); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -4230,7 +4268,7 @@ static void usage(void) fprintf(stderr, " --verbose-consumer Verbose mode for consumer. Activate DBG() macro.\n"); fprintf(stderr, " --no-kernel Disable kernel tracer\n"); fprintf(stderr, " --agent-tcp-port Agent registration TCP port\n"); - fprintf(stderr, " -f --config Load daemon configuration file\n"); + fprintf(stderr, " -f --config PATH Load daemon configuration file\n"); fprintf(stderr, " -l --load PATH Load session configuration\n"); fprintf(stderr, " --kmod-probes Specify kernel module probes to load\n"); fprintf(stderr, " --extra-kmod-probes Specify extra kernel module probes to load\n"); @@ -4246,6 +4284,17 @@ static int set_option(int opt, const char *arg, const char *optname) { int ret = 0; + if (arg && arg[0] == '\0') { + /* + * This only happens if the value is read from daemon config + * file. This means the option requires an argument and the + * configuration file contains a line such as: + * my_option = + */ + ret = -EINVAL; + goto end; + } + switch (opt) { case 0: fprintf(stderr, "option %s", optname); @@ -4437,6 +4486,23 @@ static int set_option(int opt, const char *arg, const char *optname) ret = -1; } +end: + if (ret == -EINVAL) { + const char *opt_name = "unknown"; + int i; + + for (i = 0; i < sizeof(long_options) / sizeof(struct option); + i++) { + if (opt == long_options[i].val) { + opt_name = long_options[i].name; + break; + } + } + + WARN("Invalid argument provided for option \"%s\", using default value.", + opt_name); + } + return ret; } @@ -5014,6 +5080,9 @@ int main(int argc, char **argv) void *status; const char *home_path, *env_app_timeout; + /* Initialize agent apps ht global variable */ + agent_apps_ht_by_sock = NULL; + init_kernel_workarounds(); rcu_register_thread(); @@ -5067,6 +5136,10 @@ int main(int argc, char **argv) if (is_root) { rundir = strdup(DEFAULT_LTTNG_RUNDIR); + if (!rundir) { + ret = -ENOMEM; + goto error; + } /* Create global run dir with root access */ ret = create_lttng_rundir(rundir); @@ -5201,20 +5274,24 @@ int main(int argc, char **argv) goto error; } + /* After this point, we can safely call cleanup() with "goto exit" */ + /* * Init UST app hash table. Alloc hash table before this point since * cleanup() can get called after that point. */ ust_app_ht_alloc(); - /* Initialize agent domain subsystem. */ - if ((ret = agent_setup()) < 0) { - /* ENOMEM at this point. */ - goto error; + /* + * Initialize agent app hash table. We allocate the hash table here + * since cleanup() can get called after this point. + */ + if (agent_app_ht_alloc()) { + ERR("Failed to allocate Agent app hash table"); + ret = -1; + goto exit; } - /* After this point, we can safely call cleanup() with "goto exit" */ - /* * These actions must be executed as root. We do that *after* setting up * the sockets path because we MUST make the check for another daemon using @@ -5230,10 +5307,12 @@ int main(int argc, char **argv) /* Setup kernel tracer */ if (!opt_no_kernel) { init_kernel_tracer(); - ret = syscall_init_table(); - if (ret < 0) { - ERR("Unable to populate syscall table. Syscall tracing won't" - " work for this session daemon."); + if (kernel_tracer_fd >= 0) { + ret = syscall_init_table(); + if (ret < 0) { + ERR("Unable to populate syscall table. Syscall tracing" + " won't work for this session daemon."); + } } }