X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Fmain.c;h=8c09339aba2c80d79f60fdb88afbf4481b3ee1e5;hp=5a0ad0b8aaaca228b3cb27efaedbd881fe8a1210;hb=4c93ba8b8e253ffa3943f4999bd912b535c40b88;hpb=0133c1990185d0374ec06a751da23b7a84c54d78 diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index 5a0ad0b8a..8c09339ab 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -50,7 +50,7 @@ #include "kernel-ctl.h" #include "ltt-sessiond.h" #include "shm.h" -#include "traceable-app.h" +#include "ust-app.h" #include "ust-ctl.h" #include "utils.h" #include "ust-ctl.h" @@ -344,7 +344,7 @@ static void cleanup(void) } DBG("Closing all UST sockets"); - clean_traceable_apps_list(); + ust_app_clean_list(); pthread_mutex_destroy(&kconsumerd_pid_mutex); @@ -701,6 +701,12 @@ static void *thread_manage_kernel(void *data) while (1) { if (update_poll_flag == 1) { + /* + * Reset number of fd in the poll set. Always 2 since there is the thread + * quit pipe and the kernel pipe. + */ + events.nb_fd = 2; + ret = update_kernel_poll(&events); if (ret < 0) { goto error; @@ -836,6 +842,8 @@ static void *thread_manage_kconsumerd(void *data) goto error; } + DBG2("Receiving code from kconsumerd_err_sock"); + /* Getting status code from kconsumerd */ ret = lttcomm_recv_unix_sock(sock, &code, sizeof(enum lttcomm_return_code)); @@ -855,7 +863,7 @@ static void *thread_manage_kconsumerd(void *data) sem_post(&kconsumerd_sem); DBG("Kconsumerd command socket ready"); } else { - DBG("Kconsumerd error when waiting for SOCK_READY : %s", + ERR("Kconsumerd error when waiting for SOCK_READY : %s", lttcomm_get_readable_code(-code)); goto error; } @@ -986,7 +994,7 @@ static void *thread_manage_apps(void *data) } /* Register applicaton to the session daemon */ - ret = register_traceable_app(&ust_cmd.reg_msg, + ret = ust_app_register(&ust_cmd.reg_msg, ust_cmd.sock); if (ret < 0) { /* Only critical ENOMEM error can be returned here */ @@ -999,7 +1007,7 @@ static void *thread_manage_apps(void *data) * If the registration is not possible, we simply * unregister the apps and continue */ - unregister_traceable_app(ust_cmd.sock); + ust_app_unregister(ust_cmd.sock); } else { /* * We just need here to monitor the close of the UST @@ -1028,7 +1036,7 @@ static void *thread_manage_apps(void *data) } /* Socket closed */ - unregister_traceable_app(pollfd); + ust_app_unregister(pollfd); break; } } @@ -1257,29 +1265,66 @@ error: static int spawn_kconsumerd_thread(void) { int ret; + struct timespec timeout; + + timeout.tv_sec = DEFAULT_SEM_WAIT_TIMEOUT; + timeout.tv_nsec = 0; /* Setup semaphore */ - sem_init(&kconsumerd_sem, 0, 0); + ret = sem_init(&kconsumerd_sem, 0, 0); + if (ret < 0) { + PERROR("sem_init kconsumerd_sem"); + goto error; + } ret = pthread_create(&kconsumerd_thread, NULL, thread_manage_kconsumerd, (void *) NULL); if (ret != 0) { - perror("pthread_create kconsumerd"); + PERROR("pthread_create kconsumerd"); + ret = -1; goto error; } - /* Wait for the kconsumerd thread to be ready */ - sem_wait(&kconsumerd_sem); + /* Get time for sem_timedwait absolute timeout */ + ret = clock_gettime(CLOCK_REALTIME, &timeout); + if (ret < 0) { + PERROR("clock_gettime spawn kconsumerd"); + /* Infinite wait for the kconsumerd thread to be ready */ + ret = sem_wait(&kconsumerd_sem); + } else { + /* Normal timeout if the gettime was successful */ + timeout.tv_sec += DEFAULT_SEM_WAIT_TIMEOUT; + ret = sem_timedwait(&kconsumerd_sem, &timeout); + } + + if (ret < 0) { + if (errno == ETIMEDOUT) { + /* + * Call has timed out so we kill the kconsumerd_thread and return + * an error. + */ + ERR("The kconsumerd thread was never ready. Killing it"); + ret = pthread_cancel(kconsumerd_thread); + if (ret < 0) { + PERROR("pthread_cancel kconsumerd_thread"); + } + } else { + PERROR("semaphore wait failed kconsumerd thread"); + } + goto error; + } + pthread_mutex_lock(&kconsumerd_pid_mutex); if (kconsumerd_pid == 0) { ERR("Kconsumerd did not start"); + pthread_mutex_unlock(&kconsumerd_pid_mutex); goto error; } + pthread_mutex_unlock(&kconsumerd_pid_mutex); return 0; error: - ret = LTTCOMM_KERN_CONSUMER_FAIL; return ret; } @@ -1361,18 +1406,16 @@ static int start_kconsumerd(void) 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; + DBG2("Kconsumerd pid %d", kconsumerd_pid); pthread_mutex_unlock(&kconsumerd_pid_mutex); - DBG("Kconsumerd pid %d", ret); - - DBG("Spawning kconsumerd thread"); + DBG2("Spawning kconsumerd thread"); ret = spawn_kconsumerd_thread(); if (ret < 0) { ERR("Fatal error spawning kconsumerd thread"); @@ -1432,12 +1475,13 @@ static int mount_debugfs(char *path) ret = mkdir_recursive(path, S_IRWXU | S_IRWXG, geteuid(), getegid()); if (ret < 0) { + PERROR("Cannot create debugfs path"); goto error; } ret = mount(type, path, type, 0, NULL); if (ret < 0) { - perror("mount debugfs"); + PERROR("Cannot mount debugfs"); goto error; } @@ -1455,7 +1499,7 @@ static void init_kernel_tracer(void) int ret; char *proc_mounts = "/proc/mounts"; char line[256]; - char *debugfs_path = NULL, *lttng_path; + char *debugfs_path = NULL, *lttng_path = NULL; FILE *fp; /* Detect debugfs */ @@ -1487,6 +1531,7 @@ static void init_kernel_tracer(void) } ret = mount_debugfs(debugfs_path); if (ret < 0) { + perror("Cannot mount debugfs"); goto error; } } @@ -1561,15 +1606,31 @@ error: /* * Create an UST session and add it to the session ust list. */ -static int create_ust_session(pid_t pid, struct ltt_session *session) +static int create_ust_session(struct ltt_session *session, + struct lttng_domain *domain) { - int ret = -1; - struct ltt_ust_session *lus; + int ret; + struct ltt_ust_session *lus = NULL; + struct ust_app *app; + + switch (domain->type) { + case LTTNG_DOMAIN_UST_PID: + app = ust_app_get_by_pid(domain->attr.pid); + if (app == NULL) { + ret = LTTCOMM_APP_NOT_FOUND; + goto error; + } + break; + default: + ret = LTTCOMM_UNKNOWN_DOMAIN; + goto error; + } DBG("Creating UST session"); - lus = trace_ust_create_session(session->path, pid); + lus = trace_ust_create_session(session->path, domain->attr.pid, domain); if (lus == NULL) { + ret = LTTCOMM_UST_SESS_FAIL; goto error; } @@ -1578,17 +1639,22 @@ static int create_ust_session(pid_t pid, struct ltt_session *session) if (ret < 0) { if (ret != -EEXIST) { ERR("Trace directory creation error"); + ret = LTTCOMM_UST_SESS_FAIL; goto error; } } /* Create session on the UST tracer */ - ret = ustctl_create_session(lus); + ret = ustctl_create_session(app->sock, lus); if (ret < 0) { + ret = LTTCOMM_UST_SESS_FAIL; goto error; } - return 0; + cds_list_add(&lus->list, &session->ust_session_list.head); + session->ust_session_list.count++; + + return LTTCOMM_OK; error: free(lus); @@ -1716,8 +1782,11 @@ static void list_lttng_events(struct ltt_kernel_channel *kchan, case LTTNG_KERNEL_NOOP: events[i].type = LTTNG_EVENT_NOOP; break; - case LTTNG_KERNEL_SYSCALLS: - events[i].type = LTTNG_EVENT_SYSCALLS; + case LTTNG_KERNEL_SYSCALL: + events[i].type = LTTNG_EVENT_SYSCALL; + break; + case LTTNG_KERNEL_ALL: + assert(0); break; } i++; @@ -1742,9 +1811,10 @@ static int cmd_disable_channel(struct ltt_session *session, kernel_wait_quiescent(kernel_tracer_fd); break; + case LTTNG_DOMAIN_UST_PID: + break; default: - /* TODO: Userspace tracing */ - ret = LTTCOMM_NOT_IMPLEMENTED; + ret = LTTCOMM_UNKNOWN_DOMAIN; goto error; } @@ -1754,36 +1824,115 @@ error: return ret; } +/* + * Copy channel from attributes and set it in the application channel list. + */ +static int copy_ust_channel_to_app(struct ltt_ust_session *usess, + struct lttng_channel *attr, struct ust_app *app) +{ + int ret; + struct ltt_ust_channel *uchan, *new_chan; + + uchan = trace_ust_get_channel_by_name(attr->name, usess); + if (uchan == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + + new_chan = trace_ust_create_channel(attr, usess->path); + if (new_chan == NULL) { + PERROR("malloc ltt_ust_channel"); + ret = LTTCOMM_FATAL; + goto error; + } + + ret = channel_ust_copy(new_chan, uchan); + if (ret < 0) { + ret = LTTCOMM_FATAL; + goto error; + } + + /* Add channel to the ust app channel list */ + cds_list_add(&new_chan->list, &app->channels.head); + app->channels.count++; + +error: + return ret; +} + /* * Command LTTNG_ENABLE_CHANNEL processed by the client thread. */ -static int cmd_enable_channel(struct ltt_session *session, int domain, - char *channel_name, struct lttng_channel *attr) +static int cmd_enable_channel(struct ltt_session *session, + struct lttng_domain *domain, struct lttng_channel *attr) { int ret; - struct ltt_kernel_channel *kchan; - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - kchan = trace_kernel_get_channel_by_name(channel_name, - session->kernel_session); - if (kchan == NULL) { - ret = channel_kernel_create(session->kernel_session, - channel_name, attr, kernel_poll_pipe[1]); - } else { - ret = channel_kernel_enable(session->kernel_session, kchan); - } + switch (domain->type) { + case LTTNG_DOMAIN_KERNEL: + { + struct ltt_kernel_channel *kchan; - if (ret != LTTCOMM_OK) { - goto error; - } + kchan = trace_kernel_get_channel_by_name(attr->name, + session->kernel_session); + if (kchan == NULL) { + ret = channel_kernel_create(session->kernel_session, + attr, kernel_poll_pipe[1]); + } else { + ret = channel_kernel_enable(session->kernel_session, kchan); + } - kernel_wait_quiescent(kernel_tracer_fd); - break; - default: - /* TODO: Userspace tracing */ - ret = LTTCOMM_NOT_IMPLEMENTED; + if (ret != LTTCOMM_OK) { + goto error; + } + + kernel_wait_quiescent(kernel_tracer_fd); + break; + } + case LTTNG_DOMAIN_UST_PID: + { + int sock; + struct ltt_ust_channel *uchan; + struct ltt_ust_session *usess; + struct ust_app *app; + + usess = trace_ust_get_session_by_pid(&session->ust_session_list, + domain->attr.pid); + if (usess == NULL) { + ret = LTTCOMM_UST_CHAN_NOT_FOUND; + goto error; + } + + app = ust_app_get_by_pid(domain->attr.pid); + if (app == NULL) { + ret = LTTCOMM_APP_NOT_FOUND; + goto error; + } + sock = app->sock; + + uchan = trace_ust_get_channel_by_name(attr->name, usess); + if (uchan == NULL) { + ret = channel_ust_create(usess, attr, sock); + } else { + ret = channel_ust_enable(usess, uchan, sock); + } + + if (ret != LTTCOMM_OK) { + goto error; + } + + ret = copy_ust_channel_to_app(usess, attr, app); + if (ret != LTTCOMM_OK) { goto error; + } + + DBG("UST channel %s created for app sock %d with pid %d", + attr->name, app->sock, domain->attr.pid); + break; + } + default: + ret = LTTCOMM_UNKNOWN_DOMAIN; + goto error; } ret = LTTCOMM_OK; @@ -1810,7 +1959,7 @@ static int cmd_disable_event(struct ltt_session *session, int domain, goto error; } - ret = event_kernel_disable(session->kernel_session, kchan, event_name); + ret = event_kernel_disable_tracepoint(session->kernel_session, kchan, event_name); if (ret != LTTCOMM_OK) { goto error; } @@ -1911,7 +2060,7 @@ static int cmd_enable_event(struct ltt_session *session, int domain, session->kernel_session); if (kchan == NULL) { /* This call will notify the kernel thread */ - ret = channel_kernel_create(session->kernel_session, channel_name, + ret = channel_kernel_create(session->kernel_session, NULL, kernel_poll_pipe[1]); if (ret != LTTCOMM_OK) { goto error; @@ -1927,7 +2076,7 @@ static int cmd_enable_event(struct ltt_session *session, int domain, goto error; } - ret = event_kernel_enable(session->kernel_session, kchan, event); + ret = event_kernel_enable_tracepoint(session->kernel_session, kchan, event); if (ret != LTTCOMM_OK) { goto error; } @@ -1950,7 +2099,7 @@ error: * Command LTTNG_ENABLE_ALL_EVENT processed by the client thread. */ static int cmd_enable_event_all(struct ltt_session *session, int domain, - char *channel_name) + char *channel_name, int event_type) { int ret; struct ltt_kernel_channel *kchan; @@ -1961,8 +2110,8 @@ static int cmd_enable_event_all(struct ltt_session *session, int domain, session->kernel_session); if (kchan == NULL) { /* This call will notify the kernel thread */ - ret = channel_kernel_create(session->kernel_session, channel_name, - NULL, kernel_poll_pipe[1]); + ret = channel_kernel_create(session->kernel_session, NULL, + kernel_poll_pipe[1]); if (ret != LTTCOMM_OK) { goto error; } @@ -1977,8 +2126,28 @@ static int cmd_enable_event_all(struct ltt_session *session, int domain, goto error; } - ret = event_kernel_enable_all(session->kernel_session, - kchan, kernel_tracer_fd); + switch (event_type) { + case LTTNG_KERNEL_SYSCALL: + ret = event_kernel_enable_all_syscalls(session->kernel_session, + kchan, kernel_tracer_fd); + break; + case LTTNG_KERNEL_TRACEPOINT: + /* + * This call enables all LTTNG_KERNEL_TRACEPOINTS and + * events already registered to the channel. + */ + ret = event_kernel_enable_all_tracepoints(session->kernel_session, + kchan, kernel_tracer_fd); + break; + case LTTNG_KERNEL_ALL: + /* Enable syscalls and tracepoints */ + ret = event_kernel_enable_all(session->kernel_session, + kchan, kernel_tracer_fd); + break; + default: + ret = LTTCOMM_KERN_ENABLE_FAIL; + goto error; + } if (ret != LTTCOMM_OK) { goto error; } @@ -2181,7 +2350,7 @@ static int cmd_destroy_session(struct ltt_session *session, char *name) perror("write kernel poll pipe"); } - ret = session_destroy(name); + ret = session_destroy(session); return ret; } @@ -2358,13 +2527,13 @@ error: static int process_client_msg(struct command_ctx *cmd_ctx) { int ret = LTTCOMM_OK; - int need_kernel_session = 1; + int need_tracing_session = 1; DBG("Processing client command %d", cmd_ctx->lsm->cmd_type); /* * Check for command that don't needs to allocate a returned payload. We do - * this here so we don't have to make the call for no payload" at each + * this here so we don't have to make the call for no payload at each * command. */ switch(cmd_ctx->lsm->cmd_type) { @@ -2389,11 +2558,13 @@ static int process_client_msg(struct command_ctx *cmd_ctx) case LTTNG_CREATE_SESSION: case LTTNG_LIST_SESSIONS: case LTTNG_LIST_TRACEPOINTS: - need_kernel_session = 0; + need_tracing_session = 0; break; default: DBG("Getting session %s by name", cmd_ctx->lsm->session.name); + 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; @@ -2425,7 +2596,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } /* Need a session for kernel command */ - if (need_kernel_session) { + if (need_tracing_session) { if (cmd_ctx->session->kernel_session == NULL) { ret = create_kernel_session(cmd_ctx->session); if (ret < 0) { @@ -2435,16 +2606,37 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } /* Start the kernel consumer daemon */ + pthread_mutex_lock(&kconsumerd_pid_mutex); if (kconsumerd_pid == 0 && cmd_ctx->lsm->cmd_type != LTTNG_REGISTER_CONSUMER) { + pthread_mutex_unlock(&kconsumerd_pid_mutex); ret = start_kconsumerd(); if (ret < 0) { ret = LTTCOMM_KERN_CONSUMER_FAIL; goto error; } } + pthread_mutex_unlock(&kconsumerd_pid_mutex); } break; + case LTTNG_DOMAIN_UST_PID: + { + struct ltt_ust_session *usess; + + if (need_tracing_session) { + usess = trace_ust_get_session_by_pid( + &cmd_ctx->session->ust_session_list, + cmd_ctx->lsm->domain.attr.pid); + if (usess == NULL) { + ret = create_ust_session(cmd_ctx->session, + &cmd_ctx->lsm->domain); + if (ret != LTTCOMM_OK) { + goto error; + } + } + } + break; + } default: /* TODO Userspace tracer */ break; @@ -2484,8 +2676,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } case LTTNG_ENABLE_CHANNEL: { - ret = cmd_enable_channel(cmd_ctx->session, cmd_ctx->lsm->domain.type, - cmd_ctx->lsm->u.enable.channel_name, + ret = cmd_enable_channel(cmd_ctx->session, &cmd_ctx->lsm->domain, &cmd_ctx->lsm->u.channel.chan); break; } @@ -2501,7 +2692,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx) DBG("Enabling all kernel event"); ret = cmd_enable_event_all(cmd_ctx->session, cmd_ctx->lsm->domain.type, - cmd_ctx->lsm->u.enable.channel_name); + cmd_ctx->lsm->u.enable.channel_name, + cmd_ctx->lsm->u.enable.event.type); break; } case LTTNG_LIST_TRACEPOINTS: @@ -2609,7 +2801,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) case LTTNG_LIST_EVENTS: { size_t nb_event; - struct lttng_event *events; + struct lttng_event *events = NULL; nb_event = cmd_list_events(cmd_ctx->session, cmd_ctx->lsm->u.list.channel_name, &events); @@ -2823,7 +3015,7 @@ static void *thread_manage_clients(void *data) DBG("Sending response (size: %d, retcode: %s)", cmd_ctx->lttng_msg_size, - lttng_get_readable_code(cmd_ctx->llm->ret_code)); + lttng_get_readable_code(-cmd_ctx->llm->ret_code)); ret = send_unix_sock(sock, cmd_ctx->llm, cmd_ctx->lttng_msg_size); if (ret < 0) { ERR("Failed to send data back to client");