Introduce the lttng domain that is used to identify the tracer.
Remove all 'kernel' from the functions name and now take the domain
struct as first parameter.
Add channel feature is removed and merged with enable-channel.
Move kernel specific data structure from lttng.h to lttng-kernel.h which
is copied from the LTTng kernel modules ABI. Genereic structures are
used to create a generic view of lttng event and attributes (agnostif of
the Kernel and user-space).
Default channel is NOT created unless it is needed.
A lot of comments has been added to lttng.h
Fix a bug in the liblttngctl. A return value was not set correctly.
Signed-off-by: David Goulet <david.goulet@polymtl.ca>
#define LTTNG_SYM_NAME_LEN 128
+/*
+ * LTTng DebugFS ABI structures.
+ *
+ * This is the kernel ABI copied from lttng-modules tree.
+ */
+
enum lttng_kernel_instrumentation {
LTTNG_KERNEL_TRACEPOINT = 0,
LTTNG_KERNEL_KPROBE = 1,
LTTNG_KERNEL_FUNCTION = 2,
};
-/*
- * LTTng consumer mode
- */
-enum lttng_kernel_output {
- LTTNG_KERNEL_SPLICE = 0,
- LTTNG_KERNEL_MMAP = 1,
+enum lttng_kernel_context_type {
+ LTTNG_KERNEL_CONTEXT_PID = 0,
+ LTTNG_KERNEL_CONTEXT_PERF_COUNTER = 1,
+ LTTNG_KERNEL_CONTEXT_COMM = 2,
+ LTTNG_KERNEL_CONTEXT_PRIO = 3,
+ LTTNG_KERNEL_CONTEXT_NICE = 4,
+ LTTNG_KERNEL_CONTEXT_VPID = 5,
+ LTTNG_KERNEL_CONTEXT_TID = 6,
+ LTTNG_KERNEL_CONTEXT_VTID = 7,
+ LTTNG_KERNEL_CONTEXT_PPID = 8,
+ LTTNG_KERNEL_CONTEXT_VPPID = 9,
+};
+
+/* Perf counter attributes */
+struct lttng_kernel_perf_counter_ctx {
+ uint32_t type;
+ uint64_t config;
+ char name[LTTNG_SYMBOL_NAME_LEN];
+};
+
+/* Event/Channel context */
+struct lttng_kernel_context {
+ enum lttng_kernel_context_type ctx;
+ union {
+ struct lttng_kernel_perf_counter_ctx perf_counter;
+ } u;
};
/*
- * LTTng DebugFS ABI structures.
- *
- * This is the kernel ABI copied from lttng-modules tree.
+ * Either addr is used, or symbol_name and offset.
*/
+struct lttng_kernel_kprobe {
+ uint64_t addr;
+
+ uint64_t offset;
+ char symbol_name[LTTNG_SYM_NAME_LEN];
+};
/* Function tracer */
-struct lttng_kernel_function_attr {
+struct lttng_kernel_function {
char symbol_name[LTTNG_SYM_NAME_LEN];
};
enum lttng_kernel_instrumentation instrumentation;
/* Per instrumentation type configuration */
union {
- struct lttng_kernel_kprobe_attr kprobe;
- struct lttng_kernel_function_attr ftrace;
+ struct lttng_kernel_kprobe kprobe;
+ struct lttng_kernel_function ftrace;
} u;
};
#define DEFAULT_CHANNEL_SWITCH_TIMER 0 /* usec */
#define DEFAULT_CHANNEL_READ_TIMER 200 /* usec */
/* See lttng-kernel.h enum lttng_kernel_output for channel output */
-#define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_KERNEL_SPLICE
+#define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE
/* == NOT IMPLEMENTED ==
#define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_UST_MMAP
#define _LTTNG_H
#include <asm/types.h>
+#include <sys/types.h>
#include <stdint.h>
#include <limits.h>
/*
* Every lttng_event_* structure both apply to kernel event and user-space
* event.
- *
- * Every lttng_kernel_* is copied from the LTTng kernel ABI.
*/
+/*
+ * Domain type are the different possible tracers.
+ */
+enum lttng_domain_type {
+ LTTNG_DOMAIN_KERNEL,
+ LTTNG_DOMAIN_UST,
+ LTTNG_DOMAIN_UST_EXEC_NAME,
+ LTTNG_DOMAIN_UST_PID,
+ LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN,
+};
+
+struct lttng_domain {
+ enum lttng_domain_type type;
+ union {
+ pid_t pid;
+ char exec_name[NAME_MAX];
+ } attr;
+};
+
+/*
+ * Instrumentation type of tracing event.
+ */
enum lttng_event_type {
LTTNG_EVENT_TRACEPOINT,
- LTTNG_EVENT_KPROBE,
+ LTTNG_EVENT_PROBE,
LTTNG_EVENT_FUNCTION,
};
* LTTng consumer mode
*/
enum lttng_event_output {
- /* Using splice(2) */
- LTTNG_EVENT_SPLICE = 0,
- /* Using mmap(2) */
- LTTNG_EVENT_MMAP = 1,
+ LTTNG_EVENT_SPLICE = 0,
+ LTTNG_EVENT_MMAP = 1,
};
-/* Kernel context possible type */
-enum lttng_kernel_context_type {
- LTTNG_KERNEL_CONTEXT_PID = 0,
- LTTNG_KERNEL_CONTEXT_PERF_COUNTER = 1,
- LTTNG_KERNEL_CONTEXT_COMM = 2,
- LTTNG_KERNEL_CONTEXT_PRIO = 3,
- LTTNG_KERNEL_CONTEXT_NICE = 4,
- LTTNG_KERNEL_CONTEXT_VPID = 5,
- LTTNG_KERNEL_CONTEXT_TID = 6,
- LTTNG_KERNEL_CONTEXT_VTID = 7,
- LTTNG_KERNEL_CONTEXT_PPID = 8,
- LTTNG_KERNEL_CONTEXT_VPPID = 9,
+/* Event context possible type */
+enum lttng_event_context_type {
+ LTTNG_EVENT_CONTEXT_PID = 0,
+ LTTNG_EVENT_CONTEXT_PERF_COUNTER = 1,
+ LTTNG_EVENT_CONTEXT_COMM = 2,
+ LTTNG_EVENT_CONTEXT_PRIO = 3,
+ LTTNG_EVENT_CONTEXT_NICE = 4,
+ LTTNG_EVENT_CONTEXT_VPID = 5,
+ LTTNG_EVENT_CONTEXT_TID = 6,
+ LTTNG_EVENT_CONTEXT_VTID = 7,
+ LTTNG_EVENT_CONTEXT_PPID = 8,
+ LTTNG_EVENT_CONTEXT_VPPID = 9,
};
/* Perf counter attributes */
-struct lttng_kernel_perf_counter_ctx {
+struct lttng_event_perf_counter_ctx {
uint32_t type;
uint64_t config;
char name[LTTNG_SYMBOL_NAME_LEN];
};
/* Event/Channel context */
-struct lttng_kernel_context {
- enum lttng_kernel_context_type ctx;
+struct lttng_event_context {
+ enum lttng_event_context_type ctx;
union {
- struct lttng_kernel_perf_counter_ctx perf_counter;
+ struct lttng_event_perf_counter_ctx perf_counter;
} u;
};
/*
- * Kernel Kprobe. Either addr is used or symbol_name and offset.
+ * Event probe.
+ *
+ * Either addr is used or symbol_name and offset.
*/
-struct lttng_kernel_kprobe_attr {
+struct lttng_event_probe_attr {
uint64_t addr;
uint64_t offset;
enum lttng_event_type type;
/* Per event type configuration */
union {
- struct lttng_kernel_kprobe_attr kprobe;
+ struct lttng_event_probe_attr probe;
struct lttng_event_function_attr ftrace;
} attr;
};
char path[PATH_MAX];
};
+/*
+ * Public LTTng control API
+ *
+ * For functions having a lttng domain type as parameter, if a bad value is
+ * given, NO default is applied and an error is returned.
+ *
+ * On success, all functions of the API return 0 or the size of the allocated
+ * array.
+ *
+ * On error, a negative value is returned being a specific lttng-tools error
+ * code which can be humanly interpreted with lttng_get_readable_code(err).
+ */
+
/*
* Session daemon control
*/
+
+/*
+ * Create tracing session using a name and a path where trace will be written.
+ */
extern int lttng_create_session(char *name, char *path);
+/*
+ * Destroy tracing session.
+ *
+ * The session will not be useable anymore, tracing will stopped for all
+ * registered trace and tracing buffers will be flushed.
+ */
extern int lttng_destroy_session(char *name);
/*
- * Return a "lttng_session" array. Caller must free(3) the returned data.
+ * List tracing sessions.
+ *
+ * Return the size of the "lttng_session" array. Caller must free(3) the
+ * returned data.
*/
extern int lttng_list_sessions(struct lttng_session **sessions);
+/*
+ * Check if a session daemon is alive.
+ */
extern int lttng_session_daemon_alive(void);
-/* Set tracing group for the current execution */
+/*
+ * Set tracing group for the *current* flow of execution.
+ */
extern int lttng_set_tracing_group(const char *name);
+/*
+ * Set the session name of the *current* flow of execution.
+ *
+ * This is a VERY important things to do before doing any tracing actions. If
+ * it's not done, you'll get an error saying that the session is not found.
+ * It avoids the use of a session name on every API call.
+ */
extern void lttng_set_session_name(char *name);
+/*
+ * Return a human readable error message of a lttng-tools error code.
+ *
+ * Parameter MUST be a negative value or else you'll get a generic message.
+ */
extern const char *lttng_get_readable_code(int code);
+/*
+ * Start tracing for *all* registered trace (kernel and user-space).
+ */
extern int lttng_start_tracing(char *session_name);
+/*
+ * Stop tracing for *all* registered trace (kernel and user-space).
+ */
extern int lttng_stop_tracing(char *session_name);
/*
- * LTTng Kernel tracer control
+ * Add context to event for a specific channel.
+ *
+ * If event_name is NULL, the context is applied to all event of the channel.
+ * If channel_name is NULL, a lookup of the event's channel is done.
+ * If both are NULL, the context is applied on all events of all channels.
*/
-extern int lttng_kernel_add_context(struct lttng_kernel_context *ctx,
- char *event_name, char *channel_name);
-
-extern int lttng_kernel_create_channel(struct lttng_channel *chan);
-
-extern int lttng_kernel_enable_event(struct lttng_event *ev, char *channel_name);
-extern int lttng_kernel_enable_channel(char *name);
+extern int lttng_add_context(struct lttng_domain *domain,
+ struct lttng_event_context *ctx, char *event_name, char *channel_name);
-extern int lttng_kernel_disable_event(char *name, char *channel_name);
+/*
+ * Create or enable a kernel event.
+ *
+ * If the event you are trying to enable does not exist, it will be created,
+ * else it is enabled.
+ *
+ * If channel_name is NULL, the default channel is used (channel0).
+ */
+extern int lttng_enable_event(struct lttng_domain *domain, struct lttng_event *ev,
+ char *channel_name);
-extern int lttng_kernel_disable_channel(char *name);
+/*
+ * Create or enable a kernel channel.
+ *
+ * If name is NULL, the default channel is enabled (channel0).
+ */
+extern int lttng_enable_channel(struct lttng_domain *domain, struct lttng_channel *chan);
-extern int lttng_kernel_list_events(char **event_list);
+/*
+ * Disable kernel event.
+ *
+ * If channel_name is NULL, the default channel is used (channel0).
+ */
+extern int lttng_disable_event(struct lttng_domain *domain, char *name,
+ char *channel_name);
/*
- * LTTng User-space tracer control
+ * Disable kernel channel.
+ *
+ * If channel_name is NULL, the default channel is disabled (channel0).
*/
+extern int lttng_disable_channel(struct lttng_domain *domain, char *name);
-//extern int lttng_ust_list_traceable_apps(pid_t **pids);
+/*
+ * List kernel events.
+ *
+ * Return the size of the allocated event list. Caller must free(3) the data.
+ */
+extern int lttng_list_events(struct lttng_domain *domain, char **event_list);
#endif /* _LTTNG_H */
}
switch (DEFAULT_KERNEL_CHANNEL_OUTPUT) {
- case LTTNG_KERNEL_SPLICE:
+ case LTTNG_EVENT_SPLICE:
/* read the whole subbuffer */
err = kernctl_get_padded_subbuf_size(infd, &len);
if (err != 0) {
ERR("Error splicing to tracefile");
}
break;
- case LTTNG_KERNEL_MMAP:
+ case LTTNG_EVENT_MMAP:
/* read the used subbuffer size */
err = kernctl_get_subbuf_size(infd, &len);
if (err != 0) {
size = llm.data_size;
if (size == 0) {
+ ret = 0;
goto end;
}
}
/*
- * lttng_start_tracing
- *
* Start tracing for all trace of the session.
*/
int lttng_start_tracing(char *session_name)
}
/*
- * lttng_stop_tracing
- *
* Stop tracing for all trace of the session.
*/
int lttng_stop_tracing(char *session_name)
}
/*
- * BEGIN Kernel control API
+ * lttng_add_context
*/
+int lttng_add_context(struct lttng_domain *domain,
+ struct lttng_event_context *ctx, char *event_name, char *channel_name)
-/*
- * lttng_kernel_add_context
- */
-int lttng_kernel_add_context(struct lttng_kernel_context *ctx,
- char *event_name, char *channel_name)
{
+ int ret;
+
if (channel_name != NULL) {
strncpy(lsm.u.context.channel_name, channel_name, NAME_MAX);
}
strncpy(lsm.u.context.event_name, event_name, NAME_MAX);
}
- memcpy(&lsm.u.context.ctx, ctx, sizeof(struct lttng_kernel_context));
- return ask_sessiond(LTTNG_KERNEL_ADD_CONTEXT, NULL);
+ memcpy(&lsm.u.context.ctx, ctx, sizeof(struct lttng_event_context));
+
+ switch (domain->type) {
+ case LTTNG_DOMAIN_KERNEL:
+ ret = ask_sessiond(LTTNG_KERNEL_ADD_CONTEXT, NULL);
+ break;
+ case LTTNG_DOMAIN_UST:
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ break;
+ default:
+ ret = LTTCOMM_UNKNOWN_DOMAIN;
+ break;
+ };
+
+ return ret;
}
/*
- * lttng_kernel_enable_event
+ * lttng_enable_event
*/
-int lttng_kernel_enable_event(struct lttng_event *ev, char *channel_name)
+int lttng_enable_event(struct lttng_domain *domain,
+ struct lttng_event *ev, char *channel_name)
{
int ret;
strncpy(lsm.u.enable.channel_name, channel_name, NAME_MAX);
}
- if (ev == NULL) {
- ret = ask_sessiond(LTTNG_KERNEL_ENABLE_ALL_EVENT, NULL);
- } else {
- memcpy(&lsm.u.enable.event, ev, sizeof(struct lttng_event));
- ret = ask_sessiond(LTTNG_KERNEL_ENABLE_EVENT, NULL);
- }
+ switch (domain->type) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (ev == NULL) {
+ ret = ask_sessiond(LTTNG_KERNEL_ENABLE_ALL_EVENT, NULL);
+ } else {
+ memcpy(&lsm.u.enable.event, ev, sizeof(struct lttng_event));
+ ret = ask_sessiond(LTTNG_KERNEL_ENABLE_EVENT, NULL);
+ }
+ break;
+ case LTTNG_DOMAIN_UST:
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ break;
+ default:
+ ret = LTTCOMM_UNKNOWN_DOMAIN;
+ break;
+ };
return ret;
}
/*
- * lttng_kernel_disable_event
- *
- * Disable an event in the kernel tracer.
+ * Disable an event in the kernel tracer.
*/
-int lttng_kernel_disable_event(char *name, char *channel_name)
+int lttng_disable_event(struct lttng_domain *domain, char *name,
+ char *channel_name)
{
int ret;
strncpy(lsm.u.disable.channel_name, channel_name, NAME_MAX);
}
- if (name == NULL) {
- ret = ask_sessiond(LTTNG_KERNEL_DISABLE_ALL_EVENT, NULL);
- } else {
- strncpy(lsm.u.disable.name, name, NAME_MAX);
- ret = ask_sessiond(LTTNG_KERNEL_DISABLE_EVENT, NULL);
- }
+ switch (domain->type) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (name == NULL) {
+ ret = ask_sessiond(LTTNG_KERNEL_DISABLE_ALL_EVENT, NULL);
+ } else {
+ strncpy(lsm.u.disable.name, name, NAME_MAX);
+ ret = ask_sessiond(LTTNG_KERNEL_DISABLE_EVENT, NULL);
+ }
+ break;
+ case LTTNG_DOMAIN_UST:
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ break;
+ default:
+ ret = LTTCOMM_UNKNOWN_DOMAIN;
+ break;
+ };
return ret;
}
/*
- * lttng_kernel_enable_channel
- *
- * Enable recording for a channel for the kernel tracer.
- */
-int lttng_kernel_enable_channel(char *name)
-{
- strncpy(lsm.u.enable.channel_name, name, NAME_MAX);
- return ask_sessiond(LTTNG_KERNEL_ENABLE_CHANNEL, NULL);
-}
-
-/*
- * lttng_kernel_disable_channel
- *
- * Disable recording for the channel for the kernel tracer.
+ * Enable recording for a channel for the kernel tracer.
*/
-int lttng_kernel_disable_channel(char *name)
+int lttng_enable_channel(struct lttng_domain *domain, struct lttng_channel *chan)
{
- strncpy(lsm.u.disable.channel_name, name, NAME_MAX);
- return ask_sessiond(LTTNG_KERNEL_DISABLE_CHANNEL, NULL);
-}
+ int ret;
-/*
- * lttng_kernel_create_channel
- *
- * Create a channel in the kernel tracer.
- */
-int lttng_kernel_create_channel(struct lttng_channel *chan)
-{
memcpy(&lsm.u.channel.chan, chan, sizeof(struct lttng_channel));
- return ask_sessiond(LTTNG_KERNEL_CREATE_CHANNEL, NULL);
+
+ switch (domain->type) {
+ case LTTNG_DOMAIN_KERNEL:
+ ret = ask_sessiond(LTTNG_KERNEL_ENABLE_CHANNEL, NULL);
+ break;
+ case LTTNG_DOMAIN_UST:
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ break;
+ default:
+ ret = LTTCOMM_UNKNOWN_DOMAIN;
+ break;
+ };
+
+ return ret;
}
/*
- * lttng_list_events
- *
- * List all available events in the kernel.
- *
- * Return the size (bytes) of the list and set the event_list array.
- * On error, return negative value.
+ * Disable recording for the channel for the kernel tracer.
*/
-int lttng_kernel_list_events(char **event_list)
+int lttng_disable_channel(struct lttng_domain *domain, char *name)
{
- return ask_sessiond(LTTNG_KERNEL_LIST_EVENTS, (void **) event_list);
-}
+ int ret;
-/*
- * END Kernel control API
- */
+ strncpy(lsm.u.disable.channel_name, name, NAME_MAX);
-/*
- * lttng_get_readable_code
- *
- * Return a human readable string of code
- */
-const char *lttng_get_readable_code(int code)
-{
- if (code > -LTTCOMM_OK) {
- return "Ended with errors";
- }
+ switch (domain->type) {
+ case LTTNG_DOMAIN_KERNEL:
+ ret = ask_sessiond(LTTNG_KERNEL_DISABLE_CHANNEL, NULL);
+ break;
+ case LTTNG_DOMAIN_UST:
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ break;
+ default:
+ ret = LTTCOMM_UNKNOWN_DOMAIN;
+ break;
+ };
- return lttcomm_get_readable_code(code);
+ return ret;
}
/*
- * lttng_ust_list_apps
- *
- * Ask the session daemon for all UST traceable applications.
+ * List all available events in the kernel.
*
- * Return the number of pids.
- * On error, return negative value.
+ * Return the size (bytes) of the list and set the event_list array.
+ * On error, return negative value.
*/
-int lttng_ust_list_traceable_apps(pid_t **pids)
+int lttng_list_events(struct lttng_domain *domain, char **event_list)
{
int ret;
- ret = ask_sessiond(LTTNG_LIST_TRACEABLE_APPS, (void**) pids);
- if (ret < 0) {
- return ret;
- }
+ switch (domain->type) {
+ case LTTNG_DOMAIN_KERNEL:
+ ret = ask_sessiond(LTTNG_KERNEL_LIST_EVENTS, (void **) event_list);
+ break;
+ case LTTNG_DOMAIN_UST:
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ break;
+ default:
+ ret = LTTCOMM_UNKNOWN_DOMAIN;
+ break;
+ };
- return ret / sizeof(pid_t);
+ return ret;
}
/*
- * lttng_list_traces
- *
- * Ask the session daemon for all traces (kernel and ust) for the session
- * identified by name.
- *
- * Return the number of traces.
- * On error, return negative value.
+ * Return a human readable string of code
*/
-/*
-int lttng_list_traces(char *session_name, struct lttng_trace **traces)
+const char *lttng_get_readable_code(int code)
{
- int ret;
-
- strncpy(lsm.session_name, session_name, NAME_MAX);
-
- ret = ask_sessiond(LTTNG_LIST_TRACES, (void **) traces);
- if (ret < 0) {
- return ret;
+ if (code > -LTTCOMM_OK) {
+ return "Ended with errors";
}
- return ret / sizeof(struct lttng_trace);
+ return lttcomm_get_readable_code(code);
}
-*/
/*
- * lttng_create_session
- *
* Create a brand new session using name.
*/
int lttng_create_session(char *name, char *path)
}
/*
- * lttng_destroy_session
- *
* Destroy session using name.
*/
int lttng_destroy_session(char *name)
}
/*
- * lttng_list_sessions
- *
* Ask the session daemon for all available sessions.
*
* Return number of session.
return ret / sizeof(struct lttng_session);
}
+/*
+ * Set session name for the current lsm.
+ */
void lttng_set_session_name(char *name)
{
strncpy(lsm.session_name, name, NAME_MAX);
[ LTTCOMM_ERR_INDEX(LTTCOMM_OK) ] = "Success",
[ LTTCOMM_ERR_INDEX(LTTCOMM_ERR) ] = "Unknown error",
[ LTTCOMM_ERR_INDEX(LTTCOMM_UND) ] = "Undefined command",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_NOT_IMPLEMENTED) ] = "Not implemented",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_UNKNOWN_DOMAIN) ] = "Unknown tracing domain",
[ LTTCOMM_ERR_INDEX(LTTCOMM_NO_SESSION) ] = "No session found",
[ LTTCOMM_ERR_INDEX(LTTCOMM_LIST_FAIL) ] = "Unable to list traceable apps",
[ LTTCOMM_ERR_INDEX(LTTCOMM_NO_APPS) ] = "No traceable apps found",
[ LTTCOMM_ERR_INDEX(LTTCOMM_SELECT_SESS) ] = "A session MUST be selected",
[ LTTCOMM_ERR_INDEX(LTTCOMM_EXIST_SESS) ] = "Session name already exist",
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_NA) ] = "Kernel tracer not available",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_EVENT_EXIST) ] = "Kernel event already exists",
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_SESS_FAIL) ] = "Kernel create session failed",
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_FAIL) ] = "Kernel create channel failed",
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_NOT_FOUND) ] = "Kernel channel not found",
enum lttcomm_sessiond_command {
/* Tracer context command */
LTTNG_KERNEL_ADD_CONTEXT,
- LTTNG_KERNEL_CREATE_CHANNEL,
LTTNG_KERNEL_DISABLE_CHANNEL,
LTTNG_KERNEL_DISABLE_EVENT,
LTTNG_KERNEL_DISABLE_ALL_EVENT,
LTTCOMM_OK = 1000, /* Ok */
LTTCOMM_ERR, /* Unknown Error */
LTTCOMM_UND, /* Undefine command */
+ LTTCOMM_NOT_IMPLEMENTED, /* Command not implemented */
+ LTTCOMM_UNKNOWN_DOMAIN, /* Tracing domain not known */
LTTCOMM_ALLOC_FAIL, /* Trace allocation fail */
LTTCOMM_NO_SESSION, /* No session found */
LTTCOMM_CREATE_FAIL, /* Create trace fail */
LTTCOMM_EXIST_SESS, /* Session name already exist */
LTTCOMM_NO_EVENT, /* No event found */
LTTCOMM_KERN_NA, /* Kernel tracer unavalable */
+ LTTCOMM_KERN_EVENT_EXIST, /* Kernel event already exists */
LTTCOMM_KERN_SESS_FAIL, /* Kernel create session failed */
LTTCOMM_KERN_CHAN_FAIL, /* Kernel create channel failed */
LTTCOMM_KERN_CHAN_NOT_FOUND, /* Kernel channel not found */
struct {
char channel_name[NAME_MAX];
char event_name[NAME_MAX];
- struct lttng_kernel_context ctx;
+ struct lttng_event_context ctx;
} context;
} u;
};
ret = kernctl_enable(event->fd);
if (ret < 0) {
perror("enable event ioctl");
+ if (errno == EEXIST) {
+ ret = -EEXIST;
+ }
goto error;
}
static int create_kernel_session(struct ltt_session *session)
{
int ret;
- struct lttng_channel *chan;
DBG("Creating kernel session");
goto error;
}
- chan = init_default_channel();
- if (chan == NULL) {
- ret = LTTCOMM_FATAL;
- goto error;
- }
-
ret = mkdir_recursive(session->path, S_IRWXU | S_IRWXG );
if (ret < 0) {
if (ret != EEXIST) {
}
}
- DBG("Creating default kernel channel %s", DEFAULT_CHANNEL_NAME);
-
- ret = kernel_create_channel(session->kernel_session, chan, session->path);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CHAN_FAIL;
- goto error;
- }
-
- ret = notify_kernel_pollfd();
-
error:
return ret;
}
*/
switch (cmd_ctx->lsm->cmd_type) {
case LTTNG_KERNEL_ADD_CONTEXT:
- case LTTNG_KERNEL_CREATE_CHANNEL:
case LTTNG_KERNEL_DISABLE_ALL_EVENT:
case LTTNG_KERNEL_DISABLE_CHANNEL:
case LTTNG_KERNEL_DISABLE_EVENT:
int found = 0, no_event = 0;
struct ltt_kernel_channel *chan;
struct ltt_kernel_event *event;
+ struct lttng_kernel_context ctx;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 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,
- &cmd_ctx->lsm->u.context.ctx);
+ 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,
- &cmd_ctx->lsm->u.context.ctx);
+ ret = kernel_add_event_context(event, &ctx);
if (ret < 0) {
ret = LTTCOMM_KERN_CONTEXT_FAIL;
goto error;
}
if (no_event) {
- ret = kernel_add_channel_context(chan,
- &cmd_ctx->lsm->u.context.ctx);
+ 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,
- &cmd_ctx->lsm->u.context.ctx);
+ ret = kernel_add_event_context(event, &ctx);
if (ret < 0) {
ret = LTTCOMM_KERN_CONTEXT_FAIL;
goto error;
ret = LTTCOMM_OK;
break;
}
- case LTTNG_KERNEL_CREATE_CHANNEL:
- {
- /* Setup lttng message with no payload */
- ret = setup_lttng_msg(cmd_ctx, 0);
- if (ret < 0) {
- goto setup_error;
- }
-
- /* Kernel tracer */
- 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 = notify_kernel_pollfd();
- if (ret < 0) {
- ret = LTTCOMM_FATAL;
- goto error;
- }
-
- ret = LTTCOMM_OK;
- break;
- }
case LTTNG_KERNEL_DISABLE_CHANNEL:
{
struct ltt_kernel_channel *chan;
chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.enable.channel_name,
cmd_ctx->session->kernel_session);
if (chan == NULL) {
- ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
- goto error;
+ /* 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;
+ }
+
+ /* 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) {
}
case LTTNG_KERNEL_ENABLE_EVENT:
{
- struct ltt_kernel_channel *chan;
+ char *channel_name;
+ struct ltt_kernel_channel *kchan;
struct ltt_kernel_event *ev;
+ struct lttng_channel *chan;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 0);
goto setup_error;
}
- chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.enable.channel_name,
- cmd_ctx->session->kernel_session);
- if (chan == NULL) {
- ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
- goto error;
- }
+ channel_name = cmd_ctx->lsm->u.enable.channel_name;
- ev = get_kernel_event_by_name(cmd_ctx->lsm->u.enable.event.name, chan);
+ do {
+ kchan = get_kernel_channel_by_name(channel_name,
+ cmd_ctx->session->kernel_session);
+ if (kchan == NULL) {
+ DBG("Creating default channel");
+
+ 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);
+
+ 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, chan->channel->name);
- ret = kernel_create_event(&cmd_ctx->lsm->u.enable.event, chan);
+ 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, chan->channel->name);
+ cmd_ctx->lsm->u.enable.event.name, channel_name);
ret = kernel_enable_event(ev);
+ if (ret == -EEXIST) {
+ ret = LTTCOMM_KERN_EVENT_EXIST;
+ goto error;
+ }
}
if (ret < 0) {
case LTTNG_KERNEL_ENABLE_ALL_EVENT:
{
int pos, size;
- char *event_list, *event, *ptr;
- struct ltt_kernel_channel *chan;
+ char *event_list, *event, *ptr, *channel_name;
+ struct ltt_kernel_channel *kchan;
struct ltt_kernel_event *ev;
struct lttng_event ev_attr;
+ struct lttng_channel *chan;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 0);
DBG("Enabling all kernel event");
- chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.enable.channel_name,
- cmd_ctx->session->kernel_session);
- if (chan == NULL) {
- ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
- goto error;
- }
+ 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");
+
+ chan = init_default_channel();
+ if (chan == NULL) {
+ ret = LTTCOMM_FATAL;
+ 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;
+ }
+ }
+ } while (kchan == NULL);
/* For each event in the kernel session */
- cds_list_for_each_entry(ev, &chan->events_list.head, list) {
+ cds_list_for_each_entry(ev, &kchan->events_list.head, list) {
DBG("Enabling kernel event %s for channel %s.",
- ev->event->name, chan->channel->name);
+ ev->event->name, channel_name);
ret = kernel_enable_event(ev);
if (ret < 0) {
continue;
ptr = event_list;
while ((size = sscanf(ptr, "event { name = %m[^;]; };%n\n", &event, &pos)) == 1) {
- ev = get_kernel_event_by_name(event, chan);
+ 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, chan);
+ ret = kernel_create_event(&ev_attr, kchan);
if (ret < 0) {
/* Ignore error here and continue */
}
}
switch (ev->type) {
- case LTTNG_EVENT_KPROBE:
+ case LTTNG_EVENT_PROBE:
attr->instrumentation = LTTNG_KERNEL_KPROBE;
- attr->u.kprobe.addr = ev->attr.kprobe.addr;
- attr->u.kprobe.offset = ev->attr.kprobe.offset;
+ attr->u.kprobe.addr = ev->attr.probe.addr;
+ attr->u.kprobe.offset = ev->attr.probe.offset;
strncpy(attr->u.kprobe.symbol_name,
- ev->attr.kprobe.symbol_name, LTTNG_SYM_NAME_LEN);
+ ev->attr.probe.symbol_name, LTTNG_SYM_NAME_LEN);
break;
case LTTNG_EVENT_FUNCTION:
attr->instrumentation = LTTNG_KERNEL_FUNCTION;
bin_PROGRAMS = lttng
-lttng_SOURCES = conf.c commands/start.c commands/add_channel.c \
+lttng_SOURCES = conf.c commands/start.c \
commands/list.c commands/create.c commands/destroy.c \
commands/stop.c commands/enable_events.c \
commands/disable_events.c commands/enable_channels.c \
extern int cmd_list(int argc, const char **argv);
extern int cmd_create(int argc, const char **argv);
extern int cmd_destroy(int argc, const char **argv);
-extern int cmd_add_channel(int argc, const char **argv);
extern int cmd_start(int argc, const char **argv);
extern int cmd_stop(int argc, const char **argv);
extern int cmd_enable_events(int argc, const char **argv);
+++ /dev/null
-/*
- * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-#include <popt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "cmd.h"
-#include "conf.h"
-#include "utils.h"
-
-static char *opt_channel_name;
-static char *opt_kernel;
-static char *opt_cmd_name;
-static char *opt_session_name;
-static int opt_pid_all;
-static int opt_userspace;
-static pid_t opt_pid;
-static struct lttng_channel chan;
-
-enum {
- OPT_HELP = 1,
- OPT_DISCARD,
- OPT_OVERWRITE,
- OPT_SUBBUF_SIZE,
- OPT_NUM_SUBBUF,
- OPT_SWITCH_TIMER,
- OPT_READ_TIMER,
- OPT_USERSPACE,
-};
-
-static struct poptOption long_options[] = {
- /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
- {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
- {"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
- {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
- {"userspace", 'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, 0, OPT_USERSPACE, 0, 0},
- {"all", 0, POPT_ARG_VAL, &opt_pid_all, 1, 0, 0},
- {"pid", 'p', POPT_ARG_INT, &opt_pid, 0, 0, 0},
- {"discard", 0, POPT_ARG_NONE, 0, OPT_DISCARD, 0, 0},
- {"overwrite", 0, POPT_ARG_NONE, 0, OPT_OVERWRITE, 0, 0},
- {"subbuf_size", 0, POPT_ARG_DOUBLE, 0, OPT_SUBBUF_SIZE, 0, 0},
- {"num_subbuf", 0, POPT_ARG_INT, 0, OPT_NUM_SUBBUF, 0, 0},
- {"switch_timer", 0, POPT_ARG_INT, 0, OPT_SWITCH_TIMER, 0, 0},
- {"read_timer", 0, POPT_ARG_INT, 0, OPT_READ_TIMER, 0, 0},
- {0, 0, 0, 0, 0, 0, 0}
-};
-
-/*
- * usage
- */
-static void usage(FILE *ofp)
-{
- fprintf(ofp, "usage: lttng add-channel NAME [options] [channel_options]\n");
- fprintf(ofp, "\n");
- fprintf(ofp, " -h, --help Show this help\n");
- fprintf(ofp, " -s, --session Apply on session name\n");
- fprintf(ofp, " -k, --kernel Apply on the kernel tracer\n");
- fprintf(ofp, " -u, --userspace [CMD] Apply on the user-space tracer\n");
- fprintf(ofp, " --all If -u, apply on all traceable apps\n");
- fprintf(ofp, " -p, --pid PID If -u, apply on a specific PID\n");
- fprintf(ofp, "\n");
- fprintf(ofp, "Channel options:\n");
- fprintf(ofp, " --discard Discard event when buffers are full (default)\n");
- fprintf(ofp, " --overwrite Flight recorder mode\n");
- fprintf(ofp, " --subbuf_size Subbuffer size in bytes (default: 4096)\n");
- fprintf(ofp, " --num_subbuf Number of subbufers (default: 2)\n");
- fprintf(ofp, " --switch_timer Switch timer interval in usec (default: 0)\n");
- fprintf(ofp, " --read_timer Read timer interval in usec (default: 200)\n");
- fprintf(ofp, "\n");
-}
-
-/*
- * add_channel
- *
- * Adding channel using the lttng API.
- */
-static int add_channel(void)
-{
- int ret = CMD_SUCCESS;
-
- if (set_session_name(opt_session_name) < 0) {
- ret = CMD_ERROR;
- goto error;
- }
-
- /* Copy channel name and normalize it */
- strncpy(chan.name, opt_channel_name, NAME_MAX);
- chan.name[NAME_MAX - 1] = '\0';
-
- /* Kernel tracer action */
- if (opt_kernel) {
- /* Create kernel channel */
- ret = lttng_kernel_create_channel(&chan);
- if (ret < 0) {
- goto error;
- }
- } else if (opt_userspace) { /* User-space tracer action */
- /*
- * TODO: Waiting on lttng UST 2.0
- */
- if (opt_pid_all) {
- } else if (opt_pid != 0) {
- }
- ret = CMD_NOT_IMPLEMENTED;
- goto error;
- } else {
- ERR("Please specify a tracer (kernel or user-space)");
- goto error;
- }
-
- MSG("Channel %s created", opt_channel_name);
-
-error:
- return ret;
-}
-
-/*
- * init_channel_config
- *
- * Default value for channel configuration.
- */
-static void init_channel_config(void)
-{
- chan.attr.overwrite = DEFAULT_CHANNEL_OVERWRITE;
- chan.attr.subbuf_size = DEFAULT_CHANNEL_SUBBUF_SIZE;
- chan.attr.num_subbuf = DEFAULT_CHANNEL_SUBBUF_NUM;
- chan.attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER;
- chan.attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER;
- chan.attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
-}
-
-/*
- * cmd_add_channel
- *
- * Add channel to trace session
- */
-int cmd_add_channel(int argc, const char **argv)
-{
- int opt, ret;
- static poptContext pc;
-
- init_channel_config();
-
- pc = poptGetContext(NULL, argc, argv, long_options, 0);
- poptReadDefaultConfig(pc, 0);
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case OPT_HELP:
- usage(stderr);
- ret = CMD_SUCCESS;
- goto end;
- case OPT_USERSPACE:
- opt_userspace = 1;
- opt_cmd_name = poptGetOptArg(pc);
- break;
- case OPT_DISCARD:
- chan.attr.overwrite = 0;
- DBG("Channel set to discard");
- break;
- case OPT_OVERWRITE:
- chan.attr.overwrite = 1;
- DBG("Channel set to overwrite");
- break;
- case OPT_SUBBUF_SIZE:
- chan.attr.subbuf_size = atol(poptGetOptArg(pc));
- DBG("Channel subbuf size set to %lu", chan.attr.subbuf_size);
- break;
- case OPT_NUM_SUBBUF:
- chan.attr.num_subbuf = atoi(poptGetOptArg(pc));
- DBG("Channel subbuf num set to %lu", chan.attr.num_subbuf);
- break;
- case OPT_SWITCH_TIMER:
- chan.attr.switch_timer_interval = atoi(poptGetOptArg(pc));
- DBG("Channel switch timer interval set to %d", chan.attr.switch_timer_interval);
- break;
- case OPT_READ_TIMER:
- chan.attr.read_timer_interval = atoi(poptGetOptArg(pc));
- DBG("Channel read timer interval set to %d", chan.attr.read_timer_interval);
- break;
- default:
- usage(stderr);
- ret = CMD_UNDEFINED;
- goto end;
- }
- }
-
- opt_channel_name = (char*) poptGetArg(pc);
- if (opt_channel_name == NULL) {
- ERR("Missing channel name.\n");
- usage(stderr);
- ret = CMD_SUCCESS;
- goto end;
- }
-
- ret = add_channel();
-
-end:
- return ret;
-}
static int add_context(int type)
{
int ret = CMD_SUCCESS;
- struct lttng_kernel_context context;
+ struct lttng_event_context context;
+ struct lttng_domain dom;
if (set_session_name(opt_session_name) < 0) {
ret = CMD_ERROR;
}
if (opt_kernel) {
+ /* Create kernel domain */
+ dom.type = LTTNG_DOMAIN_KERNEL;
+
DBG("Adding kernel context");
- ret = lttng_kernel_add_context(&context, opt_event_name, opt_channel_name);
+ ret = lttng_add_context(&dom, &context, opt_event_name,
+ opt_channel_name);
if (ret < 0) {
goto error;
} else {
}
MSG("Session %s created.", session_name);
- MSG("Traces will be written in %s ", traces_path);
+ MSG("Traces will be written in %s/%s-<date>-<time> ", traces_path, session_name);
ret = CMD_SUCCESS;
{
int ret = CMD_SUCCESS;
char *channel_name;
+ struct lttng_domain dom;
if (set_session_name(opt_session_name) < 0) {
ret = CMD_ERROR;
goto error;
}
+ if (opt_kernel) {
+ dom.type = LTTNG_DOMAIN_KERNEL;
+ }
+
/* Strip channel list */
channel_name = strtok(opt_channels, ",");
while (channel_name != NULL) {
/* Kernel tracer action */
if (opt_kernel) {
DBG("Disabling kernel channel %s", channel_name);
- ret = lttng_kernel_disable_channel(channel_name);
+ ret = lttng_disable_channel(&dom, channel_name);
if (ret < 0) {
goto error;
} else {
int err, ret = CMD_SUCCESS;
char *event_name, *channel_name = NULL;
struct lttng_event ev;
+ struct lttng_domain dom;
if (set_session_name(opt_session_name) < 0) {
ret = CMD_ERROR;
channel_name = opt_channel_name;
}
+ if (opt_kernel) {
+ dom.type = LTTNG_DOMAIN_KERNEL;
+ }
+
if (opt_disable_all) {
if (opt_kernel) {
- ret = lttng_kernel_disable_event(NULL, channel_name);
+ ret = lttng_disable_event(&dom, NULL, channel_name);
goto error;
}
/* Copy name and type of the event */
strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN);
- ret = lttng_kernel_disable_event(event_name, channel_name);
+ ret = lttng_disable_event(&dom, event_name, channel_name);
if (ret < 0) {
MSG("Unable to disable event %s for channel %s",
event_name, channel_name);
static char *opt_channels;
static char *opt_kernel;
+static char *opt_cmd_name;
static char *opt_session_name;
static int opt_pid_all;
static int opt_userspace;
static pid_t opt_pid;
+static struct lttng_channel chan;
enum {
OPT_HELP = 1,
+ OPT_DISCARD,
+ OPT_OVERWRITE,
+ OPT_SUBBUF_SIZE,
+ OPT_NUM_SUBBUF,
+ OPT_SWITCH_TIMER,
+ OPT_READ_TIMER,
OPT_USERSPACE,
};
{"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
{"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
{"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
- {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
+ {"userspace", 'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, 0, OPT_USERSPACE, 0, 0},
{"all", 0, POPT_ARG_VAL, &opt_pid_all, 1, 0, 0},
{"pid", 'p', POPT_ARG_INT, &opt_pid, 0, 0, 0},
+ {"discard", 0, POPT_ARG_NONE, 0, OPT_DISCARD, 0, 0},
+ {"overwrite", 0, POPT_ARG_NONE, 0, OPT_OVERWRITE, 0, 0},
+ {"subbuf_size", 0, POPT_ARG_DOUBLE, 0, OPT_SUBBUF_SIZE, 0, 0},
+ {"num_subbuf", 0, POPT_ARG_INT, 0, OPT_NUM_SUBBUF, 0, 0},
+ {"switch_timer", 0, POPT_ARG_INT, 0, OPT_SWITCH_TIMER, 0, 0},
+ {"read_timer", 0, POPT_ARG_INT, 0, OPT_READ_TIMER, 0, 0},
{0, 0, 0, 0, 0, 0, 0}
};
*/
static void usage(FILE *ofp)
{
- fprintf(ofp, "usage: lttng enable-channel NAME[,NAME2,...] [options]\n");
+ fprintf(ofp, "usage: lttng enable-channel NAME[,NAME2,...] [options] [channel_options]\n");
fprintf(ofp, "\n");
- fprintf(ofp, " -h, --help Show this help\n");
+ fprintf(ofp, " -h, --help Show this help\n");
fprintf(ofp, " -s, --session Apply on session name\n");
- fprintf(ofp, " -k, --kernel Apply for the kernel tracer\n");
- fprintf(ofp, " -u, --userspace Apply for the user-space tracer\n");
- fprintf(ofp, " --all If -u, apply on all traceable apps\n");
- fprintf(ofp, " -p, --pid PID If -u, apply on a specific PID\n");
+ fprintf(ofp, " -k, --kernel Apply on the kernel tracer\n");
+ fprintf(ofp, " -u, --userspace [CMD] Apply on the user-space tracer\n");
+ fprintf(ofp, " --all If -u, apply on all traceable apps\n");
+ fprintf(ofp, " -p, --pid PID If -u, apply on a specific PID\n");
+ fprintf(ofp, "\n");
+ fprintf(ofp, "Channel options:\n");
+ fprintf(ofp, " --discard Discard event when buffers are full (default)\n");
+ fprintf(ofp, " --overwrite Flight recorder mode\n");
+ fprintf(ofp, " --subbuf_size Subbuffer size in bytes (default: 4096)\n");
+ fprintf(ofp, " --num_subbuf Number of subbufers (default: 2)\n");
+ fprintf(ofp, " --switch_timer Switch timer interval in usec (default: 0)\n");
+ fprintf(ofp, " --read_timer Read timer interval in usec (default: 200)\n");
fprintf(ofp, "\n");
}
/*
- * enable_channels
+ * enable_channel
*
- * Enabling channel using the lttng API.
+ * Adding channel using the lttng API.
*/
-static int enable_channels(void)
+static int enable_channel(void)
{
int ret = CMD_SUCCESS;
char *channel_name;
+ struct lttng_domain dom;
if (set_session_name(opt_session_name) < 0) {
ret = CMD_ERROR;
goto error;
}
+ if (opt_kernel) {
+ dom.type = LTTNG_DOMAIN_KERNEL;
+ }
+
/* Strip event list */
channel_name = strtok(opt_channels, ",");
while (channel_name != NULL) {
/* Kernel tracer action */
if (opt_kernel) {
DBG("Enabling kernel channel %s", channel_name);
- ret = lttng_kernel_enable_channel(channel_name);
+
+ /* Copy channel name and normalize it */
+ strncpy(chan.name, channel_name, NAME_MAX);
+ chan.name[NAME_MAX - 1] = '\0';
+
+ ret = lttng_enable_channel(&dom, &chan);
if (ret < 0) {
goto error;
} else {
}
/*
- * cmd_enable_channels
+ * init_channel_config
*
- * Enable channel to trace session
+ * Default value for channel configuration.
+ */
+static void init_channel_config(void)
+{
+ chan.attr.overwrite = DEFAULT_CHANNEL_OVERWRITE;
+ chan.attr.subbuf_size = DEFAULT_CHANNEL_SUBBUF_SIZE;
+ chan.attr.num_subbuf = DEFAULT_CHANNEL_SUBBUF_NUM;
+ chan.attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER;
+ chan.attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER;
+ chan.attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
+}
+
+/*
+ * Add channel to trace session
*/
int cmd_enable_channels(int argc, const char **argv)
{
int opt, ret;
static poptContext pc;
+ init_channel_config();
+
pc = poptGetContext(NULL, argc, argv, long_options, 0);
poptReadDefaultConfig(pc, 0);
goto end;
case OPT_USERSPACE:
opt_userspace = 1;
+ opt_cmd_name = poptGetOptArg(pc);
+ break;
+ case OPT_DISCARD:
+ chan.attr.overwrite = 0;
+ DBG("Channel set to discard");
+ break;
+ case OPT_OVERWRITE:
+ chan.attr.overwrite = 1;
+ DBG("Channel set to overwrite");
+ break;
+ case OPT_SUBBUF_SIZE:
+ chan.attr.subbuf_size = atol(poptGetOptArg(pc));
+ DBG("Channel subbuf size set to %lu", chan.attr.subbuf_size);
+ break;
+ case OPT_NUM_SUBBUF:
+ chan.attr.num_subbuf = atoi(poptGetOptArg(pc));
+ DBG("Channel subbuf num set to %lu", chan.attr.num_subbuf);
+ break;
+ case OPT_SWITCH_TIMER:
+ chan.attr.switch_timer_interval = atoi(poptGetOptArg(pc));
+ DBG("Channel switch timer interval set to %d", chan.attr.switch_timer_interval);
+ break;
+ case OPT_READ_TIMER:
+ chan.attr.read_timer_interval = atoi(poptGetOptArg(pc));
+ DBG("Channel read timer interval set to %d", chan.attr.read_timer_interval);
break;
default:
usage(stderr);
opt_channels = (char*) poptGetArg(pc);
if (opt_channels == NULL) {
- ERR("Missing channel name(s).\n");
+ ERR("Missing channel name.\n");
usage(stderr);
ret = CMD_SUCCESS;
goto end;
}
- ret = enable_channels();
+ ret = enable_channel();
end:
return ret;
/* Check for symbol+offset */
ret = sscanf(opt, "%[^'+']+%li", name, &hex);
if (ret == 2) {
- strncpy(ev->attr.kprobe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
- DBG("kprobe symbol %s", ev->attr.kprobe.symbol_name);
+ strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
+ DBG("kprobe symbol %s", ev->attr.probe.symbol_name);
if (hex == 0) {
ERR("Invalid kprobe offset %lu", hex);
ret = -1;
goto error;
}
- ev->attr.kprobe.offset = hex;
- DBG("kprobe offset %lu", ev->attr.kprobe.offset);
+ ev->attr.probe.offset = hex;
+ DBG("kprobe offset %lu", ev->attr.probe.offset);
goto error;
}
ret = -1;
goto error;
}
- ev->attr.kprobe.addr = hex;
- DBG("kprobe addr %lu", ev->attr.kprobe.addr);
+ ev->attr.probe.addr = hex;
+ DBG("kprobe addr %lu", ev->attr.probe.addr);
goto error;
}
int err, ret = CMD_SUCCESS;
char *event_name, *channel_name = NULL;
struct lttng_event ev;
+ struct lttng_domain dom;
if (set_session_name(opt_session_name) < 0) {
ret = CMD_ERROR;
channel_name = opt_channel_name;
}
+ /* Create lttng domain */
+ if (opt_kernel) {
+ dom.type = LTTNG_DOMAIN_KERNEL;
+ }
+
if (opt_enable_all) {
if (opt_kernel) {
- ret = lttng_kernel_enable_event(NULL, channel_name);
+ ret = lttng_enable_event(&dom, NULL, channel_name);
goto error;
}
switch (opt_event_type) {
case LTTNG_EVENT_TRACEPOINT:
- ret = lttng_kernel_enable_event(&ev, channel_name);
- if (ret < 0) {
- ERR("Unable to find event %s", ev.name);
- }
break;
- case LTTNG_EVENT_KPROBE:
+ case LTTNG_EVENT_PROBE:
ret = parse_kprobe_opts(&ev, opt_kprobe);
if (ret < 0) {
ERR("Unable to parse kprobe options");
ret = 0;
goto error;
}
-
- ret = lttng_kernel_enable_event(&ev, channel_name);
break;
case LTTNG_EVENT_FUNCTION:
strncpy(ev.attr.ftrace.symbol_name, opt_function_symbol, LTTNG_SYMBOL_NAME_LEN);
- ret = lttng_kernel_enable_event(&ev, channel_name);
break;
default:
ret = CMD_NOT_IMPLEMENTED;
goto error;
}
- if (ret > 0) {
+ ret = lttng_enable_event(&dom, &ev, channel_name);
+ if (ret == 0) {
MSG("Kernel event %s created in channel %s", event_name, channel_name);
+ } else if (ret < 0) {
+ ERR("Unable to find event %s", ev.name);
}
} else if (opt_userspace) { /* User-space tracer action */
/*
ret = CMD_NOT_IMPLEMENTED;
goto end;
case OPT_KPROBE:
- opt_event_type = LTTNG_EVENT_KPROBE;
+ opt_event_type = LTTNG_EVENT_PROBE;
opt_kprobe = poptGetOptArg(pc);
break;
case OPT_FUNCTION:
{
int ret, pos, size;
char *event_list, *event, *ptr;
+ struct lttng_domain dom;
DBG("Getting all tracing events");
- ret = lttng_kernel_list_events(&event_list);
+ dom.type = LTTNG_DOMAIN_KERNEL;
+
+ ret = lttng_list_events(&dom, &event_list);
if (ret < 0) {
ERR("Unable to list kernel instrumentation");
return ret;
pid_t *pids;
char *cmdline;
- count = 0;
+ count = -1;
//count = lttng_ust_list_traceable_apps(&pids);
if (count < 0) {
ret = count;
{ "list", cmd_list},
{ "create", cmd_create},
{ "destroy", cmd_destroy},
- { "add-channel", cmd_add_channel},
{ "start", cmd_start},
{ "stop", cmd_stop},
{ "enable-event", cmd_enable_events},
fprintf(ofp, " --list-commands Simple listing of lttng commands\n");
fprintf(ofp, "\n");
fprintf(ofp, "Commands:\n");
- fprintf(ofp, " add-channel Add channel to tracer\n");
fprintf(ofp, " add-context Add context to event or/and channel\n");
fprintf(ofp, " create Create tracing session\n");
fprintf(ofp, " destroy Teardown tracing session\n");