return ret;
}
+/*
+ * Enable all UST tracepoints for a channel from a UST session.
+ */
+int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain,
+ struct ltt_ust_channel *uchan)
+{
+ int ret, i;
+ size_t size;
+ struct cds_lfht_iter iter;
+ struct ltt_ust_event *uevent = NULL;
+ struct lttng_event *events;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_UST:
+ {
+ /* Enable existing events */
+ cds_lfht_for_each_entry(uchan->events, &iter, uevent, node) {
+ if (uevent->enabled == 0) {
+ ret = ust_app_enable_event_glb(usess, uchan, uevent);
+ if (ret < 0) {
+ continue;
+ }
+ uevent->enabled = 1;
+ }
+ }
+
+ /* Get all UST available events */
+ size = ust_app_list_events(&events);
+ if (size < 0) {
+ ret = LTTCOMM_UST_LIST_FAIL;
+ goto error;
+ }
+
+ for (i = 0; i < size; i++) {
+ /*
+ * Check if event exist and if so, continue since it was enable
+ * previously.
+ */
+ uevent = trace_ust_find_event_by_name(uchan->events,
+ events[i].name);
+ if (uevent != NULL) {
+ ret = ust_app_enable_event_pid(usess, uchan, uevent,
+ events[i].pid);
+ if (ret < 0) {
+ if (ret != -EEXIST) {
+ ret = LTTCOMM_UST_ENABLE_FAIL;
+ goto error;
+ }
+ }
+ continue;
+ }
+
+ /* Create ust event */
+ uevent = trace_ust_create_event(&events[i]);
+ if (uevent == NULL) {
+ ret = LTTCOMM_FATAL;
+ goto error;
+ }
+
+ /* Create event for the specific PID */
+ ret = ust_app_enable_event_pid(usess, uchan, uevent,
+ events[i].pid);
+ if (ret < 0) {
+ if (ret == -EEXIST) {
+ ret = LTTCOMM_UST_EVENT_EXIST;
+ } else {
+ ret = LTTCOMM_UST_ENABLE_FAIL;
+ }
+ goto error;
+ }
+
+ uevent->enabled = 1;
+ /* Add ltt ust event to channel */
+ rcu_read_lock();
+ hashtable_add_unique(uchan->events, &uevent->node);
+ rcu_read_unlock();
+ }
+
+ free(events);
+ break;
+ }
+ case LTTNG_DOMAIN_UST_EXEC_NAME:
+ case LTTNG_DOMAIN_UST_PID:
+ case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
+ default:
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ goto error;
+ }
+
+ return LTTCOMM_OK;
+
+error:
+ trace_ust_destroy_event(uevent);
+ return ret;
+}
+
/*
* Enable UST tracepoint event for a channel from a UST session.
*/
struct ltt_ust_channel *uchan, struct lttng_event *event);
int event_ust_disable_tracepoint(struct ltt_ust_session *ustsession,
struct ltt_ust_channel *ustchan, char *event_name);
+int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain,
+ struct ltt_ust_channel *uchan);
#endif /* _LTT_EVENT_H */
}
switch (event_type) {
- case LTTNG_KERNEL_SYSCALL:
+ case LTTNG_EVENT_SYSCALL:
ret = event_kernel_enable_all_syscalls(session->kernel_session,
kchan, kernel_tracer_fd);
break;
- case LTTNG_KERNEL_TRACEPOINT:
+ case LTTNG_EVENT_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:
+ case LTTNG_EVENT_ALL:
/* Enable syscalls and tracepoints */
ret = event_kernel_enable_all(session->kernel_session,
kchan, kernel_tracer_fd);
kernel_wait_quiescent(kernel_tracer_fd);
break;
+ case LTTNG_DOMAIN_UST:
+ {
+ struct lttng_channel *attr;
+ struct ltt_ust_channel *uchan;
+ struct ltt_ust_session *usess = session->ust_session;
+
+ /* Get channel from global UST domain */
+ uchan = trace_ust_find_channel_by_name(usess->domain_global.channels,
+ channel_name);
+ if (uchan == NULL) {
+ /* Create default channel */
+ attr = channel_new_default_attr(domain);
+ if (attr == NULL) {
+ ret = LTTCOMM_FATAL;
+ goto error;
+ }
+ snprintf(attr->name, NAME_MAX, "%s", channel_name);
+ attr->name[NAME_MAX - 1] = '\0';
+
+ /* Use the internal command enable channel */
+ ret = cmd_enable_channel(session, domain, attr);
+ if (ret != LTTCOMM_OK) {
+ free(attr);
+ goto error;
+ }
+ free(attr);
+
+ /* Get the newly created channel reference back */
+ uchan = trace_ust_find_channel_by_name(
+ usess->domain_global.channels, channel_name);
+ if (uchan == NULL) {
+ /* Something is really wrong */
+ ret = LTTCOMM_FATAL;
+ goto error;
+ }
+ }
+
+ /* At this point, the session and channel exist on the tracer */
+
+ switch (event_type) {
+ case LTTNG_EVENT_ALL:
+ case LTTNG_EVENT_TRACEPOINT:
+ ret = event_ust_enable_all_tracepoints(usess, domain, uchan);
+ if (ret != LTTCOMM_OK) {
+ goto error;
+ }
+ break;
+ default:
+ ret = LTTCOMM_UST_ENABLE_FAIL;
+ goto error;
+ }
+
+ /* Manage return value */
+ if (ret != LTTCOMM_OK) {
+ 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;
}
rcu_read_unlock();
return ret;
}
+
+/*
+ * Enable event for a channel from a UST session for a specific PID.
+ */
+int ust_app_enable_event_pid(struct ltt_ust_session *usess,
+ struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, pid_t pid)
+{
+ int ret = 0;
+ struct cds_lfht_iter iter;
+ struct cds_lfht_node *ua_chan_node, *ua_event_node;
+ struct ust_app *app;
+ struct ust_app_session *ua_sess;
+ struct ust_app_channel *ua_chan;
+ struct ust_app_event *ua_event;
+
+ DBG("UST app enabling event %s for PID %d", uevent->attr.name, pid);
+
+ rcu_read_lock();
+
+ app = ust_app_find_by_pid(pid);
+ if (app == NULL) {
+ ERR("UST app enable event per PID %d not found", pid);
+ ret = -1;
+ goto error;
+ }
+
+ ua_sess = lookup_session_by_app(usess, app);
+ /* If ua_sess is NULL, there is a code flow error */
+ assert(ua_sess);
+
+ /* Lookup channel in the ust app session */
+ ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
+ strlen(uchan->name), &iter);
+ /* If the channel is not found, there is a code flow error */
+ assert(ua_chan_node);
+
+ ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+
+ ua_event_node = hashtable_lookup(ua_sess->channels,
+ (void*)uevent->attr.name, strlen(uevent->attr.name), &iter);
+ if (ua_event_node == NULL) {
+ ret = create_ust_app_event(ua_sess, ua_chan, uevent, app);
+ if (ret < 0) {
+ goto error;
+ }
+ } else {
+ ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
+
+ ret = enable_ust_app_event(ua_sess, ua_event, app);
+ if (ret < 0) {
+ goto error;
+ }
+ }
+
+error:
+ rcu_read_unlock();
+ return ret;
+}
struct ltt_ust_channel *uchan);
int ust_app_create_event_glb(struct ltt_ust_session *usess,
struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent);
+int ust_app_enable_event_pid(struct ltt_ust_session *usess,
+ struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent,
+ pid_t pid);
int ust_app_disable_channel_glb(struct ltt_ust_session *usess,
struct ltt_ust_channel *uchan);
int ust_app_enable_channel_glb(struct ltt_ust_session *usess,
{
return 0;
}
+static inline
+int ust_app_enable_event_pid(struct ltt_ust_session *usess,
+ struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent,
+ pid_t pid)
+{
+ return 0;
+}
#endif /* HAVE_LIBLTTNG_UST_CTL */
static char *opt_event_list;
static int opt_event_type;
-static char *opt_kernel;
+static int opt_kernel;
static char *opt_session_name;
static int opt_pid_all;
static int opt_userspace;
}
/*
- * parse_probe_addr
- *
- * Parse probe options.
+ * Parse probe options.
*/
static int parse_probe_opts(struct lttng_event *ev, char *opt)
{
}
/*
- * enable_events
- *
- * Enabling event using the lttng API.
+ * Enabling event using the lttng API.
*/
static int enable_events(char *session_name)
{
ret = CMD_FATAL;
goto error;
}
+
/* Create lttng domain */
if (opt_kernel) {
dom.type = LTTNG_DOMAIN_KERNEL;
- }
- if (opt_userspace) {
- /* TODO
- * LTTNG_DOMAIN_UST_EXEC_NAME,
- * LTTNG_DOMAIN_UST_PID,
- * LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN
- */
+ } else if (opt_pid != 0) {
+ dom.type = LTTNG_DOMAIN_UST_PID;
+ dom.attr.pid = opt_pid;
+ DBG("PID %d set to lttng handle", opt_pid);
+ } else if (opt_userspace && opt_cmd_name == NULL) {
dom.type = LTTNG_DOMAIN_UST;
+ } else if (opt_userspace && opt_cmd_name != NULL) {
+ dom.type = LTTNG_DOMAIN_UST_EXEC_NAME;
+ strncpy(dom.attr.exec_name, opt_cmd_name, NAME_MAX);
+ } else {
+ ERR("Please specify a tracer (--kernel or --userspace)");
+ ret = CMD_NOT_IMPLEMENTED;
+ goto error;
}
handle = lttng_create_handle(session_name, &dom);
break;
default:
/*
- * We should not be here since
- * lttng_enable_event should have failed on the
- * event type.
+ * We should not be here since lttng_enable_event should have
+ * failed on the event type.
*/
goto error;
}
/* Strip event list */
event_name = strtok(opt_event_list, ",");
while (event_name != NULL) {
+ /* Copy name and type of the event */
+ strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN);
+ ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
+ ev.type = opt_event_type;
+
/* Kernel tracer action */
if (opt_kernel) {
DBG("Enabling kernel event %s for channel %s",
event_name, channel_name);
- /* Copy name and type of the event */
- strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN);
- ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
- ev.type = opt_event_type;
switch (opt_event_type) {
case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */
}
break;
case LTTNG_EVENT_FUNCTION_ENTRY:
- strncpy(ev.attr.ftrace.symbol_name,
- opt_function_entry_symbol,
- LTTNG_SYMBOL_NAME_LEN);
+ strncpy(ev.attr.ftrace.symbol_name, opt_function_entry_symbol,
+ LTTNG_SYMBOL_NAME_LEN);
ev.attr.ftrace.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
break;
case LTTNG_EVENT_SYSCALL:
- MSG("per-syscall selection not supported yet. Use \"-a\" for all syscalls.");
- ret = CMD_NOT_IMPLEMENTED;
- goto error;
+ MSG("per-syscall selection not supported yet. Use \"-a\" "
+ "for all syscalls.");
default:
ret = CMD_NOT_IMPLEMENTED;
goto error;
}
-
- ret = lttng_enable_event(handle, &ev, channel_name);
- if (ret == 0) {
- MSG("Kernel event %s created in channel %s", event_name, channel_name);
- }
} else if (opt_userspace) { /* User-space tracer action */
- /*
- * TODO: only supporting pid_all tracing for
- * now. Should have different domain based on
- * opt_pid.
- */
if (!opt_pid_all) {
- MSG("Only supporting tracing all UST processes (-u --all) for now.");
+ MSG("Only supporting tracing all UST processes "
+ "(-u --all) for now.");
ret = CMD_NOT_IMPLEMENTED;
goto error;
}
- DBG("Enabling UST event %s for channel %s",
- event_name, channel_name);
+
+ DBG("Enabling UST event %s for channel %s", event_name,
+ channel_name);
switch (opt_event_type) {
case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */
ret = CMD_NOT_IMPLEMENTED;
goto error;
}
-
- ret = lttng_enable_event(handle, &ev, channel_name);
- if (ret == 0) {
- MSG("UST event %s created in channel %s", event_name, channel_name);
- }
} else {
ERR("Please specify a tracer (--kernel or --userspace)");
goto error;
}
+ ret = lttng_enable_event(handle, &ev, channel_name);
+ if (ret == 0) {
+ MSG("%s event %s created in channel %s",
+ opt_kernel ? "kernel": "UST", event_name, channel_name);
+ }
+
/* Next event */
event_name = strtok(NULL, ",");
}
}
/*
- * cmd_enable_events
- *
- * Add event to trace session
+ * Add event to trace session
*/
int cmd_enable_events(int argc, const char **argv)
{