lttng-modules v0.19-stable: setup_trace_write: Fix recursive locking
[lttng-modules.git] / ltt-trace-control.c
1 /*
2 * LTT trace control module over debugfs.
3 *
4 * Copyright 2008 - Zhaolei <zhaolei@cn.fujitsu.com>
5 *
6 * Copyright 2009 - Gui Jianfeng <guijianfeng@cn.fujitsu.com>
7 * Make mark-control work in debugfs
8 *
9 * Dual LGPL v2.1/GPL v2 license.
10 */
11
12 /*
13 * Todo:
14 * Impl read operations for control file to read attributes
15 * Create a README file in ltt control dir, for display help info
16 */
17
18 #include <linux/module.h>
19 #include <linux/fs.h>
20 #include <linux/uaccess.h>
21 #include <linux/debugfs.h>
22 #include <linux/notifier.h>
23 #include <linux/jiffies.h>
24 #include <linux/marker.h>
25
26 #include "ltt-tracer.h"
27
28 #define LTT_CONTROL_DIR "control"
29 #define MARKERS_CONTROL_DIR "markers"
30 #define LTT_SETUP_TRACE_FILE "setup_trace"
31 #define LTT_DESTROY_TRACE_FILE "destroy_trace"
32
33 #define LTT_WRITE_MAXLEN (128)
34
35 struct dentry *ltt_control_dir, *ltt_setup_trace_file, *ltt_destroy_trace_file,
36 *markers_control_dir;
37
38 /*
39 * the traces_lock nests inside control_lock.
40 * control_lock protects the consistency of directories presented in ltt
41 * directory.
42 */
43 static DEFINE_MUTEX(control_lock);
44
45 /*
46 * big note about locking for marker control files :
47 * If a marker control file is added/removed manually racing with module
48 * load/unload, there may be warning messages appearing, but those two
49 * operations should be able to execute concurrently without any lock
50 * synchronizing their operation one wrt another.
51 * Locking the marker mutex, module mutex and also keeping a mutex here
52 * from mkdir/rmdir _and_ from the notifier called from module load/unload makes
53 * life miserable and just asks for deadlocks.
54 */
55
56 /*
57 * lookup a file/dir in parent dir.
58 * only designed to work well for debugfs.
59 * (although it maybe ok for other fs)
60 *
61 * return:
62 * file/dir's dentry on success
63 * NULL on failure
64 */
65 static struct dentry *dir_lookup(struct dentry *parent, const char *name)
66 {
67 struct qstr q;
68 struct dentry *d;
69
70 q.name = name;
71 q.len = strlen(name);
72 q.hash = full_name_hash(q.name, q.len);
73
74 d = d_lookup(parent, &q);
75 if (d)
76 dput(d);
77
78 return d;
79 }
80
81
82 static ssize_t alloc_write(struct file *file, const char __user *user_buf,
83 size_t count, loff_t *ppos)
84 {
85 int err = 0;
86 int buf_size;
87 char *buf = (char *)__get_free_page(GFP_KERNEL);
88 char *cmd = (char *)__get_free_page(GFP_KERNEL);
89
90 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
91 err = copy_from_user(buf, user_buf, buf_size);
92 if (err)
93 goto err_copy_from_user;
94 buf[buf_size] = 0;
95
96 if (sscanf(buf, "%s", cmd) != 1) {
97 err = -EPERM;
98 goto err_get_cmd;
99 }
100
101 if ((cmd[0] != 'Y' && cmd[0] != 'y' && cmd[0] != '1') || cmd[1]) {
102 err = -EPERM;
103 goto err_bad_cmd;
104 }
105
106 err = ltt_trace_alloc(file->f_dentry->d_parent->d_name.name);
107 if (IS_ERR_VALUE(err)) {
108 printk(KERN_ERR "alloc_write: ltt_trace_alloc failed: %d\n",
109 err);
110 goto err_alloc_trace;
111 }
112
113 free_page((unsigned long)buf);
114 free_page((unsigned long)cmd);
115 return count;
116
117 err_alloc_trace:
118 err_bad_cmd:
119 err_get_cmd:
120 err_copy_from_user:
121 free_page((unsigned long)buf);
122 free_page((unsigned long)cmd);
123 return err;
124 }
125
126 static const struct file_operations ltt_alloc_operations = {
127 .write = alloc_write,
128 };
129
130
131 static ssize_t enabled_write(struct file *file, const char __user *user_buf,
132 size_t count, loff_t *ppos)
133 {
134 int err = 0;
135 int buf_size;
136 char *buf = (char *)__get_free_page(GFP_KERNEL);
137 char *cmd = (char *)__get_free_page(GFP_KERNEL);
138
139 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
140 err = copy_from_user(buf, user_buf, buf_size);
141 if (err)
142 goto err_copy_from_user;
143 buf[buf_size] = 0;
144
145 if (sscanf(buf, "%s", cmd) != 1) {
146 err = -EPERM;
147 goto err_get_cmd;
148 }
149
150 if (cmd[1]) {
151 err = -EPERM;
152 goto err_bad_cmd;
153 }
154
155 switch (cmd[0]) {
156 case 'Y':
157 case 'y':
158 case '1':
159 err = ltt_trace_start(file->f_dentry->d_parent->d_name.name);
160 if (IS_ERR_VALUE(err)) {
161 printk(KERN_ERR
162 "enabled_write: ltt_trace_start failed: %d\n",
163 err);
164 err = -EPERM;
165 goto err_start_trace;
166 }
167 break;
168 case 'N':
169 case 'n':
170 case '0':
171 err = ltt_trace_stop(file->f_dentry->d_parent->d_name.name);
172 if (IS_ERR_VALUE(err)) {
173 printk(KERN_ERR
174 "enabled_write: ltt_trace_stop failed: %d\n",
175 err);
176 err = -EPERM;
177 goto err_stop_trace;
178 }
179 break;
180 default:
181 err = -EPERM;
182 goto err_bad_cmd;
183 }
184
185 free_page((unsigned long)buf);
186 free_page((unsigned long)cmd);
187 return count;
188
189 err_stop_trace:
190 err_start_trace:
191 err_bad_cmd:
192 err_get_cmd:
193 err_copy_from_user:
194 free_page((unsigned long)buf);
195 free_page((unsigned long)cmd);
196 return err;
197 }
198
199 static const struct file_operations ltt_enabled_operations = {
200 .write = enabled_write,
201 };
202
203
204 static ssize_t trans_write(struct file *file, const char __user *user_buf,
205 size_t count, loff_t *ppos)
206 {
207 char *buf = (char *)__get_free_page(GFP_KERNEL);
208 char *trans_name = (char *)__get_free_page(GFP_KERNEL);
209 int err = 0;
210 int buf_size;
211
212 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
213 err = copy_from_user(buf, user_buf, buf_size);
214 if (err)
215 goto err_copy_from_user;
216 buf[buf_size] = 0;
217
218 if (sscanf(buf, "%s", trans_name) != 1) {
219 err = -EPERM;
220 goto err_get_transname;
221 }
222
223 err = ltt_trace_set_type(file->f_dentry->d_parent->d_name.name,
224 trans_name);
225 if (IS_ERR_VALUE(err)) {
226 printk(KERN_ERR "trans_write: ltt_trace_set_type failed: %d\n",
227 err);
228 goto err_set_trans;
229 }
230
231 free_page((unsigned long)buf);
232 free_page((unsigned long)trans_name);
233 return count;
234
235 err_set_trans:
236 err_get_transname:
237 err_copy_from_user:
238 free_page((unsigned long)buf);
239 free_page((unsigned long)trans_name);
240 return err;
241 }
242
243 static const struct file_operations ltt_trans_operations = {
244 .write = trans_write,
245 };
246
247
248 static ssize_t channel_subbuf_num_write(struct file *file,
249 const char __user *user_buf, size_t count, loff_t *ppos)
250 {
251 int err = 0;
252 int buf_size;
253 unsigned int num;
254 const char *channel_name;
255 const char *trace_name;
256 char *buf = (char *)__get_free_page(GFP_KERNEL);
257
258 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
259 err = copy_from_user(buf, user_buf, buf_size);
260 if (err)
261 goto err_copy_from_user;
262 buf[buf_size] = 0;
263
264 if (sscanf(buf, "%u", &num) != 1) {
265 err = -EPERM;
266 goto err_get_number;
267 }
268
269 channel_name = file->f_dentry->d_parent->d_name.name;
270 trace_name = file->f_dentry->d_parent->d_parent->d_parent->d_name.name;
271
272 err = ltt_trace_set_channel_subbufcount(trace_name, channel_name, num);
273 if (IS_ERR_VALUE(err)) {
274 printk(KERN_ERR "channel_subbuf_num_write: "
275 "ltt_trace_set_channel_subbufcount failed: %d\n", err);
276 goto err_set_subbufcount;
277 }
278
279 free_page((unsigned long)buf);
280 return count;
281
282 err_set_subbufcount:
283 err_get_number:
284 err_copy_from_user:
285 free_page((unsigned long)buf);
286 return err;
287 }
288
289 static const struct file_operations ltt_channel_subbuf_num_operations = {
290 .write = channel_subbuf_num_write,
291 };
292
293
294 static
295 ssize_t channel_subbuf_size_write(struct file *file,
296 const char __user *user_buf,
297 size_t count, loff_t *ppos)
298 {
299 int err = 0;
300 int buf_size;
301 unsigned int num;
302 const char *channel_name;
303 const char *trace_name;
304 char *buf = (char *)__get_free_page(GFP_KERNEL);
305
306 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
307 err = copy_from_user(buf, user_buf, buf_size);
308 if (err)
309 goto err_copy_from_user;
310 buf[buf_size] = 0;
311
312 if (sscanf(buf, "%u", &num) != 1) {
313 err = -EPERM;
314 goto err_get_number;
315 }
316
317 channel_name = file->f_dentry->d_parent->d_name.name;
318 trace_name = file->f_dentry->d_parent->d_parent->d_parent->d_name.name;
319
320 err = ltt_trace_set_channel_subbufsize(trace_name, channel_name, num);
321 if (IS_ERR_VALUE(err)) {
322 printk(KERN_ERR "channel_subbuf_size_write: "
323 "ltt_trace_set_channel_subbufsize failed: %d\n", err);
324 goto err_set_subbufsize;
325 }
326
327 free_page((unsigned long)buf);
328 return count;
329
330 err_set_subbufsize:
331 err_get_number:
332 err_copy_from_user:
333 free_page((unsigned long)buf);
334 return err;
335 }
336
337 static const struct file_operations ltt_channel_subbuf_size_operations = {
338 .write = channel_subbuf_size_write,
339 };
340
341 static
342 ssize_t channel_switch_timer_write(struct file *file,
343 const char __user *user_buf,
344 size_t count, loff_t *ppos)
345 {
346 int err = 0;
347 int buf_size;
348 unsigned long num;
349 const char *channel_name;
350 const char *trace_name;
351 char *buf = (char *)__get_free_page(GFP_KERNEL);
352
353 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
354 err = copy_from_user(buf, user_buf, buf_size);
355 if (err)
356 goto err_copy_from_user;
357 buf[buf_size] = 0;
358
359 if (sscanf(buf, "%lu", &num) != 1) {
360 err = -EPERM;
361 goto err_get_number;
362 }
363
364 channel_name = file->f_dentry->d_parent->d_name.name;
365 trace_name = file->f_dentry->d_parent->d_parent->d_parent->d_name.name;
366
367 /* Convert from ms to jiffies */
368 num = msecs_to_jiffies(num);
369
370 err = ltt_trace_set_channel_switch_timer(trace_name, channel_name, num);
371 if (IS_ERR_VALUE(err)) {
372 printk(KERN_ERR "channel_switch_timer_write: "
373 "ltt_trace_set_channel_switch_timer failed: %d\n", err);
374 goto err_set_switch_timer;
375 }
376
377 free_page((unsigned long)buf);
378 return count;
379
380 err_set_switch_timer:
381 err_get_number:
382 err_copy_from_user:
383 free_page((unsigned long)buf);
384 return err;
385 }
386
387 static struct file_operations ltt_channel_switch_timer_operations = {
388 .write = channel_switch_timer_write,
389 };
390
391 static
392 ssize_t channel_overwrite_write(struct file *file,
393 const char __user *user_buf, size_t count,
394 loff_t *ppos)
395 {
396 int err = 0;
397 int buf_size;
398 const char *channel_name;
399 const char *trace_name;
400 char *buf = (char *)__get_free_page(GFP_KERNEL);
401 char *cmd = (char *)__get_free_page(GFP_KERNEL);
402
403 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
404 err = copy_from_user(buf, user_buf, buf_size);
405 if (err)
406 goto err_copy_from_user;
407 buf[buf_size] = 0;
408
409 if (sscanf(buf, "%s", cmd) != 1) {
410 err = -EPERM;
411 goto err_get_cmd;
412 }
413
414 if (cmd[1]) {
415 err = -EPERM;
416 goto err_bad_cmd;
417 }
418
419 channel_name = file->f_dentry->d_parent->d_name.name;
420 trace_name = file->f_dentry->d_parent->d_parent->d_parent->d_name.name;
421
422 switch (cmd[0]) {
423 case 'Y':
424 case 'y':
425 case '1':
426 err = ltt_trace_set_channel_overwrite(trace_name, channel_name,
427 1);
428 if (IS_ERR_VALUE(err)) {
429 printk(KERN_ERR "channel_overwrite_write: "
430 "ltt_trace_set_channel_overwrite failed: %d\n",
431 err);
432 goto err_set_subbufsize;
433 }
434 break;
435 case 'N':
436 case 'n':
437 case '0':
438 err = ltt_trace_set_channel_overwrite(trace_name, channel_name,
439 0);
440 if (IS_ERR_VALUE(err)) {
441 printk(KERN_ERR "channel_overwrite_write: "
442 "ltt_trace_set_channel_overwrite failed: %d\n",
443 err);
444 goto err_set_subbufsize;
445 }
446 break;
447 default:
448 err = -EPERM;
449 goto err_bad_cmd;
450 }
451
452 free_page((unsigned long)buf);
453 free_page((unsigned long)cmd);
454 return count;
455
456 err_set_subbufsize:
457 err_bad_cmd:
458 err_get_cmd:
459 err_copy_from_user:
460 free_page((unsigned long)buf);
461 free_page((unsigned long)cmd);
462 return err;
463 }
464
465 static const struct file_operations ltt_channel_overwrite_operations = {
466 .write = channel_overwrite_write,
467 };
468
469
470 static
471 ssize_t channel_enable_write(struct file *file,
472 const char __user *user_buf, size_t count,
473 loff_t *ppos)
474 {
475 int err = 0;
476 int buf_size;
477 const char *channel_name;
478 const char *trace_name;
479 char *buf = (char *)__get_free_page(GFP_KERNEL);
480 char *cmd = (char *)__get_free_page(GFP_KERNEL);
481
482 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
483 err = copy_from_user(buf, user_buf, buf_size);
484 if (err)
485 goto err_copy_from_user;
486 buf[buf_size] = 0;
487
488 if (sscanf(buf, "%s", cmd) != 1) {
489 err = -EPERM;
490 goto err_get_cmd;
491 }
492
493 if (cmd[1]) {
494 err = -EPERM;
495 goto err_bad_cmd;
496 }
497
498 channel_name = file->f_dentry->d_parent->d_name.name;
499 trace_name = file->f_dentry->d_parent->d_parent->d_parent->d_name.name;
500
501 switch (cmd[0]) {
502 case 'Y':
503 case 'y':
504 case '1':
505 err = ltt_trace_set_channel_enable(trace_name, channel_name,
506 1);
507 if (IS_ERR_VALUE(err)) {
508 printk(KERN_ERR "channel_enable_write: "
509 "ltt_trace_set_channel_enable failed: %d\n",
510 err);
511 goto err_set_subbufsize;
512 }
513 break;
514 case 'N':
515 case 'n':
516 case '0':
517 err = ltt_trace_set_channel_enable(trace_name, channel_name,
518 0);
519 if (IS_ERR_VALUE(err)) {
520 printk(KERN_ERR "channel_enable_write: "
521 "ltt_trace_set_channel_enable failed: %d\n",
522 err);
523 goto err_set_subbufsize;
524 }
525 break;
526 default:
527 err = -EPERM;
528 goto err_bad_cmd;
529 }
530
531 free_page((unsigned long)buf);
532 free_page((unsigned long)cmd);
533 return count;
534
535 err_set_subbufsize:
536 err_bad_cmd:
537 err_get_cmd:
538 err_copy_from_user:
539 free_page((unsigned long)buf);
540 free_page((unsigned long)cmd);
541 return err;
542 }
543
544 static const struct file_operations ltt_channel_enable_operations = {
545 .write = channel_enable_write,
546 };
547
548
549 static int _create_trace_control_dir(const char *trace_name,
550 struct ltt_trace *trace)
551 {
552 int err;
553 struct dentry *trace_root, *channel_root;
554 struct dentry *tmp_den;
555 int i;
556
557 /* debugfs/control/trace_name */
558 trace_root = debugfs_create_dir(trace_name, ltt_control_dir);
559 if (IS_ERR(trace_root) || !trace_root) {
560 printk(KERN_ERR "_create_trace_control_dir: "
561 "create control root dir of %s failed\n", trace_name);
562 err = -ENOMEM;
563 goto err_create_trace_root;
564 }
565
566 /* debugfs/control/trace_name/alloc */
567 tmp_den = debugfs_create_file("alloc", S_IWUSR, trace_root, NULL,
568 &ltt_alloc_operations);
569 if (IS_ERR(tmp_den) || !tmp_den) {
570 printk(KERN_ERR "_create_trace_control_dir: "
571 "create file of alloc failed\n");
572 err = -ENOMEM;
573 goto err_create_subdir;
574 }
575
576 /* debugfs/control/trace_name/trans */
577 tmp_den = debugfs_create_file("trans", S_IWUSR, trace_root, NULL,
578 &ltt_trans_operations);
579 if (IS_ERR(tmp_den) || !tmp_den) {
580 printk(KERN_ERR "_create_trace_control_dir: "
581 "create file of trans failed\n");
582 err = -ENOMEM;
583 goto err_create_subdir;
584 }
585
586 /* debugfs/control/trace_name/enabled */
587 tmp_den = debugfs_create_file("enabled", S_IWUSR, trace_root, NULL,
588 &ltt_enabled_operations);
589 if (IS_ERR(tmp_den) || !tmp_den) {
590 printk(KERN_ERR "_create_trace_control_dir: "
591 "create file of enabled failed\n");
592 err = -ENOMEM;
593 goto err_create_subdir;
594 }
595
596 /* debugfs/control/trace_name/channel/ */
597 channel_root = debugfs_create_dir("channel", trace_root);
598 if (IS_ERR(channel_root) || !channel_root) {
599 printk(KERN_ERR "_create_trace_control_dir: "
600 "create dir of channel failed\n");
601 err = -ENOMEM;
602 goto err_create_subdir;
603 }
604
605 /*
606 * Create dir and files in debugfs/ltt/control/trace_name/channel/
607 * Following things(without <>) will be created:
608 * `-- <control>
609 * `-- <trace_name>
610 * `-- <channel>
611 * |-- <channel_name>
612 * | |-- enable
613 * | |-- overwrite
614 * | |-- subbuf_num
615 * | |-- subbuf_size
616 * | `-- switch_timer
617 * `-- ...
618 */
619
620 for (i = 0; i < trace->nr_channels; i++) {
621 struct dentry *channel_den;
622 struct ltt_chan *chan;
623
624 chan = &trace->channels[i];
625 if (!chan->active)
626 continue;
627 channel_den = debugfs_create_dir(chan->a.filename,
628 channel_root);
629 if (IS_ERR(channel_den) || !channel_den) {
630 printk(KERN_ERR "_create_trace_control_dir: "
631 "create channel dir of %s failed\n",
632 chan->a.filename);
633 err = -ENOMEM;
634 goto err_create_subdir;
635 }
636
637 tmp_den = debugfs_create_file("subbuf_num", S_IWUSR,
638 channel_den, NULL,
639 &ltt_channel_subbuf_num_operations);
640 if (IS_ERR(tmp_den) || !tmp_den) {
641 printk(KERN_ERR "_create_trace_control_dir: "
642 "create subbuf_num in %s failed\n",
643 chan->a.filename);
644 err = -ENOMEM;
645 goto err_create_subdir;
646 }
647
648 tmp_den = debugfs_create_file("subbuf_size", S_IWUSR,
649 channel_den, NULL,
650 &ltt_channel_subbuf_size_operations);
651 if (IS_ERR(tmp_den) || !tmp_den) {
652 printk(KERN_ERR "_create_trace_control_dir: "
653 "create subbuf_size in %s failed\n",
654 chan->a.filename);
655 err = -ENOMEM;
656 goto err_create_subdir;
657 }
658
659 tmp_den = debugfs_create_file("enable", S_IWUSR, channel_den,
660 NULL,
661 &ltt_channel_enable_operations);
662 if (IS_ERR(tmp_den) || !tmp_den) {
663 printk(KERN_ERR "_create_trace_control_dir: "
664 "create enable in %s failed\n",
665 chan->a.filename);
666 err = -ENOMEM;
667 goto err_create_subdir;
668 }
669
670 tmp_den = debugfs_create_file("overwrite", S_IWUSR, channel_den,
671 NULL,
672 &ltt_channel_overwrite_operations);
673 if (IS_ERR(tmp_den) || !tmp_den) {
674 printk(KERN_ERR "_create_trace_control_dir: "
675 "create overwrite in %s failed\n",
676 chan->a.filename);
677 err = -ENOMEM;
678 goto err_create_subdir;
679 }
680
681 tmp_den = debugfs_create_file("switch_timer", S_IWUSR,
682 channel_den, NULL,
683 &ltt_channel_switch_timer_operations);
684 if (IS_ERR(tmp_den) || !tmp_den) {
685 printk(KERN_ERR "_create_trace_control_dir: "
686 "create switch_timer in %s failed\n",
687 chan->a.filename);
688 err = -ENOMEM;
689 goto err_create_subdir;
690 }
691 }
692
693 return 0;
694
695 err_create_subdir:
696 debugfs_remove_recursive(trace_root);
697 err_create_trace_root:
698 return err;
699 }
700
701 static
702 ssize_t setup_trace_write(struct file *file, const char __user *user_buf,
703 size_t count, loff_t *ppos)
704 {
705 int err = 0;
706 int buf_size;
707 struct ltt_trace *trace;
708 char *buf = (char *)__get_free_page(GFP_KERNEL);
709 char *trace_name = (char *)__get_free_page(GFP_KERNEL);
710
711 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
712 err = copy_from_user(buf, user_buf, buf_size);
713 if (err)
714 goto err_copy_from_user;
715 buf[buf_size] = 0;
716
717 if (sscanf(buf, "%s", trace_name) != 1) {
718 err = -EPERM;
719 goto err_get_tracename;
720 }
721
722 mutex_lock(&control_lock);
723 ltt_lock_traces();
724
725 err = _ltt_trace_setup(trace_name);
726 if (IS_ERR_VALUE(err)) {
727 printk(KERN_ERR
728 "setup_trace_write: ltt_trace_setup failed: %d\n", err);
729 goto err_setup_trace;
730 }
731 trace = _ltt_trace_find_setup(trace_name);
732 BUG_ON(!trace);
733 err = _create_trace_control_dir(trace_name, trace);
734 if (IS_ERR_VALUE(err)) {
735 printk(KERN_ERR "setup_trace_write: "
736 "_create_trace_control_dir failed: %d\n", err);
737 ltt_unlock_traces();
738 ltt_trace_destroy(trace_name);
739 goto err_create_trace_control_dir;
740 }
741
742 ltt_unlock_traces();
743 mutex_unlock(&control_lock);
744
745 free_page((unsigned long)buf);
746 free_page((unsigned long)trace_name);
747 return count;
748
749 err_setup_trace:
750 ltt_unlock_traces();
751 err_create_trace_control_dir:
752 mutex_unlock(&control_lock);
753 err_get_tracename:
754 err_copy_from_user:
755 free_page((unsigned long)buf);
756 free_page((unsigned long)trace_name);
757 return err;
758 }
759
760 static const struct file_operations ltt_setup_trace_operations = {
761 .write = setup_trace_write,
762 };
763
764 static
765 ssize_t destroy_trace_write(struct file *file, const char __user *user_buf,
766 size_t count, loff_t *ppos)
767 {
768 struct dentry *trace_den;
769 int buf_size;
770 int err = 0;
771 char *buf = (char *)__get_free_page(GFP_KERNEL);
772 char *trace_name = (char *)__get_free_page(GFP_KERNEL);
773
774 buf_size = min_t(size_t, count, PAGE_SIZE - 1);
775 err = copy_from_user(buf, user_buf, buf_size);
776 if (err)
777 goto err_copy_from_user;
778 buf[buf_size] = 0;
779
780 if (sscanf(buf, "%s", trace_name) != 1) {
781 err = -EPERM;
782 goto err_get_tracename;
783 }
784
785 mutex_lock(&control_lock);
786
787 err = ltt_trace_destroy(trace_name);
788 if (IS_ERR_VALUE(err)) {
789 printk(KERN_ERR
790 "destroy_trace_write: ltt_trace_destroy failed: %d\n",
791 err);
792 err = -EPERM;
793 goto err_destroy_trace;
794 }
795
796 trace_den = dir_lookup(ltt_control_dir, trace_name);
797 if (!trace_den) {
798 printk(KERN_ERR
799 "destroy_trace_write: lookup for %s's dentry failed\n",
800 trace_name);
801 err = -ENOENT;
802 goto err_get_dentry;
803 }
804
805 debugfs_remove_recursive(trace_den);
806
807 mutex_unlock(&control_lock);
808
809 free_page((unsigned long)buf);
810 free_page((unsigned long)trace_name);
811 return count;
812
813 err_get_dentry:
814 err_destroy_trace:
815 mutex_unlock(&control_lock);
816 err_get_tracename:
817 err_copy_from_user:
818 free_page((unsigned long)buf);
819 free_page((unsigned long)trace_name);
820 return err;
821 }
822
823 static const struct file_operations ltt_destroy_trace_operations = {
824 .write = destroy_trace_write,
825 };
826
827 static void init_marker_dir(struct dentry *dentry,
828 const struct inode_operations *opt)
829 {
830 dentry->d_inode->i_op = opt;
831 }
832
833 static
834 ssize_t marker_enable_read(struct file *filp, char __user *ubuf,
835 size_t cnt, loff_t *ppos)
836 {
837 char *buf;
838 const char *channel, *marker;
839 int len, enabled, present;
840
841 marker = filp->f_dentry->d_parent->d_name.name;
842 channel = filp->f_dentry->d_parent->d_parent->d_name.name;
843
844 len = 0;
845 buf = (char *)__get_free_page(GFP_KERNEL);
846
847 /*
848 * Note: we cannot take the marker lock to make these two checks
849 * atomic, because the marker mutex nests inside the module mutex, taken
850 * inside the marker present check.
851 */
852 enabled = is_marker_enabled(channel, marker);
853 present = is_marker_present(channel, marker);
854
855 if (enabled && present)
856 len = snprintf(buf, PAGE_SIZE, "%d\n", 1);
857 else if (enabled && !present)
858 len = snprintf(buf, PAGE_SIZE, "%d\n", 2);
859 else
860 len = snprintf(buf, PAGE_SIZE, "%d\n", 0);
861
862
863 if (len >= PAGE_SIZE) {
864 len = PAGE_SIZE;
865 buf[PAGE_SIZE] = '\0';
866 }
867 len = simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
868 free_page((unsigned long)buf);
869
870 return len;
871 }
872
873 static
874 ssize_t marker_enable_write(struct file *filp, const char __user *ubuf,
875 size_t cnt, loff_t *ppos)
876 {
877 char *buf = (char *)__get_free_page(GFP_KERNEL);
878 int buf_size;
879 ssize_t ret = 0;
880 const char *channel, *marker;
881
882 marker = filp->f_dentry->d_parent->d_name.name;
883 channel = filp->f_dentry->d_parent->d_parent->d_name.name;
884
885 buf_size = min_t(size_t, cnt, PAGE_SIZE - 1);
886 ret = copy_from_user(buf, ubuf, buf_size);
887 if (ret)
888 goto end;
889
890 buf[buf_size] = 0;
891
892 switch (buf[0]) {
893 case 'Y':
894 case 'y':
895 case '1':
896 ret = ltt_marker_connect(channel, marker, "default");
897 if (ret)
898 goto end;
899 break;
900 case 'N':
901 case 'n':
902 case '0':
903 ret = ltt_marker_disconnect(channel, marker, "default");
904 if (ret)
905 goto end;
906 break;
907 default:
908 ret = -EPERM;
909 goto end;
910 }
911 ret = cnt;
912 end:
913 free_page((unsigned long)buf);
914 return ret;
915 }
916
917 static const struct file_operations enable_fops = {
918 .read = marker_enable_read,
919 .write = marker_enable_write,
920 };
921
922 /*
923 * In practice, the output size should never be larger than 4096 kB. If it
924 * ever happens, the output will simply be truncated.
925 */
926 static
927 ssize_t marker_info_read(struct file *filp, char __user *ubuf,
928 size_t cnt, loff_t *ppos)
929 {
930 char *buf;
931 const char *channel, *marker;
932 int len;
933 struct marker_iter iter;
934
935 marker = filp->f_dentry->d_parent->d_name.name;
936 channel = filp->f_dentry->d_parent->d_parent->d_name.name;
937
938 len = 0;
939 buf = (char *)__get_free_page(GFP_KERNEL);
940
941 if (is_marker_enabled(channel, marker) &&
942 !is_marker_present(channel, marker)) {
943 len += snprintf(buf + len, PAGE_SIZE - len,
944 "Marker Pre-enabled\n");
945 goto out;
946 }
947
948 marker_iter_reset(&iter);
949 marker_iter_start(&iter);
950 for (; iter.marker != NULL; marker_iter_next(&iter)) {
951 if (!strcmp(iter.marker->channel, channel) &&
952 !strcmp(iter.marker->name, marker))
953 len += snprintf(buf + len, PAGE_SIZE - len,
954 "Location: %s\n"
955 "format: \"%s\"\nstate: %d\n"
956 "event_id: %hu\n"
957 "call: 0x%p\n"
958 "probe %s : 0x%p\n\n",
959 #ifdef CONFIG_MODULES
960 iter.module ? iter.module->name :
961 #endif
962 "Core Kernel",
963 iter.marker->format,
964 _imv_read(iter.marker->state),
965 iter.marker->event_id,
966 iter.marker->call,
967 iter.marker->ptype ?
968 "multi" : "single", iter.marker->ptype ?
969 (void *)iter.marker->multi :
970 (void *)iter.marker->single.func);
971 if (len >= PAGE_SIZE)
972 break;
973 }
974 marker_iter_stop(&iter);
975
976 out:
977 if (len >= PAGE_SIZE) {
978 len = PAGE_SIZE;
979 buf[PAGE_SIZE] = '\0';
980 }
981
982 len = simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
983 free_page((unsigned long)buf);
984
985 return len;
986 }
987
988 static const struct file_operations info_fops = {
989 .read = marker_info_read,
990 };
991
992 static int marker_mkdir(struct inode *dir, struct dentry *dentry, int mode)
993 {
994 struct dentry *marker_d, *enable_d, *info_d, *channel_d;
995 int ret;
996
997 ret = 0;
998 channel_d = (struct dentry *)dir->i_private;
999 mutex_unlock(&dir->i_mutex);
1000
1001 marker_d = debugfs_create_dir(dentry->d_name.name,
1002 channel_d);
1003 if (IS_ERR(marker_d)) {
1004 ret = PTR_ERR(marker_d);
1005 goto out;
1006 }
1007
1008 enable_d = debugfs_create_file("enable", 0644, marker_d,
1009 NULL, &enable_fops);
1010 if (IS_ERR(enable_d) || !enable_d) {
1011 printk(KERN_ERR
1012 "%s: create file of %s failed\n",
1013 __func__, "enable");
1014 ret = -ENOMEM;
1015 goto remove_marker_dir;
1016 }
1017
1018 info_d = debugfs_create_file("info", 0644, marker_d,
1019 NULL, &info_fops);
1020 if (IS_ERR(info_d) || !info_d) {
1021 printk(KERN_ERR
1022 "%s: create file of %s failed\n",
1023 __func__, "info");
1024 ret = -ENOMEM;
1025 goto remove_enable_dir;
1026 }
1027
1028 goto out;
1029
1030 remove_enable_dir:
1031 debugfs_remove(enable_d);
1032 remove_marker_dir:
1033 debugfs_remove(marker_d);
1034 out:
1035 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
1036 return ret;
1037 }
1038
1039 static int marker_rmdir(struct inode *dir, struct dentry *dentry)
1040 {
1041 struct dentry *marker_d, *channel_d;
1042 const char *channel, *name;
1043 int ret, enabled, present;
1044
1045 ret = 0;
1046
1047 channel_d = (struct dentry *)dir->i_private;
1048 channel = channel_d->d_name.name;
1049
1050 marker_d = dir_lookup(channel_d, dentry->d_name.name);
1051
1052 if (!marker_d) {
1053 ret = -ENOENT;
1054 goto out;
1055 }
1056
1057 name = marker_d->d_name.name;
1058
1059 enabled = is_marker_enabled(channel, name);
1060 present = is_marker_present(channel, name);
1061
1062 if (present || (!present && enabled)) {
1063 ret = -EPERM;
1064 goto out;
1065 }
1066
1067 mutex_unlock(&dir->i_mutex);
1068 mutex_unlock(&dentry->d_inode->i_mutex);
1069 debugfs_remove_recursive(marker_d);
1070 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
1071 mutex_lock(&dentry->d_inode->i_mutex);
1072 out:
1073 return ret;
1074 }
1075
1076 const struct inode_operations channel_dir_opt = {
1077 .lookup = simple_lookup,
1078 .mkdir = marker_mkdir,
1079 .rmdir = marker_rmdir,
1080 };
1081
1082 static int channel_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1083 {
1084 struct dentry *channel_d;
1085 int ret;
1086
1087 ret = 0;
1088 mutex_unlock(&dir->i_mutex);
1089
1090 channel_d = debugfs_create_dir(dentry->d_name.name,
1091 markers_control_dir);
1092 if (IS_ERR(channel_d)) {
1093 ret = PTR_ERR(channel_d);
1094 goto out;
1095 }
1096
1097 channel_d->d_inode->i_private = (void *)channel_d;
1098 init_marker_dir(channel_d, &channel_dir_opt);
1099 out:
1100 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
1101 return ret;
1102 }
1103
1104 static int channel_rmdir(struct inode *dir, struct dentry *dentry)
1105 {
1106 struct dentry *channel_d;
1107 int ret;
1108
1109 ret = 0;
1110
1111 channel_d = dir_lookup(markers_control_dir, dentry->d_name.name);
1112 if (!channel_d) {
1113 ret = -ENOENT;
1114 goto out;
1115 }
1116
1117 if (list_empty(&channel_d->d_subdirs)) {
1118 mutex_unlock(&dir->i_mutex);
1119 mutex_unlock(&dentry->d_inode->i_mutex);
1120 debugfs_remove(channel_d);
1121 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
1122 mutex_lock(&dentry->d_inode->i_mutex);
1123 } else
1124 ret = -EPERM;
1125
1126 out:
1127 return ret;
1128 }
1129
1130 const struct inode_operations root_dir_opt = {
1131 .lookup = simple_lookup,
1132 .mkdir = channel_mkdir,
1133 .rmdir = channel_rmdir
1134 };
1135
1136 static int build_marker_file(struct marker *marker)
1137 {
1138 struct dentry *channel_d, *marker_d, *enable_d, *info_d;
1139 int err;
1140
1141 channel_d = dir_lookup(markers_control_dir, marker->channel);
1142 if (!channel_d) {
1143 channel_d = debugfs_create_dir(marker->channel,
1144 markers_control_dir);
1145 if (IS_ERR(channel_d) || !channel_d) {
1146 printk(KERN_ERR
1147 "%s: build channel dir of %s failed\n",
1148 __func__, marker->channel);
1149 err = -ENOMEM;
1150 goto err_build_fail;
1151 }
1152 channel_d->d_inode->i_private = (void *)channel_d;
1153 init_marker_dir(channel_d, &channel_dir_opt);
1154 }
1155
1156 marker_d = dir_lookup(channel_d, marker->name);
1157 if (!marker_d) {
1158 marker_d = debugfs_create_dir(marker->name, channel_d);
1159 if (IS_ERR(marker_d) || !marker_d) {
1160 printk(KERN_ERR
1161 "%s: marker dir of %s failed\n",
1162 __func__, marker->name);
1163 err = -ENOMEM;
1164 goto err_build_fail;
1165 }
1166 }
1167
1168 enable_d = dir_lookup(marker_d, "enable");
1169 if (!enable_d) {
1170 enable_d = debugfs_create_file("enable", 0644, marker_d,
1171 NULL, &enable_fops);
1172 if (IS_ERR(enable_d) || !enable_d) {
1173 printk(KERN_ERR
1174 "%s: create file of %s failed\n",
1175 __func__, "enable");
1176 err = -ENOMEM;
1177 goto err_build_fail;
1178 }
1179 }
1180
1181 info_d = dir_lookup(marker_d, "info");
1182 if (!info_d) {
1183 info_d = debugfs_create_file("info", 0444, marker_d,
1184 NULL, &info_fops);
1185 if (IS_ERR(info_d) || !info_d) {
1186 printk(KERN_ERR
1187 "%s: create file of %s failed\n",
1188 __func__, "enable");
1189 err = -ENOMEM;
1190 goto err_build_fail;
1191 }
1192 }
1193
1194 return 0;
1195
1196 err_build_fail:
1197 return err;
1198 }
1199
1200 static int build_marker_control_files(void)
1201 {
1202 struct marker_iter iter;
1203 int err;
1204
1205 err = 0;
1206 if (!markers_control_dir)
1207 return -EEXIST;
1208
1209 marker_iter_reset(&iter);
1210 marker_iter_start(&iter);
1211 for (; iter.marker != NULL; marker_iter_next(&iter)) {
1212 err = build_marker_file(iter.marker);
1213 if (err)
1214 goto out;
1215 }
1216 marker_iter_stop(&iter);
1217
1218 out:
1219 return err;
1220 }
1221
1222 #ifdef CONFIG_MODULES
1223 static int remove_marker_control_dir(struct module *mod, struct marker *marker)
1224 {
1225 struct dentry *channel_d, *marker_d;
1226 const char *channel, *name;
1227 int count;
1228 struct marker_iter iter;
1229
1230 count = 0;
1231
1232 channel_d = dir_lookup(markers_control_dir, marker->channel);
1233 if (!channel_d)
1234 return -ENOENT;
1235 channel = channel_d->d_name.name;
1236
1237 marker_d = dir_lookup(channel_d, marker->name);
1238 if (!marker_d)
1239 return -ENOENT;
1240 name = marker_d->d_name.name;
1241
1242 marker_iter_reset(&iter);
1243 marker_iter_start(&iter);
1244 for (; iter.marker != NULL; marker_iter_next(&iter)) {
1245 if (!strcmp(iter.marker->channel, channel) &&
1246 !strcmp(iter.marker->name, name) && mod != iter.module)
1247 count++;
1248 }
1249
1250 if (count > 0)
1251 goto end;
1252
1253 debugfs_remove_recursive(marker_d);
1254 if (list_empty(&channel_d->d_subdirs))
1255 debugfs_remove(channel_d);
1256
1257 end:
1258 marker_iter_stop(&iter);
1259 return 0;
1260 }
1261
1262 static void cleanup_control_dir(struct module *mod, struct marker *begin,
1263 struct marker *end)
1264 {
1265 struct marker *iter;
1266
1267 if (!markers_control_dir)
1268 return;
1269
1270 for (iter = begin; iter < end; iter++)
1271 remove_marker_control_dir(mod, iter);
1272
1273 return;
1274 }
1275
1276 static void build_control_dir(struct module *mod, struct marker *begin,
1277 struct marker *end)
1278 {
1279 struct marker *iter;
1280 int err;
1281
1282 err = 0;
1283 if (!markers_control_dir)
1284 return;
1285
1286 for (iter = begin; iter < end; iter++) {
1287 err = build_marker_file(iter);
1288 if (err)
1289 goto err_build_fail;
1290 }
1291
1292 return;
1293 err_build_fail:
1294 cleanup_control_dir(mod, begin, end);
1295 }
1296
1297 static int module_notify(struct notifier_block *self,
1298 unsigned long val, void *data)
1299 {
1300 struct module *mod = data;
1301
1302 switch (val) {
1303 case MODULE_STATE_COMING:
1304 build_control_dir(mod, mod->markers,
1305 mod->markers + mod->num_markers);
1306 break;
1307 case MODULE_STATE_GOING:
1308 cleanup_control_dir(mod, mod->markers,
1309 mod->markers + mod->num_markers);
1310 break;
1311 }
1312 return NOTIFY_DONE;
1313 }
1314 #else
1315 static inline int module_notify(struct notifier_block *self,
1316 unsigned long val, void *data)
1317 {
1318 return 0;
1319 }
1320 #endif
1321
1322 static struct notifier_block module_nb = {
1323 .notifier_call = module_notify,
1324 };
1325
1326 static int __init ltt_trace_control_init(void)
1327 {
1328 int err = 0;
1329 struct dentry *ltt_root_dentry;
1330
1331 ltt_root_dentry = get_ltt_root();
1332 if (!ltt_root_dentry) {
1333 err = -ENOENT;
1334 goto err_no_root;
1335 }
1336
1337 ltt_control_dir = debugfs_create_dir(LTT_CONTROL_DIR, ltt_root_dentry);
1338 if (IS_ERR(ltt_control_dir) || !ltt_control_dir) {
1339 printk(KERN_ERR
1340 "ltt_channel_control_init: create dir of %s failed\n",
1341 LTT_CONTROL_DIR);
1342 err = -ENOMEM;
1343 goto err_create_control_dir;
1344 }
1345
1346 ltt_setup_trace_file = debugfs_create_file(LTT_SETUP_TRACE_FILE,
1347 S_IWUSR, ltt_root_dentry,
1348 NULL,
1349 &ltt_setup_trace_operations);
1350 if (IS_ERR(ltt_setup_trace_file) || !ltt_setup_trace_file) {
1351 printk(KERN_ERR
1352 "ltt_channel_control_init: create file of %s failed\n",
1353 LTT_SETUP_TRACE_FILE);
1354 err = -ENOMEM;
1355 goto err_create_setup_trace_file;
1356 }
1357
1358 ltt_destroy_trace_file = debugfs_create_file(LTT_DESTROY_TRACE_FILE,
1359 S_IWUSR, ltt_root_dentry,
1360 NULL,
1361 &ltt_destroy_trace_operations);
1362 if (IS_ERR(ltt_destroy_trace_file) || !ltt_destroy_trace_file) {
1363 printk(KERN_ERR
1364 "ltt_channel_control_init: create file of %s failed\n",
1365 LTT_DESTROY_TRACE_FILE);
1366 err = -ENOMEM;
1367 goto err_create_destroy_trace_file;
1368 }
1369
1370 markers_control_dir = debugfs_create_dir(MARKERS_CONTROL_DIR,
1371 ltt_root_dentry);
1372 if (IS_ERR(markers_control_dir) || !markers_control_dir) {
1373 printk(KERN_ERR
1374 "ltt_channel_control_init: create dir of %s failed\n",
1375 MARKERS_CONTROL_DIR);
1376 err = -ENOMEM;
1377 goto err_create_marker_control_dir;
1378 }
1379
1380 init_marker_dir(markers_control_dir, &root_dir_opt);
1381
1382 if (build_marker_control_files())
1383 goto err_build_fail;
1384
1385 if (!register_module_notifier(&module_nb))
1386 return 0;
1387
1388 err_build_fail:
1389 debugfs_remove_recursive(markers_control_dir);
1390 markers_control_dir = NULL;
1391 err_create_marker_control_dir:
1392 debugfs_remove(ltt_destroy_trace_file);
1393 err_create_destroy_trace_file:
1394 debugfs_remove(ltt_setup_trace_file);
1395 err_create_setup_trace_file:
1396 debugfs_remove(ltt_control_dir);
1397 err_create_control_dir:
1398 err_no_root:
1399 return err;
1400 }
1401
1402 static void __exit ltt_trace_control_exit(void)
1403 {
1404 struct dentry *trace_dir;
1405
1406 /* destory all traces */
1407 list_for_each_entry(trace_dir, &ltt_control_dir->d_subdirs,
1408 d_u.d_child) {
1409 ltt_trace_stop(trace_dir->d_name.name);
1410 ltt_trace_destroy(trace_dir->d_name.name);
1411 }
1412
1413 /* clean dirs in debugfs */
1414 debugfs_remove(ltt_setup_trace_file);
1415 debugfs_remove(ltt_destroy_trace_file);
1416 debugfs_remove_recursive(ltt_control_dir);
1417 debugfs_remove_recursive(markers_control_dir);
1418 unregister_module_notifier(&module_nb);
1419 put_ltt_root();
1420 }
1421
1422 module_init(ltt_trace_control_init);
1423 module_exit(ltt_trace_control_exit);
1424
1425 MODULE_LICENSE("GPL and additional rights");
1426 MODULE_AUTHOR("Zhao Lei <zhaolei@cn.fujitsu.com>");
1427 MODULE_DESCRIPTION("Linux Trace Toolkit Trace Controller");
This page took 0.094645 seconds and 4 git commands to generate.