From ca95a21633510288dbb18a3cd8825195e5cbb4f3 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 21 Apr 2011 17:29:32 -0400 Subject: [PATCH] Major changes for the daemon data transmission This commit reengineer the data transmission from the session daemon to the liblttngctl. Instead of sending a packet on a per data structure basis, this scheme uses lttcomm_lttng_msg structure has a header control structure adding the payload_size to it. The payload data is then appended after and only one send() is used. This will permit AF_INET socket scaling for future development. List sessions and list apps command has been modified to fit this change. In the meantime, some unuse code is removed and minor cleanup. Signed-off-by: David Goulet --- include/lttng/liblttngctl.h | 4 +- liblttngctl/liblttngctl.c | 197 +++++++++--------------- liblttsessiondcomm/liblttsessiondcomm.c | 1 + liblttsessiondcomm/liblttsessiondcomm.h | 24 +-- ltt-sessiond/ltt-sessiond.c | 154 ++++++++++++------ ltt-sessiond/ltt-sessiond.h | 3 +- 6 files changed, 193 insertions(+), 190 deletions(-) diff --git a/include/lttng/liblttngctl.h b/include/lttng/liblttngctl.h index ea6d001e1..7d2bb8862 100644 --- a/include/lttng/liblttngctl.h +++ b/include/lttng/liblttngctl.h @@ -46,7 +46,7 @@ extern int lttng_connect_sessiond(void); extern int lttng_set_tracing_group(const char *name); extern int lttng_check_session_daemon(void); extern const char *lttng_get_readable_code(int code); -extern size_t lttng_ust_list_apps(pid_t **pids); -extern size_t lttng_list_sessions(struct lttng_session **sessions); +extern int lttng_ust_list_apps(pid_t **pids); +extern int lttng_list_sessions(struct lttng_session **sessions); #endif /* _LIBLTTNGCTL_H */ diff --git a/liblttngctl/liblttngctl.c b/liblttngctl/liblttngctl.c index 658f646f0..fda45ae10 100644 --- a/liblttngctl/liblttngctl.c +++ b/liblttngctl/liblttngctl.c @@ -34,33 +34,28 @@ 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; /* Prototypes */ static int check_tracing_group(const char *grp_name); -static int ask_sessiond(void); -static int recvfrom_sessiond(void); +static int ask_sessiond(enum lttcomm_command_type 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 session daemon. * * On success, return 0 * On error, return error code */ -static int ask_sessiond(void) +static int send_data_sessiond(void) { int ret; @@ -76,14 +71,14 @@ end: } /* - * recvfrom_sessiond + * recv_data_sessiond * * Receive data from the sessiond socket. * * On success, return 0 * On error, return recv() error code */ -static int recvfrom_sessiond(void) +static int recv_data_sessiond(void *buf, size_t len) { int ret; @@ -92,113 +87,105 @@ static int recvfrom_sessiond(void) goto end; } - ret = lttcomm_recv_unix_sock(sessiond_socket, &llm, sizeof(llm)); + ret = lttcomm_recv_unix_sock(sessiond_socket, buf, len); if (ret < 0) { goto end; } - /* Check return code */ - if (llm.ret_code != LTTCOMM_OK) { - ret = -llm.ret_code; - goto end; - } - end: return ret; } /* - * lttng_get_readable_code + * ask_sessiond * - * Return a human readable string of code + * Ask the session daemon a specific command + * and put the data into buf. + * + * Return size of data (only payload, not header). */ -const char *lttng_get_readable_code(int code) +static int ask_sessiond(enum lttcomm_command_type lct, void **buf) { - if (code > -LTTCOMM_OK) { - return "Ended with errors"; + int ret; + size_t size; + void *data = NULL; + struct lttcomm_lttng_msg llm; + + lsm.cmd_type = lct; + + /* Send command to session daemon */ + ret = send_data_sessiond(); + if (ret < 0) { + goto end; } - return lttcomm_get_readable_code(code); -} + /* Get header from data transmission */ + ret = recv_data_sessiond(&llm, sizeof(llm)); + if (ret < 0) { + goto end; + } -/* - * lttng_create_session - * - * 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. - * - * On success, return 0 and session_id point to the uuid str. - * On error, negative value is returned. - */ -int lttng_create_session(const char *name, char *session_id) -{ - int ret; + /* Check error code if OK */ + if (llm.ret_code != LTTCOMM_OK) { + ret = -llm.ret_code; + goto end; + } - 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; + size = llm.size_payload; + if (size == 0) { + goto end; } - /* Ask the session daemon */ - ret = ask_sessiond(); + data = (void*) malloc(size); + + /* Get payload data */ + ret = recv_data_sessiond(data, size); if (ret < 0) { goto end; } - /* Unparse session ID */ - uuid_unparse(llm.session_id, session_id); + *buf = data; + ret = size; end: - reset_data_struct(); - + /* Reset lsm data struct */ + memset(&lsm, 0, sizeof(lsm)); return ret; } +/* + * 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"; + } + + return lttcomm_get_readable_code(code); +} + /* * lttng_ust_list_apps * * 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, first = 0; - size_t size = 0; - pid_t *p = NULL; - - lsm.cmd_type = UST_LIST_APPS; + int ret; - ret = ask_sessiond(); + ret = ask_sessiond(UST_LIST_APPS, (void**) pids); if (ret < 0) { - goto error; + return ret; } - do { - ret = recvfrom_sessiond(); - if (ret < 0) { - goto error; - } - - if (first == 0) { - first = 1; - size = llm.num_pckt; - p = malloc(sizeof(pid_t) * size); - } - p[size - llm.num_pckt] = llm.u.list_apps.pid; - } while ((llm.num_pckt-1) != 0); - - *pids = p; - - return size; - -error: - return ret; + return ret / sizeof(pid_t); } /* @@ -206,44 +193,19 @@ error: * * Ask the session daemon for all available sessions. * - * Return number of sessions + * Return number of session. + * On error, return negative value. */ -size_t lttng_list_sessions(struct lttng_session **sessions) +int lttng_list_sessions(struct lttng_session **sessions) { - int ret, first = 0; - size_t size = 0; - struct lttng_session *ls = NULL; - - lsm.cmd_type = LTTNG_LIST_SESSIONS; + int ret; - ret = ask_sessiond(); + ret = ask_sessiond(LTTNG_LIST_SESSIONS, (void**) sessions); if (ret < 0) { - goto error; + return ret; } - do { - ret = recvfrom_sessiond(); - if (ret < 0) { - goto error; - } - - if (first == 0) { - first = 1; - size = llm.num_pckt; - ls = malloc(sizeof(struct lttng_session) * size); - } - strncpy(ls[size - llm.num_pckt].name, llm.u.list_sessions.name, - sizeof(ls[size - llm.num_pckt].name)); - strncpy(ls[size - llm.num_pckt].uuid, llm.u.list_sessions.uuid, - sizeof(ls[size - llm.num_pckt].uuid)); - } while ((llm.num_pckt - 1) != 0); - - *sessions = ls; - - return size; - -error: - return ret; + return ret / sizeof(struct lttng_session); } /* @@ -313,17 +275,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 * diff --git a/liblttsessiondcomm/liblttsessiondcomm.c b/liblttsessiondcomm/liblttsessiondcomm.c index adae84104..0e9c290fe 100644 --- a/liblttsessiondcomm/liblttsessiondcomm.c +++ b/liblttsessiondcomm/liblttsessiondcomm.c @@ -40,6 +40,7 @@ static const char *lttcomm_readable_code[] = { [ 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_NO_SESS) ] = "No session found", + [ LTTCOMM_ERR_INDEX(LTTCOMM_FATAL) ] = "Fatal error of the session daemon", }; /* diff --git a/liblttsessiondcomm/liblttsessiondcomm.h b/liblttsessiondcomm/liblttsessiondcomm.h index f4180cf0a..6d6290d0a 100644 --- a/liblttsessiondcomm/liblttsessiondcomm.h +++ b/liblttsessiondcomm/liblttsessiondcomm.h @@ -75,6 +75,7 @@ enum lttcomm_return_code { LTTCOMM_LIST_FAIL, /* Listing apps fail */ LTTCOMM_NO_APPS, /* No traceable application */ LTTCOMM_NO_SESS, /* No sessions available */ + LTTCOMM_FATAL, /* Session daemon had a fatal error */ LTTCOMM_NR, /* Last element */ }; @@ -115,7 +116,11 @@ struct lttcomm_session_msg { }; /* - * Data structure for the lttng client response + * Data structure for the lttng client response. + * + * This data structure is the control struct use in + * the header of the transmission. NEVER put variable + * size data in here. */ struct lttcomm_lttng_msg { enum lttcomm_command_type cmd_type; @@ -123,22 +128,7 @@ struct lttcomm_lttng_msg { uuid_t session_id; pid_t pid; char trace_name[NAME_MAX]; - /* This flag indicates how many packet are in - * the transmission. Ex: If list apps is requested, - * and there is 4 pids registered, num_pckt will be 4 - */ - unsigned int num_pckt; - union { - /* UST_LIST_APPS */ - struct { - pid_t pid; - } list_apps; - /* LTTNG_LIST_SESSIONS */ - struct { - char name[NAME_MAX]; - char uuid[37]; /* See libuuid not exported size UUID_STR_LEN */ - } list_sessions; - } u; + unsigned int size_payload; }; extern int lttcomm_create_unix_sock(const char *pathname); diff --git a/ltt-sessiond/ltt-sessiond.c b/ltt-sessiond/ltt-sessiond.c index a51593a96..fb197d43b 100644 --- a/ltt-sessiond/ltt-sessiond.c +++ b/ltt-sessiond/ltt-sessiond.c @@ -35,6 +35,7 @@ #include /* URCU list library (-lurcu) */ #include /* UST control lib (-lust) */ +#include #include "liblttsessiondcomm.h" #include "ltt-sessiond.h" @@ -58,7 +59,10 @@ static int connect_app(pid_t); static int init_daemon_socket(void); static int process_client_msg(int sock, struct lttcomm_session_msg*); static int send_unix_sock(int sock, void *buf, size_t len); -static size_t ust_list_apps(pid_t **pids); + +/* Command function */ +static void get_list_apps(void *buf); +static void get_list_sessions(void *buf); static void *thread_manage_clients(void *); static void *thread_manage_apps(void *); @@ -396,36 +400,47 @@ error: } /* - * ust_list_apps + * get_list_apps * * List traceable user-space application and fill an * array of pids. - * - * Return size of the array. */ -static size_t ust_list_apps(pid_t **pids) +static void get_list_apps(void *buf) { - size_t size = 0; + size_t index = 0; struct ltt_traceable_app *iter = NULL; - pid_t *p; - - if (traceable_app_count == 0) { - /* No dynamic allocation is done */ - goto end; - } - - p = malloc(sizeof(pid_t) * traceable_app_count); + pid_t *pids = (pid_t *) buf; /* TODO: Mutex needed to access this list */ cds_list_for_each_entry(iter, <t_traceable_app_list.head, list) { - p[size] = iter->pid; - size++; + pids[index] = iter->pid; + index++; } +} - *pids = p; +/* + * get_list_sessions + * + * List sessions and fill the data buffer. + */ +static void get_list_sessions(void *buf) +{ + int i = 0; + struct ltt_session *iter = NULL; + struct lttng_session lsess; + struct lttng_session *data = (struct lttng_session *) buf; -end: - return size; + /* Iterate over session list and append data after + * the control struct in the buffer. + */ + cds_list_for_each_entry(iter, <t_session_list.head, list) { + uuid_unparse(iter->uuid, lsess.uuid); + strncpy(lsess.name, iter->name, sizeof(lsess.name)); + memcpy(data + (i * sizeof(struct lttng_session)), &lsess, sizeof(lsess)); + i++; + /* Reset struct for next pass */ + memset(&lsess, 0, sizeof(lsess)); + } } /* @@ -443,6 +458,42 @@ static void copy_common_data(struct lttcomm_lttng_msg *llm, struct lttcomm_sessi strncpy(llm->trace_name, lsm->trace_name, sizeof(llm->trace_name)); } +/* + * setup_data_buffer + * + * Setup the outgoing data buffer for the response + * data allocating the right amount of memory. + * + * Return total size of the buffer pointed by buf. + */ +static int setup_data_buffer(void **buf, size_t s_data, struct lttcomm_lttng_msg *llm) +{ + int ret = 0; + void *new_buf; + size_t buf_size; + + buf_size = sizeof(struct lttcomm_lttng_msg) + s_data; + new_buf = malloc(buf_size); + if (new_buf == NULL) { + perror("malloc"); + ret = -1; + goto error; + } + + /* Setup lttcomm_lttng_msg data and copy + * it to the newly allocated buffer. + */ + llm->size_payload = s_data; + memcpy(new_buf, llm, sizeof(struct lttcomm_lttng_msg)); + + *buf = new_buf; + + return buf_size; + +error: + return ret; +} + /* * process_client_msg * @@ -456,6 +507,8 @@ static int process_client_msg(int sock, struct lttcomm_session_msg *lsm) { int ret; struct lttcomm_lttng_msg llm; + void *send_buf = NULL; + int buf_size; /* Copy common data to identify the response * on the lttng client side. @@ -471,46 +524,50 @@ static int process_client_msg(int sock, struct lttcomm_session_msg *lsm) switch (lsm->cmd_type) { case UST_LIST_APPS: { - pid_t *pids; - llm.num_pckt = ust_list_apps(&pids); - if (llm.num_pckt == 0) { + /* Stop right now if no apps */ + if (traceable_app_count == 0) { ret = LTTCOMM_NO_APPS; goto error; } - /* Send all packets */ - while (llm.num_pckt != 0) { - llm.u.list_apps.pid = pids[traceable_app_count - llm.num_pckt]; - ret = send_unix_sock(sock, (void*) &llm, sizeof(llm)); - if (ret < 0) { - goto send_error; - } - llm.num_pckt--; + /* Setup data buffer and details for transmission */ + buf_size = setup_data_buffer(&send_buf, + sizeof(pid_t) * traceable_app_count, &llm); + if (buf_size < 0) { + ret = LTTCOMM_FATAL; + goto error; + } + + get_list_apps(send_buf + sizeof(struct lttcomm_lttng_msg)); + + ret = send_unix_sock(sock, send_buf, buf_size); + if (ret < 0) { + goto send_error; } - /* Allocated array by ust_list_apps() */ - free(pids); break; } case LTTNG_LIST_SESSIONS: { - struct ltt_session *iter = NULL; - - llm.num_pckt = session_count; - if (llm.num_pckt == 0) { + /* Stop right now if no session */ + if (session_count == 0) { ret = LTTCOMM_NO_SESS; goto error; } - cds_list_for_each_entry(iter, <t_session_list.head, list) { - uuid_unparse(iter->uuid, llm.u.list_sessions.uuid); - strncpy(llm.u.list_sessions.name, iter->name, - sizeof(llm.u.list_sessions.name)); - ret = send_unix_sock(sock, (void*) &llm, sizeof(llm)); - if (ret < 0) { - goto send_error; - } - llm.num_pckt--; + /* Setup data buffer and details for transmission */ + buf_size = setup_data_buffer(&send_buf, + (sizeof(struct lttng_session) * session_count), &llm); + if (buf_size < 0) { + ret = LTTCOMM_FATAL; + goto error; + } + + get_list_sessions(send_buf + sizeof(struct lttcomm_lttng_msg)); + + ret = send_unix_sock(sock, send_buf, buf_size); + if (ret < 0) { + goto send_error; } break; @@ -519,10 +576,14 @@ static int process_client_msg(int sock, struct lttcomm_session_msg *lsm) { /* Undefined command */ ret = LTTCOMM_UND; - break; + goto error; } } + if (send_buf != NULL) { + free(send_buf); + } + return 0; send_error: @@ -531,6 +592,7 @@ send_error: error: /* Notify client of error */ llm.ret_code = ret; + llm.size_payload = 0; send_unix_sock(sock, (void*) &llm, sizeof(llm)); return -1; diff --git a/ltt-sessiond/ltt-sessiond.h b/ltt-sessiond/ltt-sessiond.h index cff3ae754..97f8658e1 100644 --- a/ltt-sessiond/ltt-sessiond.h +++ b/ltt-sessiond/ltt-sessiond.h @@ -19,8 +19,7 @@ #ifndef _LTT_SESSIOND_H #define _LTT_SESSIOND_H -#define DEFAULT_HOME_DIR "/tmp" -#define DEFAULT_TRACING_GROUP "/tracing" +#define DEFAULT_HOME_DIR "/tmp" #define DEFAULT_UST_SOCK_DIR "/tmp/ust-app-socks" #define DEFAULT_GLOBAL_APPS_PIPE "/tmp/ust-app-socks/global" -- 2.34.1