Add a new /dev/lttng-logger interface
[lttng-modules.git] / probes / lttng.c
CommitLineData
0c956676
MD
1/*
2 * lttng.c
3 *
4 * LTTng logger ABI
5 *
6 * Copyright (C) 2008-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/tracepoint.h>
25#include <linux/uaccess.h>
26#include <linux/gfp.h>
27#include <linux/fs.h>
28#include <linux/proc_fs.h>
29#include <linux/slab.h>
30#include <linux/mm.h>
4d328377 31#include <linux/miscdevice.h>
156a3977
MD
32#include <wrapper/vmalloc.h>
33#include <lttng-events.h>
0c956676
MD
34
35#define TP_MODULE_NOAUTOLOAD
36#define LTTNG_PACKAGE_BUILD
37#define CREATE_TRACE_POINTS
c075712b 38#define TRACE_INCLUDE_PATH instrumentation/events/lttng-module
0c956676 39#define TRACE_INCLUDE_FILE lttng
3bc29f0a 40#define LTTNG_INSTRUMENTATION
0c956676 41
156a3977 42#include <instrumentation/events/lttng-module/lttng.h>
0c956676
MD
43
44/* Events written through logger are truncated at 1024 bytes */
45#define LTTNG_LOGGER_COUNT_MAX 1024
46#define LTTNG_LOGGER_FILE "lttng-logger"
47
20591cf7
MD
48DEFINE_TRACE(lttng_logger);
49
0c956676
MD
50static struct proc_dir_entry *lttng_logger_dentry;
51
52/**
53 * lttng_logger_write - write a userspace string into the trace system
54 * @file: file pointer
55 * @user_buf: user string
56 * @count: length to copy
57 * @ppos: file position
58 *
59 * Copy a userspace string into a trace event named "lttng:logger".
60 * Copies at most @count bytes into the event "msg" dynamic array.
61 * Truncates the count at LTTNG_LOGGER_COUNT_MAX. Returns the number of
62 * bytes copied from the source.
63 * Return -1 on error, with EFAULT errno.
64 */
65static
66ssize_t lttng_logger_write(struct file *file, const char __user *user_buf,
67 size_t count, loff_t *ppos)
68{
467f3a48 69 int nr_pages = 1, i;
0c956676
MD
70 unsigned long uaddr = (unsigned long) user_buf;
71 struct page *pages[2];
72 ssize_t written;
73 int ret;
74
75 /* Truncate count */
76 if (unlikely(count > LTTNG_LOGGER_COUNT_MAX))
77 count = LTTNG_LOGGER_COUNT_MAX;
78
79 /* How many pages are we dealing with ? */
80 if (unlikely((uaddr & PAGE_MASK) != ((uaddr + count) & PAGE_MASK)))
81 nr_pages = 2;
82
83 /* Pin userspace pages */
84 ret = get_user_pages_fast(uaddr, nr_pages, 0, pages);
85 if (unlikely(ret < nr_pages)) {
86 if (ret > 0) {
87 BUG_ON(ret != 1);
88 put_page(pages[0]);
89 }
90 written = -EFAULT;
91 goto end;
92 }
93
94 /* Trace the event */
95 trace_lttng_logger(user_buf, count);
96 written = count;
97 *ppos += written;
98
99 for (i = 0; i < nr_pages; i++)
100 put_page(pages[i]);
101end:
102 return written;
103}
104
105static const struct file_operations lttng_logger_operations = {
106 .write = lttng_logger_write,
107};
108
4d328377
SG
109static struct miscdevice logger_dev = {
110 .minor = MISC_DYNAMIC_MINOR,
111 .name = "lttng-logger",
112 .mode = 0666,
113 .fops = &lttng_logger_operations
114};
115
0c956676
MD
116int __init lttng_logger_init(void)
117{
118 int ret = 0;
119
120 wrapper_vmalloc_sync_all();
4d328377
SG
121
122 /* /dev/lttng-logger */
123 ret = misc_register(&logger_dev);
124 if (ret) {
125 printk(KERN_ERR "Error creating LTTng logger device\n");
126 goto error;
127 }
128
129 /* /proc/lttng-logger */
0c956676
MD
130 lttng_logger_dentry = proc_create_data(LTTNG_LOGGER_FILE,
131 S_IRUGO | S_IWUGO, NULL,
132 &lttng_logger_operations, NULL);
133 if (!lttng_logger_dentry) {
4d328377 134 printk(KERN_ERR "Error creating LTTng logger proc file\n");
0c956676 135 ret = -ENOMEM;
4d328377 136 goto error_proc;
0c956676 137 }
4d328377
SG
138
139 /* Init */
0c956676
MD
140 ret = __lttng_events_init__lttng();
141 if (ret)
142 goto error_events;
143 return ret;
144
145error_events:
146 remove_proc_entry("lttng-logger", NULL);
4d328377
SG
147error_proc:
148 misc_deregister(&logger_dev);
0c956676
MD
149error:
150 return ret;
151}
152
32fe46fb 153void lttng_logger_exit(void)
0c956676
MD
154{
155 __lttng_events_exit__lttng();
156 if (lttng_logger_dentry)
157 remove_proc_entry("lttng-logger", NULL);
4d328377 158 misc_deregister(&logger_dev);
0c956676 159}
This page took 0.036323 seconds and 4 git commands to generate.