fix: lttng_ht_destroy memleak
[lttng-tools.git] / src / bin / lttng-sessiond / session.c
CommitLineData
5b74c7b1
DG
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
d14d33bf
AM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
91d76f53 7 *
5b74c7b1
DG
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
d14d33bf 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5b74c7b1
DG
11 * GNU General Public License for more details.
12 *
d14d33bf
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
5b74c7b1
DG
16 */
17
18#define _GNU_SOURCE
6c9cc2ab 19#include <limits.h>
5b74c7b1
DG
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
a304c14c
MD
23#include <sys/stat.h>
24#include <sys/types.h>
f6a9efaa 25#include <urcu.h>
5b74c7b1 26
990570ed 27#include <common/common.h>
db758600 28#include <common/sessiond-comm/sessiond-comm.h>
1e307fab 29
5b74c7b1
DG
30#include "session.h"
31
8c0faa1d 32/*
b5541356 33 * NOTES:
8c0faa1d 34 *
b5541356
DG
35 * No ltt_session.lock is taken here because those data structure are widely
36 * spread across the lttng-tools code base so before caling functions below
37 * that can read/write a session, the caller MUST acquire the session lock
54d01ffb 38 * using session_lock() and session_unlock().
8c0faa1d 39 */
8c0faa1d 40
5b74c7b1 41/*
b5541356 42 * Init tracing session list.
5b74c7b1 43 *
b5541356 44 * Please see session.h for more explanation and correct usage of the list.
5b74c7b1 45 */
b5541356
DG
46static struct ltt_session_list ltt_session_list = {
47 .head = CDS_LIST_HEAD_INIT(ltt_session_list.head),
48 .lock = PTHREAD_MUTEX_INITIALIZER,
49 .count = 0,
50};
5b74c7b1
DG
51
52/*
050349bb 53 * Add a ltt_session structure to the global list.
5b74c7b1 54 *
050349bb 55 * The caller MUST acquire the session list lock before.
44e96653 56 * Returns the unique identifier for the session.
5b74c7b1 57 */
44e96653 58static int add_session_list(struct ltt_session *ls)
5b74c7b1
DG
59{
60 cds_list_add(&ls->list, &ltt_session_list.head);
44e96653 61 return ++ltt_session_list.count;
5b74c7b1
DG
62}
63
64/*
050349bb 65 * Delete a ltt_session structure to the global list.
b5541356 66 *
050349bb 67 * The caller MUST acquire the session list lock before.
5b74c7b1
DG
68 */
69static void del_session_list(struct ltt_session *ls)
70{
71 cds_list_del(&ls->list);
72 /* Sanity check */
b5541356
DG
73 if (ltt_session_list.count > 0) {
74 ltt_session_list.count--;
5b74c7b1
DG
75 }
76}
77
b5541356 78/*
050349bb 79 * Return a pointer to the session list.
b5541356 80 */
54d01ffb 81struct ltt_session_list *session_get_list(void)
b5541356
DG
82{
83 return &ltt_session_list;
84}
85
86/*
6c9cc2ab 87 * Acquire session list lock
b5541356 88 */
54d01ffb 89void session_lock_list(void)
b5541356 90{
6c9cc2ab 91 pthread_mutex_lock(&ltt_session_list.lock);
b5541356
DG
92}
93
94/*
6c9cc2ab 95 * Release session list lock
b5541356 96 */
54d01ffb 97void session_unlock_list(void)
b5541356 98{
6c9cc2ab 99 pthread_mutex_unlock(&ltt_session_list.lock);
b5541356
DG
100}
101
102/*
6c9cc2ab 103 * Acquire session lock
b5541356 104 */
54d01ffb 105void session_lock(struct ltt_session *session)
b5541356 106{
6c9cc2ab
DG
107 pthread_mutex_lock(&session->lock);
108}
b5541356 109
6c9cc2ab
DG
110/*
111 * Release session lock
112 */
54d01ffb 113void session_unlock(struct ltt_session *session)
6c9cc2ab
DG
114{
115 pthread_mutex_unlock(&session->lock);
b5541356
DG
116}
117
5b74c7b1 118/*
74babd95
DG
119 * Return a ltt_session structure ptr that matches name. If no session found,
120 * NULL is returned. This must be called with the session lock held using
121 * session_lock_list and session_unlock_list.
5b74c7b1 122 */
54d01ffb 123struct ltt_session *session_find_by_name(char *name)
5b74c7b1 124{
5b74c7b1
DG
125 struct ltt_session *iter;
126
5f822d0a
DG
127 DBG2("Trying to find session by name %s", name);
128
5b74c7b1 129 cds_list_for_each_entry(iter, &ltt_session_list.head, list) {
1b110e1b 130 if (strncmp(iter->name, name, NAME_MAX) == 0) {
74babd95 131 goto found;
5b74c7b1
DG
132 }
133 }
134
74babd95 135 iter = NULL;
5b74c7b1 136
74babd95 137found:
5b74c7b1
DG
138 return iter;
139}
140
141/*
050349bb 142 * Delete session from the session list and free the memory.
5b74c7b1 143 *
050349bb 144 * Return -1 if no session is found. On success, return 1;
5b74c7b1 145 */
271933a4 146int session_destroy(struct ltt_session *session)
5b74c7b1 147{
271933a4
DG
148 /* Safety check */
149 if (session == NULL) {
150 ERR("Session pointer was null on session destroy");
151 return LTTCOMM_OK;
5b74c7b1 152 }
271933a4
DG
153
154 DBG("Destroying session %s", session->name);
155 del_session_list(session);
271933a4
DG
156 pthread_mutex_destroy(&session->lock);
157 free(session);
5b74c7b1 158
54d01ffb 159 return LTTCOMM_OK;
5b74c7b1
DG
160}
161
162/*
050349bb 163 * Create a brand new session and add it to the session list.
5b74c7b1 164 */
6df2e2c9 165int session_create(char *name, char *path, uid_t uid, gid_t gid)
5b74c7b1 166{
f3ed775e 167 int ret;
5b74c7b1 168 struct ltt_session *new_session;
e07ae692 169
54d01ffb 170 new_session = session_find_by_name(name);
5b74c7b1 171 if (new_session != NULL) {
54d01ffb 172 ret = LTTCOMM_EXIST_SESS;
f3ed775e 173 goto error_exist;
5b74c7b1
DG
174 }
175
176 /* Allocate session data structure */
ba7f0ae5 177 new_session = zmalloc(sizeof(struct ltt_session));
5b74c7b1 178 if (new_session == NULL) {
df0f840b 179 PERROR("zmalloc");
54d01ffb 180 ret = LTTCOMM_FATAL;
f3ed775e 181 goto error_malloc;
5b74c7b1
DG
182 }
183
f3ed775e 184 /* Define session name */
5b74c7b1 185 if (name != NULL) {
74babd95 186 if (snprintf(new_session->name, NAME_MAX, "%s", name) < 0) {
54d01ffb 187 ret = LTTCOMM_FATAL;
f3ed775e 188 goto error_asprintf;
5b74c7b1
DG
189 }
190 } else {
f3ed775e 191 ERR("No session name given");
54d01ffb 192 ret = LTTCOMM_FATAL;
f3ed775e
DG
193 goto error;
194 }
195
196 /* Define session system path */
197 if (path != NULL) {
74babd95 198 if (snprintf(new_session->path, PATH_MAX, "%s", path) < 0) {
54d01ffb 199 ret = LTTCOMM_FATAL;
f3ed775e 200 goto error_asprintf;
5b74c7b1 201 }
f3ed775e
DG
202 } else {
203 ERR("No session path given");
54d01ffb 204 ret = LTTCOMM_FATAL;
f3ed775e 205 goto error;
5b74c7b1
DG
206 }
207
1d4b027a
DG
208 /* Init kernel session */
209 new_session->kernel_session = NULL;
f6a9efaa 210 new_session->ust_session = NULL;
1657e9bb 211
0177d773
DG
212 /* Init lock */
213 pthread_mutex_init(&new_session->lock, NULL);
5b74c7b1 214
6df2e2c9
MD
215 new_session->uid = uid;
216 new_session->gid = gid;
217
e11d277b 218 ret = run_as_mkdir_recursive(new_session->path, S_IRWXU | S_IRWXG,
a304c14c
MD
219 new_session->uid, new_session->gid);
220 if (ret < 0) {
221 if (ret != -EEXIST) {
222 ERR("Trace directory creation error");
ae856491 223 ret = LTTCOMM_CREATE_DIR_FAIL;
a304c14c
MD
224 goto error;
225 }
226 }
227
b5541356 228 /* Add new session to the session list */
54d01ffb 229 session_lock_list();
a991f516 230 new_session->id = add_session_list(new_session);
54d01ffb 231 session_unlock_list();
b5541356 232
6df2e2c9
MD
233 DBG("Tracing session %s created in %s with ID %d by UID %d GID %d",
234 name, path, new_session->id,
235 new_session->uid, new_session->gid);
b082db07 236
54d01ffb 237 return LTTCOMM_OK;
5b74c7b1
DG
238
239error:
f3ed775e
DG
240error_asprintf:
241 if (new_session != NULL) {
242 free(new_session);
243 }
5b74c7b1 244
f3ed775e
DG
245error_exist:
246error_malloc:
247 return ret;
5b74c7b1 248}
This page took 0.042251 seconds and 4 git commands to generate.