4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2012, 2015 Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 #include <linux/module.h>
37 #include <linux/kernel.h>
39 #include <linux/string.h>
40 #include <linux/stat.h>
41 #include <linux/errno.h>
42 #include <linux/unistd.h>
44 #include <linux/uio.h>
46 #include <linux/uaccess.h>
49 #include <linux/file.h>
50 #include <linux/list.h>
52 #include <linux/sysctl.h>
53 #include <linux/debugfs.h>
55 # define DEBUG_SUBSYSTEM S_LNET
57 #include "../../include/linux/libcfs/libcfs.h"
58 #include <asm/div64.h>
60 #include "../../include/linux/libcfs/libcfs_crypto.h"
61 #include "../../include/linux/lnet/lib-lnet.h"
62 #include "../../include/linux/lnet/lib-dlc.h"
63 #include "../../include/linux/lnet/lnet.h"
64 #include "tracefile.h"
66 static struct dentry
*lnet_debugfs_root
;
68 /* called when opening /dev/device */
69 static int libcfs_psdev_open(unsigned long flags
, void *args
)
71 try_module_get(THIS_MODULE
);
75 /* called when closing /dev/device */
76 static int libcfs_psdev_release(unsigned long flags
, void *args
)
78 module_put(THIS_MODULE
);
82 static DECLARE_RWSEM(ioctl_list_sem
);
83 static LIST_HEAD(ioctl_list
);
85 int libcfs_register_ioctl(struct libcfs_ioctl_handler
*hand
)
89 down_write(&ioctl_list_sem
);
90 if (!list_empty(&hand
->item
))
93 list_add_tail(&hand
->item
, &ioctl_list
);
94 up_write(&ioctl_list_sem
);
98 EXPORT_SYMBOL(libcfs_register_ioctl
);
100 int libcfs_deregister_ioctl(struct libcfs_ioctl_handler
*hand
)
104 down_write(&ioctl_list_sem
);
105 if (list_empty(&hand
->item
))
108 list_del_init(&hand
->item
);
109 up_write(&ioctl_list_sem
);
113 EXPORT_SYMBOL(libcfs_deregister_ioctl
);
115 static int libcfs_ioctl(struct cfs_psdev_file
*pfile
, unsigned long cmd
,
118 struct libcfs_ioctl_data
*data
= NULL
;
119 struct libcfs_ioctl_hdr
*hdr
;
122 /* 'cmd' and permissions get checked in our arch-specific caller */
123 err
= libcfs_ioctl_getdata(&hdr
, uparam
);
125 CDEBUG_LIMIT(D_ERROR
,
126 "libcfs ioctl: data header error %d\n", err
);
130 if (hdr
->ioc_version
== LIBCFS_IOCTL_VERSION
) {
132 * The libcfs_ioctl_data_adjust() function performs adjustment
133 * operations on the libcfs_ioctl_data structure to make
134 * it usable by the code. This doesn't need to be called
135 * for new data structures added.
137 data
= container_of(hdr
, struct libcfs_ioctl_data
, ioc_hdr
);
138 err
= libcfs_ioctl_data_adjust(data
);
143 CDEBUG(D_IOCTL
, "libcfs ioctl cmd %lu\n", cmd
);
145 case IOC_LIBCFS_CLEAR_DEBUG
:
146 libcfs_debug_clear_buffer();
149 * case IOC_LIBCFS_PANIC:
150 * Handled in arch/cfs_module.c
152 case IOC_LIBCFS_MARK_DEBUG
:
153 if (!data
|| !data
->ioc_inlbuf1
||
154 data
->ioc_inlbuf1
[data
->ioc_inllen1
- 1] != '\0') {
158 libcfs_debug_mark_buffer(data
->ioc_inlbuf1
);
162 struct libcfs_ioctl_handler
*hand
;
165 down_read(&ioctl_list_sem
);
166 list_for_each_entry(hand
, &ioctl_list
, item
) {
167 err
= hand
->handle_ioctl(cmd
, hdr
);
172 err
= libcfs_ioctl_popdata(uparam
, hdr
,
176 up_read(&ioctl_list_sem
);
180 LIBCFS_FREE(hdr
, hdr
->ioc_len
);
184 struct cfs_psdev_ops libcfs_psdev_ops
= {
186 libcfs_psdev_release
,
192 int lprocfs_call_handler(void *data
, int write
, loff_t
*ppos
,
193 void __user
*buffer
, size_t *lenp
,
194 int (*handler
)(void *data
, int write
, loff_t pos
,
195 void __user
*buffer
, int len
))
197 int rc
= handler(data
, write
, *ppos
, buffer
, *lenp
);
210 EXPORT_SYMBOL(lprocfs_call_handler
);
212 static int __proc_dobitmasks(void *data
, int write
,
213 loff_t pos
, void __user
*buffer
, int nob
)
215 const int tmpstrlen
= 512;
218 unsigned int *mask
= data
;
219 int is_subsys
= (mask
== &libcfs_subsystem_debug
) ? 1 : 0;
220 int is_printk
= (mask
== &libcfs_printk
) ? 1 : 0;
222 rc
= cfs_trace_allocate_string_buffer(&tmpstr
, tmpstrlen
);
227 libcfs_debug_mask2str(tmpstr
, tmpstrlen
, *mask
, is_subsys
);
233 rc
= cfs_trace_copyout_string(buffer
, nob
,
237 rc
= cfs_trace_copyin_string(tmpstr
, tmpstrlen
, buffer
, nob
);
243 rc
= libcfs_debug_str2mask(mask
, tmpstr
, is_subsys
);
244 /* Always print LBUG/LASSERT to console, so keep this mask */
253 static int proc_dobitmasks(struct ctl_table
*table
, int write
,
254 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
256 return lprocfs_call_handler(table
->data
, write
, ppos
, buffer
, lenp
,
260 static int __proc_dump_kernel(void *data
, int write
,
261 loff_t pos
, void __user
*buffer
, int nob
)
266 return cfs_trace_dump_debug_buffer_usrstr(buffer
, nob
);
269 static int proc_dump_kernel(struct ctl_table
*table
, int write
,
270 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
272 return lprocfs_call_handler(table
->data
, write
, ppos
, buffer
, lenp
,
276 static int __proc_daemon_file(void *data
, int write
,
277 loff_t pos
, void __user
*buffer
, int nob
)
280 int len
= strlen(cfs_tracefile
);
285 return cfs_trace_copyout_string(buffer
, nob
,
286 cfs_tracefile
+ pos
, "\n");
289 return cfs_trace_daemon_command_usrstr(buffer
, nob
);
292 static int proc_daemon_file(struct ctl_table
*table
, int write
,
293 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
295 return lprocfs_call_handler(table
->data
, write
, ppos
, buffer
, lenp
,
299 static int libcfs_force_lbug(struct ctl_table
*table
, int write
,
301 size_t *lenp
, loff_t
*ppos
)
308 static int proc_fail_loc(struct ctl_table
*table
, int write
,
310 size_t *lenp
, loff_t
*ppos
)
313 long old_fail_loc
= cfs_fail_loc
;
315 rc
= proc_doulongvec_minmax(table
, write
, buffer
, lenp
, ppos
);
316 if (old_fail_loc
!= cfs_fail_loc
)
317 wake_up(&cfs_race_waitq
);
321 static int __proc_cpt_table(void *data
, int write
,
322 loff_t pos
, void __user
*buffer
, int nob
)
331 LASSERT(cfs_cpt_table
);
334 LIBCFS_ALLOC(buf
, len
);
338 rc
= cfs_cpt_table_print(cfs_cpt_table
, buf
, len
);
343 LIBCFS_FREE(buf
, len
);
355 rc
= cfs_trace_copyout_string(buffer
, nob
, buf
+ pos
, NULL
);
358 LIBCFS_FREE(buf
, len
);
362 static int proc_cpt_table(struct ctl_table
*table
, int write
,
363 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
365 return lprocfs_call_handler(table
->data
, write
, ppos
, buffer
, lenp
,
369 static struct ctl_table lnet_table
[] = {
372 .data
= &libcfs_debug
,
373 .maxlen
= sizeof(int),
375 .proc_handler
= &proc_dobitmasks
,
378 .procname
= "subsystem_debug",
379 .data
= &libcfs_subsystem_debug
,
380 .maxlen
= sizeof(int),
382 .proc_handler
= &proc_dobitmasks
,
385 .procname
= "printk",
386 .data
= &libcfs_printk
,
387 .maxlen
= sizeof(int),
389 .proc_handler
= &proc_dobitmasks
,
392 .procname
= "cpu_partition_table",
395 .proc_handler
= &proc_cpt_table
,
399 .procname
= "upcall",
401 .maxlen
= sizeof(lnet_upcall
),
403 .proc_handler
= &proc_dostring
,
406 .procname
= "debug_log_upcall",
407 .data
= lnet_debug_log_upcall
,
408 .maxlen
= sizeof(lnet_debug_log_upcall
),
410 .proc_handler
= &proc_dostring
,
413 .procname
= "catastrophe",
414 .data
= &libcfs_catastrophe
,
415 .maxlen
= sizeof(int),
417 .proc_handler
= &proc_dointvec
,
420 .procname
= "dump_kernel",
423 .proc_handler
= &proc_dump_kernel
,
426 .procname
= "daemon_file",
429 .proc_handler
= &proc_daemon_file
,
432 .procname
= "force_lbug",
436 .proc_handler
= &libcfs_force_lbug
439 .procname
= "fail_loc",
440 .data
= &cfs_fail_loc
,
441 .maxlen
= sizeof(cfs_fail_loc
),
443 .proc_handler
= &proc_fail_loc
446 .procname
= "fail_val",
447 .data
= &cfs_fail_val
,
448 .maxlen
= sizeof(int),
450 .proc_handler
= &proc_dointvec
456 static const struct lnet_debugfs_symlink_def lnet_debugfs_symlinks
[] = {
457 { "console_ratelimit",
458 "/sys/module/libcfs/parameters/libcfs_console_ratelimit"},
460 "/sys/module/libcfs/parameters/libcfs_debug_file_path"},
462 "/sys/module/libcfs/parameters/libcfs_panic_on_lbug"},
463 { "libcfs_console_backoff",
464 "/sys/module/libcfs/parameters/libcfs_console_backoff"},
466 "/sys/module/libcfs/parameters/libcfs_debug_mb"},
467 { "console_min_delay_centisecs",
468 "/sys/module/libcfs/parameters/libcfs_console_min_delay"},
469 { "console_max_delay_centisecs",
470 "/sys/module/libcfs/parameters/libcfs_console_max_delay"},
474 static ssize_t
lnet_debugfs_read(struct file
*filp
, char __user
*buf
,
475 size_t count
, loff_t
*ppos
)
477 struct ctl_table
*table
= filp
->private_data
;
480 error
= table
->proc_handler(table
, 0, (void __user
*)buf
, &count
, ppos
);
487 static ssize_t
lnet_debugfs_write(struct file
*filp
, const char __user
*buf
,
488 size_t count
, loff_t
*ppos
)
490 struct ctl_table
*table
= filp
->private_data
;
493 error
= table
->proc_handler(table
, 1, (void __user
*)buf
, &count
, ppos
);
500 static const struct file_operations lnet_debugfs_file_operations_rw
= {
502 .read
= lnet_debugfs_read
,
503 .write
= lnet_debugfs_write
,
504 .llseek
= default_llseek
,
507 static const struct file_operations lnet_debugfs_file_operations_ro
= {
509 .read
= lnet_debugfs_read
,
510 .llseek
= default_llseek
,
513 static const struct file_operations lnet_debugfs_file_operations_wo
= {
515 .write
= lnet_debugfs_write
,
516 .llseek
= default_llseek
,
519 static const struct file_operations
*lnet_debugfs_fops_select(umode_t mode
)
521 if (!(mode
& S_IWUGO
))
522 return &lnet_debugfs_file_operations_ro
;
524 if (!(mode
& S_IRUGO
))
525 return &lnet_debugfs_file_operations_wo
;
527 return &lnet_debugfs_file_operations_rw
;
530 void lustre_insert_debugfs(struct ctl_table
*table
,
531 const struct lnet_debugfs_symlink_def
*symlinks
)
533 if (!lnet_debugfs_root
)
534 lnet_debugfs_root
= debugfs_create_dir("lnet", NULL
);
536 /* Even if we cannot create, just ignore it altogether) */
537 if (IS_ERR_OR_NULL(lnet_debugfs_root
))
540 /* We don't save the dentry returned in next two calls, because
541 * we don't call debugfs_remove() but rather remove_recursive()
543 for (; table
->procname
; table
++)
544 debugfs_create_file(table
->procname
, table
->mode
,
545 lnet_debugfs_root
, table
,
546 lnet_debugfs_fops_select(table
->mode
));
548 for (; symlinks
&& symlinks
->name
; symlinks
++)
549 debugfs_create_symlink(symlinks
->name
, lnet_debugfs_root
,
552 EXPORT_SYMBOL_GPL(lustre_insert_debugfs
);
554 static void lustre_remove_debugfs(void)
556 debugfs_remove_recursive(lnet_debugfs_root
);
558 lnet_debugfs_root
= NULL
;
561 static int libcfs_init(void)
565 rc
= libcfs_debug_init(5 * 1024 * 1024);
567 pr_err("LustreError: libcfs_debug_init: %d\n", rc
);
575 rc
= misc_register(&libcfs_dev
);
577 CERROR("misc_register: error %d\n", rc
);
581 rc
= cfs_wi_startup();
583 CERROR("initialize workitem: error %d\n", rc
);
584 goto cleanup_deregister
;
587 /* max to 4 threads, should be enough for rehash */
588 rc
= min(cfs_cpt_weight(cfs_cpt_table
, CFS_CPT_ANY
), 4);
589 rc
= cfs_wi_sched_create("cfs_rh", cfs_cpt_table
, CFS_CPT_ANY
,
590 rc
, &cfs_sched_rehash
);
592 CERROR("Startup workitem scheduler: error: %d\n", rc
);
593 goto cleanup_deregister
;
596 rc
= cfs_crypto_register();
598 CERROR("cfs_crypto_register: error %d\n", rc
);
602 lustre_insert_debugfs(lnet_table
, lnet_debugfs_symlinks
);
604 CDEBUG(D_OTHER
, "portals setup OK\n");
609 misc_deregister(&libcfs_dev
);
613 libcfs_debug_cleanup();
617 static void libcfs_exit(void)
621 lustre_remove_debugfs();
623 if (cfs_sched_rehash
) {
624 cfs_wi_sched_destroy(cfs_sched_rehash
);
625 cfs_sched_rehash
= NULL
;
628 cfs_crypto_unregister();
631 misc_deregister(&libcfs_dev
);
635 rc
= libcfs_debug_cleanup();
637 pr_err("LustreError: libcfs_debug_cleanup: %d\n", rc
);
640 MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
641 MODULE_DESCRIPTION("Lustre helper library");
642 MODULE_VERSION(LIBCFS_VERSION
);
643 MODULE_LICENSE("GPL");
645 module_init(libcfs_init
);
646 module_exit(libcfs_exit
);