X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Fmain.c;h=2c2fe44bf52771c54415e58766f03bd385e4c9ec;hp=ddf5acd2f116664b2777421338033a0c64fc0aa4;hb=1316184615e422526ef4fae68f980443414969c1;hpb=e96b947ac3c1f39563a1f6748405f3bb42eba23a diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index ddf5acd2f..2c2fe44bf 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -41,6 +41,7 @@ #include #include #include + #include #include "channel.h" @@ -48,13 +49,13 @@ #include "context.h" #include "event.h" #include "futex.h" +#include "hashtable.h" #include "kernel-ctl.h" #include "ltt-sessiond.h" #include "shm.h" #include "ust-app.h" #include "ust-ctl.h" #include "utils.h" -#include "ust-ctl.h" struct consumer_data { enum lttng_consumer_type type; @@ -210,16 +211,16 @@ static int modprobe_remove_kernel_modules(void) for (i = ARRAY_SIZE(kernel_modules_list) - 1; i >= 0; i--) { ret = snprintf(modprobe, sizeof(modprobe), - "/sbin/modprobe --remove --quiet %s", + "/sbin/modprobe -r -q %s", kernel_modules_list[i].name); if (ret < 0) { - perror("snprintf modprobe --remove"); + perror("snprintf modprobe -r"); goto error; } modprobe[sizeof(modprobe) - 1] = '\0'; ret = system(modprobe); if (ret == -1) { - ERR("Unable to launch modprobe --remove for module %s", + ERR("Unable to launch modprobe -r for module %s", kernel_modules_list[i].name); } else if (kernel_modules_list[i].required && WEXITSTATUS(ret) != 0) { @@ -296,6 +297,17 @@ static void teardown_kernel_session(struct ltt_session *session) } } +/* + * Complete teardown of all UST sessions. This will free everything on his path + * and destroy the core essence of all ust sessions :) + */ +static void teardown_ust_session(struct ltt_session *session) +{ + DBG("Tearing down UST session(s)"); + + trace_ust_destroy_session(session->ust_session); +} + /* * Stop all threads by closing the thread quit pipe. */ @@ -356,7 +368,8 @@ static void cleanup(void) cds_list_for_each_entry_safe(sess, stmp, &session_list_ptr->head, list) { teardown_kernel_session(sess); - // TODO complete session cleanup (including UST) + teardown_ust_session(sess); + free(sess); } } @@ -413,7 +426,7 @@ static void clean_command_ctx(struct command_ctx **cmd_ctx) /* * Send all stream fds of kernel channel to the consumer. */ -static int send_consumer_channel_streams(struct consumer_data *consumer_data, +static int send_kconsumer_channel_streams(struct consumer_data *consumer_data, int sock, struct ltt_kernel_channel *channel) { int ret; @@ -428,7 +441,7 @@ static int send_consumer_channel_streams(struct consumer_data *consumer_data, lkm.u.channel.channel_key = channel->fd; lkm.u.channel.max_sb_size = channel->channel->attr.subbuf_size; lkm.u.channel.mmap_len = 0; /* for kernel */ - DBG("Sending channel %d to consumer", lkm.u.stream.stream_key); + DBG("Sending 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"); @@ -472,7 +485,7 @@ error: /* * Send all stream fds of the kernel session to the consumer. */ -static int send_consumer_session_streams(struct consumer_data *consumer_data, +static int send_kconsumer_session_streams(struct consumer_data *consumer_data, struct ltt_kernel_session *session) { int ret; @@ -482,7 +495,7 @@ static int send_consumer_session_streams(struct consumer_data *consumer_data, DBG("Sending metadata stream fd"); - /* Extra protection. It's NOT suppose to be set to 0 at this point */ + /* Extra protection. It's NOT supposed to be set to 0 at this point */ if (session->consumer_fd == 0) { session->consumer_fd = consumer_data->cmd_sock; } @@ -523,7 +536,7 @@ static int send_consumer_session_streams(struct consumer_data *consumer_data, } cds_list_for_each_entry(chan, &session->channel_list.head, list) { - ret = send_consumer_channel_streams(consumer_data, sock, chan); + ret = send_kconsumer_channel_streams(consumer_data, sock, chan); if (ret < 0) { goto error; } @@ -642,7 +655,7 @@ error: * * Useful for CPU hotplug feature. */ -static int update_stream(struct consumer_data *consumer_data, int fd) +static int update_kernel_stream(struct consumer_data *consumer_data, int fd) { int ret = 0; struct ltt_session *session; @@ -678,7 +691,7 @@ static int update_stream(struct consumer_data *consumer_data, int fd) * stream fds. */ if (session->kernel_session->consumer_fds_sent == 1) { - ret = send_consumer_channel_streams(consumer_data, + ret = send_kconsumer_channel_streams(consumer_data, session->kernel_session->consumer_fd, channel); if (ret < 0) { goto error; @@ -778,7 +791,7 @@ static void *thread_manage_kernel(void *data) * kernel session and updating the kernel consumer */ if (revents & LPOLLIN) { - ret = update_stream(&kconsumer_data, pollfd); + ret = update_kernel_stream(&kconsumer_data, pollfd); if (ret < 0) { continue; } @@ -881,7 +894,7 @@ static void *thread_manage_consumer(void *data) lttcomm_connect_unix_sock(consumer_data->cmd_unix_sock_path); if (consumer_data->cmd_sock < 0) { sem_post(&consumer_data->sem); - perror("consumer connect"); + PERROR("consumer connect"); goto error; } /* Signal condition to tell that the kconsumerd is ready */ @@ -970,6 +983,9 @@ static void *thread_manage_apps(void *data) DBG("[thread] Manage application started"); + rcu_register_thread(); + rcu_thread_online(); + ret = create_thread_poll_set(&events, 2); if (ret < 0) { goto error; @@ -1075,6 +1091,8 @@ error: lttng_poll_clean(&events); + rcu_thread_offline(); + rcu_unregister_thread(); return NULL; } @@ -1444,7 +1462,7 @@ static int start_consumerd(struct consumer_data *consumer_data) /* Setting up the consumer_data pid */ consumer_data->pid = ret; - DBG2("consumer pid %d", consumer_data->pid); + DBG2("Consumer pid %d", consumer_data->pid); pthread_mutex_unlock(&consumer_data->pid_mutex); DBG2("Spawning consumer control thread"); @@ -1472,7 +1490,7 @@ static int modprobe_kernel_modules(void) for (i = 0; i < ARRAY_SIZE(kernel_modules_list); i++) { ret = snprintf(modprobe, sizeof(modprobe), "/sbin/modprobe %s%s", - kernel_modules_list[i].required ? "" : "--quiet ", + kernel_modules_list[i].required ? "" : "-q ", kernel_modules_list[i].name); if (ret < 0) { perror("snprintf modprobe"); @@ -1622,7 +1640,7 @@ static int init_kernel_tracing(struct ltt_kernel_session *session) session->consumer_fd = kconsumer_data.cmd_sock; } - ret = send_consumer_session_streams(&kconsumer_data, session); + ret = send_kconsumer_session_streams(&kconsumer_data, session); if (ret < 0) { ret = LTTCOMM_KERN_CONSUMER_FAIL; goto error; @@ -1642,16 +1660,11 @@ static int create_ust_session(struct ltt_session *session, struct lttng_domain *domain) { int ret; + unsigned int uid; 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; - } + case LTTNG_DOMAIN_UST: break; default: ret = LTTCOMM_UNKNOWN_DOMAIN; @@ -1660,13 +1673,17 @@ static int create_ust_session(struct ltt_session *session, DBG("Creating UST session"); - lus = trace_ust_create_session(session->path, domain->attr.pid, domain); + session_lock_list(); + uid = session_list_ptr->count; + session_unlock_list(); + + lus = trace_ust_create_session(session->path, uid, domain); if (lus == NULL) { ret = LTTCOMM_UST_SESS_FAIL; goto error; } - ret = mkdir_recursive(lus->path, S_IRWXU | S_IRWXG, + ret = mkdir_recursive(lus->pathname, S_IRWXU | S_IRWXG, geteuid(), allowed_group()); if (ret < 0) { if (ret != -EEXIST) { @@ -1676,15 +1693,15 @@ static int create_ust_session(struct ltt_session *session, } } - /* Create session on the UST tracer */ - ret = ustctl_create_session(app->sock, lus); - if (ret < 0) { - ret = LTTCOMM_UST_SESS_FAIL; + /* The domain type dictate different actions on session creation */ + switch (domain->type) { + case LTTNG_DOMAIN_UST: + /* No ustctl for the global UST domain */ + break; + default: goto error; } - - cds_list_add(&lus->list, &session->ust_session_list.head); - session->ust_session_list.count++; + session->ust_session = lus; return LTTCOMM_OK; @@ -1859,13 +1876,14 @@ error: /* * 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); + uchan = trace_ust_get_channel_by_key(usess->channels, attr->name); if (uchan == NULL) { ret = LTTCOMM_FATAL; goto error; @@ -1884,13 +1902,10 @@ static int copy_ust_channel_to_app(struct ltt_ust_session *usess, 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. @@ -1899,6 +1914,9 @@ static int cmd_enable_channel(struct ltt_session *session, struct lttng_domain *domain, struct lttng_channel *attr) { int ret; + struct ltt_ust_session *usess = session->ust_session; + + DBG("Enabling channel %s for session %s", session->name, attr->name); switch (domain->type) { case LTTNG_DOMAIN_KERNEL: @@ -1921,8 +1939,40 @@ static int cmd_enable_channel(struct ltt_session *session, kernel_wait_quiescent(kernel_tracer_fd); break; } + case LTTNG_DOMAIN_UST: + { + struct ltt_ust_channel *uchan; + + DBG2("Enabling channel for LTTNG_DOMAIN_UST"); + + /* Get channel in global UST domain HT */ + uchan = trace_ust_find_channel_by_name(usess->domain_global.channels, + attr->name); + if (uchan == NULL) { + uchan = trace_ust_create_channel(attr, usess->pathname); + if (uchan == NULL) { + ret = LTTCOMM_UST_CHAN_FAIL; + goto error; + } + rcu_read_lock(); + hashtable_add_unique(usess->domain_global.channels, &uchan->node); + rcu_read_unlock(); + DBG2("UST channel %s added to global domain HT", attr->name); + } else { + ret = LTTCOMM_UST_CHAN_EXIST; + goto error; + } + + ret = ust_app_add_channel(usess, uchan); + if (ret != LTTCOMM_OK) { + goto error; + } + + break; + } case LTTNG_DOMAIN_UST_PID: { + /* int sock; struct ltt_ust_channel *uchan; struct ltt_ust_session *usess; @@ -1960,7 +2010,9 @@ static int cmd_enable_channel(struct ltt_session *session, DBG("UST channel %s created for app sock %d with pid %d", attr->name, app->sock, domain->attr.pid); - break; + */ + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; } default: ret = LTTCOMM_UNKNOWN_DOMAIN; @@ -1980,10 +2032,12 @@ static int cmd_disable_event(struct ltt_session *session, int domain, char *channel_name, char *event_name) { int ret; - struct ltt_kernel_channel *kchan; switch (domain) { case LTTNG_DOMAIN_KERNEL: + { + struct ltt_kernel_channel *kchan; + kchan = trace_kernel_get_channel_by_name(channel_name, session->kernel_session); if (kchan == NULL) { @@ -1998,8 +2052,13 @@ static int cmd_disable_event(struct ltt_session *session, int domain, kernel_wait_quiescent(kernel_tracer_fd); break; + } + case LTTNG_DOMAIN_UST: + case LTTNG_DOMAIN_UST_EXEC_NAME: + case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: default: - /* TODO: Userspace tracing */ + /* TODO: Other UST domains */ ret = LTTCOMM_NOT_IMPLEMENTED; goto error; } @@ -2063,10 +2122,24 @@ static int cmd_add_context(struct ltt_session *session, int domain, if (ret != LTTCOMM_OK) { goto error; } + break; + case LTTNG_DOMAIN_UST: + { + /* + struct ltt_ust_session *usess; + cds_list_for_each_entry(usess, &session->ust_session_list.head, list) { + ret = context_ust_add(usess, ctx, + event_name, channel_name, domain); + if (ret != LTTCOMM_OK) { + goto error; + } + } break; + */ + } default: - /* TODO: Userspace tracing */ + /* TODO: UST other domains */ ret = LTTCOMM_NOT_IMPLEMENTED; goto error; } @@ -2084,11 +2157,14 @@ static int cmd_enable_event(struct ltt_session *session, int domain, char *channel_name, struct lttng_event *event) { int ret; - struct ltt_kernel_channel *kchan; struct lttng_channel *attr; + struct ltt_ust_session *usess = session->ust_session; switch (domain) { case LTTNG_DOMAIN_KERNEL: + { + struct ltt_kernel_channel *kchan; + kchan = trace_kernel_get_channel_by_name(channel_name, session->kernel_session); if (kchan == NULL) { @@ -2116,15 +2192,48 @@ static int cmd_enable_event(struct ltt_session *session, int domain, goto error; } - ret = event_kernel_enable_tracepoint(session->kernel_session, kchan, event); + ret = event_kernel_enable_tracepoint(session->kernel_session, kchan, + event); if (ret != LTTCOMM_OK) { goto error; } kernel_wait_quiescent(kernel_tracer_fd); break; + } + case LTTNG_DOMAIN_UST: + { + struct ltt_ust_channel *uchan; + struct ltt_ust_event *uevent; + + uchan = trace_ust_find_channel_by_name(usess->domain_global.channels, + channel_name); + if (uchan == NULL) { + /* TODO: Create default channel */ + ret = LTTCOMM_UST_CHAN_NOT_FOUND; + goto error; + } + + uevent = trace_ust_find_event_by_name(uchan->events, event->name); + if (uevent == NULL) { + uevent = trace_ust_create_event(event); + if (uevent == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + } + + ret = ust_app_add_event(usess, uchan, uevent); + if (ret < 0) { + ret = LTTCOMM_UST_ENABLE_FAIL; + goto error; + } + break; + } + case LTTNG_DOMAIN_UST_EXEC_NAME: + case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: default: - /* TODO: Userspace tracing */ ret = LTTCOMM_NOT_IMPLEMENTED; goto error; } @@ -2241,14 +2350,16 @@ error: static int cmd_start_trace(struct ltt_session *session) { int ret; - struct ltt_kernel_channel *kchan; struct ltt_kernel_session *ksession; + struct ltt_ust_session *usess = session->ust_session; /* Short cut */ ksession = session->kernel_session; /* Kernel tracing */ if (ksession != NULL) { + struct ltt_kernel_channel *kchan; + /* Open kernel metadata */ if (ksession->metadata == NULL) { ret = kernel_open_metadata(ksession, ksession->trace_path); @@ -2299,7 +2410,11 @@ static int cmd_start_trace(struct ltt_session *session) kernel_wait_quiescent(kernel_tracer_fd); } - /* TODO: Start all UST traces */ + ret = ust_app_start_trace(usess); + if (ret < 0) { + ret = LTTCOMM_UST_START_FAIL; + goto error; + } ret = LTTCOMM_OK; @@ -2315,6 +2430,8 @@ static int cmd_stop_trace(struct ltt_session *session) int ret; struct ltt_kernel_channel *kchan; struct ltt_kernel_session *ksession; + //struct ltt_ust_session *usess; + //struct ltt_ust_channel *ustchan; /* Short cut */ ksession = session->kernel_session; @@ -2345,7 +2462,32 @@ static int cmd_stop_trace(struct ltt_session *session) kernel_wait_quiescent(kernel_tracer_fd); } - /* TODO : User-space tracer */ +#ifdef DISABLE + /* Stop each UST session */ + DBG("Stop UST tracing"); + cds_list_for_each_entry(usess, &session->ust_session_list.head, list) { + /* Flush all buffers before stopping */ + ret = ustctl_flush_buffer(usess->sock, usess->metadata->obj); + if (ret < 0) { + ERR("UST metadata flush failed"); + } + + cds_list_for_each_entry(ustchan, &usess->channels.head, list) { + ret = ustctl_flush_buffer(usess->sock, ustchan->obj); + if (ret < 0) { + ERR("UST flush buffer error"); + } + } + + ret = ustctl_stop_session(usess->sock, usess->handle); + if (ret < 0) { + ret = LTTCOMM_KERN_STOP_FAIL; + goto error; + } + + ustctl_wait_quiescent(usess->sock); + } +#endif ret = LTTCOMM_OK; @@ -2476,7 +2618,7 @@ static ssize_t cmd_list_domains(struct ltt_session *session, nb_dom++; } - nb_dom += session->ust_session_list.count; + /* TODO: User-space tracer domain support */ *domains = malloc(nb_dom * sizeof(struct lttng_domain)); if (*domains == NULL) { @@ -2486,8 +2628,6 @@ static ssize_t cmd_list_domains(struct ltt_session *session, (*domains)[0].type = LTTNG_DOMAIN_KERNEL; - /* TODO: User-space tracer domain support */ - return nb_dom; error: @@ -2515,6 +2655,8 @@ static ssize_t cmd_list_channels(struct ltt_session *session, list_lttng_channels(session, *channels); + /* TODO UST support */ + return nb_chan; error: @@ -2659,26 +2801,35 @@ static int process_client_msg(struct command_ctx *cmd_ctx) pthread_mutex_unlock(&kconsumer_data.pid_mutex); } break; - case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST: { - 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) { + if (cmd_ctx->session->ust_session == NULL) { ret = create_ust_session(cmd_ctx->session, &cmd_ctx->lsm->domain); if (ret != LTTCOMM_OK) { goto error; } } + /* Start the kernel consumer daemon */ + pthread_mutex_lock(&ustconsumer_data.pid_mutex); + if (ustconsumer_data.pid == 0 && + cmd_ctx->lsm->cmd_type != LTTNG_REGISTER_CONSUMER) { + pthread_mutex_unlock(&ustconsumer_data.pid_mutex); + ret = start_consumerd(&ustconsumer_data); + if (ret < 0) { + ret = LTTCOMM_KERN_CONSUMER_FAIL; + goto error; + } + + cmd_ctx->session->ust_session->consumer_fd = + ustconsumer_data.cmd_sock; + } + pthread_mutex_unlock(&ustconsumer_data.pid_mutex); } break; } default: - /* TODO Userspace tracer */ break; } @@ -2708,7 +2859,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } case LTTNG_DISABLE_ALL_EVENT: { - DBG("Disabling all kernel event"); + DBG("Disabling all events"); ret = cmd_disable_event_all(cmd_ctx->session, cmd_ctx->lsm->domain.type, cmd_ctx->lsm->u.disable.channel_name); @@ -2729,7 +2880,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } case LTTNG_ENABLE_ALL_EVENT: { - DBG("Enabling all kernel event"); + DBG("Enabling all events"); ret = cmd_enable_event_all(cmd_ctx->session, cmd_ctx->lsm->domain.type, cmd_ctx->lsm->u.enable.channel_name, @@ -2936,6 +3087,8 @@ static void *thread_manage_clients(void *data) DBG("[thread] Manage client started"); + rcu_register_thread(); + ret = lttcomm_listen_unix_sock(client_sock); if (ret < 0) { goto error; @@ -3036,6 +3189,7 @@ static void *thread_manage_clients(void *data) // TODO: Validate cmd_ctx including sanity check for // security purpose. + rcu_thread_online(); /* * This function dispatch the work to the kernel or userspace tracer * libs and fill the lttcomm_lttng_msg data structure of all the needed @@ -3043,6 +3197,7 @@ static void *thread_manage_clients(void *data) * everything this function may needs. */ ret = process_client_msg(cmd_ctx); + rcu_thread_offline(); if (ret < 0) { /* * TODO: Inform client somehow of the fatal error. At @@ -3075,6 +3230,8 @@ error: lttng_poll_clean(&events); clean_command_ctx(&cmd_ctx); + + rcu_unregister_thread(); return NULL; } @@ -3503,6 +3660,8 @@ int main(int argc, char **argv) void *status; const char *home_path; + rcu_register_thread(); + /* Create thread quit pipe */ if ((ret = init_thread_quit_pipe()) < 0) { goto error; @@ -3602,6 +3761,7 @@ int main(int argc, char **argv) if (ret < 0) { goto exit; } + ret = set_consumer_sockets(&ustconsumer_data); if (ret < 0) { goto exit; @@ -3645,6 +3805,9 @@ 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 @@ -3739,7 +3902,10 @@ exit: /* * cleanup() is called when no other thread is running. */ + rcu_thread_online(); cleanup(); + rcu_thread_offline(); + rcu_unregister_thread(); if (!ret) exit(EXIT_SUCCESS); error: