Fix possible error on close
[lttng-tools.git] / ltt-sessiond / trace.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
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.
8 *
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
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <urcu/list.h>
25
26 #include "lttngerr.h"
27 #include "ltt-sessiond.h"
28 #include "trace.h"
29
30 /*
31 * trace_create_kernel_session
32 *
33 * Allocate and initialize a kernel session data structure.
34 *
35 * Return pointer to structure or NULL.
36 */
37 struct ltt_kernel_session *trace_create_kernel_session(void)
38 {
39 struct ltt_kernel_session *lks;
40
41 /* Allocate a new ltt kernel session */
42 lks = malloc(sizeof(struct ltt_kernel_session));
43 if (lks == NULL) {
44 perror("create kernel session malloc");
45 goto error;
46 }
47
48 /* Init data structure */
49 lks->fd = 0;
50 lks->metadata_stream_fd = 0;
51 lks->channel_count = 0;
52 lks->stream_count_global = 0;
53 lks->metadata = NULL;
54 CDS_INIT_LIST_HEAD(&lks->channel_list.head);
55
56 return lks;
57
58 error:
59 return NULL;
60 }
61
62 /*
63 * trace_create_kernel_channel
64 *
65 * Allocate and initialize a kernel channel data structure.
66 *
67 * Return pointer to structure or NULL.
68 */
69 struct ltt_kernel_channel *trace_create_kernel_channel(struct lttng_channel *chan)
70 {
71 int ret;
72 struct ltt_kernel_channel *lkc;
73
74 lkc = malloc(sizeof(struct ltt_kernel_channel));
75 if (lkc == NULL) {
76 perror("ltt_kernel_channel malloc");
77 goto error;
78 }
79
80 lkc->channel = malloc(sizeof(struct lttng_channel));
81 if (lkc->channel == NULL) {
82 perror("lttng_channel malloc");
83 goto error;
84 }
85 memcpy(lkc->channel, chan, sizeof(struct lttng_channel));
86
87 lkc->fd = 0;
88 lkc->stream_count = 0;
89 /* Init linked list */
90 CDS_INIT_LIST_HEAD(&lkc->events_list.head);
91 CDS_INIT_LIST_HEAD(&lkc->stream_list.head);
92 /* Set default trace output path */
93 ret = asprintf(&lkc->pathname, "%s", DEFAULT_TRACE_OUTPUT);
94 if (ret < 0) {
95 perror("asprintf kernel create channel");
96 goto error;
97 }
98
99 return lkc;
100
101 error:
102 return NULL;
103 }
104
105 /*
106 * trace_create_kernel_event
107 *
108 * Allocate and initialize a kernel event. Set name and event type.
109 *
110 * Return pointer to structure or NULL.
111 */
112 struct ltt_kernel_event *trace_create_kernel_event(struct lttng_event *ev)
113 {
114 struct ltt_kernel_event *lke;
115 struct lttng_kernel_event *attr;
116
117 lke = malloc(sizeof(struct ltt_kernel_event));
118 attr = malloc(sizeof(struct lttng_kernel_event));
119 if (lke == NULL || attr == NULL) {
120 perror("kernel event malloc");
121 goto error;
122 }
123
124 switch (ev->type) {
125 case LTTNG_EVENT_KPROBES:
126 attr->instrumentation = LTTNG_KERNEL_KPROBES;
127 attr->u.kprobe.addr = ev->attr.kprobe.addr;
128 attr->u.kprobe.offset = ev->attr.kprobe.offset;
129 strncpy(attr->u.kprobe.symbol_name,
130 ev->attr.kprobe.symbol_name, LTTNG_SYM_NAME_LEN);
131 break;
132 case LTTNG_EVENT_FUNCTION:
133 attr->instrumentation = LTTNG_KERNEL_FUNCTION;
134 strncpy(attr->u.ftrace.symbol_name,
135 ev->attr.ftrace.symbol_name, LTTNG_SYM_NAME_LEN);
136 break;
137 case LTTNG_EVENT_TRACEPOINTS:
138 attr->instrumentation = LTTNG_KERNEL_TRACEPOINTS;
139 break;
140 default:
141 ERR("Unknown kernel instrumentation type (%d)", ev->type);
142 goto error;
143 }
144
145 /* Copy event name */
146 strncpy(attr->name, ev->name, LTTNG_SYM_NAME_LEN);
147
148 /* Setting up a kernel event */
149 lke->fd = 0;
150 lke->event = attr;
151
152 return lke;
153
154 error:
155 return NULL;
156 }
157
158 /*
159 * trace_create_kernel_metadata
160 *
161 * Allocate and initialize a kernel metadata.
162 *
163 * Return pointer to structure or NULL.
164 */
165 struct ltt_kernel_metadata *trace_create_kernel_metadata(void)
166 {
167 int ret;
168 struct ltt_kernel_metadata *lkm;
169 struct lttng_channel *chan;
170
171 lkm = malloc(sizeof(struct ltt_kernel_metadata));
172 chan = malloc(sizeof(struct lttng_channel));
173 if (lkm == NULL || chan == NULL) {
174 perror("kernel metadata malloc");
175 goto error;
176 }
177
178 /* Set default attributes */
179 chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE;
180 chan->attr.subbuf_size = DEFAULT_CHANNEL_SUBBUF_SIZE;
181 chan->attr.num_subbuf = DEFAULT_CHANNEL_SUBBUF_NUM;
182 chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER;
183 chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER;
184
185 /* Init metadata */
186 lkm->fd = 0;
187 lkm->conf = chan;
188 /* Set default metadata path */
189 ret = asprintf(&lkm->pathname, "%s/metadata", DEFAULT_TRACE_OUTPUT);
190 if (ret < 0) {
191 perror("asprintf kernel metadata");
192 goto error;
193 }
194
195 return lkm;
196
197 error:
198 return NULL;
199 }
200
201 /*
202 * trace_create_kernel_stream
203 *
204 * Allocate and initialize a kernel stream. The stream is set to ACTIVE_FD by
205 * default.
206 *
207 * Return pointer to structure or NULL.
208 */
209 struct ltt_kernel_stream *trace_create_kernel_stream(void)
210 {
211 struct ltt_kernel_stream *lks;
212
213 lks = malloc(sizeof(struct ltt_kernel_stream));
214 if (lks == NULL) {
215 perror("kernel stream malloc");
216 goto error;
217 }
218
219 /* Init stream */
220 lks->fd = 0;
221 lks->pathname = NULL;
222 lks->state = 0;
223
224 return lks;
225
226 error:
227 return NULL;
228 }
229
230 void trace_destroy_kernel_stream(struct ltt_kernel_stream *stream)
231 {
232 DBG("[trace] Closing stream fd %d", stream->fd);
233 /* Close kernel fd */
234 close(stream->fd);
235 free(stream->pathname);
236
237 /* Remove from stream list */
238 cds_list_del(&stream->list);
239 free(stream);
240 }
241
242 void trace_destroy_kernel_event(struct ltt_kernel_event *event)
243 {
244 DBG("[trace] Closing event fd %d", event->fd);
245 /* Close kernel fd */
246 close(event->fd);
247 /* Free attributes */
248 free(event->event);
249
250 /* Remove from event list */
251 cds_list_del(&event->list);
252 free(event);
253 }
254
255 void trace_destroy_kernel_channel(struct ltt_kernel_channel *channel)
256 {
257 struct ltt_kernel_stream *stream;
258 struct ltt_kernel_event *event;
259
260 DBG("[trace] Closing channel fd %d", channel->fd);
261 /* Close kernel fd */
262 close(channel->fd);
263 free(channel->pathname);
264 /* Free attributes structure */
265 free(channel->channel);
266
267 /* For each stream in the channel list */
268 cds_list_for_each_entry(stream, &channel->stream_list.head, list) {
269 trace_destroy_kernel_stream(stream);
270 }
271
272 /* For each event in the channel list */
273 cds_list_for_each_entry(event, &channel->events_list.head, list) {
274 trace_destroy_kernel_event(event);
275 }
276
277 /* Remove from channel list */
278 cds_list_del(&channel->list);
279 free(channel);
280 }
281
282 void trace_destroy_kernel_metadata(struct ltt_kernel_metadata *metadata)
283 {
284 DBG("[trace] Closing metadata fd %d", metadata->fd);
285 /* Close kernel fd */
286 close(metadata->fd);
287 /* Free attributes */
288 free(metadata->conf);
289
290 free(metadata);
291 }
292
293 void trace_destroy_kernel_session(struct ltt_kernel_session *session)
294 {
295 struct ltt_kernel_channel *channel;
296
297 DBG("[trace] Closing session fd %d", session->fd);
298 /* Close kernel fds */
299 close(session->fd);
300 if (session->metadata_stream_fd != 0) {
301 DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd);
302 close(session->metadata_stream_fd);
303 }
304
305 trace_destroy_kernel_metadata(session->metadata);
306
307 cds_list_for_each_entry(channel, &session->channel_list.head, list) {
308 trace_destroy_kernel_channel(channel);
309 }
310
311 free(session);
312 }
This page took 0.037193 seconds and 5 git commands to generate.