Commit | Line | Data |
---|---|---|
5b74c7b1 DG |
1 | /* |
2 | * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca> | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License | |
82a3637f DG |
6 | * as published by the Free Software Foundation; only version 2 |
7 | * of the License. | |
91d76f53 | 8 | * |
5b74c7b1 DG |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
050349bb | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5b74c7b1 DG |
12 | * GNU General Public License for more details. |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program; if not, write to the Free Software | |
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 | */ | |
18 | ||
19 | #define _GNU_SOURCE | |
6c9cc2ab | 20 | #include <limits.h> |
5b74c7b1 DG |
21 | #include <stdio.h> |
22 | #include <stdlib.h> | |
23 | #include <string.h> | |
5b74c7b1 | 24 | |
1e307fab DG |
25 | #include <lttngerr.h> |
26 | ||
5b74c7b1 DG |
27 | #include "session.h" |
28 | ||
8c0faa1d | 29 | /* |
b5541356 | 30 | * NOTES: |
8c0faa1d | 31 | * |
b5541356 DG |
32 | * No ltt_session.lock is taken here because those data structure are widely |
33 | * spread across the lttng-tools code base so before caling functions below | |
34 | * that can read/write a session, the caller MUST acquire the session lock | |
35 | * using lock_session() and unlock_session(). | |
8c0faa1d | 36 | */ |
8c0faa1d | 37 | |
5b74c7b1 | 38 | /* |
b5541356 | 39 | * Init tracing session list. |
5b74c7b1 | 40 | * |
b5541356 | 41 | * Please see session.h for more explanation and correct usage of the list. |
5b74c7b1 | 42 | */ |
b5541356 DG |
43 | static struct ltt_session_list ltt_session_list = { |
44 | .head = CDS_LIST_HEAD_INIT(ltt_session_list.head), | |
45 | .lock = PTHREAD_MUTEX_INITIALIZER, | |
46 | .count = 0, | |
47 | }; | |
5b74c7b1 DG |
48 | |
49 | /* | |
050349bb | 50 | * Add a ltt_session structure to the global list. |
5b74c7b1 | 51 | * |
050349bb | 52 | * The caller MUST acquire the session list lock before. |
5b74c7b1 DG |
53 | */ |
54 | static void add_session_list(struct ltt_session *ls) | |
55 | { | |
56 | cds_list_add(&ls->list, <t_session_list.head); | |
b5541356 | 57 | ltt_session_list.count++; |
5b74c7b1 DG |
58 | } |
59 | ||
60 | /* | |
050349bb | 61 | * Delete a ltt_session structure to the global list. |
b5541356 | 62 | * |
050349bb | 63 | * The caller MUST acquire the session list lock before. |
5b74c7b1 DG |
64 | */ |
65 | static void del_session_list(struct ltt_session *ls) | |
66 | { | |
67 | cds_list_del(&ls->list); | |
68 | /* Sanity check */ | |
b5541356 DG |
69 | if (ltt_session_list.count > 0) { |
70 | ltt_session_list.count--; | |
5b74c7b1 DG |
71 | } |
72 | } | |
73 | ||
b5541356 | 74 | /* |
050349bb | 75 | * Return a pointer to the session list. |
b5541356 DG |
76 | */ |
77 | struct ltt_session_list *get_session_list(void) | |
78 | { | |
79 | return <t_session_list; | |
80 | } | |
81 | ||
82 | /* | |
6c9cc2ab | 83 | * Acquire session list lock |
b5541356 | 84 | */ |
6c9cc2ab | 85 | void lock_session_list(void) |
b5541356 | 86 | { |
6c9cc2ab | 87 | pthread_mutex_lock(<t_session_list.lock); |
b5541356 DG |
88 | } |
89 | ||
90 | /* | |
6c9cc2ab | 91 | * Release session list lock |
b5541356 | 92 | */ |
6c9cc2ab | 93 | void unlock_session_list(void) |
b5541356 | 94 | { |
6c9cc2ab | 95 | pthread_mutex_unlock(<t_session_list.lock); |
b5541356 DG |
96 | } |
97 | ||
98 | /* | |
6c9cc2ab | 99 | * Acquire session lock |
b5541356 | 100 | */ |
6c9cc2ab | 101 | void lock_session(struct ltt_session *session) |
b5541356 | 102 | { |
6c9cc2ab DG |
103 | pthread_mutex_lock(&session->lock); |
104 | } | |
b5541356 | 105 | |
6c9cc2ab DG |
106 | /* |
107 | * Release session lock | |
108 | */ | |
109 | void unlock_session(struct ltt_session *session) | |
110 | { | |
111 | pthread_mutex_unlock(&session->lock); | |
b5541356 DG |
112 | } |
113 | ||
5b74c7b1 | 114 | /* |
050349bb DG |
115 | * Return a ltt_session structure ptr that matches name. |
116 | * If no session found, NULL is returned. | |
5b74c7b1 DG |
117 | */ |
118 | struct ltt_session *find_session_by_name(char *name) | |
119 | { | |
120 | int found = 0; | |
121 | struct ltt_session *iter; | |
122 | ||
6c9cc2ab | 123 | lock_session_list(); |
5b74c7b1 | 124 | cds_list_for_each_entry(iter, <t_session_list.head, list) { |
1b110e1b | 125 | if (strncmp(iter->name, name, NAME_MAX) == 0) { |
5b74c7b1 DG |
126 | found = 1; |
127 | break; | |
128 | } | |
129 | } | |
6c9cc2ab | 130 | unlock_session_list(); |
5b74c7b1 DG |
131 | |
132 | if (!found) { | |
133 | iter = NULL; | |
134 | } | |
135 | ||
136 | return iter; | |
137 | } | |
138 | ||
139 | /* | |
050349bb | 140 | * Delete session from the session list and free the memory. |
5b74c7b1 | 141 | * |
050349bb | 142 | * Return -1 if no session is found. On success, return 1; |
5b74c7b1 | 143 | */ |
f3ed775e | 144 | int destroy_session(char *name) |
5b74c7b1 DG |
145 | { |
146 | int found = -1; | |
af9737e9 | 147 | struct ltt_session *iter, *tmp; |
5b74c7b1 | 148 | |
6c9cc2ab | 149 | lock_session_list(); |
af9737e9 | 150 | cds_list_for_each_entry_safe(iter, tmp, <t_session_list.head, list) { |
f3ed775e | 151 | if (strcmp(iter->name, name) == 0) { |
e07ae692 | 152 | DBG("Destroying session %s", iter->name); |
5b74c7b1 | 153 | del_session_list(iter); |
b5541356 DG |
154 | free(iter->name); |
155 | free(iter->path); | |
156 | pthread_mutex_destroy(&iter->lock); | |
5b74c7b1 DG |
157 | free(iter); |
158 | found = 1; | |
159 | break; | |
160 | } | |
161 | } | |
6c9cc2ab | 162 | unlock_session_list(); |
5b74c7b1 DG |
163 | |
164 | return found; | |
165 | } | |
166 | ||
167 | /* | |
050349bb | 168 | * Create a brand new session and add it to the session list. |
5b74c7b1 | 169 | */ |
f3ed775e | 170 | int create_session(char *name, char *path) |
5b74c7b1 | 171 | { |
f3ed775e | 172 | int ret; |
5b74c7b1 | 173 | struct ltt_session *new_session; |
e07ae692 | 174 | |
5b74c7b1 DG |
175 | new_session = find_session_by_name(name); |
176 | if (new_session != NULL) { | |
f3ed775e DG |
177 | ret = -EEXIST; |
178 | goto error_exist; | |
5b74c7b1 DG |
179 | } |
180 | ||
181 | /* Allocate session data structure */ | |
182 | new_session = malloc(sizeof(struct ltt_session)); | |
183 | if (new_session == NULL) { | |
184 | perror("malloc"); | |
f3ed775e DG |
185 | ret = -ENOMEM; |
186 | goto error_malloc; | |
5b74c7b1 DG |
187 | } |
188 | ||
f3ed775e | 189 | /* Define session name */ |
5b74c7b1 DG |
190 | if (name != NULL) { |
191 | if (asprintf(&new_session->name, "%s", name) < 0) { | |
f3ed775e DG |
192 | ret = -ENOMEM; |
193 | goto error_asprintf; | |
5b74c7b1 DG |
194 | } |
195 | } else { | |
f3ed775e DG |
196 | ERR("No session name given"); |
197 | ret = -1; | |
198 | goto error; | |
199 | } | |
200 | ||
201 | /* Define session system path */ | |
202 | if (path != NULL) { | |
d6175221 | 203 | if (asprintf(&new_session->path, "%s", path) < 0) { |
f3ed775e DG |
204 | ret = -ENOMEM; |
205 | goto error_asprintf; | |
5b74c7b1 | 206 | } |
f3ed775e DG |
207 | } else { |
208 | ERR("No session path given"); | |
209 | ret = -1; | |
210 | goto error; | |
5b74c7b1 DG |
211 | } |
212 | ||
1d4b027a DG |
213 | /* Init kernel session */ |
214 | new_session->kernel_session = NULL; | |
5b74c7b1 DG |
215 | |
216 | /* Init list */ | |
217 | CDS_INIT_LIST_HEAD(&new_session->ust_traces); | |
1657e9bb DG |
218 | |
219 | /* Set trace list counter */ | |
220 | new_session->ust_trace_count = 0; | |
5b74c7b1 | 221 | |
b5541356 | 222 | /* Add new session to the session list */ |
6c9cc2ab | 223 | lock_session_list(); |
5b74c7b1 | 224 | add_session_list(new_session); |
6c9cc2ab | 225 | unlock_session_list(); |
b5541356 DG |
226 | |
227 | /* Init lock */ | |
228 | pthread_mutex_init(&new_session->lock, NULL); | |
5b74c7b1 | 229 | |
b5541356 | 230 | DBG("Tracing session %s created in %s", new_session->name, new_session->path); |
b082db07 | 231 | |
5b74c7b1 DG |
232 | return 0; |
233 | ||
234 | error: | |
f3ed775e DG |
235 | error_asprintf: |
236 | if (new_session != NULL) { | |
237 | free(new_session); | |
238 | } | |
5b74c7b1 | 239 | |
f3ed775e DG |
240 | error_exist: |
241 | error_malloc: | |
242 | return ret; | |
5b74c7b1 | 243 | } |