X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=4d8851ef813168a8445ad77ef12c1fdc838101d9;hp=17ef7f71c318b60990f36ebe6ea2b6bde326e647;hb=0cd3b1d4a59305a7efb608605d2e74c0ea347383;hpb=76d7553fcee76da7c103c3b51a6b01f46cd784c8 diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 17ef7f71c..4d8851ef8 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -2,22 +2,21 @@ * Copyright (C) 2011 - David Goulet * Mathieu Desnoyers * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; only version 2 of the License. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 only, + * as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _GNU_SOURCE -#include #include #include #include @@ -40,6 +39,7 @@ #include #include +#include #include #include #include @@ -81,14 +81,10 @@ const char default_tracing_group[] = DEFAULT_TRACING_GROUP; const char default_ust_sock_dir[] = DEFAULT_UST_SOCK_DIR; const char default_global_apps_pipe[] = DEFAULT_GLOBAL_APPS_PIPE; -/* Variables */ -int opt_verbose; /* Not static for lttngerr.h */ -int opt_verbose_consumer; /* Not static for lttngerr.h */ -int opt_quiet; /* Not static for lttngerr.h */ - const char *progname; const char *opt_tracing_group; static int opt_sig_parent; +static int opt_verbose_consumer; static int opt_daemon; static int opt_no_kernel; static int is_root; /* Set to 1 if the daemon is running as root */ @@ -100,16 +96,22 @@ static struct consumer_data kconsumer_data = { .type = LTTNG_CONSUMER_KERNEL, .err_unix_sock_path = DEFAULT_KCONSUMERD_ERR_SOCK_PATH, .cmd_unix_sock_path = DEFAULT_KCONSUMERD_CMD_SOCK_PATH, + .err_sock = -1, + .cmd_sock = -1, }; static struct consumer_data ustconsumer64_data = { .type = LTTNG_CONSUMER64_UST, .err_unix_sock_path = DEFAULT_USTCONSUMERD64_ERR_SOCK_PATH, .cmd_unix_sock_path = DEFAULT_USTCONSUMERD64_CMD_SOCK_PATH, + .err_sock = -1, + .cmd_sock = -1, }; static struct consumer_data ustconsumer32_data = { .type = LTTNG_CONSUMER32_UST, .err_unix_sock_path = DEFAULT_USTCONSUMERD32_ERR_SOCK_PATH, .cmd_unix_sock_path = DEFAULT_USTCONSUMERD32_CMD_SOCK_PATH, + .err_sock = -1, + .cmd_sock = -1, }; static int dispatch_thread_exit; @@ -295,14 +297,22 @@ static gid_t allowed_group(void) */ static int init_thread_quit_pipe(void) { - int ret; + int ret, i; - ret = pipe2(thread_quit_pipe, O_CLOEXEC); + ret = pipe(thread_quit_pipe); if (ret < 0) { PERROR("thread quit pipe"); goto error; } + for (i = 0; i < 2; i++) { + ret = fcntl(thread_quit_pipe[i], F_SETFD, FD_CLOEXEC); + if (ret < 0) { + PERROR("fcntl"); + goto error; + } + } + error: return ret; } @@ -324,7 +334,8 @@ static void teardown_kernel_session(struct ltt_session *session) * If a custom kernel consumer was registered, close the socket before * tearing down the complete kernel session structure */ - if (session->kernel_session->consumer_fd != kconsumer_data.cmd_sock) { + if (kconsumer_data.cmd_sock >= 0 && + session->kernel_session->consumer_fd != kconsumer_data.cmd_sock) { lttcomm_close_unix_sock(session->kernel_session->consumer_fd); } @@ -573,18 +584,18 @@ static int send_kconsumer_session_streams(struct consumer_data *consumer_data, DBG("Sending metadata stream fd"); - /* Extra protection. It's NOT supposed to be set to 0 at this point */ - if (session->consumer_fd == 0) { + /* Extra protection. It's NOT supposed to be set to -1 at this point */ + if (session->consumer_fd < 0) { session->consumer_fd = consumer_data->cmd_sock; } - if (session->metadata_stream_fd != 0) { + if (session->metadata_stream_fd >= 0) { /* Send metadata channel fd */ lkm.cmd_type = LTTNG_CONSUMER_ADD_CHANNEL; lkm.u.channel.channel_key = session->metadata->fd; lkm.u.channel.max_sb_size = session->metadata->conf->attr.subbuf_size; lkm.u.channel.mmap_len = 0; /* for kernel */ - DBG("Sending metadata channel %d to consumer", lkm.u.stream.stream_key); + DBG("Sending metadata channel %d to consumer", lkm.u.channel.channel_key); ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm)); if (ret < 0) { PERROR("send consumer channel"); @@ -752,8 +763,8 @@ static int update_kernel_stream(struct consumer_data *consumer_data, int fd) continue; } - /* This is not suppose to be 0 but this is an extra security check */ - if (session->kernel_session->consumer_fd == 0) { + /* This is not suppose to be -1 but this is an extra security check */ + if (session->kernel_session->consumer_fd < 0) { session->kernel_session->consumer_fd = consumer_data->cmd_sock; } @@ -1431,6 +1442,7 @@ static void *thread_registration_apps(void *data) } ust_cmd->sock = sock; + sock = -1; DBG("UST registration received with pid:%d ppid:%d uid:%d" " gid:%d sock:%d name:%s (version %d.%d)", @@ -1465,7 +1477,7 @@ error: PERROR("close"); } } - if (clock >= 0) { + if (sock >= 0) { ret = close(sock); if (ret) { PERROR("close"); @@ -1837,7 +1849,11 @@ error_open: error: WARN("No kernel tracer available"); kernel_tracer_fd = -1; - return LTTCOMM_KERN_NA; + if (!is_root) { + return LTTCOMM_NEED_ROOT_SESSIOND; + } else { + return LTTCOMM_KERN_NA; + } } /* @@ -1850,10 +1866,10 @@ static int init_kernel_tracing(struct ltt_kernel_session *session) if (session->consumer_fds_sent == 0) { /* * Assign default kernel consumer socket if no consumer assigned to the - * kernel session. At this point, it's NOT suppose to be 0 but this is + * kernel session. At this point, it's NOT supposed to be -1 but this is * an extra security check. */ - if (session->consumer_fd == 0) { + if (session->consumer_fd < 0) { session->consumer_fd = kconsumer_data.cmd_sock; } @@ -1941,7 +1957,7 @@ static int create_kernel_session(struct ltt_session *session) } /* Set kernel consumer socket fd */ - if (kconsumer_data.cmd_sock) { + if (kconsumer_data.cmd_sock >= 0) { session->kernel_session->consumer_fd = kconsumer_data.cmd_sock; } @@ -2830,7 +2846,8 @@ static int cmd_start_trace(struct ltt_session *session) usess = session->ust_session; if (session->enabled) { - ret = LTTCOMM_UST_START_FAIL; + /* Already started. */ + ret = LTTCOMM_TRACE_ALREADY_STARTED; goto error; } @@ -2850,7 +2867,7 @@ static int cmd_start_trace(struct ltt_session *session) } /* Open kernel metadata stream */ - if (ksession->metadata_stream_fd == 0) { + if (ksession->metadata_stream_fd < 0) { ret = kernel_open_metadata_stream(ksession); if (ret < 0) { ERR("Kernel create metadata stream failed"); @@ -2922,7 +2939,7 @@ static int cmd_stop_trace(struct ltt_session *session) usess = session->ust_session; if (!session->enabled) { - ret = LTTCOMM_UST_STOP_FAIL; + ret = LTTCOMM_TRACE_ALREADY_STOPPED; goto error; } @@ -2973,11 +2990,12 @@ error: /* * Command LTTNG_CREATE_SESSION processed by the client thread. */ -static int cmd_create_session(char *name, char *path, struct ucred *creds) +static int cmd_create_session(char *name, char *path, lttng_sock_cred *creds) { int ret; - ret = session_create(name, path, creds->uid, creds->gid); + ret = session_create(name, path, LTTNG_SOCK_GET_UID_CRED(creds), + LTTNG_SOCK_GET_GID_CRED(creds)); if (ret != LTTCOMM_OK) { goto error; } @@ -3246,7 +3264,11 @@ static int process_client_msg(struct command_ctx *cmd_ctx) if (opt_no_kernel && need_domain && cmd_ctx->lsm->domain.type == LTTNG_DOMAIN_KERNEL) { - ret = LTTCOMM_KERN_NA; + if (!is_root) { + ret = LTTCOMM_NEED_ROOT_SESSIOND; + } else { + ret = LTTCOMM_KERN_NA; + } goto error; } @@ -3281,9 +3303,13 @@ static int process_client_msg(struct command_ctx *cmd_ctx) break; default: DBG("Getting session %s by name", cmd_ctx->lsm->session.name); + /* + * We keep the session list lock across _all_ commands + * for now, because the per-session lock does not + * handle teardown properly. + */ session_lock_list(); cmd_ctx->session = session_find_by_name(cmd_ctx->lsm->session.name); - session_unlock_list(); if (cmd_ctx->session == NULL) { if (cmd_ctx->lsm->session.name != NULL) { ret = LTTCOMM_SESS_NOT_FOUND; @@ -3308,7 +3334,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: if (!is_root) { - ret = LTTCOMM_KERN_NA; + ret = LTTCOMM_NEED_ROOT_SESSIOND; goto error; } @@ -3403,7 +3429,8 @@ skip_domain: */ if (need_tracing_session) { if (!session_access_ok(cmd_ctx->session, - cmd_ctx->creds.uid, cmd_ctx->creds.gid)) { + LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds), + LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds))) { ret = LTTCOMM_EPERM; goto error; } @@ -3512,6 +3539,11 @@ skip_domain: { ret = cmd_destroy_session(cmd_ctx->session, cmd_ctx->lsm->session.name); + /* + * Set session to NULL so we do not unlock it after + * free. + */ + cmd_ctx->session = NULL; break; } case LTTNG_LIST_DOMAINS: @@ -3596,7 +3628,9 @@ skip_domain: unsigned int nr_sessions; session_lock_list(); - nr_sessions = lttng_sessions_count(cmd_ctx->creds.uid, cmd_ctx->creds.gid); + nr_sessions = lttng_sessions_count( + LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds), + LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds)); ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) * nr_sessions); if (ret < 0) { @@ -3606,7 +3640,8 @@ skip_domain: /* Filled the session array */ list_lttng_sessions((struct lttng_session *)(cmd_ctx->llm->payload), - cmd_ctx->creds.uid, cmd_ctx->creds.gid); + LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds), + LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds)); session_unlock_list(); @@ -3643,6 +3678,9 @@ setup_error: if (cmd_ctx->session) { session_unlock(cmd_ctx->session); } + if (need_tracing_session) { + session_unlock_list(); + } init_setup_error: return ret; } @@ -3772,7 +3810,7 @@ static void *thread_manage_clients(void *data) PERROR("close"); } sock = -1; - free(cmd_ctx); + clean_command_ctx(&cmd_ctx); continue; } @@ -3959,11 +3997,11 @@ static int parse_args(int argc, char **argv) opt_no_kernel = 1; break; case 'q': - opt_quiet = 1; + lttng_opt_quiet = 1; break; case 'v': /* Verbose level can increase using multiple -v */ - opt_verbose += 1; + lttng_opt_verbose += 1; break; case 'Z': opt_verbose_consumer += 1; @@ -4126,7 +4164,24 @@ end: */ static int create_kernel_poll_pipe(void) { - return pipe2(kernel_poll_pipe, O_CLOEXEC); + int ret, i; + + ret = pipe(kernel_poll_pipe); + if (ret < 0) { + PERROR("kernel poll pipe"); + goto error; + } + + for (i = 0; i < 2; i++) { + ret = fcntl(kernel_poll_pipe[i], F_SETFD, FD_CLOEXEC); + if (ret < 0) { + PERROR("fcntl kernel_poll_pipe"); + goto error; + } + } + +error: + return ret; } /* @@ -4135,7 +4190,24 @@ static int create_kernel_poll_pipe(void) */ static int create_apps_cmd_pipe(void) { - return pipe2(apps_cmd_pipe, O_CLOEXEC); + int ret, i; + + ret = pipe(apps_cmd_pipe); + if (ret < 0) { + PERROR("apps cmd pipe"); + goto error; + } + + for (i = 0; i < 2; i++) { + ret = fcntl(apps_cmd_pipe[i], F_SETFD, FD_CLOEXEC); + if (ret < 0) { + PERROR("fcntl apps_cmd_pipe"); + goto error; + } + } + +error: + return ret; } /* @@ -4192,10 +4264,11 @@ static int set_consumer_sockets(struct consumer_data *consumer_data, ret = mkdir(path, S_IRWXU); if (ret < 0) { if (errno != EEXIST) { + PERROR("mkdir"); ERR("Failed to create %s", path); goto error; } - ret = 0; + ret = -1; } /* Create the kconsumerd error unix socket */ @@ -4455,6 +4528,12 @@ int main(int argc, char **argv) goto error; } + /* + * Init UST app hash table. Alloc hash table before this point since + * cleanup() can get called after that point. + */ + ust_app_ht_alloc(); + /* After this point, we can safely call cleanup() with "goto exit" */ /* @@ -4520,9 +4599,6 @@ int main(int argc, char **argv) /* Init UST command queue. */ cds_wfq_init(&ust_cmd_queue.queue); - /* Init UST app hash table */ - ust_app_ht_alloc(); - /* * Get session list pointer. This pointer MUST NOT be free(). This list is * statically declared in session.c