debugfs ABI in progress
[lttng-modules.git] / ltt-debugfs-abi.c
CommitLineData
baf20995
MD
1/*
2 * ltt-debugfs-abi.c
3 *
4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * LTTng debugfs ABI
7 *
8 * Mimic system calls for:
9 * - session creation, returns a file descriptor or failure.
10 * - channel creation, returns a file descriptor or failure.
11 * - Takes a session file descriptor parameter
12 * - Takes all channel options as parameters.
13 * - event creation, returns a file descriptor or failure.
14 * - Takes an event name as parameter
15 * - Takes an instrumentation source as parameter
16 * - e.g. tracepoints, dynamic_probes...
17 * - Takes instrumentation source specific arguments.
18 */
19
20#include <linux/debugfs.h>
21
22/*
23 * This is LTTng's own personal way to create a system call as an external
24 * module. We use ioctl() on /sys/kernel/debug/lttng.
25 */
26
27static struct dentry *lttng_dentry;
28
29/*
30 * LTTng DebugFS ABI structures.
31 */
32
33struct lttng_channel {
34 int session; /* Session file descriptor */
35 int overwrite; /* 1: overwrite, 0: discard */
36 u64 subbuf_size;
37 u64 num_subbuf;
38 unsigned int switch_timer_interval;
39 unsigned int read_timer_interval;
40};
41
42struct lttng_event {
43 int channel; /* Channel file descriptor */
44 enum instrum_type itype;
45 char name[];
46};
47
48int lttng_abi_create_session(void)
49{
50 struct ltt_session *session;
51 struct file *session_file;
52 int session_fd;
53
54 session = ltt_session_create()
55 if (!session)
56 return -ENOMEM;
57 session_fd = get_unused_fd_flags(O_RDWR);
58 if (session_fd < 0) {
59 ret = session_fd;
60 goto fd_error;
61 }
62 session_file = anon_inode_getfile("[lttng_session]",
63 &lttng_fops,
64 session, O_RDWR);
65 if (IS_ERR(session_file)) {
66 ret = PTR_ERR(session_file);
67 goto file_error;
68 }
69 return session_fd;
70
71file_error:
72 put_unused_fd(session_fd);
73fd_error:
74 ltt_session_destroy(session);
75 return ret;
76}
77
78int lttng_abi_create_channel(struct lttng_channel __user *uchan_param)
79{
80 struct ltt_channel *chan;
81 struct file *chan_file;
82 struct lttng_channel chan_param;
83 int chan_fd;
84
85 if (copy_from_user(&chan_param, ucham_param, sizeof(chan_param)))
86 return -EFAULT;
87 /* TODO: fetch session pointer from file descriptor */
88 chan = ltt_channel_create();
89 if (!chan)
90 return -ENOMEM;
91 chan_fd = get_unused_fd_flags(O_RDWR);
92 if (chan_fd < 0) {
93 ret = chan_fd;
94 goto fd_error;
95 }
96 chan_file = anon_inode_getfile("[lttng_channel]",
97 &lttng_fops,
98 chan, O_RDWR);
99 if (IS_ERR(chan_file)) {
100 ret = PTR_ERR(chan_file);
101 goto file_error;
102 }
103 return chan_fd;
104
105file_error:
106 put_unused_fd(chan_fd);
107fd_error:
108 ltt_channel_destroy(chan);
109 return ret;
110}
111
112/**
113 * lttng_ioctl - lttng syscall through ioctl
114 *
115 * @filp: the file
116 * @cmd: the command
117 * @arg: command arg
118 *
119 * This ioctl implements lttng commands:
120 * LTTNG_SESSION
121 * Returns a LTTng trace session file descriptor
122 * LTTNG_CHANNEL
123 * Returns a LTTng channel file descriptor
124 * LTTNG_EVENT
125 * Returns a file descriptor or failure.
126 *
127 * The returned session will be deleted when its file descriptor is closed.
128 * Channel and event file descriptors also hold a reference on the session.
129 */
130long lttng_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
131{
132 struct inode *inode = filp->f_dentry->d_inode;
133
134 switch (cmd) {
135 case LTTNG_SESSION:
136 return lttng_abi_create_session();
137 case LTTNG_CHANNEL:
138 return lttng_abi_create_channel((struct lttng_channel __user *)arg);
139 case LTTNG_EVENT:
140 return lttng_abi_create_event((struct lttng_event __user *)arg);
141 default:
142 return -ENOIOCTLCMD;
143 }
144}
145
146#ifdef CONFIG_COMPAT
147long lttng_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
148{
149 struct inode *inode = filp->f_dentry->d_inode;
150
151 switch (cmd) {
152 case LTTNG_SESSION:
153 return lttng_abi_create_session();
154 case LTTNG_CHANNEL:
155 return lttng_abi_create_channel((struct lttng_channel __user *)arg);
156 case LTTNG_EVENT:
157 return lttng_abi_create_event((struct lttng_event __user *)arg);
158 default:
159 return -ENOIOCTLCMD;
160 }
161}
162#endif
163
164const struct file_operations lttng_file_operations = {
165 .unlocked_ioctl = lttng_ioctl,
166#ifdef CONFIG_COMPAT
167 .compat_ioctl = lttng_compat_ioctl,
168#endif
169}
170
171static int __init ltt_debugfs_abi_init(void)
172{
173 int ret = 0;
174
175 lttng_dentry = debugfs_create_file("lttng", NULL);
176 if (IS_ERR(lttng_dentry) || !lttng_dentry)
177 printk(KERN_ERR "Error creating LTTng control file\n");
178 ret = -ENOMEM;
179 goto error;
180 }
181error:
182 return ret;
183}
184
185static void __exit ltt_debugfs_abi_exit(void)
186{
187 debugfs_remote(lttng_dentry);
188}
This page took 0.028707 seconds and 4 git commands to generate.