X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Fsession.c;h=1ffe1d8e7ec05a47a2c0e1d372025eca764cc61a;hp=f355303365590dc467ccc94f069f348527fc6f32;hb=050349bbb362ea993533591532643022efeab864;hpb=f10719180ada8b6aec080a8f81aeae1b673edbb8 diff --git a/ltt-sessiond/session.c b/ltt-sessiond/session.c index f35530336..1ffe1d8e7 100644 --- a/ltt-sessiond/session.c +++ b/ltt-sessiond/session.c @@ -3,12 +3,12 @@ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * as published by the Free Software Foundation; only version 2 + * of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -17,6 +17,8 @@ */ #define _GNU_SOURCE +#include +#include #include #include #include @@ -26,22 +28,53 @@ #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); +/* + * NOTES: + * + * 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(). + */ -/* Init global session list */ -struct ltt_session_list ltt_session_list = { +/* + * Init tracing session list. + * + * Please see session.h for more explanation and correct usage of the list. + */ +static struct ltt_session_list ltt_session_list = { .head = CDS_LIST_HEAD_INIT(ltt_session_list.head), + .lock = PTHREAD_MUTEX_INITIALIZER, + .count = 0, }; /* - * get_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); + ltt_session_list.count++; +} + +/* + * Delete a ltt_session structure to the global list. * - * Return a pointer to the session 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 (ltt_session_list.count > 0) { + ltt_session_list.count--; + } +} + +/* + * Return a pointer to the session list. */ struct ltt_session_list *get_session_list(void) { @@ -49,57 +82,54 @@ struct ltt_session_list *get_session_list(void) } /* - * get_session_count - * - * Return session_count + * Acquire session list lock */ -unsigned int get_session_count(void) +void lock_session_list(void) { - return session_count; + pthread_mutex_lock(<t_session_list.lock); } /* - * add_session_list - * - * Add a ltt_session structure to the global list. + * Release session list lock */ -static void add_session_list(struct ltt_session *ls) +void unlock_session_list(void) { - cds_list_add(&ls->list, <t_session_list.head); - session_count++; + pthread_mutex_unlock(<t_session_list.lock); } /* - * del_session_list - * - * Delete a ltt_session structure to the global list. + * Acquire session lock */ -static void del_session_list(struct ltt_session *ls) +void lock_session(struct ltt_session *session) { - cds_list_del(&ls->list); - /* Sanity check */ - if (session_count != 0) { - session_count--; - } + pthread_mutex_lock(&session->lock); } /* - * find_session_by_name - * - * Return a ltt_session structure ptr that matches name. - * If no session found, NULL is returned. + * Release session lock + */ +void unlock_session(struct ltt_session *session) +{ + pthread_mutex_unlock(&session->lock); +} + +/* + * Return a ltt_session structure ptr that matches name. + * If no session found, NULL is returned. */ struct ltt_session *find_session_by_name(char *name) { int found = 0; struct ltt_session *iter; + lock_session_list(); cds_list_for_each_entry(iter, <t_session_list.head, list) { - if (strncmp(iter->name, name, strlen(name)) == 0) { + if (strncmp(iter->name, name, NAME_MAX) == 0) { found = 1; break; } } + unlock_session_list(); if (!found) { iter = NULL; @@ -109,44 +139,40 @@ 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(char *name) { int found = -1; - struct ltt_session *iter; + struct ltt_session *iter, *tmp; - cds_list_for_each_entry(iter, <t_session_list.head, list) { + lock_session_list(); + cds_list_for_each_entry_safe(iter, tmp, <t_session_list.head, list) { 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; } } + unlock_session_list(); return found; } /* - * 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, char *path) { int ret; - char date_time[NAME_MAX]; struct ltt_session *new_session; - time_t rawtime; - struct tm *timeinfo; new_session = find_session_by_name(name); if (new_session != NULL) { @@ -176,15 +202,7 @@ int create_session(char *name, char *path) /* 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'; - } - - if (asprintf(&new_session->path, "%s/%s%s", path, name, date_time) < 0) { + if (asprintf(&new_session->path, "%s", path) < 0) { ret = -ENOMEM; goto error_asprintf; } @@ -194,15 +212,8 @@ int create_session(char *name, char *path) goto error; } - /* - * Set consumer (identifier) to 0. This means that there is - * NO consumer attach to that session yet. - */ - new_session->ust_consumer = 0; - /* Init kernel session */ new_session->kernel_session = NULL; - new_session->kern_session_count = 0; /* Init list */ CDS_INIT_LIST_HEAD(&new_session->ust_traces); @@ -210,10 +221,15 @@ int create_session(char *name, char *path) /* 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 */ + lock_session_list(); add_session_list(new_session); + unlock_session_list(); + + /* Init lock */ + pthread_mutex_init(&new_session->lock, NULL); - DBG("Tracing session %s created in %s", name, new_session->path); + DBG("Tracing session %s created in %s", new_session->name, new_session->path); return 0; @@ -227,32 +243,3 @@ error_exist: error_malloc: return ret; } - -/* - * get_lttng_session - * - * Iterate over the global session list and fill the lttng_session array. - */ -void get_lttng_session(struct lttng_session *sessions) -{ - int i = 0; - struct ltt_session *iter; - struct lttng_session lsess; - - DBG("Getting all available session"); - - /* 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) { - 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)); - i++; - /* Reset struct for next pass */ - memset(&lsess, 0, sizeof(lsess)); - } -} -