4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * Mimic system calls for:
9 * - session creation, returns a file descriptor or failure.
10 * - channel creation, returns a file descriptor or failure.
11 * - Operates on a session file descriptor
12 * - Takes all channel options as parameters.
13 * - stream get, returns a file descriptor or failure.
14 * - Operates on a channel file descriptor.
15 * - stream notifier get, returns a file descriptor or failure.
16 * - Operates on a channel file descriptor.
17 * - event creation, returns a file descriptor or failure.
18 * - Operates on a channel file descriptor
19 * - Takes an event name as parameter
20 * - Takes an instrumentation source as parameter
21 * - e.g. tracepoints, dynamic_probes...
22 * - Takes instrumentation source specific arguments.
25 #include <linux/module.h>
26 #include <linux/debugfs.h>
27 #include <linux/anon_inodes.h>
28 #include <linux/file.h>
29 #include <linux/uaccess.h>
30 #include <linux/slab.h>
31 #include <linux/ringbuffer/vfs.h>
32 #include "ltt-debugfs-abi.h"
33 #include "ltt-events.h"
36 * This is LTTng's own personal way to create a system call as an external
37 * module. We use ioctl() on /sys/kernel/debug/lttng.
40 static struct dentry
*lttng_dentry
;
41 static const struct file_operations lttng_fops
;
42 static const struct file_operations lttng_session_fops
;
43 static const struct file_operations lttng_channel_fops
;
44 static const struct file_operations lttng_event_fops
;
47 int lttng_abi_create_session(void)
49 struct ltt_session
*session
;
50 struct file
*session_file
;
53 session
= ltt_session_create();
56 session_fd
= get_unused_fd();
61 session_file
= anon_inode_getfile("[lttng_session]",
64 if (IS_ERR(session_file
)) {
65 ret
= PTR_ERR(session_file
);
68 session
->file
= session_file
;
69 fd_install(session_fd
, session_file
);
73 put_unused_fd(session_fd
);
75 ltt_session_destroy(session
);
80 * lttng_ioctl - lttng syscall through ioctl
86 * This ioctl implements lttng commands:
88 * Returns a LTTng trace session file descriptor
90 * The returned session will be deleted when its file descriptor is closed.
93 long lttng_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
97 return lttng_abi_create_session();
103 static const struct file_operations lttng_fops
= {
104 .unlocked_ioctl
= lttng_ioctl
,
106 .compat_ioctl
= lttng_ioctl
,
110 int lttng_abi_create_channel(struct file
*session_file
,
111 struct lttng_channel __user
*uchan_param
)
113 struct ltt_session
*session
= session_file
->private_data
;
114 struct ltt_channel
*chan
;
115 struct file
*chan_file
;
116 struct lttng_channel chan_param
;
120 if (copy_from_user(&chan_param
, uchan_param
, sizeof(chan_param
)))
122 chan_fd
= get_unused_fd();
127 chan_file
= anon_inode_getfile("[lttng_channel]",
130 if (IS_ERR(chan_file
)) {
131 ret
= PTR_ERR(chan_file
);
135 * We tolerate no failure path after channel creation. It will stay
136 * invariant for the rest of the session.
138 chan
= ltt_channel_create(session
, chan_param
.overwrite
, NULL
,
139 chan_param
.subbuf_size
,
140 chan_param
.num_subbuf
,
141 chan_param
.switch_timer_interval
,
142 chan_param
.read_timer_interval
);
147 chan
->file
= chan_file
;
148 chan_file
->private_data
= chan
;
149 fd_install(chan_fd
, chan_file
);
150 /* The channel created holds a reference on the session */
151 atomic_long_inc(&session_file
->f_count
);
158 put_unused_fd(chan_fd
);
164 * lttng_session_ioctl - lttng session fd ioctl
170 * This ioctl implements lttng commands:
172 * Returns a LTTng channel file descriptor
174 * The returned channel will be deleted when its file descriptor is closed.
177 long lttng_session_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
179 struct ltt_session
*session
= file
->private_data
;
183 return lttng_abi_create_channel(file
, (struct lttng_channel __user
*)arg
);
184 case LTTNG_SESSION_START
:
185 return ltt_session_start(session
);
186 case LTTNG_SESSION_STOP
:
187 return ltt_session_stop(session
);
194 * Called when the last file reference is dropped.
196 * Big fat note: channels and events are invariant for the whole session after
197 * their creation. So this session destruction also destroys all channel and
198 * event structures specific to this session (they are not destroyed when their
199 * individual file is released).
202 int lttng_session_release(struct inode
*inode
, struct file
*file
)
204 struct ltt_session
*session
= file
->private_data
;
207 ltt_session_destroy(session
);
211 static const struct file_operations lttng_session_fops
= {
212 .release
= lttng_session_release
,
213 .unlocked_ioctl
= lttng_session_ioctl
,
215 .compat_ioctl
= lttng_session_ioctl
,
220 int lttng_abi_open_stream(struct file
*channel_file
)
222 struct ltt_channel
*channel
= channel_file
->private_data
;
223 struct lib_ring_buffer
*buf
;
225 struct file
*stream_file
;
227 buf
= channel
->ops
->buffer_read_open(channel
->chan
);
231 stream_fd
= get_unused_fd();
236 stream_file
= anon_inode_getfile("[lttng_stream]",
237 &lib_ring_buffer_file_operations
,
239 if (IS_ERR(stream_file
)) {
240 ret
= PTR_ERR(stream_file
);
243 fd_install(stream_fd
, stream_file
);
244 /* The stream holds a reference on the channel */
245 atomic_long_inc(&channel_file
->f_count
);
249 put_unused_fd(stream_fd
);
251 channel
->ops
->buffer_read_close(buf
);
256 int lttng_abi_create_event(struct file
*channel_file
,
257 struct lttng_event __user
*uevent_param
)
259 struct ltt_channel
*channel
= channel_file
->private_data
;
260 struct ltt_event
*event
;
262 struct lttng_event event_param
;
264 struct file
*event_file
;
266 if (copy_from_user(&event_param
, uevent_param
, sizeof(event_param
)))
268 event_name
= kmalloc(PATH_MAX
, GFP_KERNEL
);
271 if (strncpy_from_user(event_name
, uevent_param
->name
, PATH_MAX
) < 0) {
275 event_name
[PATH_MAX
- 1] = '\0';
276 event_fd
= get_unused_fd();
281 event_file
= anon_inode_getfile("[lttng_event]",
284 if (IS_ERR(event_file
)) {
285 ret
= PTR_ERR(event_file
);
289 * We tolerate no failure path after event creation. It will stay
290 * invariant for the rest of the session.
292 event
= ltt_event_create(channel
, event_name
, event_param
.itype
,
293 NULL
, NULL
); /* TODO non-null probe */
298 event_file
->private_data
= event
;
299 fd_install(event_fd
, event_file
);
300 /* The event holds a reference on the channel */
301 atomic_long_inc(&channel_file
->f_count
);
308 put_unused_fd(event_fd
);
316 * lttng_channel_ioctl - lttng syscall through ioctl
322 * This ioctl implements lttng commands:
324 * Returns an event stream file descriptor or failure.
325 * (typically, one event stream records events from one CPU)
327 * Returns an event file descriptor or failure.
329 * The returned session will be deleted when its file descriptor is closed.
330 * Channel and event file descriptors also hold a reference on the session.
333 long lttng_channel_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
337 return lttng_abi_open_stream(file
);
339 return lttng_abi_create_event(file
, (struct lttng_event __user
*)arg
);
348 * lttng_channel_poll - lttng stream addition/removal monitoring
353 unsigned int lttng_channel_poll(struct file
*file
, poll_table
*wait
)
355 struct ltt_channel
*channel
= file
->private_data
;
356 unsigned int mask
= 0;
358 if (file
->f_mode
& FMODE_READ
) {
359 poll_wait_set_exclusive(wait
);
360 poll_wait(file
, &channel
->notify_wait
, wait
);
362 /* TODO: identify when the channel is being finalized. */
366 return POLLIN
| POLLRDNORM
;
374 int lttng_channel_release(struct inode
*inode
, struct file
*file
)
376 struct ltt_channel
*channel
= file
->private_data
;
379 fput(channel
->session
->file
);
383 static const struct file_operations lttng_channel_fops
= {
384 .release
= lttng_channel_release
,
387 .poll
= lttng_channel_poll
,
389 .unlocked_ioctl
= lttng_channel_ioctl
,
391 .compat_ioctl
= lttng_channel_ioctl
,
396 int lttng_event_release(struct inode
*inode
, struct file
*file
)
398 struct ltt_event
*event
= file
->private_data
;
401 fput(event
->chan
->file
);
405 /* TODO: filter control ioctl */
406 static const struct file_operations lttng_event_fops
= {
407 .release
= lttng_event_release
,
410 int __init
ltt_debugfs_abi_init(void)
414 lttng_dentry
= debugfs_create_file("lttng", S_IWUSR
, NULL
, NULL
,
416 if (IS_ERR(lttng_dentry
) || !lttng_dentry
) {
417 printk(KERN_ERR
"Error creating LTTng control file\n");
425 void __exit
ltt_debugfs_abi_exit(void)
427 debugfs_remove(lttng_dentry
);