X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Fmain.c;h=b3dc0e3a6f08ee397935c8a672e2470179633980;hp=bba8aa64d4dfebcb4a3c35150969c72070af7fb2;hb=ab14718513c62c38a882d103b1dc727467271ff7;hpb=af9737e9006817895374706246dcf3d9efbeb58f diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index bba8aa64d..b3dc0e3a6 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -41,6 +41,7 @@ #include /* URCU list library (-lurcu) */ #include +#include "context.h" #include "liblttsessiondcomm.h" #include "ltt-sessiond.h" #include "lttngerr.h" @@ -98,6 +99,8 @@ static sem_t kconsumerd_sem; static pthread_mutex_t kconsumerd_pid_mutex; /* Mutex to control kconsumerd pid assignation */ +static int modprobe_remove_kernel_modules(void); + /* * Pointer initialized before thread creation. * @@ -194,6 +197,9 @@ static void cleanup() DBG("Closing kernel fd"); close(kernel_tracer_fd); + + DBG("Unloading kernel modules"); + modprobe_remove_kernel_modules(); } /* @@ -416,7 +422,7 @@ static int setup_lttng_msg(struct command_ctx *cmd_ctx, size_t size) /* Copy common data */ cmd_ctx->llm->cmd_type = cmd_ctx->lsm->cmd_type; - cmd_ctx->llm->pid = cmd_ctx->lsm->pid; + cmd_ctx->llm->pid = cmd_ctx->lsm->domain.attr.pid; cmd_ctx->llm->data_size = size; cmd_ctx->lttng_msg_size = sizeof(struct lttcomm_lttng_msg) + buf_size; @@ -943,22 +949,67 @@ error: */ static int modprobe_kernel_modules(void) { - int ret = 0, i = 0; + int ret = 0, i; char modprobe[256]; - while (kernel_modules_list[i] != NULL) { - ret = snprintf(modprobe, sizeof(modprobe), "/sbin/modprobe %s", - kernel_modules_list[i]); + 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].name); if (ret < 0) { perror("snprintf modprobe"); goto error; } + modprobe[sizeof(modprobe) - 1] = '\0'; ret = system(modprobe); + if (ret == -1) { + ERR("Unable to launch modprobe for module %s", + kernel_modules_list[i].name); + } else if (kernel_modules_list[i].required + && WEXITSTATUS(ret) != 0) { + ERR("Unable to load module %s", + kernel_modules_list[i].name); + } else { + DBG("Modprobe successfully %s", + kernel_modules_list[i].name); + } + } + +error: + return ret; +} + +/* + * modprobe_remove_kernel_modules + * Remove modules in reverse load order. + */ +static int modprobe_remove_kernel_modules(void) +{ + int ret = 0, i; + char modprobe[256]; + + for (i = ARRAY_SIZE(kernel_modules_list) - 1; i >= 0; i--) { + ret = snprintf(modprobe, sizeof(modprobe), + "/sbin/modprobe --remove --quiet %s", + kernel_modules_list[i].name); if (ret < 0) { - ERR("Unable to load module %s", kernel_modules_list[i]); + perror("snprintf modprobe --remove"); + goto error; + } + modprobe[sizeof(modprobe) - 1] = '\0'; + ret = system(modprobe); + if (ret == -1) { + ERR("Unable to launch modprobe --remove for module %s", + kernel_modules_list[i].name); + } else if (kernel_modules_list[i].required + && WEXITSTATUS(ret) != 0) { + ERR("Unable to remove module %s", + kernel_modules_list[i].name); + } else { + DBG("Modprobe removal successful %s", + kernel_modules_list[i].name); } - DBG("Modprobe successfully %s", kernel_modules_list[i]); - i++; } error: @@ -1113,7 +1164,7 @@ static int notify_kernel_pollfd(void) /* * Allocate a channel structure and fill it. */ -static struct lttng_channel *init_default_channel(void) +static struct lttng_channel *init_default_channel(char *name) { struct lttng_channel *chan; @@ -1123,8 +1174,8 @@ static struct lttng_channel *init_default_channel(void) goto error; } - if (snprintf(chan->name, NAME_MAX, DEFAULT_CHANNEL_NAME) < 0) { - perror("snprintf defautl channel name"); + if (snprintf(chan->name, NAME_MAX, "%s", name) < 0) { + perror("snprintf channel name"); return NULL; } @@ -1190,6 +1241,68 @@ static void list_lttng_sessions(struct lttng_session *sessions) } } +/* + * Fill lttng_channel array of all channels. + */ +static void list_lttng_channels(struct ltt_session *session, + struct lttng_channel *channels) +{ + int i = 0; + struct ltt_kernel_channel *kchan; + + DBG("Listing channels for session %s", session->name); + + /* Kernel channels */ + if (session->kernel_session != NULL) { + cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head, list) { + /* Copy lttng_channel struct to array */ + memcpy(&channels[i], kchan->channel, sizeof(struct lttng_channel)); + channels[i].enabled = kchan->enabled; + i++; + } + } + + /* TODO: Missing UST listing */ +} + +/* + * Fill lttng_event array of all events in the channel. + */ +static void list_lttng_events(struct ltt_kernel_channel *kchan, + struct lttng_event *events) +{ + /* + * TODO: This is ONLY kernel. Need UST support. + */ + int i = 0; + struct ltt_kernel_event *event; + + DBG("Listing events for channel %s", kchan->channel->name); + + /* Kernel channels */ + cds_list_for_each_entry(event, &kchan->events_list.head , list) { + strncpy(events[i].name, event->event->name, LTTNG_SYMBOL_NAME_LEN); + events[i].enabled = event->enabled; + switch (event->event->instrumentation) { + case LTTNG_KERNEL_TRACEPOINT: + events[i].type = LTTNG_EVENT_TRACEPOINT; + break; + case LTTNG_KERNEL_KPROBE: + case LTTNG_KERNEL_KRETPROBE: + events[i].type = LTTNG_EVENT_PROBE; + memcpy(&events[i].attr.probe, &event->event->u.kprobe, + sizeof(struct lttng_kernel_kprobe)); + break; + case LTTNG_KERNEL_FUNCTION: + events[i].type = LTTNG_EVENT_FUNCTION; + memcpy(&events[i].attr.ftrace, &event->event->u.ftrace, + sizeof(struct lttng_kernel_function)); + break; + } + i++; + } +} + /* * Process the command requested by the lttng client within the command * context structure. This function make sure that the return structure (llm) @@ -1207,16 +1320,14 @@ 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 LTTNG_LIST_EVENTS: - case LTTNG_KERNEL_LIST_EVENTS: - case LTTNG_LIST_TRACEABLE_APPS: + case LTTNG_LIST_TRACEPOINTS: break; default: - DBG("Getting session %s by name", cmd_ctx->lsm->session_name); - cmd_ctx->session = find_session_by_name(cmd_ctx->lsm->session_name); + DBG("Getting session %s by name", cmd_ctx->lsm->session.name); + cmd_ctx->session = find_session_by_name(cmd_ctx->lsm->session.name); if (cmd_ctx->session == NULL) { /* If session name not found */ - if (cmd_ctx->lsm->session_name != NULL) { + if (cmd_ctx->lsm->session.name != NULL) { ret = LTTCOMM_SESS_NOT_FOUND; } else { /* If no session name specified */ ret = LTTCOMM_SELECT_SESS; @@ -1230,17 +1341,10 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } /* - * Check kernel command for kernel session. + * Check domain type for specifif "pre-action". */ - switch (cmd_ctx->lsm->cmd_type) { - case LTTNG_KERNEL_ADD_CONTEXT: - case LTTNG_KERNEL_DISABLE_ALL_EVENT: - case LTTNG_KERNEL_DISABLE_CHANNEL: - case LTTNG_KERNEL_DISABLE_EVENT: - case LTTNG_KERNEL_ENABLE_ALL_EVENT: - case LTTNG_KERNEL_ENABLE_CHANNEL: - case LTTNG_KERNEL_ENABLE_EVENT: - case LTTNG_KERNEL_LIST_EVENTS: + switch (cmd_ctx->lsm->domain.type) { + case LTTNG_DOMAIN_KERNEL: /* Kernel tracer check */ if (kernel_tracer_fd == 0) { init_kernel_tracer(); @@ -1251,7 +1355,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } /* Need a session for kernel command */ - if (cmd_ctx->lsm->cmd_type != LTTNG_KERNEL_LIST_EVENTS && + if (cmd_ctx->lsm->cmd_type != LTTNG_LIST_TRACEPOINTS && cmd_ctx->session->kernel_session == NULL) { ret = create_kernel_session(cmd_ctx->session); @@ -1268,28 +1372,16 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } } } + break; + default: + break; } -#ifdef DISABLED - /* Connect to ust apps if available pid */ - if (cmd_ctx->lsm->pid > 0) { - /* Connect to app using ustctl API */ - cmd_ctx->ust_sock = ust_connect_app(cmd_ctx->lsm->pid); - if (cmd_ctx->ust_sock < 0) { - ret = LTTCOMM_NO_TRACEABLE; - goto error; - } - } -#endif /* DISABLED */ - /* Process by command type */ switch (cmd_ctx->lsm->cmd_type) { - case LTTNG_KERNEL_ADD_CONTEXT: + case LTTNG_ADD_CONTEXT: { - int found = 0, no_event = 0; - struct ltt_kernel_channel *chan; - struct ltt_kernel_event *event; - struct lttng_kernel_context ctx; + struct lttng_kernel_context kctx; /* Setup lttng message with no payload */ ret = setup_lttng_msg(cmd_ctx, 0); @@ -1297,79 +1389,36 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_error; } - /* Check if event name is given */ - if (strlen(cmd_ctx->lsm->u.context.event_name) == 0) { - no_event = 1; - } - - /* Create Kernel context */ - ctx.ctx = cmd_ctx->lsm->u.context.ctx.ctx; - ctx.u.perf_counter.type = cmd_ctx->lsm->u.context.ctx.u.perf_counter.type; - ctx.u.perf_counter.config = cmd_ctx->lsm->u.context.ctx.u.perf_counter.config; - strncpy(ctx.u.perf_counter.name, - cmd_ctx->lsm->u.context.ctx.u.perf_counter.name, - sizeof(ctx.u.perf_counter.name)); - - if (strlen(cmd_ctx->lsm->u.context.channel_name) == 0) { - /* Go over all channels */ - DBG("Adding context to all channels"); - cds_list_for_each_entry(chan, - &cmd_ctx->session->kernel_session->channel_list.head, list) { - if (no_event) { - ret = kernel_add_channel_context(chan, &ctx); - if (ret < 0) { - continue; - } - } else { - event = get_kernel_event_by_name(cmd_ctx->lsm->u.context.event_name, chan); - if (event != NULL) { - ret = kernel_add_event_context(event, &ctx); - if (ret < 0) { - ret = LTTCOMM_KERN_CONTEXT_FAIL; - goto error; - } - found = 1; - break; - } - } - } - } else { - chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.context.channel_name, - cmd_ctx->session->kernel_session); - if (chan == NULL) { - ret = LTTCOMM_KERN_CHAN_NOT_FOUND; + switch (cmd_ctx->lsm->domain.type) { + case LTTNG_DOMAIN_KERNEL: + /* Create Kernel context */ + kctx.ctx = cmd_ctx->lsm->u.context.ctx.ctx; + kctx.u.perf_counter.type = cmd_ctx->lsm->u.context.ctx.u.perf_counter.type; + kctx.u.perf_counter.config = cmd_ctx->lsm->u.context.ctx.u.perf_counter.config; + strncpy(kctx.u.perf_counter.name, + cmd_ctx->lsm->u.context.ctx.u.perf_counter.name, + LTTNG_SYMBOL_NAME_LEN); + + /* Add kernel context to kernel tracer. See context.c */ + ret = add_kernel_context(cmd_ctx->session->kernel_session, &kctx, + cmd_ctx->lsm->u.context.event_name, + cmd_ctx->lsm->u.context.channel_name); + if (ret != LTTCOMM_OK) { goto error; } - - if (no_event) { - ret = kernel_add_channel_context(chan, &ctx); - if (ret < 0) { - ret = LTTCOMM_KERN_CONTEXT_FAIL; - goto error; - } - } else { - event = get_kernel_event_by_name(cmd_ctx->lsm->u.context.event_name, chan); - if (event != NULL) { - ret = kernel_add_event_context(event, &ctx); - if (ret < 0) { - ret = LTTCOMM_KERN_CONTEXT_FAIL; - goto error; - } - } - } - } - - if (!found && !no_event) { - ret = LTTCOMM_NO_EVENT; + break; + default: + /* TODO: Userspace tracing */ + ret = LTTCOMM_NOT_IMPLEMENTED; goto error; } ret = LTTCOMM_OK; break; } - case LTTNG_KERNEL_DISABLE_CHANNEL: + case LTTNG_DISABLE_CHANNEL: { - struct ltt_kernel_channel *chan; + struct ltt_kernel_channel *kchan; /* Setup lttng message with no payload */ ret = setup_lttng_msg(cmd_ctx, 0); @@ -1377,29 +1426,37 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_error; } - chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, - cmd_ctx->session->kernel_session); - if (chan == NULL) { - ret = LTTCOMM_KERN_CHAN_NOT_FOUND; - goto error; - } else if (chan->enabled == 1) { - ret = kernel_disable_channel(chan); - if (ret < 0) { - if (ret != EEXIST) { - ret = LTTCOMM_KERN_CHAN_DISABLE_FAIL; - } + switch (cmd_ctx->lsm->domain.type) { + case LTTNG_DOMAIN_KERNEL: + kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, + cmd_ctx->session->kernel_session); + if (kchan == NULL) { + ret = LTTCOMM_KERN_CHAN_NOT_FOUND; goto error; + } else if (kchan->enabled == 1) { + ret = kernel_disable_channel(kchan); + if (ret < 0) { + if (ret != EEXIST) { + ret = LTTCOMM_KERN_CHAN_DISABLE_FAIL; + } + goto error; + } } + kernel_wait_quiescent(kernel_tracer_fd); + break; + default: + /* TODO: Userspace tracing */ + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; } - kernel_wait_quiescent(kernel_tracer_fd); ret = LTTCOMM_OK; break; } - case LTTNG_KERNEL_DISABLE_EVENT: + case LTTNG_DISABLE_EVENT: { - struct ltt_kernel_channel *chan; - struct ltt_kernel_event *ev; + struct ltt_kernel_channel *kchan; + struct ltt_kernel_event *kevent; /* Setup lttng message with no payload */ ret = setup_lttng_msg(cmd_ctx, 0); @@ -1407,32 +1464,41 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_error; } - chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, - cmd_ctx->session->kernel_session); - if (chan == NULL) { - ret = LTTCOMM_KERN_CHAN_NOT_FOUND; - goto error; - } - - ev = get_kernel_event_by_name(cmd_ctx->lsm->u.disable.name, chan); - if (ev != NULL) { - DBG("Disabling kernel event %s for channel %s.", - cmd_ctx->lsm->u.disable.name, cmd_ctx->lsm->u.disable.channel_name); - ret = kernel_disable_event(ev); - if (ret < 0) { - ret = LTTCOMM_KERN_ENABLE_FAIL; + switch (cmd_ctx->lsm->domain.type) { + case LTTNG_DOMAIN_KERNEL: + kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, + cmd_ctx->session->kernel_session); + if (kchan == NULL) { + ret = LTTCOMM_KERN_CHAN_NOT_FOUND; goto error; } + + kevent = get_kernel_event_by_name(cmd_ctx->lsm->u.disable.name, kchan); + if (kevent != NULL) { + DBG("Disabling kernel event %s for channel %s.", kevent->event->name, + kchan->channel->name); + ret = kernel_disable_event(kevent); + if (ret < 0) { + ret = LTTCOMM_KERN_ENABLE_FAIL; + goto error; + } + } + + kernel_wait_quiescent(kernel_tracer_fd); + break; + default: + /* TODO: Userspace tracing */ + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; } - kernel_wait_quiescent(kernel_tracer_fd); ret = LTTCOMM_OK; break; } - case LTTNG_KERNEL_DISABLE_ALL_EVENT: + case LTTNG_DISABLE_ALL_EVENT: { - struct ltt_kernel_channel *chan; - struct ltt_kernel_event *ev; + struct ltt_kernel_channel *kchan; + struct ltt_kernel_event *kevent; /* Setup lttng message with no payload */ ret = setup_lttng_msg(cmd_ctx, 0); @@ -1440,33 +1506,41 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_error; } - DBG("Disabling all enabled kernel events"); - - chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, - cmd_ctx->session->kernel_session); - if (chan == NULL) { - ret = LTTCOMM_KERN_CHAN_NOT_FOUND; - goto error; - } + switch (cmd_ctx->lsm->domain.type) { + case LTTNG_DOMAIN_KERNEL: + DBG("Disabling all enabled kernel events"); + kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, + cmd_ctx->session->kernel_session); + if (kchan == NULL) { + ret = LTTCOMM_KERN_CHAN_NOT_FOUND; + goto error; + } - /* For each event in the kernel session */ - cds_list_for_each_entry(ev, &chan->events_list.head, list) { - DBG("Disabling kernel event %s for channel %s.", - ev->event->name, cmd_ctx->lsm->u.disable.channel_name); - ret = kernel_disable_event(ev); - if (ret < 0) { - continue; + /* For each event in the kernel session */ + cds_list_for_each_entry(kevent, &kchan->events_list.head, list) { + DBG("Disabling kernel event %s for channel %s.", + kevent->event->name, kchan->channel->name); + ret = kernel_disable_event(kevent); + if (ret < 0) { + continue; + } } + + /* Quiescent wait after event disable */ + kernel_wait_quiescent(kernel_tracer_fd); + break; + default: + /* TODO: Userspace tracing */ + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; } - /* Quiescent wait after event disable */ - kernel_wait_quiescent(kernel_tracer_fd); ret = LTTCOMM_OK; break; } - case LTTNG_KERNEL_ENABLE_CHANNEL: + case LTTNG_ENABLE_CHANNEL: { - struct ltt_kernel_channel *chan; + struct ltt_kernel_channel *kchan; /* Setup lttng message with no payload */ ret = setup_lttng_msg(cmd_ctx, 0); @@ -1474,44 +1548,53 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_error; } - chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.enable.channel_name, - cmd_ctx->session->kernel_session); - if (chan == NULL) { - /* Channel not found, creating it */ - DBG("Creating kernel channel"); + switch (cmd_ctx->lsm->domain.type) { + case LTTNG_DOMAIN_KERNEL: + kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.enable.channel_name, + cmd_ctx->session->kernel_session); + if (kchan == NULL) { + /* Channel not found, creating it */ + DBG("Creating kernel channel"); - ret = kernel_create_channel(cmd_ctx->session->kernel_session, - &cmd_ctx->lsm->u.channel.chan, cmd_ctx->session->path); - if (ret < 0) { - ret = LTTCOMM_KERN_CHAN_FAIL; - goto error; - } + ret = kernel_create_channel(cmd_ctx->session->kernel_session, + &cmd_ctx->lsm->u.channel.chan, cmd_ctx->session->path); + if (ret < 0) { + ret = LTTCOMM_KERN_CHAN_FAIL; + goto error; + } - /* Notify kernel thread that there is a new channel */ - ret = notify_kernel_pollfd(); - if (ret < 0) { - ret = LTTCOMM_FATAL; - goto error; - } - } else if (chan->enabled == 0) { - ret = kernel_enable_channel(chan); - if (ret < 0) { - if (ret != EEXIST) { - ret = LTTCOMM_KERN_CHAN_ENABLE_FAIL; + /* Notify kernel thread that there is a new channel */ + ret = notify_kernel_pollfd(); + if (ret < 0) { + ret = LTTCOMM_FATAL; + goto error; + } + } else if (kchan->enabled == 0) { + ret = kernel_enable_channel(kchan); + if (ret < 0) { + if (ret != EEXIST) { + ret = LTTCOMM_KERN_CHAN_ENABLE_FAIL; + } + goto error; } - goto error; } + + kernel_wait_quiescent(kernel_tracer_fd); + break; + default: + /* TODO: Userspace tracing */ + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; } - kernel_wait_quiescent(kernel_tracer_fd); ret = LTTCOMM_OK; break; } - case LTTNG_KERNEL_ENABLE_EVENT: + case LTTNG_ENABLE_EVENT: { char *channel_name; struct ltt_kernel_channel *kchan; - struct ltt_kernel_event *ev; + struct ltt_kernel_event *kevent; struct lttng_channel *chan; /* Setup lttng message with no payload */ @@ -1522,58 +1605,66 @@ static int process_client_msg(struct command_ctx *cmd_ctx) channel_name = cmd_ctx->lsm->u.enable.channel_name; - do { - kchan = get_kernel_channel_by_name(channel_name, - cmd_ctx->session->kernel_session); - if (kchan == NULL) { - DBG("Creating default channel"); + 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(channel_name); + if (chan == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } - chan = init_default_channel(); - if (chan == NULL) { - ret = LTTCOMM_FATAL; - goto error; + ret = kernel_create_channel(cmd_ctx->session->kernel_session, + chan, cmd_ctx->session->path); + if (ret < 0) { + ret = LTTCOMM_KERN_CHAN_FAIL; + goto error; + } } + } while (kchan == NULL); - ret = kernel_create_channel(cmd_ctx->session->kernel_session, - chan, cmd_ctx->session->path); - if (ret < 0) { - ret = LTTCOMM_KERN_CHAN_FAIL; + kevent = get_kernel_event_by_name(cmd_ctx->lsm->u.enable.event.name, kchan); + if (kevent == NULL) { + DBG("Creating kernel event %s for channel %s.", + cmd_ctx->lsm->u.enable.event.name, channel_name); + ret = kernel_create_event(&cmd_ctx->lsm->u.enable.event, kchan); + } else { + DBG("Enabling kernel event %s for channel %s.", + kevent->event->name, channel_name); + ret = kernel_enable_event(kevent); + if (ret == -EEXIST) { + ret = LTTCOMM_KERN_EVENT_EXIST; goto error; } } - } while (kchan == NULL); - ev = get_kernel_event_by_name(cmd_ctx->lsm->u.enable.event.name, kchan); - if (ev == NULL) { - DBG("Creating kernel event %s for channel %s.", - cmd_ctx->lsm->u.enable.event.name, channel_name); - ret = kernel_create_event(&cmd_ctx->lsm->u.enable.event, kchan); - } else { - DBG("Enabling kernel event %s for channel %s.", - cmd_ctx->lsm->u.enable.event.name, channel_name); - ret = kernel_enable_event(ev); - if (ret == -EEXIST) { - ret = LTTCOMM_KERN_EVENT_EXIST; + if (ret < 0) { + ret = LTTCOMM_KERN_ENABLE_FAIL; goto error; } - } - if (ret < 0) { - ret = LTTCOMM_KERN_ENABLE_FAIL; + kernel_wait_quiescent(kernel_tracer_fd); + break; + default: + /* TODO: Userspace tracing */ + ret = LTTCOMM_NOT_IMPLEMENTED; goto error; } - - kernel_wait_quiescent(kernel_tracer_fd); ret = LTTCOMM_OK; break; } - case LTTNG_KERNEL_ENABLE_ALL_EVENT: + case LTTNG_ENABLE_ALL_EVENT: { - int pos, size; - char *event_list, *event, *ptr, *channel_name; + int size, i; + char *channel_name; struct ltt_kernel_channel *kchan; - struct ltt_kernel_event *ev; - struct lttng_event ev_attr; + struct ltt_kernel_event *kevent; + struct lttng_event *event_list; struct lttng_channel *chan; /* Setup lttng message with no payload */ @@ -1586,95 +1677,107 @@ static int process_client_msg(struct command_ctx *cmd_ctx) channel_name = cmd_ctx->lsm->u.enable.channel_name; - do { - kchan = get_kernel_channel_by_name(channel_name, - cmd_ctx->session->kernel_session); - if (kchan == NULL) { - DBG("Creating default channel"); + 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(channel_name); + if (chan == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } - chan = init_default_channel(); - if (chan == NULL) { - ret = LTTCOMM_FATAL; - goto error; + ret = kernel_create_channel(cmd_ctx->session->kernel_session, + chan, cmd_ctx->session->path); + if (ret < 0) { + ret = LTTCOMM_KERN_CHAN_FAIL; + goto error; + } } + } while (kchan == NULL); - ret = kernel_create_channel(cmd_ctx->session->kernel_session, - chan, cmd_ctx->session->path); + /* For each event in the kernel session */ + cds_list_for_each_entry(kevent, &kchan->events_list.head, list) { + DBG("Enabling kernel event %s for channel %s.", + kevent->event->name, channel_name); + ret = kernel_enable_event(kevent); if (ret < 0) { - ret = LTTCOMM_KERN_CHAN_FAIL; - goto error; + continue; } } - } while (kchan == NULL); - /* For each event in the kernel session */ - cds_list_for_each_entry(ev, &kchan->events_list.head, list) { - DBG("Enabling kernel event %s for channel %s.", - ev->event->name, channel_name); - ret = kernel_enable_event(ev); - if (ret < 0) { - continue; + size = kernel_list_events(kernel_tracer_fd, &event_list); + if (size < 0) { + ret = LTTCOMM_KERN_LIST_FAIL; + goto error; } - } - 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) { - ev = get_kernel_event_by_name(event, kchan); - if (ev == NULL) { - strncpy(ev_attr.name, event, LTTNG_SYM_NAME_LEN); - /* Default event type for enable all */ - ev_attr.type = LTTNG_EVENT_TRACEPOINT; - /* Enable each single tracepoint event */ - ret = kernel_create_event(&ev_attr, kchan); - if (ret < 0) { - /* Ignore error here and continue */ + for (i = 0; i < size; i++) { + kevent = get_kernel_event_by_name(event_list[i].name, kchan); + if (kevent == NULL) { + /* Default event type for enable all */ + event_list[i].type = LTTNG_EVENT_TRACEPOINT; + /* Enable each single tracepoint event */ + ret = kernel_create_event(&event_list[i], kchan); + if (ret < 0) { + /* Ignore error here and continue */ + } } } - /* Move pointer to the next line */ - ptr += pos + 1; - free(event); - } + free(event_list); - free(event_list); + /* Quiescent wait after event enable */ + kernel_wait_quiescent(kernel_tracer_fd); + break; + default: + /* TODO: Userspace tracing */ + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; + } - /* Quiescent wait after event enable */ - kernel_wait_quiescent(kernel_tracer_fd); ret = LTTCOMM_OK; break; } - case LTTNG_KERNEL_LIST_EVENTS: + case LTTNG_LIST_TRACEPOINTS: { - char *event_list; - ssize_t size = 0; - - DBG("Listing kernel events"); - - size = kernel_list_events(kernel_tracer_fd, &event_list); - if (size < 0) { - ret = LTTCOMM_KERN_LIST_FAIL; - goto error; + struct lttng_event *events; + ssize_t nb_events = 0; + + switch (cmd_ctx->lsm->domain.type) { + case LTTNG_DOMAIN_KERNEL: + DBG("Listing kernel events"); + nb_events = kernel_list_events(kernel_tracer_fd, &events); + if (nb_events < 0) { + ret = LTTCOMM_KERN_LIST_FAIL; + goto error; + } + break; + default: + /* TODO: Userspace listing */ + ret = LTTCOMM_NOT_IMPLEMENTED; + break; } /* * 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); + ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_event) * nb_events); if (ret < 0) { + free(events); goto setup_error; } /* Copy event list into message payload */ - memcpy(cmd_ctx->llm->payload, event_list, size); + memcpy(cmd_ctx->llm->payload, events, + sizeof(struct lttng_event) * nb_events); - free(event_list); + free(events); ret = LTTCOMM_OK; break; @@ -1714,7 +1817,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } /* For each channel */ - cds_list_for_each_entry(chan, &cmd_ctx->session->kernel_session->channel_list.head, list) { + cds_list_for_each_entry(chan, + &cmd_ctx->session->kernel_session->channel_list.head, list) { if (chan->stream_count == 0) { ret = kernel_open_channel_stream(chan); if (ret < 0) { @@ -1799,7 +1903,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_error; } - ret = create_session(cmd_ctx->lsm->session_name, cmd_ctx->lsm->path); + ret = create_session(cmd_ctx->lsm->session.name, cmd_ctx->lsm->session.path); if (ret < 0) { if (ret == -EEXIST) { ret = LTTCOMM_EXIST_SESS; @@ -1823,7 +1927,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) /* Clean kernel session teardown */ teardown_kernel_session(cmd_ctx->session); - ret = destroy_session(cmd_ctx->lsm->session_name); + ret = destroy_session(cmd_ctx->lsm->session.name); if (ret < 0) { ret = LTTCOMM_FATAL; goto error; @@ -1842,105 +1946,98 @@ static int process_client_msg(struct command_ctx *cmd_ctx) ret = LTTCOMM_OK; break; } - /* - case LTTNG_LIST_TRACES: + case LTTNG_LIST_DOMAINS: { - unsigned int trace_count; + size_t nb_dom = 0; - trace_count = get_trace_count_per_session(cmd_ctx->session); - if (trace_count == 0) { - ret = LTTCOMM_NO_TRACE; - goto error; + if (cmd_ctx->session->kernel_session != NULL) { + nb_dom++; } - ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_trace) * trace_count); + nb_dom += cmd_ctx->session->ust_trace_count; + + ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_domain) * nb_dom); if (ret < 0) { goto setup_error; } - get_traces_per_session(cmd_ctx->session, - (struct lttng_trace *)(cmd_ctx->llm->payload)); + ((struct lttng_domain *)(cmd_ctx->llm->payload))[0].type = + LTTNG_DOMAIN_KERNEL; + /* TODO: User-space tracer domain support */ ret = LTTCOMM_OK; break; } - */ - /* - case UST_CREATE_TRACE: + case LTTNG_LIST_CHANNELS: { - ret = setup_lttng_msg(cmd_ctx, 0); - if (ret < 0) { - goto setup_error; - } - - ret = ust_create_trace(cmd_ctx); - if (ret < 0) { - goto error; - } - break; - } - */ - case LTTNG_LIST_TRACEABLE_APPS: - { - unsigned int app_count; - - app_count = get_app_count(); - DBG("Traceable application count : %d", app_count); - if (app_count == 0) { - ret = LTTCOMM_NO_APPS; - goto error; + /* + * TODO: Only kernel channels are listed here. UST listing + * is needed on lttng-ust 2.0 release. + */ + size_t nb_chan = 0; + if (cmd_ctx->session->kernel_session != NULL) { + nb_chan += cmd_ctx->session->kernel_session->channel_count; } - ret = setup_lttng_msg(cmd_ctx, sizeof(pid_t) * app_count); + ret = setup_lttng_msg(cmd_ctx, + sizeof(struct lttng_channel) * nb_chan); if (ret < 0) { goto setup_error; } - get_app_list_pids((pid_t *)(cmd_ctx->llm->payload)); + list_lttng_channels(cmd_ctx->session, + (struct lttng_channel *)(cmd_ctx->llm->payload)); ret = LTTCOMM_OK; break; } - /* - case UST_START_TRACE: + case LTTNG_LIST_EVENTS: { - ret = setup_lttng_msg(cmd_ctx, 0); - if (ret < 0) { - goto setup_error; - } + /* + * TODO: Only kernel events are listed here. UST listing + * is needed on lttng-ust 2.0 release. + */ + size_t nb_event = 0; + struct ltt_kernel_channel *kchan = NULL; - ret = ust_start_trace(cmd_ctx); - if (ret < 0) { - goto setup_error; - } - break; - } - case UST_STOP_TRACE: - { - ret = setup_lttng_msg(cmd_ctx, 0); - if (ret < 0) { - goto setup_error; + if (cmd_ctx->session->kernel_session != NULL) { + kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.list.channel_name, + cmd_ctx->session->kernel_session); + if (kchan == NULL) { + ret = LTTCOMM_KERN_CHAN_NOT_FOUND; + goto error; + } + nb_event += kchan->event_count; } - ret = ust_stop_trace(cmd_ctx); + ret = setup_lttng_msg(cmd_ctx, + sizeof(struct lttng_event) * nb_event); if (ret < 0) { goto setup_error; } + + DBG("Listing events (%ld events)", nb_event); + + list_lttng_events(kchan, + (struct lttng_event *)(cmd_ctx->llm->payload)); + + ret = LTTCOMM_OK; break; } - */ case LTTNG_LIST_SESSIONS: { lock_session_list(); if (session_list_ptr->count == 0) { ret = LTTCOMM_NO_SESSION; + unlock_session_list(); goto error; } ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) * session_list_ptr->count); if (ret < 0) { + unlock_session_list(); goto setup_error; }