X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;ds=sidebyside;f=ltt-sessiond%2Fltt-sessiond.c;h=4f9ca1bd4d2e45396edbbe367a165dca50af3830;hb=7e6e59cdaccc23e1e69166490f7167a396748d69;hp=a4baafc0761147687a9b03410df5a986dff609a0;hpb=379473d2e442e5273e3afb7f71b1d3fb37641d0c;p=lttng-tools.git diff --git a/ltt-sessiond/ltt-sessiond.c b/ltt-sessiond/ltt-sessiond.c index a4baafc07..4f9ca1bd4 100644 --- a/ltt-sessiond/ltt-sessiond.c +++ b/ltt-sessiond/ltt-sessiond.c @@ -61,6 +61,10 @@ 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); @@ -107,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 * @@ -154,18 +161,13 @@ 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 */ 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); + del_traceable_app(lta); free(lta); - /* Check to not overflow here */ - if (traceable_app_count != 0) { - traceable_app_count--; - } break; } } @@ -233,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 * @@ -316,12 +374,15 @@ 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; } @@ -396,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; } @@ -417,21 +477,26 @@ static int create_session(char *name, uuid_t *session_id) { struct ltt_session *new_session; + new_session = find_session_by_name(name); + if (new_session != NULL) { + goto error; + } + /* Allocate session data structure */ new_session = malloc(sizeof(struct ltt_session)); if (new_session == NULL) { perror("malloc"); - goto error; + goto error_mem; } if (name != NULL) { if (asprintf(&new_session->name, "%s", name) < 0) { - goto error; + goto error_mem; } } else { /* Generate session name based on the session count */ if (asprintf(&new_session->name, "%s%d", "lttng-", session_count) < 0) { - goto error; + goto error_mem; } } @@ -450,14 +515,15 @@ 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; error: return -1; + +error_mem: + return -ENOMEM; } /* @@ -516,11 +582,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); } /* @@ -614,6 +684,7 @@ static int process_client_msg(int sock, struct lttcomm_session_msg *lsm) { int ret; int buf_size; + size_t header_size; char *send_buf = NULL; struct lttcomm_lttng_msg llm; @@ -634,18 +705,24 @@ static int process_client_msg(int sock, struct lttcomm_session_msg *lsm) } } - /* Default return code. * In our world, everything is OK... right? ;) */ llm.ret_code = LTTCOMM_OK; + header_size = sizeof(struct lttcomm_lttng_msg); + /* Process by command type */ switch (lsm->cmd_type) { case LTTNG_CREATE_SESSION: { ret = create_session(lsm->session_name, &llm.session_id); if (ret < 0) { + if (ret == -1) { + ret = LTTCOMM_EXIST_SESS; + } else { + ret = LTTCOMM_FATAL; + } goto end; } @@ -696,7 +773,7 @@ static int process_client_msg(int sock, struct lttcomm_session_msg *lsm) goto end; } - get_list_apps((pid_t *)(send_buf + sizeof(struct lttcomm_lttng_msg))); + get_list_apps((pid_t *)(send_buf + header_size)); break; } @@ -716,7 +793,7 @@ static int process_client_msg(int sock, struct lttcomm_session_msg *lsm) goto end; } - get_list_sessions((struct lttng_session *)(send_buf + sizeof(struct lttcomm_lttng_msg))); + get_list_sessions((struct lttng_session *)(send_buf + header_size)); break; } @@ -750,16 +827,15 @@ end: */ static void usage(void) { - fprintf(stderr, "Usage:\n%s OPTIONS\n\nOptions:\n" - "\t-h, --help\t\tDisplay this usage.\n" - "\t-c, --client-sock PATH\t\tSpecify path for the client unix socket\n" - "\t-a, --apps-sock PATH\t\tSpecify path for apps unix socket.\n" - "\t-d, --daemonize\t\tStart as a daemon.\n" - "\t-g, --group NAME\t\tSpecify the tracing group name. (default: tracing)\n" - "\t-V, --version\t\tShow version number.\n" - "\t-S, --sig-parent\t\tSend SIGCHLD to parent pid to notify readiness.\n" - "\t-q, --quiet\t\tNo output at all.\n", - progname); + fprintf(stderr, "Usage: %s OPTIONS\n\nOptions:\n", progname); + fprintf(stderr, " -h, --help Display this usage.\n"); + fprintf(stderr, " -c, --client-sock PATH Specify path for the client unix socket\n"); + fprintf(stderr, " -a, --apps-sock PATH Specify path for apps unix socket.\n"); + fprintf(stderr, " -d, --daemonize Start as a daemon.\n"); + fprintf(stderr, " -g, --group NAME Specify the tracing group name. (default: tracing)\n"); + fprintf(stderr, " -V, --version Show version number.\n"); + fprintf(stderr, " -S, --sig-parent Send SIGCHLD to parent pid to notify readiness.\n"); + fprintf(stderr, " -q, --quiet No output at all.\n"); } /* @@ -795,7 +871,7 @@ static int parse_args(int argc, char **argv) fprintf(stderr, " with arg %s\n", optarg); } break; - case 's': + case 'c': snprintf(client_unix_sock_path, PATH_MAX, "%s", optarg); break; case 'a': @@ -1010,8 +1086,8 @@ static void sighandler(int sig) static void cleanup() { /* */ - MSG("\n\n%c[%d;%dm*** assert failed *** ==> %c[%dm", 27,1,31,27,0); - MSG("%c[%d;%dm Matthew, BEET driven development works!%c[%dm\n",27,1,33,27,0); + MSG("\n%c[%d;%dm*** assert failed *** ==> %c[%dm", 27,1,31,27,0); + MSG("%c[%d;%dmMatthew, BEET driven development works!%c[%dm",27,1,33,27,0); /* */ unlink(client_unix_sock_path); @@ -1075,7 +1151,10 @@ int main(int argc, char **argv) */ if ((ret = check_existing_daemon()) == 0) { ERR("Already running daemon.\n"); - goto error; + /* We do not goto error because we must not + * cleanup() because a daemon is already working. + */ + return EXIT_FAILURE; } if (set_signal_handler() < 0) {