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 | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
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> |
b5541356 | 21 | #include <pthread.h> |
5b74c7b1 DG |
22 | #include <stdio.h> |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
b082db07 | 25 | #include <time.h> |
5b74c7b1 | 26 | #include <urcu/list.h> |
5b74c7b1 DG |
27 | |
28 | #include "lttngerr.h" | |
29 | #include "session.h" | |
30 | ||
8c0faa1d | 31 | /* |
b5541356 | 32 | * NOTES: |
8c0faa1d | 33 | * |
b5541356 DG |
34 | * No ltt_session.lock is taken here because those data structure are widely |
35 | * spread across the lttng-tools code base so before caling functions below | |
36 | * that can read/write a session, the caller MUST acquire the session lock | |
37 | * using lock_session() and unlock_session(). | |
8c0faa1d | 38 | */ |
8c0faa1d | 39 | |
5b74c7b1 | 40 | /* |
b5541356 | 41 | * Init tracing session list. |
5b74c7b1 | 42 | * |
b5541356 | 43 | * Please see session.h for more explanation and correct usage of the list. |
5b74c7b1 | 44 | */ |
b5541356 DG |
45 | static struct ltt_session_list ltt_session_list = { |
46 | .head = CDS_LIST_HEAD_INIT(ltt_session_list.head), | |
47 | .lock = PTHREAD_MUTEX_INITIALIZER, | |
48 | .count = 0, | |
49 | }; | |
5b74c7b1 DG |
50 | |
51 | /* | |
52 | * add_session_list | |
53 | * | |
54 | * Add a ltt_session structure to the global list. | |
b5541356 DG |
55 | * |
56 | * The caller MUST acquire the session list lock before. | |
5b74c7b1 DG |
57 | */ |
58 | static void add_session_list(struct ltt_session *ls) | |
59 | { | |
60 | cds_list_add(&ls->list, <t_session_list.head); | |
b5541356 | 61 | ltt_session_list.count++; |
5b74c7b1 DG |
62 | } |
63 | ||
64 | /* | |
65 | * del_session_list | |
66 | * | |
67 | * Delete a ltt_session structure to the global list. | |
b5541356 DG |
68 | * |
69 | * The caller MUST acquire the session list lock before. | |
5b74c7b1 DG |
70 | */ |
71 | static void del_session_list(struct ltt_session *ls) | |
72 | { | |
73 | cds_list_del(&ls->list); | |
74 | /* Sanity check */ | |
b5541356 DG |
75 | if (ltt_session_list.count > 0) { |
76 | ltt_session_list.count--; | |
5b74c7b1 DG |
77 | } |
78 | } | |
79 | ||
b5541356 DG |
80 | /* |
81 | * get_session_list | |
82 | * | |
83 | * Return a pointer to the session list. | |
84 | */ | |
85 | struct ltt_session_list *get_session_list(void) | |
86 | { | |
87 | return <t_session_list; | |
88 | } | |
89 | ||
90 | /* | |
6c9cc2ab | 91 | * Acquire session list lock |
b5541356 | 92 | */ |
6c9cc2ab | 93 | void lock_session_list(void) |
b5541356 | 94 | { |
6c9cc2ab | 95 | pthread_mutex_lock(<t_session_list.lock); |
b5541356 DG |
96 | } |
97 | ||
98 | /* | |
6c9cc2ab | 99 | * Release session list lock |
b5541356 | 100 | */ |
6c9cc2ab | 101 | void unlock_session_list(void) |
b5541356 | 102 | { |
6c9cc2ab | 103 | pthread_mutex_unlock(<t_session_list.lock); |
b5541356 DG |
104 | } |
105 | ||
106 | /* | |
6c9cc2ab | 107 | * Acquire session lock |
b5541356 | 108 | */ |
6c9cc2ab | 109 | void lock_session(struct ltt_session *session) |
b5541356 | 110 | { |
6c9cc2ab DG |
111 | pthread_mutex_lock(&session->lock); |
112 | } | |
b5541356 | 113 | |
6c9cc2ab DG |
114 | /* |
115 | * Release session lock | |
116 | */ | |
117 | void unlock_session(struct ltt_session *session) | |
118 | { | |
119 | pthread_mutex_unlock(&session->lock); | |
b5541356 DG |
120 | } |
121 | ||
5b74c7b1 DG |
122 | /* |
123 | * find_session_by_name | |
124 | * | |
125 | * Return a ltt_session structure ptr that matches name. | |
126 | * If no session found, NULL is returned. | |
127 | */ | |
128 | struct ltt_session *find_session_by_name(char *name) | |
129 | { | |
130 | int found = 0; | |
131 | struct ltt_session *iter; | |
132 | ||
6c9cc2ab | 133 | lock_session_list(); |
5b74c7b1 | 134 | cds_list_for_each_entry(iter, <t_session_list.head, list) { |
1b110e1b | 135 | if (strncmp(iter->name, name, NAME_MAX) == 0) { |
5b74c7b1 DG |
136 | found = 1; |
137 | break; | |
138 | } | |
139 | } | |
6c9cc2ab | 140 | unlock_session_list(); |
5b74c7b1 DG |
141 | |
142 | if (!found) { | |
143 | iter = NULL; | |
144 | } | |
145 | ||
146 | return iter; | |
147 | } | |
148 | ||
149 | /* | |
150 | * destroy_session | |
151 | * | |
b5541356 | 152 | * Delete session from the session list and free the memory. |
5b74c7b1 | 153 | * |
b5541356 | 154 | * Return -1 if no session is found. On success, return 1; |
5b74c7b1 | 155 | */ |
f3ed775e | 156 | int destroy_session(char *name) |
5b74c7b1 DG |
157 | { |
158 | int found = -1; | |
af9737e9 | 159 | struct ltt_session *iter, *tmp; |
5b74c7b1 | 160 | |
6c9cc2ab | 161 | lock_session_list(); |
af9737e9 | 162 | cds_list_for_each_entry_safe(iter, tmp, <t_session_list.head, list) { |
f3ed775e | 163 | if (strcmp(iter->name, name) == 0) { |
e07ae692 | 164 | DBG("Destroying session %s", iter->name); |
5b74c7b1 | 165 | del_session_list(iter); |
b5541356 DG |
166 | free(iter->name); |
167 | free(iter->path); | |
168 | pthread_mutex_destroy(&iter->lock); | |
5b74c7b1 DG |
169 | free(iter); |
170 | found = 1; | |
171 | break; | |
172 | } | |
173 | } | |
6c9cc2ab | 174 | unlock_session_list(); |
5b74c7b1 DG |
175 | |
176 | return found; | |
177 | } | |
178 | ||
179 | /* | |
180 | * create_session | |
181 | * | |
b5541356 | 182 | * Create a brand new session and add it to the session list. |
5b74c7b1 | 183 | */ |
f3ed775e | 184 | int create_session(char *name, char *path) |
5b74c7b1 | 185 | { |
f3ed775e | 186 | int ret; |
5b74c7b1 | 187 | struct ltt_session *new_session; |
e07ae692 | 188 | |
5b74c7b1 DG |
189 | new_session = find_session_by_name(name); |
190 | if (new_session != NULL) { | |
f3ed775e DG |
191 | ret = -EEXIST; |
192 | goto error_exist; | |
5b74c7b1 DG |
193 | } |
194 | ||
195 | /* Allocate session data structure */ | |
196 | new_session = malloc(sizeof(struct ltt_session)); | |
197 | if (new_session == NULL) { | |
198 | perror("malloc"); | |
f3ed775e DG |
199 | ret = -ENOMEM; |
200 | goto error_malloc; | |
5b74c7b1 DG |
201 | } |
202 | ||
f3ed775e | 203 | /* Define session name */ |
5b74c7b1 DG |
204 | if (name != NULL) { |
205 | if (asprintf(&new_session->name, "%s", name) < 0) { | |
f3ed775e DG |
206 | ret = -ENOMEM; |
207 | goto error_asprintf; | |
5b74c7b1 DG |
208 | } |
209 | } else { | |
f3ed775e DG |
210 | ERR("No session name given"); |
211 | ret = -1; | |
212 | goto error; | |
213 | } | |
214 | ||
215 | /* Define session system path */ | |
216 | if (path != NULL) { | |
d6175221 | 217 | if (asprintf(&new_session->path, "%s", path) < 0) { |
f3ed775e DG |
218 | ret = -ENOMEM; |
219 | goto error_asprintf; | |
5b74c7b1 | 220 | } |
f3ed775e DG |
221 | } else { |
222 | ERR("No session path given"); | |
223 | ret = -1; | |
224 | goto error; | |
5b74c7b1 DG |
225 | } |
226 | ||
1d4b027a DG |
227 | /* Init kernel session */ |
228 | new_session->kernel_session = NULL; | |
5b74c7b1 DG |
229 | |
230 | /* Init list */ | |
231 | CDS_INIT_LIST_HEAD(&new_session->ust_traces); | |
1657e9bb DG |
232 | |
233 | /* Set trace list counter */ | |
234 | new_session->ust_trace_count = 0; | |
5b74c7b1 | 235 | |
b5541356 | 236 | /* Add new session to the session list */ |
6c9cc2ab | 237 | lock_session_list(); |
5b74c7b1 | 238 | add_session_list(new_session); |
6c9cc2ab | 239 | unlock_session_list(); |
b5541356 DG |
240 | |
241 | /* Init lock */ | |
242 | pthread_mutex_init(&new_session->lock, NULL); | |
5b74c7b1 | 243 | |
b5541356 | 244 | DBG("Tracing session %s created in %s", new_session->name, new_session->path); |
b082db07 | 245 | |
5b74c7b1 DG |
246 | return 0; |
247 | ||
248 | error: | |
f3ed775e DG |
249 | error_asprintf: |
250 | if (new_session != NULL) { | |
251 | free(new_session); | |
252 | } | |
5b74c7b1 | 253 | |
f3ed775e DG |
254 | error_exist: |
255 | error_malloc: | |
256 | return ret; | |
5b74c7b1 | 257 | } |