aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/debugfs.c
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2012-06-10 17:58:51 -0400
committerAntonio Quartulli <ordex@autistici.org>2012-07-01 16:47:22 -0400
commitb706b13b6cfde22d1f4adc540fd89426247c1e3e (patch)
treec729d6580d4a249f97317f210078b30db821c8cb /net/batman-adv/debugfs.c
parenta8a0a62d1f173620f150830db437ddd65a103d49 (diff)
batman-adv: Remove bat_ prefix from bat_{debugfs, sysfs}.{c, h}
The "bat_" prefix in the source files implementing the batman-adv sysfs and debugfs interface doesn't have a special meaning and are only used by these files and files that implement the actual B.A.T.M.A.N. path finding algorithm. The prefix is better suited to mark files that are used to implement the main part of the path finding. All other files should not use it and therefore gets renamed. Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net/batman-adv/debugfs.c')
-rw-r--r--net/batman-adv/debugfs.c405
1 files changed, 405 insertions, 0 deletions
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
new file mode 100644
index 000000000000..e45cf0e884cc
--- /dev/null
+++ b/net/batman-adv/debugfs.c
@@ -0,0 +1,405 @@
1/* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors:
2 *
3 * Marek Lindner
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA
18 */
19
20#include "main.h"
21
22#include <linux/debugfs.h>
23
24#include "debugfs.h"
25#include "translation-table.h"
26#include "originator.h"
27#include "hard-interface.h"
28#include "gateway_common.h"
29#include "gateway_client.h"
30#include "soft-interface.h"
31#include "vis.h"
32#include "icmp_socket.h"
33#include "bridge_loop_avoidance.h"
34
35static struct dentry *batadv_debugfs;
36
37#ifdef CONFIG_BATMAN_ADV_DEBUG
38#define BATADV_LOG_BUFF_MASK (batadv_log_buff_len - 1)
39
40static const int batadv_log_buff_len = BATADV_LOG_BUF_LEN;
41
42static char *batadv_log_char_addr(struct batadv_debug_log *debug_log,
43 size_t idx)
44{
45 return &debug_log->log_buff[idx & BATADV_LOG_BUFF_MASK];
46}
47
48static void batadv_emit_log_char(struct batadv_debug_log *debug_log, char c)
49{
50 char *char_addr;
51
52 char_addr = batadv_log_char_addr(debug_log, debug_log->log_end);
53 *char_addr = c;
54 debug_log->log_end++;
55
56 if (debug_log->log_end - debug_log->log_start > batadv_log_buff_len)
57 debug_log->log_start = debug_log->log_end - batadv_log_buff_len;
58}
59
60__printf(2, 3)
61static int batadv_fdebug_log(struct batadv_debug_log *debug_log,
62 const char *fmt, ...)
63{
64 va_list args;
65 static char debug_log_buf[256];
66 char *p;
67
68 if (!debug_log)
69 return 0;
70
71 spin_lock_bh(&debug_log->lock);
72 va_start(args, fmt);
73 vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt, args);
74 va_end(args);
75
76 for (p = debug_log_buf; *p != 0; p++)
77 batadv_emit_log_char(debug_log, *p);
78
79 spin_unlock_bh(&debug_log->lock);
80
81 wake_up(&debug_log->queue_wait);
82
83 return 0;
84}
85
86int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...)
87{
88 va_list args;
89 char tmp_log_buf[256];
90
91 va_start(args, fmt);
92 vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
93 batadv_fdebug_log(bat_priv->debug_log, "[%10u] %s",
94 jiffies_to_msecs(jiffies), tmp_log_buf);
95 va_end(args);
96
97 return 0;
98}
99
100static int batadv_log_open(struct inode *inode, struct file *file)
101{
102 nonseekable_open(inode, file);
103 file->private_data = inode->i_private;
104 batadv_inc_module_count();
105 return 0;
106}
107
108static int batadv_log_release(struct inode *inode, struct file *file)
109{
110 batadv_dec_module_count();
111 return 0;
112}
113
114static ssize_t batadv_log_read(struct file *file, char __user *buf,
115 size_t count, loff_t *ppos)
116{
117 struct batadv_priv *bat_priv = file->private_data;
118 struct batadv_debug_log *debug_log = bat_priv->debug_log;
119 int error, i = 0;
120 char *char_addr;
121 char c;
122
123 if ((file->f_flags & O_NONBLOCK) &&
124 !(debug_log->log_end - debug_log->log_start))
125 return -EAGAIN;
126
127 if (!buf)
128 return -EINVAL;
129
130 if (count == 0)
131 return 0;
132
133 if (!access_ok(VERIFY_WRITE, buf, count))
134 return -EFAULT;
135
136 error = wait_event_interruptible(debug_log->queue_wait,
137 (debug_log->log_start - debug_log->log_end));
138
139 if (error)
140 return error;
141
142 spin_lock_bh(&debug_log->lock);
143
144 while ((!error) && (i < count) &&
145 (debug_log->log_start != debug_log->log_end)) {
146 char_addr = batadv_log_char_addr(debug_log,
147 debug_log->log_start);
148 c = *char_addr;
149
150 debug_log->log_start++;
151
152 spin_unlock_bh(&debug_log->lock);
153
154 error = __put_user(c, buf);
155
156 spin_lock_bh(&debug_log->lock);
157
158 buf++;
159 i++;
160
161 }
162
163 spin_unlock_bh(&debug_log->lock);
164
165 if (!error)
166 return i;
167
168 return error;
169}
170
171static unsigned int batadv_log_poll(struct file *file, poll_table *wait)
172{
173 struct batadv_priv *bat_priv = file->private_data;
174 struct batadv_debug_log *debug_log = bat_priv->debug_log;
175
176 poll_wait(file, &debug_log->queue_wait, wait);
177
178 if (debug_log->log_end - debug_log->log_start)
179 return POLLIN | POLLRDNORM;
180
181 return 0;
182}
183
184static const struct file_operations batadv_log_fops = {
185 .open = batadv_log_open,
186 .release = batadv_log_release,
187 .read = batadv_log_read,
188 .poll = batadv_log_poll,
189 .llseek = no_llseek,
190};
191
192static int batadv_debug_log_setup(struct batadv_priv *bat_priv)
193{
194 struct dentry *d;
195
196 if (!bat_priv->debug_dir)
197 goto err;
198
199 bat_priv->debug_log = kzalloc(sizeof(*bat_priv->debug_log), GFP_ATOMIC);
200 if (!bat_priv->debug_log)
201 goto err;
202
203 spin_lock_init(&bat_priv->debug_log->lock);
204 init_waitqueue_head(&bat_priv->debug_log->queue_wait);
205
206 d = debugfs_create_file("log", S_IFREG | S_IRUSR,
207 bat_priv->debug_dir, bat_priv,
208 &batadv_log_fops);
209 if (!d)
210 goto err;
211
212 return 0;
213
214err:
215 return -ENOMEM;
216}
217
218static void batadv_debug_log_cleanup(struct batadv_priv *bat_priv)
219{
220 kfree(bat_priv->debug_log);
221 bat_priv->debug_log = NULL;
222}
223#else /* CONFIG_BATMAN_ADV_DEBUG */
224static int batadv_debug_log_setup(struct batadv_priv *bat_priv)
225{
226 bat_priv->debug_log = NULL;
227 return 0;
228}
229
230static void batadv_debug_log_cleanup(struct batadv_priv *bat_priv)
231{
232 return;
233}
234#endif
235
236static int batadv_algorithms_open(struct inode *inode, struct file *file)
237{
238 return single_open(file, batadv_algo_seq_print_text, NULL);
239}
240
241static int batadv_originators_open(struct inode *inode, struct file *file)
242{
243 struct net_device *net_dev = (struct net_device *)inode->i_private;
244 return single_open(file, batadv_orig_seq_print_text, net_dev);
245}
246
247static int batadv_gateways_open(struct inode *inode, struct file *file)
248{
249 struct net_device *net_dev = (struct net_device *)inode->i_private;
250 return single_open(file, batadv_gw_client_seq_print_text, net_dev);
251}
252
253static int batadv_transtable_global_open(struct inode *inode, struct file *file)
254{
255 struct net_device *net_dev = (struct net_device *)inode->i_private;
256 return single_open(file, batadv_tt_global_seq_print_text, net_dev);
257}
258
259#ifdef CONFIG_BATMAN_ADV_BLA
260static int batadv_bla_claim_table_open(struct inode *inode, struct file *file)
261{
262 struct net_device *net_dev = (struct net_device *)inode->i_private;
263 return single_open(file, batadv_bla_claim_table_seq_print_text,
264 net_dev);
265}
266#endif
267
268static int batadv_transtable_local_open(struct inode *inode, struct file *file)
269{
270 struct net_device *net_dev = (struct net_device *)inode->i_private;
271 return single_open(file, batadv_tt_local_seq_print_text, net_dev);
272}
273
274static int batadv_vis_data_open(struct inode *inode, struct file *file)
275{
276 struct net_device *net_dev = (struct net_device *)inode->i_private;
277 return single_open(file, batadv_vis_seq_print_text, net_dev);
278}
279
280struct batadv_debuginfo {
281 struct attribute attr;
282 const struct file_operations fops;
283};
284
285#define BATADV_DEBUGINFO(_name, _mode, _open) \
286struct batadv_debuginfo batadv_debuginfo_##_name = { \
287 .attr = { .name = __stringify(_name), \
288 .mode = _mode, }, \
289 .fops = { .owner = THIS_MODULE, \
290 .open = _open, \
291 .read = seq_read, \
292 .llseek = seq_lseek, \
293 .release = single_release, \
294 } \
295};
296
297static BATADV_DEBUGINFO(routing_algos, S_IRUGO, batadv_algorithms_open);
298static BATADV_DEBUGINFO(originators, S_IRUGO, batadv_originators_open);
299static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open);
300static BATADV_DEBUGINFO(transtable_global, S_IRUGO,
301 batadv_transtable_global_open);
302#ifdef CONFIG_BATMAN_ADV_BLA
303static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open);
304#endif
305static BATADV_DEBUGINFO(transtable_local, S_IRUGO,
306 batadv_transtable_local_open);
307static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open);
308
309static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
310 &batadv_debuginfo_originators,
311 &batadv_debuginfo_gateways,
312 &batadv_debuginfo_transtable_global,
313#ifdef CONFIG_BATMAN_ADV_BLA
314 &batadv_debuginfo_bla_claim_table,
315#endif
316 &batadv_debuginfo_transtable_local,
317 &batadv_debuginfo_vis_data,
318 NULL,
319};
320
321void batadv_debugfs_init(void)
322{
323 struct batadv_debuginfo *bat_debug;
324 struct dentry *file;
325
326 batadv_debugfs = debugfs_create_dir(BATADV_DEBUGFS_SUBDIR, NULL);
327 if (batadv_debugfs == ERR_PTR(-ENODEV))
328 batadv_debugfs = NULL;
329
330 if (!batadv_debugfs)
331 goto out;
332
333 bat_debug = &batadv_debuginfo_routing_algos;
334 file = debugfs_create_file(bat_debug->attr.name,
335 S_IFREG | bat_debug->attr.mode,
336 batadv_debugfs, NULL, &bat_debug->fops);
337 if (!file)
338 pr_err("Can't add debugfs file: %s\n", bat_debug->attr.name);
339
340out:
341 return;
342}
343
344void batadv_debugfs_destroy(void)
345{
346 if (batadv_debugfs) {
347 debugfs_remove_recursive(batadv_debugfs);
348 batadv_debugfs = NULL;
349 }
350}
351
352int batadv_debugfs_add_meshif(struct net_device *dev)
353{
354 struct batadv_priv *bat_priv = netdev_priv(dev);
355 struct batadv_debuginfo **bat_debug;
356 struct dentry *file;
357
358 if (!batadv_debugfs)
359 goto out;
360
361 bat_priv->debug_dir = debugfs_create_dir(dev->name, batadv_debugfs);
362 if (!bat_priv->debug_dir)
363 goto out;
364
365 if (batadv_socket_setup(bat_priv) < 0)
366 goto rem_attr;
367
368 if (batadv_debug_log_setup(bat_priv) < 0)
369 goto rem_attr;
370
371 for (bat_debug = batadv_mesh_debuginfos; *bat_debug; ++bat_debug) {
372 file = debugfs_create_file(((*bat_debug)->attr).name,
373 S_IFREG | ((*bat_debug)->attr).mode,
374 bat_priv->debug_dir,
375 dev, &(*bat_debug)->fops);
376 if (!file) {
377 batadv_err(dev, "Can't add debugfs file: %s/%s\n",
378 dev->name, ((*bat_debug)->attr).name);
379 goto rem_attr;
380 }
381 }
382
383 return 0;
384rem_attr:
385 debugfs_remove_recursive(bat_priv->debug_dir);
386 bat_priv->debug_dir = NULL;
387out:
388#ifdef CONFIG_DEBUG_FS
389 return -ENOMEM;
390#else
391 return 0;
392#endif /* CONFIG_DEBUG_FS */
393}
394
395void batadv_debugfs_del_meshif(struct net_device *dev)
396{
397 struct batadv_priv *bat_priv = netdev_priv(dev);
398
399 batadv_debug_log_cleanup(bat_priv);
400
401 if (batadv_debugfs) {
402 debugfs_remove_recursive(bat_priv->debug_dir);
403 bat_priv->debug_dir = NULL;
404 }
405}