fa207bc67eb1adc8e18a13ba27c583424f6d8a8d
[lttng-tools.git] / src / bin / lttng-sessiond / trace-kernel.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
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18 #define _LGPL_SOURCE
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23
24 #include <common/common.h>
25 #include <common/defaults.h>
26
27 #include "consumer.h"
28 #include "trace-kernel.h"
29
30 /*
31 * Find the channel name for the given kernel session.
32 */
33 struct ltt_kernel_channel *trace_kernel_get_channel_by_name(
34 char *name, struct ltt_kernel_session *session)
35 {
36 struct ltt_kernel_channel *chan;
37
38 assert(session);
39 assert(name);
40
41 /*
42 * If we receive an empty string for channel name, it means the
43 * default channel name is requested.
44 */
45 if (name[0] == '\0')
46 name = DEFAULT_CHANNEL_NAME;
47
48 DBG("Trying to find channel %s", name);
49
50 cds_list_for_each_entry(chan, &session->channel_list.head, list) {
51 if (strcmp(name, chan->channel->name) == 0) {
52 DBG("Found channel by name %s", name);
53 return chan;
54 }
55 }
56
57 return NULL;
58 }
59
60 /*
61 * Find the event for the given channel.
62 */
63 struct ltt_kernel_event *trace_kernel_find_event(
64 char *name, struct ltt_kernel_channel *channel,
65 enum lttng_event_type type,
66 struct lttng_filter_bytecode *filter)
67 {
68 struct ltt_kernel_event *ev;
69 int found = 0;
70
71 assert(name);
72 assert(channel);
73
74 cds_list_for_each_entry(ev, &channel->events_list.head, list) {
75 if (type != LTTNG_EVENT_ALL && ev->type != type) {
76 continue;
77 }
78 if (strcmp(name, ev->event->name)) {
79 continue;
80 }
81 if ((ev->filter && !filter) || (!ev->filter && filter)) {
82 continue;
83 }
84 if (ev->filter && filter) {
85 if (ev->filter->len != filter->len ||
86 memcmp(ev->filter->data, filter->data,
87 filter->len) != 0) {
88 continue;
89 }
90 }
91 found = 1;
92 break;
93 }
94 if (found) {
95 DBG("Found event %s for channel %s", name,
96 channel->channel->name);
97 return ev;
98 } else {
99 return NULL;
100 }
101 }
102
103 /*
104 * Find the event name for the given channel.
105 */
106 struct ltt_kernel_event *trace_kernel_get_event_by_name(
107 char *name, struct ltt_kernel_channel *channel,
108 enum lttng_event_type type)
109 {
110 struct ltt_kernel_event *ev;
111 int found = 0;
112
113 assert(name);
114 assert(channel);
115
116 cds_list_for_each_entry(ev, &channel->events_list.head, list) {
117 if (type != LTTNG_EVENT_ALL && ev->type != type) {
118 continue;
119 }
120 if (strcmp(name, ev->event->name)) {
121 continue;
122 }
123 found = 1;
124 break;
125 }
126 if (found) {
127 DBG("Found event %s for channel %s", name,
128 channel->channel->name);
129 return ev;
130 } else {
131 return NULL;
132 }
133 }
134
135 /*
136 * Allocate and initialize a kernel session data structure.
137 *
138 * Return pointer to structure or NULL.
139 */
140 struct ltt_kernel_session *trace_kernel_create_session(void)
141 {
142 struct ltt_kernel_session *lks = NULL;
143
144 /* Allocate a new ltt kernel session */
145 lks = zmalloc(sizeof(struct ltt_kernel_session));
146 if (lks == NULL) {
147 PERROR("create kernel session zmalloc");
148 goto alloc_error;
149 }
150
151 /* Init data structure */
152 lks->fd = -1;
153 lks->metadata_stream_fd = -1;
154 lks->channel_count = 0;
155 lks->stream_count_global = 0;
156 lks->metadata = NULL;
157 CDS_INIT_LIST_HEAD(&lks->channel_list.head);
158
159 lks->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
160 if (lks->consumer == NULL) {
161 goto error;
162 }
163
164 return lks;
165
166 error:
167 free(lks);
168
169 alloc_error:
170 return NULL;
171 }
172
173 /*
174 * Allocate and initialize a kernel channel data structure.
175 *
176 * Return pointer to structure or NULL.
177 */
178 struct ltt_kernel_channel *trace_kernel_create_channel(
179 struct lttng_channel *chan)
180 {
181 struct ltt_kernel_channel *lkc;
182
183 assert(chan);
184
185 lkc = zmalloc(sizeof(struct ltt_kernel_channel));
186 if (lkc == NULL) {
187 PERROR("ltt_kernel_channel zmalloc");
188 goto error;
189 }
190
191 lkc->channel = zmalloc(sizeof(struct lttng_channel));
192 if (lkc->channel == NULL) {
193 PERROR("lttng_channel zmalloc");
194 free(lkc);
195 goto error;
196 }
197 memcpy(lkc->channel, chan, sizeof(struct lttng_channel));
198
199 /*
200 * If we receive an empty string for channel name, it means the
201 * default channel name is requested.
202 */
203 if (chan->name[0] == '\0') {
204 strncpy(lkc->channel->name, DEFAULT_CHANNEL_NAME,
205 sizeof(lkc->channel->name));
206 }
207 lkc->channel->name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
208
209 lkc->fd = -1;
210 lkc->stream_count = 0;
211 lkc->event_count = 0;
212 lkc->enabled = 1;
213 /* Init linked list */
214 CDS_INIT_LIST_HEAD(&lkc->events_list.head);
215 CDS_INIT_LIST_HEAD(&lkc->stream_list.head);
216 CDS_INIT_LIST_HEAD(&lkc->ctx_list);
217
218 return lkc;
219
220 error:
221 return NULL;
222 }
223
224 /*
225 * Allocate and init a kernel context object.
226 *
227 * Return the allocated object or NULL on error.
228 */
229 struct ltt_kernel_context *trace_kernel_create_context(
230 struct lttng_kernel_context *ctx)
231 {
232 struct ltt_kernel_context *kctx;
233
234 kctx = zmalloc(sizeof(*kctx));
235 if (!kctx) {
236 PERROR("zmalloc kernel context");
237 goto error;
238 }
239
240 if (ctx) {
241 memcpy(&kctx->ctx, ctx, sizeof(kctx->ctx));
242 }
243 error:
244 return kctx;
245 }
246
247 /*
248 * Allocate and init a kernel context object from an existing kernel context
249 * object.
250 *
251 * Return the allocated object or NULL on error.
252 */
253 struct ltt_kernel_context *trace_kernel_copy_context(
254 struct ltt_kernel_context *kctx)
255 {
256 struct ltt_kernel_context *kctx_copy;
257
258 assert(kctx);
259 kctx_copy = zmalloc(sizeof(*kctx_copy));
260 if (!kctx_copy) {
261 PERROR("zmalloc ltt_kernel_context");
262 goto error;
263 }
264
265 memcpy(kctx_copy, kctx, sizeof(*kctx_copy));
266 memset(&kctx_copy->list, 0, sizeof(kctx_copy->list));
267
268 error:
269 return kctx_copy;
270 }
271
272 /*
273 * Allocate and initialize a kernel event. Set name and event type.
274 * We own filter_expression, and filter.
275 *
276 * Return pointer to structure or NULL.
277 */
278 struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev,
279 char *filter_expression, struct lttng_filter_bytecode *filter)
280 {
281 struct ltt_kernel_event *lke;
282 struct lttng_kernel_event *attr;
283
284 assert(ev);
285
286 lke = zmalloc(sizeof(struct ltt_kernel_event));
287 attr = zmalloc(sizeof(struct lttng_kernel_event));
288 if (lke == NULL || attr == NULL) {
289 PERROR("kernel event zmalloc");
290 goto error;
291 }
292
293 switch (ev->type) {
294 case LTTNG_EVENT_PROBE:
295 attr->instrumentation = LTTNG_KERNEL_KPROBE;
296 attr->u.kprobe.addr = ev->attr.probe.addr;
297 attr->u.kprobe.offset = ev->attr.probe.offset;
298 strncpy(attr->u.kprobe.symbol_name,
299 ev->attr.probe.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN);
300 attr->u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
301 break;
302 case LTTNG_EVENT_FUNCTION:
303 attr->instrumentation = LTTNG_KERNEL_KRETPROBE;
304 attr->u.kretprobe.addr = ev->attr.probe.addr;
305 attr->u.kretprobe.offset = ev->attr.probe.offset;
306 strncpy(attr->u.kretprobe.symbol_name,
307 ev->attr.probe.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN);
308 attr->u.kretprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
309 break;
310 case LTTNG_EVENT_FUNCTION_ENTRY:
311 attr->instrumentation = LTTNG_KERNEL_FUNCTION;
312 strncpy(attr->u.ftrace.symbol_name,
313 ev->attr.ftrace.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN);
314 attr->u.ftrace.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
315 break;
316 case LTTNG_EVENT_TRACEPOINT:
317 attr->instrumentation = LTTNG_KERNEL_TRACEPOINT;
318 break;
319 case LTTNG_EVENT_SYSCALL:
320 attr->instrumentation = LTTNG_KERNEL_SYSCALL;
321 break;
322 case LTTNG_EVENT_ALL:
323 attr->instrumentation = LTTNG_KERNEL_ALL;
324 break;
325 default:
326 ERR("Unknown kernel instrumentation type (%d)", ev->type);
327 goto error;
328 }
329
330 /* Copy event name */
331 strncpy(attr->name, ev->name, LTTNG_KERNEL_SYM_NAME_LEN);
332 attr->name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
333
334 /* Setting up a kernel event */
335 lke->fd = -1;
336 lke->event = attr;
337 lke->enabled = 1;
338 lke->filter_expression = filter_expression;
339 lke->filter = filter;
340
341 return lke;
342
343 error:
344 free(filter_expression);
345 free(filter);
346 free(lke);
347 free(attr);
348 return NULL;
349 }
350
351 /*
352 * Allocate and initialize a kernel metadata.
353 *
354 * Return pointer to structure or NULL.
355 */
356 struct ltt_kernel_metadata *trace_kernel_create_metadata(void)
357 {
358 struct ltt_kernel_metadata *lkm;
359 struct lttng_channel *chan;
360
361 lkm = zmalloc(sizeof(struct ltt_kernel_metadata));
362 chan = zmalloc(sizeof(struct lttng_channel));
363 if (lkm == NULL || chan == NULL) {
364 PERROR("kernel metadata zmalloc");
365 goto error;
366 }
367
368 /* Set default attributes */
369 chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE;
370 chan->attr.subbuf_size = default_get_metadata_subbuf_size();
371 chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM;
372 chan->attr.switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER;
373 chan->attr.read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER;
374 chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
375
376 /* Init metadata */
377 lkm->fd = -1;
378 lkm->conf = chan;
379
380 return lkm;
381
382 error:
383 free(lkm);
384 free(chan);
385 return NULL;
386 }
387
388 /*
389 * Allocate and initialize a kernel stream. The stream is set to ACTIVE_FD by
390 * default.
391 *
392 * Return pointer to structure or NULL.
393 */
394 struct ltt_kernel_stream *trace_kernel_create_stream(const char *name,
395 unsigned int count)
396 {
397 int ret;
398 struct ltt_kernel_stream *lks;
399
400 assert(name);
401
402 lks = zmalloc(sizeof(struct ltt_kernel_stream));
403 if (lks == NULL) {
404 PERROR("kernel stream zmalloc");
405 goto error;
406 }
407
408 /* Set name */
409 ret = snprintf(lks->name, sizeof(lks->name), "%s_%u", name, count);
410 if (ret < 0) {
411 PERROR("snprintf stream name");
412 goto error;
413 }
414 lks->name[sizeof(lks->name) - 1] = '\0';
415
416 /* Init stream */
417 lks->fd = -1;
418 lks->state = 0;
419 lks->cpu = count;
420
421 return lks;
422
423 error:
424 return NULL;
425 }
426
427 /*
428 * Cleanup kernel stream structure.
429 */
430 void trace_kernel_destroy_stream(struct ltt_kernel_stream *stream)
431 {
432 assert(stream);
433
434 DBG("[trace] Closing stream fd %d", stream->fd);
435 /* Close kernel fd */
436 if (stream->fd >= 0) {
437 int ret;
438
439 ret = close(stream->fd);
440 if (ret) {
441 PERROR("close");
442 }
443 }
444 /* Remove from stream list */
445 cds_list_del(&stream->list);
446
447 free(stream);
448 }
449
450 /*
451 * Cleanup kernel event structure.
452 */
453 void trace_kernel_destroy_event(struct ltt_kernel_event *event)
454 {
455 assert(event);
456
457 if (event->fd >= 0) {
458 int ret;
459
460 DBG("[trace] Closing event fd %d", event->fd);
461 /* Close kernel fd */
462 ret = close(event->fd);
463 if (ret) {
464 PERROR("close");
465 }
466 } else {
467 DBG("[trace] Tearing down event (no associated fd)");
468 }
469
470 /* Remove from event list */
471 cds_list_del(&event->list);
472
473 free(event->filter_expression);
474 free(event->filter);
475
476 free(event->event);
477 free(event);
478 }
479
480 /*
481 * Cleanup kernel context structure.
482 */
483 void trace_kernel_destroy_context(struct ltt_kernel_context *ctx)
484 {
485 assert(ctx);
486
487 if (ctx->in_list) {
488 cds_list_del(&ctx->list);
489 }
490 free(ctx);
491 }
492
493 /*
494 * Cleanup kernel channel structure.
495 */
496 void trace_kernel_destroy_channel(struct ltt_kernel_channel *channel)
497 {
498 struct ltt_kernel_stream *stream, *stmp;
499 struct ltt_kernel_event *event, *etmp;
500 struct ltt_kernel_context *ctx, *ctmp;
501 int ret;
502
503 assert(channel);
504
505 DBG("[trace] Closing channel fd %d", channel->fd);
506 /* Close kernel fd */
507 if (channel->fd >= 0) {
508 ret = close(channel->fd);
509 if (ret) {
510 PERROR("close");
511 }
512 }
513
514 /* For each stream in the channel list */
515 cds_list_for_each_entry_safe(stream, stmp, &channel->stream_list.head, list) {
516 trace_kernel_destroy_stream(stream);
517 }
518
519 /* For each event in the channel list */
520 cds_list_for_each_entry_safe(event, etmp, &channel->events_list.head, list) {
521 trace_kernel_destroy_event(event);
522 }
523
524 /* For each context in the channel list */
525 cds_list_for_each_entry_safe(ctx, ctmp, &channel->ctx_list, list) {
526 trace_kernel_destroy_context(ctx);
527 }
528
529 /* Remove from channel list */
530 cds_list_del(&channel->list);
531
532 free(channel->channel);
533 free(channel);
534 }
535
536 /*
537 * Cleanup kernel metadata structure.
538 */
539 void trace_kernel_destroy_metadata(struct ltt_kernel_metadata *metadata)
540 {
541 assert(metadata);
542
543 DBG("[trace] Closing metadata fd %d", metadata->fd);
544 /* Close kernel fd */
545 if (metadata->fd >= 0) {
546 int ret;
547
548 ret = close(metadata->fd);
549 if (ret) {
550 PERROR("close");
551 }
552 }
553
554 free(metadata->conf);
555 free(metadata);
556 }
557
558 /*
559 * Cleanup kernel session structure
560 *
561 * Should *NOT* be called with RCU read-side lock held.
562 */
563 void trace_kernel_destroy_session(struct ltt_kernel_session *session)
564 {
565 struct ltt_kernel_channel *channel, *ctmp;
566 int ret;
567
568 assert(session);
569
570 DBG("[trace] Closing session fd %d", session->fd);
571 /* Close kernel fds */
572 if (session->fd >= 0) {
573 ret = close(session->fd);
574 if (ret) {
575 PERROR("close");
576 }
577 }
578
579 if (session->metadata_stream_fd >= 0) {
580 DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd);
581 ret = close(session->metadata_stream_fd);
582 if (ret) {
583 PERROR("close");
584 }
585 }
586
587 if (session->metadata != NULL) {
588 trace_kernel_destroy_metadata(session->metadata);
589 }
590
591 cds_list_for_each_entry_safe(channel, ctmp, &session->channel_list.head, list) {
592 trace_kernel_destroy_channel(channel);
593 }
594
595 /* Wipe consumer output object */
596 consumer_output_put(session->consumer);
597
598 free(session);
599 }
This page took 0.047965 seconds and 4 git commands to generate.