X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=liblttngctl%2Fliblttngctl.c;h=c27ce092825595692b91e4552b250a190dcf486f;hp=2b4b8febc082b81c5daa3d708dac6b1c9aa9e519;hb=64a23ac4e22093a782b87fe615fabf20edacedd2;hpb=826d496db7f18f2ae1f7e0d2f4fc381144ed04a4 diff --git a/liblttngctl/liblttngctl.c b/liblttngctl/liblttngctl.c index 2b4b8febc..c27ce0928 100644 --- a/liblttngctl/liblttngctl.c +++ b/liblttngctl/liblttngctl.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include "liblttsessiondcomm.h" #include "lttngerr.h" @@ -34,63 +34,219 @@ static int sessiond_socket; static char sessiond_sock_path[PATH_MAX]; /* Communication structure to ltt-sessiond */ -static struct lttcomm_lttng_msg llm; static struct lttcomm_session_msg lsm; +static struct lttcomm_lttng_msg llm; /* Prototypes */ static int check_tracing_group(const char *grp_name); -static int ask_sessiond(void); +static int ask_sessiond(enum lttcomm_sessiond_command lct, void **buf); +static int recv_data_sessiond(void *buf, size_t len); +static int send_data_sessiond(void); static int set_session_daemon_path(void); -static void reset_data_struct(void); - -int lttng_connect_sessiond(void); -int lttng_create_session(const char *name, char *session_id); -int lttng_check_session_daemon(void); /* Variables */ static char *tracing_group; static int connected; /* - * ask_sessiond + * send_data_sessiond * - * Send lttcomm_session_msg to the daemon and wait - * for the reply. Data replied will be put in llm + * Send lttcomm_session_msg to the session daemon. * * On success, return 0 * On error, return error code */ -static int ask_sessiond(void) +static int send_data_sessiond(void) { int ret; if (!connected) { - ret = -ECONNREFUSED; - goto error; + ret = -ENOTCONN; + goto end; } ret = lttcomm_send_unix_sock(sessiond_socket, &lsm, sizeof(lsm)); + +end: + return ret; +} + +/* + * recv_data_sessiond + * + * Receive data from the sessiond socket. + * + * On success, return 0 + * On error, return recv() error code + */ +static int recv_data_sessiond(void *buf, size_t len) +{ + int ret; + + if (!connected) { + ret = -ENOTCONN; + goto end; + } + + ret = lttcomm_recv_unix_sock(sessiond_socket, buf, len); if (ret < 0) { - goto error; + goto end; } - ret = lttcomm_recv_unix_sock(sessiond_socket, &llm, sizeof(llm)); +end: + return ret; +} + +/* + * ask_sessiond + * + * Ask the session daemon a specific command + * and put the data into buf. + * + * Return size of data (only payload, not header). + */ +static int ask_sessiond(enum lttcomm_sessiond_command lct, void **buf) +{ + int ret; + size_t size; + void *data = NULL; + + ret = lttng_connect_sessiond(); + if (ret < 0) { + goto end; + } + + lsm.cmd_type = lct; + + /* Send command to session daemon */ + ret = send_data_sessiond(); if (ret < 0) { - goto error; + goto end; } - /* Check return code */ + /* Get header from data transmission */ + ret = recv_data_sessiond(&llm, sizeof(llm)); + if (ret < 0) { + goto end; + } + + /* Check error code if OK */ if (llm.ret_code != LTTCOMM_OK) { ret = -llm.ret_code; - goto error; + goto end; } - return 0; + size = llm.trace_name_offset + llm.data_size; + if (size == 0) { + goto end; + } + + data = (void*) malloc(size); + + /* Get payload data */ + ret = recv_data_sessiond(data, size); + if (ret < 0) { + goto end; + } + + *buf = data; + ret = size; -error: +end: + lttng_disconnect_sessiond(); return ret; } +/* + * BEGIN KERNEL CONTROL + */ + +/* + * lttng_kernel_enable_event + * + * Enable an event in the kernel tracer. + */ +int lttng_kernel_enable_event(char *event_name) +{ + strncpy(lsm.u.event.event_name, event_name, NAME_MAX); + return ask_sessiond(KERNEL_ENABLE_EVENT, NULL); +} + +/* + * lttng_kernel_disable_event + * + * Disable an event in the kernel tracer. + */ +int lttng_kernel_disable_event(char *event_name) +{ + strncpy(lsm.u.event.event_name, event_name, NAME_MAX); + return ask_sessiond(KERNEL_DISABLE_EVENT, NULL); +} + +/* + * lttng_kernel_create_session + * + * Create a session in the kernel tracer. + */ +int lttng_kernel_create_session(void) +{ + return ask_sessiond(KERNEL_CREATE_SESSION, NULL); +} + +/* + * lttng_kernel_create_channel + * + * Create a channel in the kernel tracer. + */ +int lttng_kernel_create_channel(void) +{ + return ask_sessiond(KERNEL_CREATE_CHANNEL, NULL); +} + +/* + * lttng_kernel_open_metadata + * + * Open metadata in the kernel tracer. + */ +int lttng_kernel_open_metadata(void) +{ + return ask_sessiond(KERNEL_OPEN_METADATA, NULL); +} + +/* + * lttng_kernel_create_stream + * + * Create stream in the kernel tracer. + */ +int lttng_kernel_create_stream(void) +{ + return ask_sessiond(KERNEL_CREATE_STREAM, NULL); +} + +/* + * lttng_kernel_start_tracing + * + * Start kernel tracing. + */ +int lttng_kernel_start_tracing(void) +{ + return ask_sessiond(KERNEL_START_TRACE, NULL); +} + +/* + * lttng_kernel_stop_tracing + * + * Stop kernel tracing. + */ +int lttng_kernel_stop_tracing(void) +{ + return ask_sessiond(KERNEL_STOP_TRACE, NULL); +} + +/* + * END KERNEL CONTROL + */ + /* * lttng_get_readable_code * @@ -106,38 +262,46 @@ const char *lttng_get_readable_code(int code) } /* - * lttng_create_session + * lttng_ust_start_trace * - * Create a tracing session using "name" to the session daemon. - * If no name is given, the auto session creation is set and - * the daemon will take care of finding a name. + * Request a trace start for pid. + */ +int lttng_ust_start_trace(pid_t pid) +{ + int ret; + + lsm.pid = pid; + ret = ask_sessiond(UST_START_TRACE, NULL); + + return ret; +} + +/* + * lttng_ust_stop_trace * - * On success, return 0 and session_id point to the uuid str. - * On error, negative value is returned. + * Request a trace stop for pid. */ -int lttng_create_session(const char *name, char *session_id) +int lttng_ust_stop_trace(pid_t pid) { int ret; - lsm.cmd_type = LTTNG_CREATE_SESSION; - if (name == NULL) { - lsm.u.create_session.auto_session = 1; - } else { - strncpy(lsm.session_name, name, strlen(name)); - lsm.u.create_session.auto_session = 0; - } + lsm.pid = pid; + ret = ask_sessiond(UST_STOP_TRACE, NULL); - /* Ask the session daemon */ - ret = ask_sessiond(); - if (ret < 0) { - goto end; - } + return ret; +} - /* Unparse session ID */ - uuid_unparse(llm.session_id, session_id); +/* + * lttng_ust_create_trace + * + * Request a trace creation for pid. + */ +int lttng_ust_create_trace(pid_t pid) +{ + int ret; -end: - reset_data_struct(); + lsm.pid = pid; + ret = ask_sessiond(UST_CREATE_TRACE, NULL); return ret; } @@ -148,27 +312,104 @@ end: * Ask the session daemon for all UST traceable * applications. * - * Return the size of pids. + * Return the number of pids. + * On error, return negative value. */ -size_t lttng_ust_list_apps(pid_t **pids) +int lttng_ust_list_apps(pid_t **pids) { int ret; - lsm.cmd_type = UST_LIST_APPS; + ret = ask_sessiond(UST_LIST_APPS, (void**) pids); + if (ret < 0) { + return ret; + } + + return ret / sizeof(pid_t); +} + +/* + * lttng_list_traces + * + * Ask the session daemon for all traces (kernel and ust) + * for the session identified by uuid. + * + * Return the number of traces. + */ +int lttng_list_traces(uuid_t *uuid, struct lttng_trace **traces) +{ + int ret; + + uuid_copy(lsm.session_uuid, *uuid); - ret = ask_sessiond(); + ret = ask_sessiond(LTTNG_LIST_TRACES, (void **) traces); if (ret < 0) { - goto error; + return ret; } - *pids = llm.u.list_apps.pids; + return ret / sizeof(struct lttng_trace); +} - return llm.u.list_apps.size; +/* + * lttng_create_session + * + * Create a brand new session using name. + */ +int lttng_create_session(char *name) +{ + int ret; + + strncpy(lsm.session_name, name, sizeof(lsm.session_name)); + lsm.session_name[sizeof(lsm.session_name) - 1] = '\0'; + + ret = ask_sessiond(LTTNG_CREATE_SESSION, NULL); + if (ret < 0) { + goto end; + } -error: +end: + return ret; +} + +/* + * lttng_destroy_session + * + * Destroy session using name. + */ +int lttng_destroy_session(uuid_t *uuid) +{ + int ret; + + uuid_copy(lsm.session_uuid, *uuid); + + ret = ask_sessiond(LTTNG_DESTROY_SESSION, NULL); + if (ret < 0) { + goto end; + } + +end: return ret; } +/* + * lttng_list_sessions + * + * Ask the session daemon for all available sessions. + * + * Return number of session. + * On error, return negative value. + */ +int lttng_list_sessions(struct lttng_session **sessions) +{ + int ret; + + ret = ask_sessiond(LTTNG_LIST_SESSIONS, (void**) sessions); + if (ret < 0) { + return ret; + } + + return ret / sizeof(struct lttng_session); +} + /* * lttng_connect_sessiond * @@ -197,6 +438,34 @@ int lttng_connect_sessiond(void) return 0; } +/* + * lttng_disconnect_sessiond + * + * Clean disconnect the session daemon. + */ +int lttng_disconnect_sessiond(void) +{ + int ret = 0; + + if (connected) { + ret = lttcomm_close_unix_sock(sessiond_socket); + sessiond_socket = 0; + connected = 0; + } + + return ret; +} + +/* + * lttng_set_current_session_uuid + * + * Set the session uuid for current lsm. + */ +void lttng_set_current_session_uuid(uuid_t *uuid) +{ + uuid_copy(lsm.session_uuid, *uuid); +} + /* * lttng_set_tracing_group * @@ -236,17 +505,6 @@ int lttng_check_session_daemon(void) return 0; } -/* - * reset_data_struct - * - * Reset session daemon structures. - */ -static void reset_data_struct(void) -{ - memset(&lsm, 0, sizeof(lsm)); - memset(&llm, 0, sizeof(llm)); -} - /* * set_session_daemon_path * @@ -259,7 +517,7 @@ static int set_session_daemon_path(void) /* Are we in the tracing group ? */ ret = check_tracing_group(tracing_group); - if (ret < 0) { + if (ret < 0 && getuid() != 0) { if (sprintf(sessiond_sock_path, DEFAULT_HOME_CLIENT_UNIX_SOCK, getenv("HOME")) < 0) { return -ENOMEM; @@ -330,5 +588,5 @@ end: static void __attribute__((constructor)) init() { /* Set default session group */ - lttng_set_tracing_group(DEFAULT_TRACING_GROUP); + lttng_set_tracing_group(LTTNG_DEFAULT_TRACING_GROUP); }