2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
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.
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.
25 #include <urcu/list.h>
33 * No ltt_session.lock is taken here because those data structure are widely
34 * spread across the lttng-tools code base so before caling functions below
35 * that can read/write a session, the caller MUST acquire the session lock
36 * using lock_session() and unlock_session().
40 * Init tracing session list.
42 * Please see session.h for more explanation and correct usage of the list.
44 static struct ltt_session_list ltt_session_list
= {
45 .head
= CDS_LIST_HEAD_INIT(ltt_session_list
.head
),
46 .lock
= PTHREAD_MUTEX_INITIALIZER
,
53 * Add a ltt_session structure to the global list.
55 * The caller MUST acquire the session list lock before.
57 static void add_session_list(struct ltt_session
*ls
)
59 cds_list_add(&ls
->list
, <t_session_list
.head
);
60 ltt_session_list
.count
++;
66 * Delete a ltt_session structure to the global list.
68 * The caller MUST acquire the session list lock before.
70 static void del_session_list(struct ltt_session
*ls
)
72 cds_list_del(&ls
->list
);
74 if (ltt_session_list
.count
> 0) {
75 ltt_session_list
.count
--;
82 * Return a pointer to the session list.
84 struct ltt_session_list
*get_session_list(void)
86 return <t_session_list
;
90 * Acquire session lock
92 void lock_session(struct ltt_session
*session
)
94 pthread_mutex_lock(&session
->lock
);
98 * Release session lock
100 void unlock_session(struct ltt_session
*session
)
102 pthread_mutex_unlock(&session
->lock
);
108 * Return session_count
110 unsigned int get_session_count(void)
114 pthread_mutex_lock(<t_session_list
.lock
);
115 count
= ltt_session_list
.count
;
116 pthread_mutex_unlock(<t_session_list
.lock
);
122 * find_session_by_name
124 * Return a ltt_session structure ptr that matches name.
125 * If no session found, NULL is returned.
127 struct ltt_session
*find_session_by_name(char *name
)
130 struct ltt_session
*iter
;
132 pthread_mutex_lock(<t_session_list
.lock
);
133 cds_list_for_each_entry(iter
, <t_session_list
.head
, list
) {
134 if (strncmp(iter
->name
, name
, strlen(name
)) == 0) {
139 pthread_mutex_unlock(<t_session_list
.lock
);
151 * Delete session from the session list and free the memory.
153 * Return -1 if no session is found. On success, return 1;
155 int destroy_session(char *name
)
158 struct ltt_session
*iter
;
160 pthread_mutex_lock(<t_session_list
.lock
);
161 cds_list_for_each_entry(iter
, <t_session_list
.head
, list
) {
162 if (strcmp(iter
->name
, name
) == 0) {
163 DBG("Destroying session %s", iter
->name
);
164 del_session_list(iter
);
167 pthread_mutex_destroy(&iter
->lock
);
173 pthread_mutex_unlock(<t_session_list
.lock
);
181 * Create a brand new session and add it to the session list.
183 int create_session(char *name
, char *path
)
186 char date_time
[NAME_MAX
];
187 struct ltt_session
*new_session
;
191 new_session
= find_session_by_name(name
);
192 if (new_session
!= NULL
) {
197 /* Allocate session data structure */
198 new_session
= malloc(sizeof(struct ltt_session
));
199 if (new_session
== NULL
) {
205 /* Define session name */
207 if (asprintf(&new_session
->name
, "%s", name
) < 0) {
212 ERR("No session name given");
217 /* Define session system path */
219 if (strstr(name
, "auto-") == NULL
) {
221 timeinfo
= localtime(&rawtime
);
222 strftime(date_time
, sizeof(date_time
), "-%Y%m%d-%H%M%S", timeinfo
);
227 if (asprintf(&new_session
->path
, "%s/%s%s", path
, name
, date_time
) < 0) {
232 ERR("No session path given");
237 /* Init kernel session */
238 new_session
->kernel_session
= NULL
;
241 CDS_INIT_LIST_HEAD(&new_session
->ust_traces
);
243 /* Set trace list counter */
244 new_session
->ust_trace_count
= 0;
246 /* Add new session to the session list */
247 pthread_mutex_lock(<t_session_list
.lock
);
248 add_session_list(new_session
);
249 pthread_mutex_unlock(<t_session_list
.lock
);
252 pthread_mutex_init(&new_session
->lock
, NULL
);
254 DBG("Tracing session %s created in %s", new_session
->name
, new_session
->path
);
260 if (new_session
!= NULL
) {
272 * Iterate over the global session list and fill the lttng_session array.
274 void get_lttng_session(struct lttng_session
*sessions
)
277 struct ltt_session
*iter
;
278 struct lttng_session lsess
;
280 DBG("Getting all available session");
283 * Iterate over session list and append data after the control struct in
286 pthread_mutex_lock(<t_session_list
.lock
);
287 cds_list_for_each_entry(iter
, <t_session_list
.head
, list
) {
288 strncpy(lsess
.path
, iter
->path
, sizeof(lsess
.path
));
289 lsess
.path
[sizeof(lsess
.path
) - 1] = '\0';
290 strncpy(lsess
.name
, iter
->name
, sizeof(lsess
.name
));
291 lsess
.name
[sizeof(lsess
.name
) - 1] = '\0';
292 memcpy(&sessions
[i
], &lsess
, sizeof(lsess
));
294 /* Reset struct for next pass */
295 memset(&lsess
, 0, sizeof(lsess
));
297 pthread_mutex_unlock(<t_session_list
.lock
);