From 44d3bd014f6ad217cff7e7c3dfaad76b1927c37b Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 26 Sep 2011 18:33:16 -0400 Subject: [PATCH] Add enable channel support for UST Also improve data structure for UST session control to fit new model where we will have a list of lttng domain to indentify the ust session. Signed-off-by: David Goulet --- ltt-sessiond/channel.c | 92 ++++++++++++++++-- ltt-sessiond/channel.h | 10 +- ltt-sessiond/main.c | 183 ++++++++++++++++++++++++++++------- ltt-sessiond/trace-ust.c | 124 ++++++++++++------------ ltt-sessiond/trace-ust.h | 31 +++--- ltt-sessiond/traceable-app.c | 13 ++- ltt-sessiond/traceable-app.h | 5 + ltt-sessiond/ust-comm.c | 6 +- ltt-sessiond/ust-ctl.c | 140 +++++++++++++++++++++++++-- ltt-sessiond/ust-ctl.h | 12 ++- 10 files changed, 485 insertions(+), 131 deletions(-) diff --git a/ltt-sessiond/channel.c b/ltt-sessiond/channel.c index ab9bf6c6d..818f6dcfd 100644 --- a/ltt-sessiond/channel.c +++ b/ltt-sessiond/channel.c @@ -23,12 +23,13 @@ #include "channel.h" #include "kernel-ctl.h" +#include "ust-ctl.h" #include "utils.h" /* * Return allocated channel attributes. */ -static struct lttng_channel *init_default_attr(int dom, char *name) +static struct lttng_channel *init_default_attr(int dom) { struct lttng_channel *chan; @@ -38,8 +39,9 @@ static struct lttng_channel *init_default_attr(int dom, char *name) goto error_alloc; } - if (snprintf(chan->name, sizeof(chan->name), "%s", name) < 0) { - perror("snprintf channel name"); + if (snprintf(chan->name, sizeof(chan->name), "%s", + DEFAULT_CHANNEL_NAME) < 0) { + perror("snprintf default channel name"); goto error; } @@ -53,7 +55,11 @@ static struct lttng_channel *init_default_attr(int dom, char *name) chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; - /* TODO: add UST */ + case LTTNG_DOMAIN_UST_PID: + chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; + chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; + break; default: goto error; /* Not implemented */ } @@ -121,14 +127,14 @@ error: * Create kernel channel of the kernel session and notify kernel thread. */ int channel_kernel_create(struct ltt_kernel_session *ksession, - char *channel_name, struct lttng_channel *chan, int kernel_pipe) + struct lttng_channel *chan, int kernel_pipe) { int ret; struct lttng_channel *attr = chan; /* Creating channel attributes if needed */ if (attr == NULL) { - attr = init_default_attr(LTTNG_DOMAIN_KERNEL, channel_name); + attr = init_default_attr(LTTNG_DOMAIN_KERNEL); if (attr == NULL) { ret = LTTCOMM_FATAL; goto error; @@ -154,3 +160,77 @@ int channel_kernel_create(struct ltt_kernel_session *ksession, error: return ret; } + +/* + * Create UST channel and enable it on the tracer. + */ +int channel_ust_create(struct ltt_ust_session *usession, + struct lttng_channel *chan, int sock) +{ + int ret; + struct lttng_channel *attr = chan; + + /* Creating channel attributes if needed */ + if (attr == NULL) { + attr = init_default_attr(LTTNG_DOMAIN_UST_PID); + if (attr == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + } + + ret = ustctl_create_channel(sock, usession, attr); + if (ret < 0) { + ret = LTTCOMM_UST_CHAN_FAIL; + goto error; + } + + DBG2("Channel %s UST create successfully for sock:%d", attr->name, sock); + + ret = LTTCOMM_OK; + +error: + return ret; +} + +/* + * Enable UST channel on the tracer. + */ +int channel_ust_enable(struct ltt_ust_session *usession, + struct ltt_ust_channel *uchan, int sock) +{ + int ret; + ret = LTTCOMM_OK; + + ret = ustctl_enable_channel(sock, usession, uchan); + if (ret < 0) { + ret = LTTCOMM_UST_CHAN_FAIL; + goto error; + } + + ret = LTTCOMM_OK; + +error: + return ret; +} + +/* + * Disable UST channel on the tracer. + */ +int channel_ust_disable(struct ltt_ust_session *usession, + struct ltt_ust_channel *uchan, int sock) +{ + int ret; + ret = LTTCOMM_OK; + + ret = ustctl_disable_channel(sock, usession, uchan); + if (ret < 0) { + ret = LTTCOMM_UST_CHAN_FAIL; + goto error; + } + + ret = LTTCOMM_OK; + +error: + return ret; +} diff --git a/ltt-sessiond/channel.h b/ltt-sessiond/channel.h index 271721a97..f9a6fbd85 100644 --- a/ltt-sessiond/channel.h +++ b/ltt-sessiond/channel.h @@ -21,12 +21,20 @@ #include #include "trace-kernel.h" +#include "trace-ust.h" int channel_kernel_disable(struct ltt_kernel_session *ksession, char *channel_name); int channel_kernel_enable(struct ltt_kernel_session *ksession, struct ltt_kernel_channel *kchan); int channel_kernel_create(struct ltt_kernel_session *ksession, - char *channel_name, struct lttng_channel *chan, int kernel_pipe); + struct lttng_channel *chan, int kernel_pipe); + +int channel_ust_create(struct ltt_ust_session *usession, + struct lttng_channel *chan, int sock); +int channel_ust_disable(struct ltt_ust_session *usession, + struct ltt_ust_channel *uchan, int sock); +int channel_ust_enable(struct ltt_ust_session *usession, + struct ltt_ust_channel *uchan, int sock); #endif /* _LTT_CHANNEL_H */ diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index bcb43e19d..825fa4371 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -1561,15 +1561,30 @@ 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 ltt_traceable_app *app; + + switch (domain->type) { + case LTTNG_DOMAIN_UST_PID: + app = traceable_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; } @@ -1578,17 +1593,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); @@ -1742,9 +1762,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; } @@ -1757,33 +1778,106 @@ error: /* * 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) { + 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); + } + + if (ret != LTTCOMM_OK) { + goto error; + } + + kernel_wait_quiescent(kernel_tracer_fd); + break; + } + case LTTNG_DOMAIN_UST_PID: + { + struct ltt_ust_event *uevent, *new_uevent; + struct ltt_ust_session *usess; + struct ltt_ust_channel *uchan, *app_chan; + struct ltt_traceable_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 = traceable_app_get_by_pid(domain->attr.pid); + if (app == NULL) { + ret = LTTCOMM_APP_NOT_FOUND; + goto error; + } + + uchan = trace_ust_get_channel_by_name(attr->name, usess); + if (uchan == NULL) { + ret = channel_ust_create(usess, attr, app->sock); + } else { + ret = channel_ust_enable(usess, uchan, app->sock); + } + + if (ret != LTTCOMM_OK) { + goto error; + } + + /*TODO: This should be put in an external function */ + + /* Copy UST channel to add to the traceable app */ + uchan = trace_ust_get_channel_by_name(attr->name, usess); + if (uchan == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + + app_chan = trace_ust_create_channel(attr, session->path); + if (app_chan == NULL) { + PERROR("malloc ltt_ust_channel"); + ret = LTTCOMM_FATAL; + goto error; + } + + memcpy(app_chan, uchan, sizeof(struct ltt_ust_channel)); + CDS_INIT_LIST_HEAD(&app_chan->events.head); + + cds_list_for_each_entry(uevent, &uchan->events.head, list) { + new_uevent = malloc(sizeof(struct ltt_ust_event)); + if (new_uevent == NULL) { + PERROR("malloc ltt_ust_event"); + ret = LTTCOMM_FATAL; goto error; } - kernel_wait_quiescent(kernel_tracer_fd); - break; - default: - /* TODO: Userspace tracing */ - ret = LTTCOMM_NOT_IMPLEMENTED; - goto error; + memcpy(new_uevent, uevent, sizeof(struct ltt_ust_event)); + cds_list_add(&new_uevent->list, &app_chan->events.head); + app_chan->events.count++; + } + + /* Add channel to traceable_app */ + cds_list_add(&app_chan->list, &app->channels.head); + app->channels.count++; + + 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; @@ -1911,7 +2005,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; @@ -1961,8 +2055,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; } @@ -2368,13 +2462,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) { @@ -2399,7 +2493,7 @@ 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); @@ -2435,7 +2529,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) { @@ -2455,6 +2549,24 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } } 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; @@ -2494,8 +2606,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; } diff --git a/ltt-sessiond/trace-ust.c b/ltt-sessiond/trace-ust.c index a9aa1abce..fe007141e 100644 --- a/ltt-sessiond/trace-ust.c +++ b/ltt-sessiond/trace-ust.c @@ -23,24 +23,33 @@ #include #include +#include #include "trace-ust.h" /* - * Return an UST session by traceable app PID. + * Using a ust session list, it will return the session corresponding to the + * pid. Must be a session of domain LTTNG_DOMAIN_UST_PID. */ -struct ltt_ust_session *trace_ust_get_session_by_pid(pid_t pid, - struct ltt_ust_session_list *session_list) +struct ltt_ust_session *trace_ust_get_session_by_pid( + struct ltt_ust_session_list *session_list, pid_t pid) { - struct ltt_ust_session *lus; + struct ltt_ust_session *sess; - cds_list_for_each_entry(lus, &session_list->head, list) { - if (lus->app->pid == pid) { - DBG("Found UST session by pid %d", pid); - return lus; + if (session_list == NULL) { + ERR("Session list is NULL"); + goto error; + } + + cds_list_for_each_entry(sess, &session_list->head, list) { + if (sess->domain.type == LTTNG_DOMAIN_UST_PID && + sess->domain.attr.pid == pid) { + DBG2("Trace UST session found by pid %d", pid); + return sess; } } +error: return NULL; } @@ -59,7 +68,7 @@ struct ltt_ust_channel *trace_ust_get_channel_by_name( cds_list_for_each_entry(chan, &session->channels.head, list) { if (strcmp(name, chan->name) == 0) { - DBG("Found UST channel by name %s", name); + DBG2("Found UST channel by name %s", name); return chan; } } @@ -82,7 +91,7 @@ struct ltt_ust_event *trace_ust_get_event_by_name( } cds_list_for_each_entry(ev, &channel->events.head, list) { - if (strcmp(name, ev->event->name) == 0) { + if (strcmp(name, ev->attr.name) == 0) { DBG("Found UST event by name %s for channel %s", name, channel->name); return ev; @@ -98,7 +107,8 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_ust_session *trace_ust_create_session(char *path, pid_t pid) +struct ltt_ust_session *trace_ust_create_session(char *path, pid_t pid, + struct lttng_domain *domain) { int ret; struct ltt_ust_session *lus; @@ -114,19 +124,22 @@ struct ltt_ust_session *trace_ust_create_session(char *path, pid_t pid) lus->handle = -1; lus->enabled = 1; lus->uconsumer_fds_sent = 0; - lus->path = NULL; lus->metadata = NULL; - lus->app = NULL; /* TODO: Search app by PID */ lus->channels.count = 0; CDS_INIT_LIST_HEAD(&lus->channels.head); + /* Copy lttng_domain */ + memcpy(&lus->domain, domain, sizeof(struct lttng_domain)); + /* Set session path */ - ret = asprintf(&lus->path, "%s/ust_%d", path, pid); + ret = snprintf(lus->path, PATH_MAX, "%s/ust_%d", path, pid); if (ret < 0) { - perror("asprintf kernel traces path"); + PERROR("snprintf kernel traces path"); goto error; } + DBG2("UST trace session create successful"); + return lus; error: @@ -138,8 +151,8 @@ error: * * Return pointer to structure or NULL. */ -struct ltt_ust_channel *trace_ust_create_channel(char *name, char *path, - struct lttng_ust_channel *chan) +struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan, + char *path) { int ret; struct ltt_ust_channel *luc; @@ -150,25 +163,29 @@ struct ltt_ust_channel *trace_ust_create_channel(char *name, char *path, goto error; } - luc->attr = malloc(sizeof(struct lttng_ust_channel)); - if (luc->attr == NULL) { - perror("lttng_ust_channel malloc"); - goto error; + /* Copy UST channel attributes */ + memcpy(&luc->attr, &chan->attr, sizeof(struct lttng_ust_channel)); + + /* Translate to UST output enum */ + switch (luc->attr.output) { + default: + luc->attr.output = LTTNG_UST_MMAP; + break; } - memcpy(luc->attr, chan, sizeof(struct lttng_ust_channel)); luc->handle = -1; luc->enabled = 1; - luc->ctx = NULL; luc->events.count = 0; CDS_INIT_LIST_HEAD(&luc->events.head); + memset(&luc->ctx, 0, sizeof(struct lttng_ust_context)); + /* Copy channel name */ - strncpy(luc->name, name, LTTNG_UST_SYM_NAME_LEN); + strncpy(luc->name, chan->name, sizeof(&luc->name)); luc->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; /* Set trace output path */ - ret = asprintf(&luc->trace_path, "%s", path); + ret = snprintf(luc->trace_path, PATH_MAX, "%s", path); if (ret < 0) { perror("asprintf ust create channel"); goto error; @@ -188,27 +205,25 @@ error: struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev) { struct ltt_ust_event *lue; - struct lttng_ust_event *event; lue = malloc(sizeof(struct ltt_ust_event)); - event = malloc(sizeof(struct lttng_ust_event)); - if (lue == NULL || event == NULL) { - perror("ust event malloc"); + if (lue == NULL) { + PERROR("ust event malloc"); goto error; } switch (ev->type) { case LTTNG_EVENT_PROBE: - event->instrumentation = LTTNG_UST_PROBE; + lue->attr.instrumentation = LTTNG_UST_PROBE; break; case LTTNG_EVENT_FUNCTION: - event->instrumentation = LTTNG_UST_FUNCTION; + lue->attr.instrumentation = LTTNG_UST_FUNCTION; break; case LTTNG_EVENT_FUNCTION_ENTRY: - event->instrumentation = LTTNG_UST_FUNCTION; + lue->attr.instrumentation = LTTNG_UST_FUNCTION; break; case LTTNG_EVENT_TRACEPOINT: - event->instrumentation = LTTNG_UST_TRACEPOINT; + lue->attr.instrumentation = LTTNG_UST_TRACEPOINT; break; default: ERR("Unknown ust instrumentation type (%d)", ev->type); @@ -216,14 +231,13 @@ struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev) } /* Copy event name */ - strncpy(event->name, ev->name, LTTNG_UST_SYM_NAME_LEN); - event->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + strncpy(lue->attr.name, ev->name, LTTNG_UST_SYM_NAME_LEN); + lue->attr.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; /* Setting up a ust event */ lue->handle = -1; - lue->event = event; lue->enabled = 1; - lue->ctx = NULL; + memset(&lue->ctx, 0, sizeof(struct lttng_ust_context)); return lue; @@ -240,24 +254,21 @@ struct ltt_ust_metadata *trace_ust_create_metadata(char *path) { int ret; struct ltt_ust_metadata *lum; - struct lttng_ust_channel *attr; lum = malloc(sizeof(struct ltt_ust_metadata)); - attr = malloc(sizeof(struct lttng_ust_channel)); - if (lum == NULL || attr == NULL) { + if (lum == NULL) { perror("ust metadata malloc"); goto error; } /* Set default attributes */ - attr->overwrite = DEFAULT_CHANNEL_OVERWRITE; - attr->subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; - attr->num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; - attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; - attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->output = DEFAULT_UST_CHANNEL_OUTPUT; - - lum->attr = attr; + lum->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; + lum->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + lum->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; + lum->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; + lum->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; + lum->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; + lum->handle = -1; /* Set metadata trace path */ ret = asprintf(&lum->trace_path, "%s/metadata", path); @@ -277,11 +288,7 @@ error: */ void trace_ust_destroy_event(struct ltt_ust_event *event) { - DBG("[trace] Destroy ust event %s", event->event->name); - - /* Free attributes */ - free(event->event); - free(event->ctx); + DBG("[trace] Destroy ust event %s", event->attr.name); /* Remove from event list */ cds_list_del(&event->list); @@ -297,11 +304,6 @@ void trace_ust_destroy_channel(struct ltt_ust_channel *channel) DBG("[trace] Destroy ust channel %d", channel->handle); - free(channel->trace_path); - /* Free attributes structure */ - free(channel->attr); - free(channel->ctx); - /* For each event in the channel list */ cds_list_for_each_entry_safe(event, etmp, &channel->events.head, list) { trace_ust_destroy_event(event); @@ -320,7 +322,6 @@ void trace_ust_destroy_metadata(struct ltt_ust_metadata *metadata) DBG("[trace] Destroy ust metadata %d", metadata->handle); /* Free attributes */ - free(metadata->attr); free(metadata->trace_path); free(metadata); @@ -348,6 +349,9 @@ void trace_ust_destroy_session(struct ltt_ust_session *session) trace_ust_destroy_channel(channel); } - free(session->path); + if (session->path) { + free(session->path); + } + free(session); } diff --git a/ltt-sessiond/trace-ust.h b/ltt-sessiond/trace-ust.h index 55a452c60..9a2366269 100644 --- a/ltt-sessiond/trace-ust.h +++ b/ltt-sessiond/trace-ust.h @@ -25,8 +25,6 @@ #include #include -#include "traceable-app.h" - /* * UST session list. */ @@ -51,8 +49,8 @@ struct ltt_ust_channel_list { struct ltt_ust_event { int handle; int enabled; - struct lttng_ust_context *ctx; - struct lttng_ust_event *event; + struct lttng_ust_context ctx; + struct lttng_ust_event attr; struct cds_list_head list; }; @@ -60,10 +58,10 @@ struct ltt_ust_event { struct ltt_ust_channel { int handle; int enabled; - char *name; - char *trace_path; /* Trace file path name */ - struct lttng_ust_context *ctx; - struct lttng_ust_channel *attr; + char name[LTTNG_UST_SYM_NAME_LEN]; + char trace_path[PATH_MAX]; /* Trace file path name */ + struct lttng_ust_context ctx; + struct lttng_ust_channel attr; struct ltt_ust_event_list events; struct cds_list_head list; }; @@ -72,7 +70,7 @@ struct ltt_ust_channel { struct ltt_ust_metadata { int handle; char *trace_path; /* Trace file path name */ - struct lttng_ust_channel *attr; + struct lttng_ust_channel attr; }; /* UST session */ @@ -80,8 +78,8 @@ struct ltt_ust_session { int handle; int enabled; int uconsumer_fds_sent; - char *path; - struct ltt_traceable_app *app; + char path[PATH_MAX]; + struct lttng_domain domain; struct ltt_ust_metadata *metadata; struct ltt_ust_channel_list channels; struct cds_list_head list; @@ -94,15 +92,16 @@ struct ltt_ust_event *trace_ust_get_event_by_name( char *name, struct ltt_ust_channel *channel); struct ltt_ust_channel *trace_ust_get_channel_by_name( char *name, struct ltt_ust_session *session); -struct ltt_ust_session *trace_ust_get_session_by_pid(pid_t pid, - struct ltt_ust_session_list *session_list); +struct ltt_ust_session *trace_ust_get_session_by_pid( + struct ltt_ust_session_list *session_list, pid_t pid); /* * Create functions malloc() the data structure. */ -struct ltt_ust_session *trace_ust_create_session(char *path, pid_t pid); -struct ltt_ust_channel *trace_ust_create_channel(char *name, char *path, - struct lttng_ust_channel *attr); +struct ltt_ust_session *trace_ust_create_session(char *path, pid_t pid, + struct lttng_domain *domain); +struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *attr, + char *path); struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev); struct ltt_ust_metadata *trace_ust_create_metadata(char *path); diff --git a/ltt-sessiond/traceable-app.c b/ltt-sessiond/traceable-app.c index 653d86b3f..41dc51111 100644 --- a/ltt-sessiond/traceable-app.c +++ b/ltt-sessiond/traceable-app.c @@ -49,11 +49,17 @@ static void add_traceable_app(struct ltt_traceable_app *lta) */ static void del_traceable_app(struct ltt_traceable_app *lta) { + struct ltt_ust_channel *chan; + cds_list_del(<a->list); /* Sanity check */ if (ltt_traceable_app_list.count > 0) { ltt_traceable_app_list.count--; } + + cds_list_for_each_entry(chan, <a->channels.head, list) { + trace_ust_destroy_channel(chan); + } } /* @@ -109,10 +115,13 @@ struct ltt_traceable_app *traceable_app_get_by_pid(pid_t pid) cds_list_for_each_entry(iter, <t_traceable_app_list.head, list) { if (iter->pid == pid) { /* Found */ + DBG2("Found traceable app by pid %d", pid); return iter; } } + DBG2("Traceable app with pid %d not found", pid); + return NULL; } @@ -141,6 +150,7 @@ int register_traceable_app(struct ust_register_msg *msg, int sock) lta->sock = sock; strncpy(lta->name, msg->name, sizeof(lta->name)); lta->name[16] = '\0'; + CDS_INIT_LIST_HEAD(<a->channels.head); lock_apps_list(); add_traceable_app(lta); @@ -167,8 +177,8 @@ void unregister_traceable_app(int sock) lta = find_app_by_sock(sock); if (lta) { DBG("PID %d unregistered with sock %d", lta->pid, sock); - close(lta->sock); del_traceable_app(lta); + close(lta->sock); free(lta); } unlock_apps_list(); @@ -200,6 +210,7 @@ void clean_traceable_apps_list(void) * cleanup() functions meaning that the program will exit. */ cds_list_for_each_entry_safe(iter, tmp, <t_traceable_app_list.head, list) { + del_traceable_app(iter); close(iter->sock); free(iter); } diff --git a/ltt-sessiond/traceable-app.h b/ltt-sessiond/traceable-app.h index 4d5e56a66..39f97f2a2 100644 --- a/ltt-sessiond/traceable-app.h +++ b/ltt-sessiond/traceable-app.h @@ -22,6 +22,8 @@ #include #include +#include "trace-ust.h" + /* * Application registration data structure. */ @@ -70,6 +72,7 @@ struct ltt_traceable_app { uint32_t v_major; /* Verion major number */ uint32_t v_minor; /* Verion minor number */ char name[17]; /* Process name (short) */ + struct ltt_ust_channel_list channels; struct cds_list_head list; }; @@ -82,4 +85,6 @@ void unlock_apps_list(void); void clean_traceable_apps_list(void); struct ltt_traceable_app_list *get_traceable_apps_list(void); +struct ltt_traceable_app *traceable_app_get_by_pid(pid_t pid); + #endif /* _TRACEABLE_APP_H */ diff --git a/ltt-sessiond/ust-comm.c b/ltt-sessiond/ust-comm.c index 31c40070e..455d40c0a 100644 --- a/ltt-sessiond/ust-comm.c +++ b/ltt-sessiond/ust-comm.c @@ -24,7 +24,7 @@ /* * Send msg containing a command to an UST application via sock and wait for - * the reply. + * the reply. Caller must free() the reply structure sent back. * * Return the replied structure or NULL. */ @@ -39,7 +39,7 @@ struct lttcomm_ust_reply *ustcomm_send_command(int sock, goto error; } - DBG("Sending UST command %d to sock %d", msg->cmd, sock); + DBG2("Sending UST command %d to sock %d", msg->cmd, sock); /* Send UST msg */ len = lttcomm_send_unix_sock(sock, msg, sizeof(*msg)); @@ -53,7 +53,7 @@ struct lttcomm_ust_reply *ustcomm_send_command(int sock, goto error; } - DBG("Receiving UST reply on sock %d", sock); + DBG2("Receiving UST reply on sock %d", sock); /* Get UST reply */ len = lttcomm_recv_unix_sock(sock, reply, sizeof(*reply)); diff --git a/ltt-sessiond/ust-ctl.c b/ltt-sessiond/ust-ctl.c index 5f4e8a9fc..2753b6f5a 100644 --- a/ltt-sessiond/ust-ctl.c +++ b/ltt-sessiond/ust-ctl.c @@ -60,17 +60,15 @@ error: /* * Create an UST session on the tracer. */ -int ustctl_create_session(struct ltt_ust_session *session) +int ustctl_create_session(int sock, struct ltt_ust_session *session) { struct lttcomm_ust_msg command; - struct lttcomm_ust_reply *reply; - - DBG("Creating UST session for app pid:%d", session->app->pid); + struct lttcomm_ust_reply *reply = NULL; command.cmd = LTTNG_UST_SESSION; command.handle = LTTNG_UST_ROOT_HANDLE; - reply = ustcomm_send_command(session->app->sock, &command); + reply = ustcomm_send_command(sock, &command); if (reply == NULL) { goto error; } @@ -81,10 +79,140 @@ int ustctl_create_session(struct ltt_ust_session *session) } /* Save session handle */ - session->handle = reply->handle; + session->handle = reply->ret_val; + free(reply); + + DBG2("ustctl create session command successful"); + return 0; + +error: + free(reply); + return -1; +} + +/* + * Create UST channel to the tracer. + */ +int ustctl_create_channel(int sock, struct ltt_ust_session *session, + struct lttng_channel *channel) +{ + struct lttcomm_ust_msg command; + struct lttcomm_ust_reply *reply = NULL; + struct ltt_ust_channel *uchan; + + uchan = trace_ust_create_channel(channel, session->path); + if (uchan == NULL) { + goto error; + } + + memset(&command, 0, sizeof(command)); + + command.cmd = LTTNG_UST_CHANNEL; + command.handle = session->handle; + + /* Copy channel attributes to command */ + memcpy(&command.u.channel, &uchan->attr, sizeof(command.u.channel)); + + reply = ustcomm_send_command(sock, &command); + if (reply == NULL) { + goto error; + } + + if (reply->ret_code != LTTCOMM_OK) { + DBG("Return code (%d): %s", reply->ret_code, + lttcomm_get_readable_code(reply->ret_code)); + goto error; + } + + uchan->handle = reply->ret_val; + + /* Add channel to session */ + cds_list_add(&uchan->list, &session->channels.head); + session->channels.count++; + + free(reply); + + return 0; + +error: + free(reply); + return -1; +} + +/* + * Enable UST channel. + */ +int ustctl_enable_channel(int sock, struct ltt_ust_session *session, + struct ltt_ust_channel *chan) +{ + struct lttcomm_ust_msg command; + struct lttcomm_ust_reply *reply = NULL; + + memset(&command, 0, sizeof(command)); + + command.cmd = LTTNG_UST_ENABLE; + command.handle = chan->handle; + + reply = ustcomm_send_command(sock, &command); + if (reply == NULL) { + goto error; + } + + if (reply->ret_code != LTTCOMM_OK) { + DBG("Return code (%d): %s", reply->ret_code, + lttcomm_get_readable_code(reply->ret_code)); + goto error; + } else if (reply->handle != chan->handle) { + ERR("Receive wrong handle from UST reply on enable channel"); + goto error; + } + + chan->enabled = 1; + free(reply); + + DBG2("ustctl enable channel successful for sock %d", sock); + return 0; + +error: + free(reply); + return -1; +} + +/* + * Disable UST channel. + */ +int ustctl_disable_channel(int sock, struct ltt_ust_session *session, + struct ltt_ust_channel *chan) +{ + struct lttcomm_ust_msg command; + struct lttcomm_ust_reply *reply = NULL; + + memset(&command, 0, sizeof(command)); + + command.cmd = LTTNG_UST_DISABLE; + command.handle = chan->handle; + + reply = ustcomm_send_command(sock, &command); + if (reply == NULL) { + goto error; + } + + if (reply->ret_code != LTTCOMM_OK) { + DBG("Return code (%d): %s", reply->ret_code, + lttcomm_get_readable_code(reply->ret_code)); + goto error; + } else if (reply->handle != chan->handle) { + ERR("Receive wrong handle from UST reply on enable channel"); + goto error; + } + + chan->enabled = 1; + free(reply); + DBG2("ustctl disable channel successful for sock %d", sock); return 0; error: + free(reply); return -1; } diff --git a/ltt-sessiond/ust-ctl.h b/ltt-sessiond/ust-ctl.h index 8f8bebc99..c4d754eca 100644 --- a/ltt-sessiond/ust-ctl.h +++ b/ltt-sessiond/ust-ctl.h @@ -19,10 +19,18 @@ #ifndef _LTT_UST_CTL_H #define _LTT_UST_CTL_H +#include + #include "trace-ust.h" int ustctl_register_done(int sock); -int ustctl_create_session(struct ltt_ust_session *session); -int ustctl_destroy_session(struct ltt_ust_session *session); +int ustctl_create_channel(int sock, struct ltt_ust_session *session, + struct lttng_channel *channel); +int ustctl_create_session(int sock, struct ltt_ust_session *session); +int ustctl_destroy_session(int sock, struct ltt_ust_session *session); +int ustctl_disable_channel(int sock, struct ltt_ust_session *session, + struct ltt_ust_channel *chan); +int ustctl_enable_channel(int sock, struct ltt_ust_session *session, + struct ltt_ust_channel *chan); #endif /* _LTT_UST_CTL_H */ -- 2.34.1