X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Fsession.c;h=97ab098dca3c93c102cc7042619783ec9dec02ec;hp=ae09625a4dba0256236171d729a70706b31d8879;hb=b5541356f517dba006af9f676df8131dcb68f132;hpb=1d4b027abdef2dc52b41b05ec56c5046c5000c4c diff --git a/ltt-sessiond/session.c b/ltt-sessiond/session.c index ae09625a4..97ab098dc 100644 --- a/ltt-sessiond/session.c +++ b/ltt-sessiond/session.c @@ -17,98 +17,105 @@ */ #define _GNU_SOURCE +#include #include #include #include +#include #include #include "lttngerr.h" #include "session.h" -/* Variables */ -static unsigned int session_count; - -/* Static internal function */ -static void add_session_list(struct ltt_session *ls); -static void del_session_list(struct ltt_session *ls); - -/* Init global session list */ -struct ltt_session_list ltt_session_list = { - .head = CDS_LIST_HEAD_INIT(ltt_session_list.head), -}; - /* - * get_session_list + * NOTES: * - * Return a pointer to the session list. + * No ltt_session.lock is taken here because those data structure are widely + * spread across the lttng-tools code base so before caling functions below + * that can read/write a session, the caller MUST acquire the session lock + * using lock_session() and unlock_session(). */ -struct ltt_session_list *get_session_list(void) -{ - return <t_session_list; -} /* - * get_session_count + * Init tracing session list. * - * Return session_count + * Please see session.h for more explanation and correct usage of the list. */ -unsigned int get_session_count(void) -{ - return session_count; -} +static struct ltt_session_list ltt_session_list = { + .head = CDS_LIST_HEAD_INIT(ltt_session_list.head), + .lock = PTHREAD_MUTEX_INITIALIZER, + .count = 0, +}; /* * add_session_list * * Add a ltt_session structure to the global list. + * + * The caller MUST acquire the session list lock before. */ static void add_session_list(struct ltt_session *ls) { cds_list_add(&ls->list, <t_session_list.head); - session_count++; + ltt_session_list.count++; } /* * del_session_list * * Delete a ltt_session structure to the global list. + * + * The caller MUST acquire the session list lock before. */ static void del_session_list(struct ltt_session *ls) { cds_list_del(&ls->list); /* Sanity check */ - if (session_count != 0) { - session_count--; + if (ltt_session_list.count > 0) { + ltt_session_list.count--; } } /* - * find_session_by_uuid + * get_session_list * - * Return a ltt_session structure ptr that matches the uuid. + * Return a pointer to the session list. */ -struct ltt_session *find_session_by_uuid(uuid_t session_id) +struct ltt_session_list *get_session_list(void) { - int found = 0; - struct ltt_session *iter; + return <t_session_list; +} - /* Sanity check for NULL session_id */ - if (uuid_is_null(session_id)) { - goto end; - } +/* + * Acquire session lock + */ +void lock_session(struct ltt_session *session) +{ + pthread_mutex_lock(&session->lock); +} - cds_list_for_each_entry(iter, <t_session_list.head, list) { - if (uuid_compare(iter->uuid, session_id) == 0) { - found = 1; - break; - } - } +/* + * Release session lock + */ +void unlock_session(struct ltt_session *session) +{ + pthread_mutex_unlock(&session->lock); +} -end: - if (!found) { - iter = NULL; - } - return iter; +/* + * get_session_count + * + * Return session_count + */ +unsigned int get_session_count(void) +{ + unsigned int count; + + pthread_mutex_lock(<t_session_list.lock); + count = ltt_session_list.count; + pthread_mutex_unlock(<t_session_list.lock); + + return count; } /* @@ -122,12 +129,14 @@ struct ltt_session *find_session_by_name(char *name) int found = 0; struct ltt_session *iter; + pthread_mutex_lock(<t_session_list.lock); cds_list_for_each_entry(iter, <t_session_list.head, list) { if (strncmp(iter->name, name, strlen(name)) == 0) { found = 1; break; } } + pthread_mutex_unlock(<t_session_list.lock); if (!found) { iter = NULL; @@ -139,26 +148,29 @@ struct ltt_session *find_session_by_name(char *name) /* * destroy_session * - * Delete session from the global session list - * and free the memory. + * Delete session from the session list and free the memory. * - * Return -1 if no session is found. - * On success, return 1; + * Return -1 if no session is found. On success, return 1; */ -int destroy_session(uuid_t *uuid) +int destroy_session(char *name) { int found = -1; struct ltt_session *iter; + pthread_mutex_lock(<t_session_list.lock); cds_list_for_each_entry(iter, <t_session_list.head, list) { - if (uuid_compare(iter->uuid, *uuid) == 0) { + if (strcmp(iter->name, name) == 0) { DBG("Destroying session %s", iter->name); del_session_list(iter); + free(iter->name); + free(iter->path); + pthread_mutex_destroy(&iter->lock); free(iter); found = 1; break; } } + pthread_mutex_unlock(<t_session_list.lock); return found; } @@ -166,51 +178,64 @@ int destroy_session(uuid_t *uuid) /* * create_session * - * Create a brand new session and add it to the - * global session list. + * Create a brand new session and add it to the session list. */ -int create_session(char *name, uuid_t *session_id) +int create_session(char *name, char *path) { + int ret; + char date_time[NAME_MAX]; struct ltt_session *new_session; - - DBG("Creating session %s", name); + time_t rawtime; + struct tm *timeinfo; new_session = find_session_by_name(name); if (new_session != NULL) { - goto error; + ret = -EEXIST; + goto error_exist; } /* Allocate session data structure */ new_session = malloc(sizeof(struct ltt_session)); if (new_session == NULL) { perror("malloc"); - goto error_mem; + ret = -ENOMEM; + goto error_malloc; } + /* Define session name */ if (name != NULL) { if (asprintf(&new_session->name, "%s", name) < 0) { - goto error_mem; + ret = -ENOMEM; + goto error_asprintf; } } else { - /* Generate session name based on the session count */ - if (asprintf(&new_session->name, "%s%d", "lttng-", session_count) < 0) { - goto error_mem; - } + ERR("No session name given"); + ret = -1; + goto error; } - /* UUID generation */ - uuid_generate(new_session->uuid); - uuid_copy(*session_id, new_session->uuid); + /* Define session system path */ + if (path != NULL) { + if (strstr(name, "auto-") == NULL) { + time(&rawtime); + timeinfo = localtime(&rawtime); + strftime(date_time, sizeof(date_time), "-%Y%m%d-%H%M%S", timeinfo); + } else { + date_time[0] = '\0'; + } - /* - * Set consumer (identifier) to 0. This means that there is - * NO consumer attach to that session yet. - */ - new_session->ust_consumer = 0; + if (asprintf(&new_session->path, "%s/%s%s", path, name, date_time) < 0) { + ret = -ENOMEM; + goto error_asprintf; + } + } else { + ERR("No session path given"); + ret = -1; + goto error; + } /* Init kernel session */ new_session->kernel_session = NULL; - new_session->kern_session_count = 0; /* Init list */ CDS_INIT_LIST_HEAD(&new_session->ust_traces); @@ -218,23 +243,33 @@ int create_session(char *name, uuid_t *session_id) /* Set trace list counter */ new_session->ust_trace_count = 0; - /* Add new session to the global session list */ + /* Add new session to the session list */ + pthread_mutex_lock(<t_session_list.lock); add_session_list(new_session); + pthread_mutex_unlock(<t_session_list.lock); + + /* Init lock */ + pthread_mutex_init(&new_session->lock, NULL); + + DBG("Tracing session %s created in %s", new_session->name, new_session->path); return 0; error: - return -1; +error_asprintf: + if (new_session != NULL) { + free(new_session); + } -error_mem: - return -ENOMEM; +error_exist: +error_malloc: + return ret; } /* * get_lttng_session * - * Iterate over the global session list and - * fill the lttng_session array. + * Iterate over the global session list and fill the lttng_session array. */ void get_lttng_session(struct lttng_session *sessions) { @@ -244,12 +279,14 @@ void get_lttng_session(struct lttng_session *sessions) DBG("Getting all available session"); - /* Iterate over session list and append data after - * the control struct in the buffer. + /* + * Iterate over session list and append data after the control struct in + * the buffer. */ + pthread_mutex_lock(<t_session_list.lock); cds_list_for_each_entry(iter, <t_session_list.head, list) { - /* Copy name and uuid */ - uuid_copy(lsess.uuid, iter->uuid); + strncpy(lsess.path, iter->path, sizeof(lsess.path)); + lsess.path[sizeof(lsess.path) - 1] = '\0'; strncpy(lsess.name, iter->name, sizeof(lsess.name)); lsess.name[sizeof(lsess.name) - 1] = '\0'; memcpy(&sessions[i], &lsess, sizeof(lsess)); @@ -257,5 +294,6 @@ void get_lttng_session(struct lttng_session *sessions) /* Reset struct for next pass */ memset(&lsess, 0, sizeof(lsess)); } + pthread_mutex_unlock(<t_session_list.lock); }