X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Fmain.c;h=cbd6a3f3f6a7469ddc2be72fb5b313555bf37989;hp=5337d6df44781980c7cc77fd4211932fcf540de0;hb=333f285e479a22c99122aa92b988b10c597551e4;hpb=1d4b027abdef2dc52b41b05ec56c5046c5000c4c diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index 5337d6df4..cbd6a3f3f 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -45,6 +45,7 @@ #include "ust-ctl.h" #include "session.h" #include "traceable-app.h" +#include "lttng-kconsumerd.h" /* * TODO: @@ -55,7 +56,7 @@ /* Const values */ const char default_home_dir[] = DEFAULT_HOME_DIR; -const char default_tracing_group[] = DEFAULT_TRACING_GROUP; +const char default_tracing_group[] = LTTNG_DEFAULT_TRACING_GROUP; const char default_ust_sock_dir[] = DEFAULT_UST_SOCK_DIR; const char default_global_apps_pipe[] = DEFAULT_GLOBAL_APPS_PIPE; @@ -90,50 +91,6 @@ static sem_t kconsumerd_sem; static pthread_mutex_t kconsumerd_pid_mutex; /* Mutex to control kconsumerd pid assignation */ -/* - * free_kernel_session - * - * Free all data structure inside a kernel session and the session pointer. - */ -static void free_kernel_session(struct ltt_kernel_session *session) -{ - struct ltt_kernel_channel *chan; - struct ltt_kernel_stream *stream; - struct ltt_kernel_event *event; - - /* Clean metadata */ - close(session->metadata_stream_fd); - close(session->metadata->fd); - free(session->metadata->conf); - free(session->metadata); - - cds_list_for_each_entry(chan, &session->channel_list.head, list) { - /* Clean all event(s) */ - cds_list_for_each_entry(event, &chan->events_list.head, list) { - close(event->fd); - free(event->event); - free(event); - } - - /* Clean streams */ - cds_list_for_each_entry(stream, &chan->stream_list.head, list) { - close(stream->fd); - free(stream->pathname); - free(stream); - } - /* Clean channel */ - close(chan->fd); - free(chan->channel); - free(chan->pathname); - free(chan); - } - - close(session->fd); - free(session); - - DBG("All kernel session data structures freed"); -} - /* * teardown_kernel_session * @@ -144,7 +101,7 @@ static void teardown_kernel_session(struct ltt_session *session) { if (session->kernel_session != NULL) { DBG("Tearing down kernel session"); - free_kernel_session(session->kernel_session); + trace_destroy_kernel_session(session->kernel_session); /* Extra precaution */ session->kernel_session = NULL; /* Decrement session count */ @@ -375,6 +332,7 @@ static void *thread_manage_kconsumerd(void *data) goto error; } + /* Getting status code from kconsumerd */ ret = lttcomm_recv_unix_sock(sock, &code, sizeof(enum lttcomm_return_code)); if (ret <= 0) { goto error; @@ -383,6 +341,7 @@ static void *thread_manage_kconsumerd(void *data) if (code == KCONSUMERD_COMMAND_SOCK_READY) { kconsumerd_cmd_sock = lttcomm_connect_unix_sock(kconsumerd_cmd_unix_sock_path); if (kconsumerd_cmd_sock < 0) { + sem_post(&kconsumerd_sem); perror("kconsumerd connect"); goto error; } @@ -390,7 +349,7 @@ static void *thread_manage_kconsumerd(void *data) sem_post(&kconsumerd_sem); DBG("Kconsumerd command socket ready"); } else { - DBG("[sessiond] Kconsumerd error when waiting for SOCK_READY : %s", + DBG("Kconsumerd error when waiting for SOCK_READY : %s", lttcomm_get_readable_code(-code)); goto error; } @@ -398,7 +357,7 @@ static void *thread_manage_kconsumerd(void *data) /* Wait for any kconsumerd error */ ret = lttcomm_recv_unix_sock(sock, &code, sizeof(enum lttcomm_return_code)); if (ret <= 0) { - ERR("[sessiond] Kconsumerd closed the command socket"); + ERR("Kconsumerd closed the command socket"); goto error; } @@ -406,6 +365,7 @@ static void *thread_manage_kconsumerd(void *data) error: kconsumerd_pid = 0; + DBG("Kconsumerd thread dying"); return NULL; } @@ -477,12 +437,12 @@ error: } /* - * start_kconsumerd_thread + * spawn_kconsumerd_thread * * Start the thread_manage_kconsumerd. This must be done after a kconsumerd * exec or it will fails. */ -static int start_kconsumerd_thread(void) +static int spawn_kconsumerd_thread(void) { int ret; @@ -495,32 +455,45 @@ static int start_kconsumerd_thread(void) goto error; } + /* Wait for the kconsumerd thread to be ready */ sem_wait(&kconsumerd_sem); + if (kconsumerd_pid == 0) { + ERR("Kconsumerd did not start"); + goto error; + } + return 0; error: + ret = LTTCOMM_KERN_CONSUMER_FAIL; return ret; } /* - * kernel_start_consumer + * spawn_kconsumerd + * + * Fork and exec a kernel consumer daemon (kconsumerd). * - * Start a kernel consumer daemon (kconsumerd). + * NOTE: It is very important to fork a kconsumerd BEFORE opening any kernel + * file descriptor using the libkernelctl or kernel-ctl functions. So, a + * kernel consumer MUST only be spawned before creating a kernel session. * * Return pid if successful else -1. */ -pid_t kernel_start_consumer(void) +static pid_t spawn_kconsumerd(void) { int ret; pid_t pid; + DBG("Spawning kconsumerd"); + pid = fork(); if (pid == 0) { /* * Exec kconsumerd. */ - execlp("kconsumerd", "kconsumerd", "--daemonize", NULL); + execlp("kconsumerd", "kconsumerd", "--verbose", NULL); if (errno != 0) { perror("kernel start consumer exec"); } @@ -538,6 +511,49 @@ error: return ret; } +/* + * start_kconsumerd + * + * Spawn the kconsumerd daemon and session daemon thread. + */ +static int start_kconsumerd(void) +{ + int ret; + + pthread_mutex_lock(&kconsumerd_pid_mutex); + if (kconsumerd_pid != 0) { + goto end; + } + + ret = spawn_kconsumerd(); + if (ret < 0) { + ERR("Spawning kconsumerd failed"); + ret = LTTCOMM_KERN_CONSUMER_FAIL; + pthread_mutex_unlock(&kconsumerd_pid_mutex); + goto error; + } + + /* Setting up the global kconsumerd_pid */ + kconsumerd_pid = ret; + pthread_mutex_unlock(&kconsumerd_pid_mutex); + + DBG("Kconsumerd pid %d", ret); + + DBG("Spawning kconsumerd thread"); + ret = spawn_kconsumerd_thread(); + if (ret < 0) { + ERR("Fatal error spawning kconsumerd thread"); + goto error; + } + +end: + pthread_mutex_unlock(&kconsumerd_pid_mutex); + return 0; + +error: + return ret; +} + /* * send_kconsumerd_fds * @@ -545,36 +561,18 @@ error: */ static int send_kconsumerd_fds(int sock, struct ltt_kernel_session *session) { - int ret, i = 0; - /* Plus one here for the metadata fd */ - size_t nb_fd = session->stream_count_global + 1; - int fds[nb_fd]; + int ret; + size_t nb_fd; struct ltt_kernel_stream *stream; struct ltt_kernel_channel *chan; struct lttcomm_kconsumerd_header lkh; - struct lttcomm_kconsumerd_msg buf[nb_fd]; + struct lttcomm_kconsumerd_msg lkm; - /* Add metadata data */ - fds[i] = session->metadata_stream_fd; - buf[i].fd = fds[i]; - buf[i].state = ACTIVE_FD; - buf[i].max_sb_size = session->metadata->conf->subbuf_size; - strncpy(buf[i].path_name, session->metadata->pathname, PATH_MAX); - - cds_list_for_each_entry(chan, &session->channel_list.head, list) { - cds_list_for_each_entry(stream, &chan->stream_list.head, list) { - i++; - fds[i] = stream->fd; - buf[i].fd = stream->fd; - buf[i].state = stream->state; - buf[i].max_sb_size = chan->channel->subbuf_size; - strncpy(buf[i].path_name, stream->pathname, PATH_MAX); - } - } + nb_fd = session->stream_count_global; /* Setup header */ - lkh.payload_size = nb_fd * sizeof(struct lttcomm_kconsumerd_msg); - lkh.cmd_type = LTTCOMM_ADD_STREAM; + lkh.payload_size = (nb_fd + 1) * sizeof(struct lttcomm_kconsumerd_msg); + lkh.cmd_type = ADD_STREAM; DBG("Sending kconsumerd header"); @@ -584,14 +582,37 @@ static int send_kconsumerd_fds(int sock, struct ltt_kernel_session *session) goto error; } - DBG("Sending all fds to kconsumerd"); + DBG("Sending metadata stream fd"); - ret = lttcomm_send_fds_unix_sock(sock, buf, fds, nb_fd, lkh.payload_size); + /* Send metadata stream fd first */ + lkm.fd = session->metadata_stream_fd; + lkm.state = ACTIVE_FD; + lkm.max_sb_size = session->metadata->conf->subbuf_size; + strncpy(lkm.path_name, session->metadata->pathname, PATH_MAX); + + ret = lttcomm_send_fds_unix_sock(sock, &lkm, &lkm.fd, 1, sizeof(lkm)); if (ret < 0) { - perror("send kconsumerd fds"); + perror("send kconsumerd fd"); goto error; } + cds_list_for_each_entry(chan, &session->channel_list.head, list) { + cds_list_for_each_entry(stream, &chan->stream_list.head, list) { + lkm.fd = stream->fd; + lkm.state = stream->state; + lkm.max_sb_size = chan->channel->subbuf_size; + strncpy(lkm.path_name, stream->pathname, PATH_MAX); + + DBG("Sending fd %d to kconsumerd", lkm.fd); + + ret = lttcomm_send_fds_unix_sock(sock, &lkm, &lkm.fd, 1, sizeof(lkm)); + if (ret < 0) { + perror("send kconsumerd fd"); + goto error; + } + } + } + DBG("Kconsumerd fds sent"); return 0; @@ -612,6 +633,7 @@ static int create_trace_dir(struct ltt_kernel_session *session) /* Create all channel directories */ cds_list_for_each_entry(chan, &session->channel_list.head, list) { + DBG("Creating trace directory at %s", chan->pathname); ret = mkdir(chan->pathname, S_IRWXU | S_IRWXG ); if (ret < 0) { perror("mkdir trace path"); @@ -626,6 +648,22 @@ error: return ret; } +/* + * init_kernel_tracer + * + * Setup necessary data for kernel tracer action. + */ +static void init_kernel_tracer(void) +{ + /* Set the global kernel tracer fd */ + kernel_tracer_fd = open(DEFAULT_KERNEL_TRACER_PATH, O_RDWR); + if (kernel_tracer_fd < 0) { + WARN("No kernel tracer available"); + kernel_tracer_fd = 0; + } + + DBG("Kernel tracer fd %d", kernel_tracer_fd); +} /* * process_client_msg @@ -646,6 +684,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->cmd_type) { case LTTNG_CREATE_SESSION: case LTTNG_LIST_SESSIONS: + case KERNEL_LIST_EVENTS: case UST_LIST_APPS: break; default: @@ -664,14 +703,17 @@ static int process_client_msg(struct command_ctx *cmd_ctx) case KERNEL_CREATE_STREAM: case KERNEL_DISABLE_EVENT: case KERNEL_ENABLE_EVENT: + case KERNEL_LIST_EVENTS: case KERNEL_OPEN_METADATA: case KERNEL_START_TRACE: case KERNEL_STOP_TRACE: - /* TODO: reconnect to kernel tracer to check if - * it's loadded */ + /* Kernel tracer check */ if (kernel_tracer_fd == 0) { - ret = LTTCOMM_KERN_NA; - goto error; + init_kernel_tracer(); + if (kernel_tracer_fd == 0) { + ret = LTTCOMM_KERN_NA; + goto error; + } } break; } @@ -695,26 +737,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_error; } - DBG("Checking if kconsumerd is alive"); - pthread_mutex_lock(&kconsumerd_pid_mutex); - if (kconsumerd_pid == 0) { - ret = kernel_start_consumer(); - if (ret < 0) { - ERR("Kernel start kconsumerd failed"); - ret = LTTCOMM_KERN_CONSUMER_FAIL; - pthread_mutex_unlock(&kconsumerd_pid_mutex); - goto error; - } - - /* Setting up the global kconsumerd_pid */ - kconsumerd_pid = ret; - } - pthread_mutex_unlock(&kconsumerd_pid_mutex); - - ret = start_kconsumerd_thread(); + ret = start_kconsumerd(); if (ret < 0) { - ERR("Fatal error : start_kconsumerd_thread()"); - ret = LTTCOMM_FATAL; goto error; } @@ -767,6 +791,71 @@ static int process_client_msg(struct command_ctx *cmd_ctx) ret = LTTCOMM_OK; break; } + case KERNEL_ENABLE_ALL_EVENT: + { + int pos, size; + char *event_list, *event, *ptr; + + /* Setup lttng message with no payload */ + ret = setup_lttng_msg(cmd_ctx, 0); + if (ret < 0) { + goto setup_error; + } + + DBG("Enabling all kernel event"); + + size = kernel_list_events(kernel_tracer_fd, &event_list); + if (size < 0) { + ret = LTTCOMM_KERN_LIST_FAIL; + goto error; + } + + ptr = event_list; + while ((size = sscanf(ptr, "event { name = %m[^;]; };%n\n", &event, &pos)) == 1) { + /* Enable each single event */ + ret = kernel_enable_event(cmd_ctx->session->kernel_session, event); + if (ret < 0) { + ret = LTTCOMM_KERN_ENABLE_FAIL; + goto error; + } + /* Move pointer to the next line */ + ptr += pos + 1; + free(event); + } + + free(event_list); + + ret = LTTCOMM_OK; + break; + } + case KERNEL_LIST_EVENTS: + { + char *event_list; + ssize_t size; + + size = kernel_list_events(kernel_tracer_fd, &event_list); + if (size < 0) { + ret = LTTCOMM_KERN_LIST_FAIL; + goto error; + } + + /* + * Setup lttng message with payload size set to the event list size in + * bytes and then copy list into the llm payload. + */ + ret = setup_lttng_msg(cmd_ctx, size); + if (ret < 0) { + goto setup_error; + } + + /* Copy event list into message payload */ + memcpy(cmd_ctx->llm->payload, event_list, size); + + free(event_list); + + ret = LTTCOMM_OK; + break; + } case KERNEL_OPEN_METADATA: { /* Setup lttng message with no payload */ @@ -864,6 +953,11 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_error; } + if (cmd_ctx->session->kernel_session == NULL) { + ret = LTTCOMM_KERN_NO_SESSION; + goto error; + } + DBG("Stop kernel tracing"); ret = kernel_stop_session(cmd_ctx->session->kernel_session); @@ -1126,6 +1220,9 @@ static void *thread_manage_clients(void *data) } clean_command_ctx(cmd_ctx); + + /* End of transmission */ + close(sock); } error: @@ -1382,31 +1479,18 @@ static int create_lttng_rundir(void) ret = mkdir(LTTNG_RUNDIR, S_IRWXU | S_IRWXG ); if (ret < 0) { - ERR("Unable to create " LTTNG_RUNDIR); - goto error; + if (errno != EEXIST) { + ERR("Unable to create " LTTNG_RUNDIR); + goto error; + } else { + ret = 0; + } } error: return ret; } -/* - * init_kernel_tracer - * - * Setup necessary data for kernel tracer action. - */ -static void init_kernel_tracer(void) -{ - /* Set the global kernel tracer fd */ - kernel_tracer_fd = open(DEFAULT_KERNEL_TRACER_PATH, O_RDWR); - if (kernel_tracer_fd < 0) { - WARN("No kernel tracer available"); - kernel_tracer_fd = 0; - } - - DBG("Kernel tracer fd %d", kernel_tracer_fd); -} - /* * set_kconsumerd_sockets *