X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Fmain.c;h=abd4e087fd313c11fea10376393b32e9f6c29e5c;hp=5a73b68dfed46fb8c1878725b3727bb2c16e2787;hb=72079caee725ad8d3ec0dc52fe7f982d61721b84;hpb=8b270bdb4dccf5571180a9906084126e90eec949 diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index 5a73b68df..abd4e087f 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -41,6 +41,7 @@ #include /* URCU list library (-lurcu) */ #include +#include #include #include "context.h" @@ -50,7 +51,7 @@ #include "ust-ctl.h" #include "session.h" #include "traceable-app.h" -#include "lttng-kconsumerd.h" +#include "ltt-kconsumerd.h" #include "utils.h" /* Const values */ @@ -158,6 +159,15 @@ static void teardown_kernel_session(struct ltt_session *session) { if (session->kernel_session != NULL) { DBG("Tearing down kernel 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 != kconsumerd_cmd_sock) { + lttcomm_close_unix_sock(session->kernel_session->consumer_fd); + } + trace_destroy_kernel_session(session->kernel_session); /* Extra precaution */ session->kernel_session = NULL; @@ -288,7 +298,7 @@ static int send_kconsumerd_channel_fds(int sock, struct ltt_kernel_channel *chan lkm.fd = stream->fd; lkm.state = stream->state; lkm.max_sb_size = channel->channel->attr.subbuf_size; - lkm.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; + lkm.output = channel->channel->attr.output; strncpy(lkm.path_name, stream->pathname, PATH_MAX); lkm.path_name[PATH_MAX - 1] = '\0'; @@ -313,7 +323,7 @@ error: /* * Send all stream fds of the kernel session to the consumer. */ -static int send_kconsumerd_fds(int sock, struct ltt_kernel_session *session) +static int send_kconsumerd_fds(struct ltt_kernel_session *session) { int ret; struct ltt_kernel_channel *chan; @@ -326,7 +336,7 @@ static int send_kconsumerd_fds(int sock, struct ltt_kernel_session *session) DBG("Sending kconsumerd header for metadata"); - ret = lttcomm_send_unix_sock(sock, &lkh, sizeof(struct lttcomm_kconsumerd_header)); + ret = lttcomm_send_unix_sock(session->consumer_fd, &lkh, sizeof(struct lttcomm_kconsumerd_header)); if (ret < 0) { perror("send kconsumerd header"); goto error; @@ -334,6 +344,11 @@ static int send_kconsumerd_fds(int sock, struct ltt_kernel_session *session) DBG("Sending metadata stream fd"); + /* Extra protection. It's NOT suppose to be set to 0 at this point */ + if (session->consumer_fd == 0) { + session->consumer_fd = kconsumerd_cmd_sock; + } + if (session->metadata_stream_fd != 0) { /* Send metadata stream fd first */ lkm.fd = session->metadata_stream_fd; @@ -343,7 +358,7 @@ static int send_kconsumerd_fds(int sock, struct ltt_kernel_session *session) strncpy(lkm.path_name, session->metadata->pathname, PATH_MAX); lkm.path_name[PATH_MAX - 1] = '\0'; - ret = lttcomm_send_fds_unix_sock(sock, &lkm, &lkm.fd, 1, sizeof(lkm)); + ret = lttcomm_send_fds_unix_sock(session->consumer_fd, &lkm, &lkm.fd, 1, sizeof(lkm)); if (ret < 0) { perror("send kconsumerd fd"); goto error; @@ -351,7 +366,7 @@ static int send_kconsumerd_fds(int sock, struct ltt_kernel_session *session) } cds_list_for_each_entry(chan, &session->channel_list.head, list) { - ret = send_kconsumerd_channel_fds(sock, chan); + ret = send_kconsumerd_channel_fds(session->consumer_fd, chan); if (ret < 0) { goto error; } @@ -550,6 +565,12 @@ static int update_kernel_stream(int fd) unlock_session(session); continue; } + + /* This is not suppose to be 0 but this is an extra security check */ + if (session->kernel_session->consumer_fd == 0) { + session->kernel_session->consumer_fd = kconsumerd_cmd_sock; + } + cds_list_for_each_entry(channel, &session->kernel_session->channel_list.head, list) { if (channel->fd == fd) { DBG("Channel found, updating kernel streams"); @@ -557,12 +578,14 @@ static int update_kernel_stream(int fd) if (ret < 0) { goto end; } + /* * Have we already sent fds to the consumer? If yes, it means that * tracing is started so it is safe to send our updated stream fds. */ if (session->kernel_session->kconsumer_fds_sent == 1) { - ret = send_kconsumerd_channel_fds(kconsumerd_cmd_sock, channel); + ret = send_kconsumerd_channel_fds(session->kernel_session->consumer_fd, + channel); if (ret < 0) { goto end; } @@ -730,6 +753,25 @@ static void *thread_manage_kconsumerd(void *data) goto error; } + /* Kconsumerd err socket */ + pollfd[1].fd = sock; + pollfd[1].events = POLLIN; + + /* Inifinite blocking call, waiting for transmission */ + ret = poll(pollfd, 2, -1); + if (ret < 0) { + perror("poll kconsumerd thread"); + goto error; + } + + /* Thread quit pipe has been closed. Killing thread. */ + if (pollfd[0].revents == POLLNVAL) { + goto error; + } else if (pollfd[1].revents == POLLERR) { + ERR("Kconsumerd err socket second poll error"); + goto error; + } + /* Wait for any kconsumerd error */ ret = lttcomm_recv_unix_sock(sock, &code, sizeof(enum lttcomm_return_code)); if (ret <= 0) { @@ -887,6 +929,9 @@ error: return ret; } +/* + * Join kernel consumer thread + */ static int join_kconsumerd_thread(void) { void *status; @@ -1009,7 +1054,7 @@ static int modprobe_kernel_modules(void) ERR("Unable to launch modprobe for module %s", kernel_modules_list[i].name); } else if (kernel_modules_list[i].required - && WEXITSTATUS(ret) != 0) { + && WEXITSTATUS(ret) != 0) { ERR("Unable to load module %s", kernel_modules_list[i].name); } else { @@ -1045,7 +1090,7 @@ static int modprobe_remove_kernel_modules(void) ERR("Unable to launch modprobe --remove for module %s", kernel_modules_list[i].name); } else if (kernel_modules_list[i].required - && WEXITSTATUS(ret) != 0) { + && WEXITSTATUS(ret) != 0) { ERR("Unable to remove module %s", kernel_modules_list[i].name); } else { @@ -1173,7 +1218,16 @@ static int start_kernel_trace(struct ltt_kernel_session *session) int ret = 0; if (session->kconsumer_fds_sent == 0) { - ret = send_kconsumerd_fds(kconsumerd_cmd_sock, session); + /* + * Assign default kernel consumer if no consumer assigned to the kernel + * session. At this point, it's NOT suppose to be 0 but this is an extra + * security check. + */ + if (session->consumer_fd == 0) { + session->consumer_fd = kconsumerd_cmd_sock; + } + + ret = send_kconsumerd_fds(session); if (ret < 0) { ERR("Send kconsumerd fds failed"); ret = LTTCOMM_KERN_CONSUMER_FAIL; @@ -1206,7 +1260,8 @@ static int notify_kernel_pollfd(void) /* * Allocate a channel structure and fill it. */ -static struct lttng_channel *init_default_channel(char *name) +static struct lttng_channel *init_default_channel(enum lttng_domain_type domain_type, + char *name) { struct lttng_channel *chan; @@ -1218,18 +1273,29 @@ static struct lttng_channel *init_default_channel(char *name) if (snprintf(chan->name, NAME_MAX, "%s", name) < 0) { perror("snprintf channel name"); - return NULL; + goto error; } chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - chan->attr.subbuf_size = DEFAULT_CHANNEL_SUBBUF_SIZE; - chan->attr.num_subbuf = DEFAULT_CHANNEL_SUBBUF_NUM; chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; -error: + switch (domain_type) { + case LTTNG_DOMAIN_KERNEL: + chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; + chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; + break; + /* TODO: add UST */ + default: + goto error; /* Not implemented */ + } + return chan; + +error: + free(chan); + return NULL; } /* @@ -1247,6 +1313,11 @@ static int create_kernel_session(struct ltt_session *session) goto error; } + /* Set kernel consumer socket fd */ + if (kconsumerd_cmd_sock) { + session->kernel_session->consumer_fd = kconsumerd_cmd_sock; + } + ret = asprintf(&session->kernel_session->trace_path, "%s/kernel", session->path); if (ret < 0) { @@ -1412,10 +1483,10 @@ static int process_client_msg(struct command_ctx *cmd_ctx) /* Need a session for kernel command */ switch (cmd_ctx->lsm->cmd_type) { + case LTTNG_CALIBRATE: case LTTNG_CREATE_SESSION: case LTTNG_LIST_SESSIONS: case LTTNG_LIST_TRACEPOINTS: - case LTTNG_CALIBRATE: break; default: if (cmd_ctx->session->kernel_session == NULL) { @@ -1426,7 +1497,9 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } /* Start the kernel consumer daemon */ - if (kconsumerd_pid == 0) { + + if (kconsumerd_pid == 0 && + cmd_ctx->lsm->cmd_type != LTTNG_REGISTER_CONSUMER) { ret = start_kconsumerd(); if (ret < 0) { goto error; @@ -1671,26 +1744,32 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: - do { + kchan = get_kernel_channel_by_name(channel_name, + cmd_ctx->session->kernel_session); + if (kchan == NULL) { + DBG("Channel not found. Creating channel %s", channel_name); + + chan = init_default_channel(cmd_ctx->lsm->domain.type, channel_name); + if (chan == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + + ret = kernel_create_channel(cmd_ctx->session->kernel_session, + chan, cmd_ctx->session->kernel_session->trace_path); + if (ret < 0) { + ret = LTTCOMM_KERN_CHAN_FAIL; + goto error; + } kchan = get_kernel_channel_by_name(channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { - DBG("Channel not found. Creating channel %s", channel_name); - - chan = init_default_channel(channel_name); - if (chan == NULL) { - ret = LTTCOMM_FATAL; - goto error; - } - - ret = kernel_create_channel(cmd_ctx->session->kernel_session, - chan, cmd_ctx->session->kernel_session->trace_path); - if (ret < 0) { - ret = LTTCOMM_KERN_CHAN_FAIL; - goto error; - } + ERR("Channel %s not found after creation. Internal error, giving up.", + channel_name); + ret = LTTCOMM_FATAL; + goto error; } - } while (kchan == NULL); + } kevent = get_kernel_event_by_name(cmd_ctx->lsm->u.enable.event.name, kchan); if (kevent == NULL) { @@ -1743,26 +1822,32 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: - do { + kchan = get_kernel_channel_by_name(channel_name, + cmd_ctx->session->kernel_session); + if (kchan == NULL) { + DBG("Channel not found. Creating channel %s", channel_name); + + chan = init_default_channel(cmd_ctx->lsm->domain.type, channel_name); + if (chan == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + + ret = kernel_create_channel(cmd_ctx->session->kernel_session, + chan, cmd_ctx->session->kernel_session->trace_path); + if (ret < 0) { + ret = LTTCOMM_KERN_CHAN_FAIL; + goto error; + } kchan = get_kernel_channel_by_name(channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { - DBG("Channel not found. Creating channel %s", channel_name); - - chan = init_default_channel(channel_name); - if (chan == NULL) { - ret = LTTCOMM_FATAL; - goto error; - } - - ret = kernel_create_channel(cmd_ctx->session->kernel_session, - chan, cmd_ctx->session->kernel_session->trace_path); - if (ret < 0) { - ret = LTTCOMM_KERN_CHAN_FAIL; - goto error; - } + ERR("Channel %s not found after creation. Internal error, giving up.", + channel_name); + ret = LTTCOMM_FATAL; + goto error; } - } while (kchan == NULL); + } /* For each event in the kernel session */ cds_list_for_each_entry(kevent, &kchan->events_list.head, list) { @@ -1895,16 +1980,16 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } } - DBG("Start kernel tracing"); - ret = kernel_start_session(cmd_ctx->session->kernel_session); + ret = start_kernel_trace(cmd_ctx->session->kernel_session); if (ret < 0) { - ERR("Kernel start session failed"); ret = LTTCOMM_KERN_START_FAIL; goto error; } - ret = start_kernel_trace(cmd_ctx->session->kernel_session); + DBG("Start kernel tracing"); + ret = kernel_start_session(cmd_ctx->session->kernel_session); if (ret < 0) { + ERR("Kernel start session failed"); ret = LTTCOMM_KERN_START_FAIL; goto error; } @@ -2113,7 +2198,6 @@ static int process_client_msg(struct command_ctx *cmd_ctx) ret = LTTCOMM_OK; break; } - case LTTNG_CALIBRATE: { /* Setup lttng message with no payload */ @@ -2143,6 +2227,43 @@ static int process_client_msg(struct command_ctx *cmd_ctx) ret = LTTCOMM_OK; break; } + case LTTNG_REGISTER_CONSUMER: + { + int sock; + + /* Setup lttng message with no payload */ + ret = setup_lttng_msg(cmd_ctx, 0); + if (ret < 0) { + goto setup_error; + } + + switch (cmd_ctx->lsm->domain.type) { + case LTTNG_DOMAIN_KERNEL: + { + /* Can't register a consumer if there is already one */ + if (cmd_ctx->session->kernel_session->consumer_fd != 0) { + ret = LTTCOMM_CONNECT_FAIL; + goto error; + } + + sock = lttcomm_connect_unix_sock(cmd_ctx->lsm->u.reg.path); + if (sock < 0) { + ret = LTTCOMM_CONNECT_FAIL; + goto error; + } + + cmd_ctx->session->kernel_session->consumer_fd = sock; + break; + } + default: + /* TODO: Userspace tracing */ + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; + } + + ret = LTTCOMM_OK; + break; + } default: /* Undefined command */