a9aa1abceb8cf3779ec7e02ab4f96eb9dc7613f3
[lttng-tools.git] / ltt-sessiond / trace-ust.c
1 /*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; only version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18 #define _GNU_SOURCE
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23
24 #include <lttngerr.h>
25 #include <lttng-share.h>
26
27 #include "trace-ust.h"
28
29 /*
30 * Return an UST session by traceable app PID.
31 */
32 struct ltt_ust_session *trace_ust_get_session_by_pid(pid_t pid,
33 struct ltt_ust_session_list *session_list)
34 {
35 struct ltt_ust_session *lus;
36
37 cds_list_for_each_entry(lus, &session_list->head, list) {
38 if (lus->app->pid == pid) {
39 DBG("Found UST session by pid %d", pid);
40 return lus;
41 }
42 }
43
44 return NULL;
45 }
46
47 /*
48 * Find the channel name for the given ust session.
49 */
50 struct ltt_ust_channel *trace_ust_get_channel_by_name(
51 char *name, struct ltt_ust_session *session)
52 {
53 struct ltt_ust_channel *chan;
54
55 if (session == NULL) {
56 ERR("Undefine session");
57 goto error;
58 }
59
60 cds_list_for_each_entry(chan, &session->channels.head, list) {
61 if (strcmp(name, chan->name) == 0) {
62 DBG("Found UST channel by name %s", name);
63 return chan;
64 }
65 }
66
67 error:
68 return NULL;
69 }
70
71 /*
72 * Find the event name for the given channel.
73 */
74 struct ltt_ust_event *trace_ust_get_event_by_name(
75 char *name, struct ltt_ust_channel *channel)
76 {
77 struct ltt_ust_event *ev;
78
79 if (channel == NULL) {
80 ERR("Undefine channel");
81 goto error;
82 }
83
84 cds_list_for_each_entry(ev, &channel->events.head, list) {
85 if (strcmp(name, ev->event->name) == 0) {
86 DBG("Found UST event by name %s for channel %s", name,
87 channel->name);
88 return ev;
89 }
90 }
91
92 error:
93 return NULL;
94 }
95
96 /*
97 * Allocate and initialize a ust session data structure.
98 *
99 * Return pointer to structure or NULL.
100 */
101 struct ltt_ust_session *trace_ust_create_session(char *path, pid_t pid)
102 {
103 int ret;
104 struct ltt_ust_session *lus;
105
106 /* Allocate a new ltt ust session */
107 lus = malloc(sizeof(struct ltt_ust_session));
108 if (lus == NULL) {
109 perror("create ust session malloc");
110 goto error;
111 }
112
113 /* Init data structure */
114 lus->handle = -1;
115 lus->enabled = 1;
116 lus->uconsumer_fds_sent = 0;
117 lus->path = NULL;
118 lus->metadata = NULL;
119 lus->app = NULL; /* TODO: Search app by PID */
120 lus->channels.count = 0;
121 CDS_INIT_LIST_HEAD(&lus->channels.head);
122
123 /* Set session path */
124 ret = asprintf(&lus->path, "%s/ust_%d", path, pid);
125 if (ret < 0) {
126 perror("asprintf kernel traces path");
127 goto error;
128 }
129
130 return lus;
131
132 error:
133 return NULL;
134 }
135
136 /*
137 * Allocate and initialize a ust channel data structure.
138 *
139 * Return pointer to structure or NULL.
140 */
141 struct ltt_ust_channel *trace_ust_create_channel(char *name, char *path,
142 struct lttng_ust_channel *chan)
143 {
144 int ret;
145 struct ltt_ust_channel *luc;
146
147 luc = malloc(sizeof(struct ltt_ust_channel));
148 if (luc == NULL) {
149 perror("ltt_ust_channel malloc");
150 goto error;
151 }
152
153 luc->attr = malloc(sizeof(struct lttng_ust_channel));
154 if (luc->attr == NULL) {
155 perror("lttng_ust_channel malloc");
156 goto error;
157 }
158 memcpy(luc->attr, chan, sizeof(struct lttng_ust_channel));
159
160 luc->handle = -1;
161 luc->enabled = 1;
162 luc->ctx = NULL;
163 luc->events.count = 0;
164 CDS_INIT_LIST_HEAD(&luc->events.head);
165
166 /* Copy channel name */
167 strncpy(luc->name, name, LTTNG_UST_SYM_NAME_LEN);
168 luc->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
169
170 /* Set trace output path */
171 ret = asprintf(&luc->trace_path, "%s", path);
172 if (ret < 0) {
173 perror("asprintf ust create channel");
174 goto error;
175 }
176
177 return luc;
178
179 error:
180 return NULL;
181 }
182
183 /*
184 * Allocate and initialize a ust event. Set name and event type.
185 *
186 * Return pointer to structure or NULL.
187 */
188 struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev)
189 {
190 struct ltt_ust_event *lue;
191 struct lttng_ust_event *event;
192
193 lue = malloc(sizeof(struct ltt_ust_event));
194 event = malloc(sizeof(struct lttng_ust_event));
195 if (lue == NULL || event == NULL) {
196 perror("ust event malloc");
197 goto error;
198 }
199
200 switch (ev->type) {
201 case LTTNG_EVENT_PROBE:
202 event->instrumentation = LTTNG_UST_PROBE;
203 break;
204 case LTTNG_EVENT_FUNCTION:
205 event->instrumentation = LTTNG_UST_FUNCTION;
206 break;
207 case LTTNG_EVENT_FUNCTION_ENTRY:
208 event->instrumentation = LTTNG_UST_FUNCTION;
209 break;
210 case LTTNG_EVENT_TRACEPOINT:
211 event->instrumentation = LTTNG_UST_TRACEPOINT;
212 break;
213 default:
214 ERR("Unknown ust instrumentation type (%d)", ev->type);
215 goto error;
216 }
217
218 /* Copy event name */
219 strncpy(event->name, ev->name, LTTNG_UST_SYM_NAME_LEN);
220 event->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
221
222 /* Setting up a ust event */
223 lue->handle = -1;
224 lue->event = event;
225 lue->enabled = 1;
226 lue->ctx = NULL;
227
228 return lue;
229
230 error:
231 return NULL;
232 }
233
234 /*
235 * Allocate and initialize a ust metadata.
236 *
237 * Return pointer to structure or NULL.
238 */
239 struct ltt_ust_metadata *trace_ust_create_metadata(char *path)
240 {
241 int ret;
242 struct ltt_ust_metadata *lum;
243 struct lttng_ust_channel *attr;
244
245 lum = malloc(sizeof(struct ltt_ust_metadata));
246 attr = malloc(sizeof(struct lttng_ust_channel));
247 if (lum == NULL || attr == NULL) {
248 perror("ust metadata malloc");
249 goto error;
250 }
251
252 /* Set default attributes */
253 attr->overwrite = DEFAULT_CHANNEL_OVERWRITE;
254 attr->subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE;
255 attr->num_subbuf = DEFAULT_METADATA_SUBBUF_NUM;
256 attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER;
257 attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER;
258 attr->output = DEFAULT_UST_CHANNEL_OUTPUT;
259
260 lum->attr = attr;
261 lum->handle = -1;
262 /* Set metadata trace path */
263 ret = asprintf(&lum->trace_path, "%s/metadata", path);
264 if (ret < 0) {
265 perror("asprintf ust metadata");
266 goto error;
267 }
268
269 return lum;
270
271 error:
272 return NULL;
273 }
274
275 /*
276 * Cleanup ust event structure.
277 */
278 void trace_ust_destroy_event(struct ltt_ust_event *event)
279 {
280 DBG("[trace] Destroy ust event %s", event->event->name);
281
282 /* Free attributes */
283 free(event->event);
284 free(event->ctx);
285
286 /* Remove from event list */
287 cds_list_del(&event->list);
288 free(event);
289 }
290
291 /*
292 * Cleanup ust channel structure.
293 */
294 void trace_ust_destroy_channel(struct ltt_ust_channel *channel)
295 {
296 struct ltt_ust_event *event, *etmp;
297
298 DBG("[trace] Destroy ust channel %d", channel->handle);
299
300 free(channel->trace_path);
301 /* Free attributes structure */
302 free(channel->attr);
303 free(channel->ctx);
304
305 /* For each event in the channel list */
306 cds_list_for_each_entry_safe(event, etmp, &channel->events.head, list) {
307 trace_ust_destroy_event(event);
308 }
309
310 /* Remove from channel list */
311 cds_list_del(&channel->list);
312 free(channel);
313 }
314
315 /*
316 * Cleanup ust metadata structure.
317 */
318 void trace_ust_destroy_metadata(struct ltt_ust_metadata *metadata)
319 {
320 DBG("[trace] Destroy ust metadata %d", metadata->handle);
321
322 /* Free attributes */
323 free(metadata->attr);
324 free(metadata->trace_path);
325
326 free(metadata);
327 }
328
329 /*
330 * Cleanup ust session structure
331 */
332 void trace_ust_destroy_session(struct ltt_ust_session *session)
333 {
334 struct ltt_ust_channel *channel, *ctmp;
335
336 DBG("[trace] Destroy ust session %d", session->handle);
337
338 /* Extra safety */
339 if (session == NULL) {
340 return;
341 }
342
343 if (session->metadata != NULL) {
344 trace_ust_destroy_metadata(session->metadata);
345 }
346
347 cds_list_for_each_entry_safe(channel, ctmp, &session->channels.head, list) {
348 trace_ust_destroy_channel(channel);
349 }
350
351 free(session->path);
352 free(session);
353 }
This page took 0.038764 seconds and 4 git commands to generate.