X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng-sessiond%2Fsession.c;fp=lttng-sessiond%2Fsession.c;h=c7ce843d71669f3b40609293341dbf8f665a73a1;hp=0000000000000000000000000000000000000000;hb=322585731ced1adba36cddcb8bdd5d997d1b2e3e;hpb=1316184615e422526ef4fae68f980443414969c1 diff --git a/lttng-sessiond/session.c b/lttng-sessiond/session.c new file mode 100644 index 000000000..c7ce843d7 --- /dev/null +++ b/lttng-sessiond/session.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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; 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 + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include +#include + +#include "hashtable.h" +#include "session.h" + +#include "../hashtable/hash.h" + +/* + * 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 session_lock() and session_unlock(). + */ + +/* + * 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, +}; + +/* + * 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. + * + * 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 *session_get_list(void) +{ + return <t_session_list; +} + +/* + * Acquire session list lock + */ +void session_lock_list(void) +{ + pthread_mutex_lock(<t_session_list.lock); +} + +/* + * Release session list lock + */ +void session_unlock_list(void) +{ + pthread_mutex_unlock(<t_session_list.lock); +} + +/* + * Acquire session lock + */ +void session_lock(struct ltt_session *session) +{ + pthread_mutex_lock(&session->lock); +} + +/* + * Release session lock + */ +void session_unlock(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. This must be called with the session lock held using + * session_lock_list and session_unlock_list. + */ +struct ltt_session *session_find_by_name(char *name) +{ + struct ltt_session *iter; + + DBG2("Trying to find session by name %s", name); + + cds_list_for_each_entry(iter, <t_session_list.head, list) { + if (strncmp(iter->name, name, NAME_MAX) == 0) { + goto found; + } + } + + iter = NULL; + +found: + return iter; +} + +/* + * Delete session from the session list and free the memory. + * + * Return -1 if no session is found. On success, return 1; + */ +int session_destroy(struct ltt_session *session) +{ + /* Safety check */ + if (session == NULL) { + ERR("Session pointer was null on session destroy"); + return LTTCOMM_OK; + } + + DBG("Destroying session %s", session->name); + del_session_list(session); + pthread_mutex_destroy(&session->lock); + free(session); + + return LTTCOMM_OK; +} + +/* + * Create a brand new session and add it to the session list. + */ +int session_create(char *name, char *path) +{ + int ret; + struct ltt_session *new_session; + + new_session = session_find_by_name(name); + if (new_session != NULL) { + ret = LTTCOMM_EXIST_SESS; + goto error_exist; + } + + /* Allocate session data structure */ + new_session = malloc(sizeof(struct ltt_session)); + if (new_session == NULL) { + perror("malloc"); + ret = LTTCOMM_FATAL; + goto error_malloc; + } + + /* Define session name */ + if (name != NULL) { + if (snprintf(new_session->name, NAME_MAX, "%s", name) < 0) { + ret = LTTCOMM_FATAL; + goto error_asprintf; + } + } else { + ERR("No session name given"); + ret = LTTCOMM_FATAL; + goto error; + } + + /* Define session system path */ + if (path != NULL) { + if (snprintf(new_session->path, PATH_MAX, "%s", path) < 0) { + ret = LTTCOMM_FATAL; + goto error_asprintf; + } + } else { + ERR("No session path given"); + ret = LTTCOMM_FATAL; + goto error; + } + + /* Init kernel session */ + new_session->kernel_session = NULL; + new_session->ust_session = NULL; + + /* Init lock */ + pthread_mutex_init(&new_session->lock, NULL); + + /* Add new session to the session list */ + session_lock_list(); + add_session_list(new_session); + session_unlock_list(); + + DBG("Tracing session %s created in %s", name, path); + + return LTTCOMM_OK; + +error: +error_asprintf: + if (new_session != NULL) { + free(new_session); + } + +error_exist: +error_malloc: + return ret; +}