#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"
+#include "benchmark.h"
+
/* Const values */
const char default_home_dir[] = DEFAULT_HOME_DIR;
const char default_tracing_group[] = LTTNG_DEFAULT_TRACING_GROUP;
}
DBG("Closing all UST sockets");
- clean_traceable_apps_list();
+ ust_app_clean_list();
pthread_mutex_destroy(&kconsumerd_pid_mutex);
close(thread_quit_pipe[0]);
close(thread_quit_pipe[1]);
+
+ /* OUTPUT BENCHMARK RESULTS */
+ bench_init();
+
+ if (getenv("BENCH_UST_NOTIFY")) {
+ bench_print_ust_notification();
+ }
+
+ if (getenv("BENCH_UST_REGISTER")) {
+ bench_print_ust_register();
+ }
+
+ if (getenv("BENCH_BOOT_PROCESS")) {
+ bench_print_boot_process();
+ }
+
+ bench_close();
+ /* END BENCHMARK */
}
/*
DBG("Notifying applications of session daemon state: %d", active);
+ tracepoint(ust_notify_apps_start);
+
/* See shm.c for this call implying mmap, shm and futex calls */
wait_shm_mmap = shm_ust_get_mmap(wait_shm_path, is_root);
if (wait_shm_mmap == NULL) {
/* Wake waiting process */
futex_wait_update((int32_t *) wait_shm_mmap, active);
+ tracepoint(ust_notify_apps_stop);
+
/* Apps notified successfully */
return 0;
char tmp;
struct lttng_poll_event events;
+ tracepoint(sessiond_th_kern_start);
+
DBG("Thread manage kernel started");
ret = create_thread_poll_set(&events, 2);
/* Zeroed the poll events */
lttng_poll_reset(&events);
+ tracepoint(sessiond_th_kern_poll);
+
/* Poll infinite value of time */
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
enum lttcomm_return_code code;
struct lttng_poll_event events;
+ tracepoint(sessiond_th_kcon_start);
+
DBG("[thread] Manage kconsumerd started");
ret = lttcomm_listen_unix_sock(kconsumerd_err_sock);
nb_fd = LTTNG_POLL_GETNB(&events);
+ tracepoint(sessiond_th_kcon_poll);
+
/* Inifinite blocking call, waiting for transmission */
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
struct ust_command ust_cmd;
struct lttng_poll_event events;
+ tracepoint(sessiond_th_apps_start);
+
DBG("[thread] Manage application started");
ret = create_thread_poll_set(&events, 2);
DBG("Apps thread polling on %d fds", nb_fd);
+ tracepoint(sessiond_th_apps_poll);
+
/* Inifinite blocking call, waiting for transmission */
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
ERR("Apps command pipe error");
goto error;
} else if (revents & LPOLLIN) {
+ tracepoint(ust_register_read_start);
/* Empty pipe */
ret = read(apps_cmd_pipe[0], &ust_cmd, sizeof(ust_cmd));
if (ret < 0 || ret < sizeof(ust_cmd)) {
perror("read apps cmd pipe");
goto error;
}
+ tracepoint(ust_register_read_stop);
+ tracepoint(ust_register_add_start);
/* 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 */
goto error;
}
+ tracepoint(ust_register_add_stop);
+ tracepoint(ust_register_done_start);
ret = ustctl_register_done(ust_cmd.sock);
if (ret < 0) {
/*
* 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
DBG("Apps with sock %d added to poll set",
ust_cmd.sock);
}
+ tracepoint(ust_register_done_stop);
break;
}
} else {
}
/* Socket closed */
- unregister_traceable_app(pollfd);
+ ust_app_unregister(pollfd);
break;
}
}
struct cds_wfq_node *node;
struct ust_command *ust_cmd = NULL;
+ tracepoint(sessiond_th_dispatch_start);
+
DBG("[thread] Dispatch UST command started");
while (!dispatch_thread_exit) {
futex_nto1_prepare(&ust_cmd_queue.futex);
do {
+ tracepoint(sessiond_th_dispatch_block);
+
/* Dequeue command for registration */
node = cds_wfq_dequeue_blocking(&ust_cmd_queue.queue);
if (node == NULL) {
break;
}
+ tracepoint(ust_dispatch_register_start);
+
ust_cmd = caa_container_of(node, struct ust_command, node);
DBG("Dispatching UST registration pid:%d ppid:%d uid:%d"
free(ust_cmd);
} while (node != NULL);
+ tracepoint(ust_dispatch_register_stop);
+
/* Futex wait on queue. Blocking call on futex() */
futex_nto1_wait(&ust_cmd_queue.futex);
}
*/
struct ust_command *ust_cmd = NULL;
+ tracepoint(sessiond_th_reg_start);
+
DBG("[thread] Manage application registration started");
ret = lttcomm_listen_unix_sock(apps_sock);
while (1) {
DBG("Accepting application registration");
+ tracepoint(sessiond_th_reg_poll);
+
nb_fd = LTTNG_POLL_GETNB(&events);
/* Inifinite blocking call, waiting for transmission */
ERR("Register apps socket poll error");
goto error;
} else if (revents & LPOLLIN) {
+ /* Registration starts here. Recording cycles */
+ tracepoint(ust_register_start);
+
sock = lttcomm_accept_unix_sock(apps_sock);
if (sock < 0) {
goto error;
* barrier with the exchange in cds_wfq_enqueue.
*/
futex_nto1_wake(&ust_cmd_queue.futex);
+
+ tracepoint(ust_register_stop);
}
}
}
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;
}
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 */
}
ret = mount_debugfs(debugfs_path);
if (ret < 0) {
+ perror("Cannot mount debugfs");
goto 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;
+ int ret;
struct ltt_ust_session *lus;
+ 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:
+ 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;
}
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);
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++;
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;
}
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;
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;
}
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;
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;
}
* 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;
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;
}
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;
}
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) {
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);
}
/* 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) {
}
}
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;
}
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;
}
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:
}
case LTTNG_CREATE_SESSION:
{
+ tracepoint(create_session_start);
ret = cmd_create_session(cmd_ctx->lsm->session.name,
cmd_ctx->lsm->session.path);
+ tracepoint(create_session_end);
break;
}
case LTTNG_DESTROY_SESSION:
{
+ tracepoint(destroy_session_start);
ret = cmd_destroy_session(cmd_ctx->session,
cmd_ctx->lsm->session.name);
+ tracepoint(destroy_session_end);
break;
}
case LTTNG_LIST_DOMAINS:
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);
struct command_ctx *cmd_ctx = NULL;
struct lttng_poll_event events;
+ tracepoint(sessiond_th_cli_start);
+
DBG("[thread] Manage client started");
ret = lttcomm_listen_unix_sock(client_sock);
while (1) {
DBG("Accepting client command ...");
+ tracepoint(sessiond_th_cli_poll);
+
nb_fd = LTTNG_POLL_GETNB(&events);
/* Inifinite blocking call, waiting for transmission */
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");
void *status;
const char *home_path;
+ tracepoint(sessiond_boot_start);
+
/* Create thread quit pipe */
if ((ret = init_thread_quit_pipe()) < 0) {
goto error;
goto exit_kernel;
}
+ tracepoint(sessiond_boot_end);
+
ret = pthread_join(kernel_thread, &status);
if (ret != 0) {
perror("pthread_join");