X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Fltt-sessiond.c;h=45f79a70980a4506b5dfc34f57f0cf17622cce7c;hp=3590d7e444c685147cf74c3a2ece2e1de2831367;hb=c01bdd9d853345f49985ed448198bf1a8ac27e79;hpb=8028d92056a3f0f8999cb895d0fd21eeca0ce849 diff --git a/ltt-sessiond/ltt-sessiond.c b/ltt-sessiond/ltt-sessiond.c index 3590d7e44..45f79a709 100644 --- a/ltt-sessiond/ltt-sessiond.c +++ b/ltt-sessiond/ltt-sessiond.c @@ -56,10 +56,15 @@ static void copy_common_data(struct lttcomm_lttng_msg *llm, struct lttcomm_sessi static int check_existing_daemon(void); static int notify_apps(const char* name); static int connect_app(pid_t pid); +static int find_app_by_pid(pid_t pid); 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 int setup_data_buffer(char **buf, size_t size, struct lttcomm_lttng_msg *llm); +static void add_traceable_app(struct ltt_traceable_app *lta); +static void del_traceable_app(struct ltt_traceable_app *lta); +static void add_session_list(struct ltt_session *ls); +static void del_session_list(struct ltt_session *ls); /* Command function */ static void get_list_apps(pid_t *pids); @@ -106,6 +111,9 @@ static struct ltt_traceable_app_list ltt_traceable_app_list = { .head = CDS_LIST_HEAD_INIT(ltt_traceable_app_list.head), }; +/* List mutex */ +pthread_mutex_t ltt_traceable_app_list_mutex; + /* * thread_manage_apps * @@ -153,26 +161,16 @@ static void *thread_manage_apps(void *data) lta = malloc(sizeof(struct ltt_traceable_app)); lta->pid = reg_msg.pid; lta->uid = reg_msg.uid; - cds_list_add(<a->list, <t_traceable_app_list.head); - traceable_app_count++; + add_traceable_app(lta); } else { /* Unregistering */ - lta = NULL; cds_list_for_each_entry(lta, <t_traceable_app_list.head, list) { if (lta->pid == reg_msg.pid && lta->uid == reg_msg.uid) { - cds_list_del(<a->list); - /* Check to not overflow here */ - if (traceable_app_count != 0) { - traceable_app_count--; - } + del_traceable_app(lta); + free(lta); break; } } - - /* If an item was found, free it from memory */ - if (lta) { - free(lta); - } } } @@ -217,7 +215,7 @@ static void *thread_manage_clients(void *data) * request of the client. */ ret = lttcomm_recv_unix_sock(sock, &lsm, sizeof(lsm)); - if (ret < 0) { + if (ret <= 0) { continue; } @@ -237,6 +235,62 @@ error: return NULL; } +/* + * add_traceable_app + * + * Add a traceable application structure to the global + * list protected by a mutex. + */ +static void add_traceable_app(struct ltt_traceable_app *lta) +{ + pthread_mutex_lock(<t_traceable_app_list_mutex); + cds_list_add(<a->list, <t_traceable_app_list.head); + traceable_app_count++; + pthread_mutex_unlock(<t_traceable_app_list_mutex); +} + +/* + * del_traceable_app + * + * Delete a traceable application structure from the + * global list protected by a mutex. + */ +static void del_traceable_app(struct ltt_traceable_app *lta) +{ + pthread_mutex_lock(<t_traceable_app_list_mutex); + cds_list_del(<a->list); + /* Sanity check */ + if (traceable_app_count != 0) { + traceable_app_count--; + } + pthread_mutex_unlock(<t_traceable_app_list_mutex); +} + +/* + * add_session_list + * + * Add a ltt_session structure to the global list. + */ +static void add_session_list(struct ltt_session *ls) +{ + cds_list_add(&ls->list, <t_session_list.head); + session_count++; +} + +/* + * del_session_list + * + * Delete a ltt_session structure to the global list. + */ +static void del_session_list(struct ltt_session *ls) +{ + cds_list_del(&ls->list); + /* Sanity check */ + if (session_count != 0) { + session_count--; + } +} + /* * send_unix_sock * @@ -259,10 +313,18 @@ static int send_unix_sock(int sock, void *buf, size_t len) * * Return a socket connected to the libust communication socket * of the application identified by the pid. + * + * If the pid is not found in the traceable list, + * return -1 to indicate error. */ static int connect_app(pid_t pid) { - int sock; + int sock, ret; + + ret = find_app_by_pid(pid); + if (ret == 0) { + return -1; + } sock = ustctl_connect_pid(pid); if (sock < 0) { @@ -302,6 +364,29 @@ error: return ret; } +/* + * find_app_by_pid + * + * Iterate over the traceable apps list. + * On success, return 1, else return 0 + */ +static int find_app_by_pid(pid_t pid) +{ + struct ltt_traceable_app *iter; + + pthread_mutex_lock(<t_traceable_app_list_mutex); + cds_list_for_each_entry(iter, <t_traceable_app_list.head, list) { + if (iter->pid == pid) { + pthread_mutex_unlock(<t_traceable_app_list_mutex); + /* Found */ + return 1; + } + } + pthread_mutex_unlock(<t_traceable_app_list_mutex); + + return 0; +} + /* * find_session_by_uuid * @@ -372,9 +457,8 @@ static int destroy_session(uuid_t *uuid) cds_list_for_each_entry(iter, <t_session_list.head, list) { if (uuid_compare(iter->uuid, *uuid) == 0) { - cds_list_del(&iter->list); + del_session_list(iter); free(iter); - session_count--; found = 1; break; } @@ -426,9 +510,7 @@ static int create_session(char *name, uuid_t *session_id) CDS_INIT_LIST_HEAD(&new_session->lttng_traces); /* Add new session to the global session list */ - cds_list_add(&new_session->list, <t_session_list.head); - - session_count++; + add_session_list(new_session); return 0; @@ -436,6 +518,51 @@ error: return -1; } +/* + * ust_create_trace + * + * Create an userspace trace using pid. + * This trace is then appended to the current session + * ust trace list. + */ +static int ust_create_trace(pid_t pid) +{ + int sock, ret; + struct ltt_ust_trace *trace; + + trace = malloc(sizeof(struct ltt_ust_trace)); + if (trace == NULL) { + perror("malloc"); + ret = -1; + goto error; + } + + /* Init */ + trace->pid = pid; + trace->shmid = 0; + + /* Connect to app using ustctl API */ + sock = connect_app(pid); + if (sock < 0) { + ret = LTTCOMM_NO_TRACEABLE; + goto error; + } + + ret = ustctl_create_trace(sock, "auto"); + if (ret < 0) { + ret = LTTCOMM_CREATE_FAIL; + goto error; + } + + /* Check if current session is valid */ + if (current_session) { + cds_list_add(&trace->list, ¤t_session->ust_traces); + } + +error: + return ret; +} + /* * get_list_apps * @@ -447,11 +574,15 @@ static void get_list_apps(pid_t *pids) int i = 0; struct ltt_traceable_app *iter; - /* TODO: Mutex needed to access this list */ + /* Protected by a mutex here because the threads manage_client + * and manage_apps can access this list. + */ + pthread_mutex_lock(<t_traceable_app_list_mutex); cds_list_for_each_entry(iter, <t_traceable_app_list.head, list) { pids[i] = iter->pid; i++; } + pthread_mutex_unlock(<t_traceable_app_list_mutex); } /* @@ -553,6 +684,19 @@ static int process_client_msg(int sock, struct lttcomm_session_msg *lsm) */ copy_common_data(&llm, lsm); + /* Check command that needs a session */ + if (lsm->cmd_type != LTTNG_CREATE_SESSION && + lsm->cmd_type != LTTNG_LIST_SESSIONS && + lsm->cmd_type != UST_LIST_APPS) + { + current_session = find_session_by_uuid(lsm->session_id); + if (current_session == NULL) { + ret = LTTCOMM_SELECT_SESS; + goto end; + } + } + + /* Default return code. * In our world, everything is OK... right? ;) */ @@ -587,6 +731,17 @@ static int process_client_msg(int sock, struct lttcomm_session_msg *lsm) /* No auxiliary data so only send the llm struct. */ goto end; } + case UST_CREATE_TRACE: + { + ret = ust_create_trace(lsm->pid); + if (ret < 0) { + ret = LTTCOMM_CREATE_FAIL; + goto end; + } + + /* No auxiliary data so only send the llm struct. */ + goto end; + } case UST_LIST_APPS: { /* Stop right now if no apps */ @@ -897,6 +1052,7 @@ static void sighandler(int sig) { switch (sig) { case SIGPIPE: + return; case SIGINT: case SIGTERM: cleanup();