Whamcloud - gitweb
LU-8066 libcfs: migrate to debugfs 88/24688/28
authorDmitry Eremin <dmitry.eremin@intel.com>
Fri, 28 Jul 2017 20:51:52 +0000 (16:51 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 5 Aug 2017 05:10:46 +0000 (05:10 +0000)
move /proc/sys/lnet to debugfs

Parameters in lnet sysctl are of debug quality, so let's move them
to debugfs instead.

Linux-commit: 0871d551af37c72c308397c16c31bae945e6a79d

Remove redundant lnet debugfs variables

/proc/sys/lnet/console_ratelimit, debug_path and panic_on_lbug
are module parameters with no special magic accessible via
/sys/module/libcfs/parameters/libcfs_console_ratelimit,
/sys/module/libcfs/parameters/libcfs_debug_file_path and
/sys/module/libcfs/parameters/libcfs_panic_on_lbug respectively.

As such just replace them with corresponding symlinks

Linux-commit: 1b4d97b6c6ca05446ff33843a7b174cdd765df5a

get rid of debugfs/lnet/console_backoff

module parameter libcfs_console_backoff accessible through
/sys/module/libcfs/parameters/libcfs_console_backoff would
do the same thing, just add a special "uintpos" parameter
type to disallow 0 values too.

Also add a symlink to the module parameter variable for
backwards compatibility

Linux-commit: 8710427dd68f4dff8976d221e220317cea20ecec

get rid of debugfs/lnet/debug_mb

It's just a fancy libcfs_debug_mb module parameter wrapper,
so just add debug buffer size check and resizing and the same
functionality now would be accessible via
/sys/module/libcfs/parameters/libcfs_debug_mb

Also add a symlink for backwards compatibility.

Linux-commit: 8dc08446d0671709bdec9e037845b014e33663b1

get rid of debugfs/lnet/console_{min, max}_delay_centisecs

They are just fancy module parameters wrappers,
so just the same functionality now would be accessible via
/sys/module/libcfs/parameters/libcfs_console_{min,max}_delay

Also install compatibility symlinks

Linux-commit: 35ca907d245e8c218f39b6ed8bd6a1c656d056cc

Fix kstrtouint return value check fix

Apparently kstrtouint could return not just -EINVAL, but also -ERANGE,
so make sure we just check the return value for something negative.

Noticed by Dan Carpenter <dan.carpenter@oracle.com>

Linux-commit: aa66d6f87f300b15ac2efdcde9e198bf5a9020ce

Properly handle debugfs read- and write-only files

It turns out that unlike procfs, debugfs does not really enforce
permissions for root (similar to regular filesystems), so we need
to ensure we are not providing ->write() method to read-only files
and ->read() method for write-only files at registration.

This fixes a couple of crashes on unexpected access.

Linux-commit:49a76d7040b466dd92f198ded4aba3cd3569d48f

Change-Id: I69ff4d9766969f2ca5d5478d4e822879ee78b467
Signed-off-by: Dmitry Eremin <dmitry.eremin@intel.com>
Signed-off-by: Oleg Drokin <oleg.drokin@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/24688
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Olaf Weber <olaf.weber@hpe.com>
libcfs/autoconf/lustre-libcfs.m4
libcfs/include/libcfs/libcfs.h
libcfs/include/libcfs/linux/linux-misc.h
libcfs/libcfs/debug.c
libcfs/libcfs/module.c
libcfs/libcfs/tracefile.c
libcfs/libcfs/tracefile.h

index 1e6f326..f61f728 100644 (file)
@@ -137,6 +137,24 @@ ctl_table_ctl_name, [
 ]) # LIBCFS_SYSCTL_CTLNAME
 
 #
 ]) # LIBCFS_SYSCTL_CTLNAME
 
 #
+# LIBCFS_MODULE_LOCKING
+#
+# 2.6.36 introduced locking to module params. RHEL6 lacks this support
+#
+AC_DEFUN([LIBCFS_MODULE_LOCKING],[
+LB_CHECK_COMPILE([does the kernel support module param locking],
+module_param_locking, [
+       #include <linux/moduleparam.h>
+],[
+       __kernel_param_lock(NULL);
+       __kernel_param_unlock(NULL);
+],[
+       AC_DEFINE(HAVE_MODULE_PARAM_LOCKING, 1,
+               [locking module param is supported])
+])
+]) # LIBCFS_MODULE_LOCKING
+
+#
 # LIBCFS_KSTRTOUL
 #
 # 2.6.38 kstrtoul is added
 # LIBCFS_KSTRTOUL
 #
 # 2.6.38 kstrtoul is added
@@ -295,6 +313,23 @@ ktime_get_ts64, [
 ]) # LIBCFS_KTIME_GET_TS64
 
 #
 ]) # LIBCFS_KTIME_GET_TS64
 
 #
+# Linux kernel 3.12 introduced struct kernel_param_ops
+# This has been backported to all lustre supported
+# clients expect RHEL6. We have to handle the differences.
+#
+AC_DEFUN([LIBCFS_KERNEL_PARAM_OPS],[
+LB_CHECK_COMPILE([does 'struct kernel_param_ops' exist],
+kernel_param_ops, [
+       #include <linux/module.h>
+],[
+       struct kernel_param_ops ops;
+],[
+       AC_DEFINE(HAVE_KERNEL_PARAM_OPS, 1,
+               ['struct kernel_param_ops' is available])
+])
+]) # LIBCFS_KERNEL_PARAM_OPS
+
+#
 # Kernel version 3.12 introduced ktime_add
 #
 AC_DEFUN([LIBCFS_KTIME_ADD],[
 # Kernel version 3.12 introduced ktime_add
 #
 AC_DEFUN([LIBCFS_KTIME_ADD],[
@@ -524,6 +559,25 @@ cpumap_print_to_pagebuf, [
 ]) # LIBCFS_HAVE_CPUMASK_PRINT_TO_PAGEBUF
 
 #
 ]) # LIBCFS_HAVE_CPUMASK_PRINT_TO_PAGEBUF
 
 #
+# Kernel version 4.1 commit b51d23e4e9fea6f264d39535c2a62d1f51e7ccc3
+# create per module locks which added kernel_param_[un]lock(). Older
+# kernels you have to use __kernel_param_[un]lock(). In that case its
+# a global lock for all modules but that is okay since its a rare event.
+#
+AC_DEFUN([LIBCFS_KERNEL_PARAM_LOCK],[
+LB_CHECK_COMPILE([does function 'kernel_param_[un]lock' exist],
+kernel_param_lock, [
+       #include <linux/moduleparam.h>
+],[
+       kernel_param_lock(NULL);
+       kernel_param_unlock(NULL);
+],[
+       AC_DEFINE(HAVE_KERNEL_PARAM_LOCK, 1,
+               ['kernel_param_[un]lock' is available])
+])
+]) # LIBCFS_KERNEL_PARAM_LOCK
+
+#
 # Kernel version 4.2 changed topology_thread_cpumask
 # to topology_sibling_cpumask
 #
 # Kernel version 4.2 changed topology_thread_cpumask
 # to topology_sibling_cpumask
 #
@@ -685,6 +739,8 @@ LIBCFS_STACKTRACE_OPS_HAVE_WALK_STACK
 LC_SHRINKER_WANT_SHRINK_PTR
 # 2.6.33
 LIBCFS_SYSCTL_CTLNAME
 LC_SHRINKER_WANT_SHRINK_PTR
 # 2.6.33
 LIBCFS_SYSCTL_CTLNAME
+# 2.6.36
+LIBCFS_MODULE_LOCKING
 # 2.6.38
 LIBCFS_KSTRTOUL
 # 2.6.39
 # 2.6.38
 LIBCFS_KSTRTOUL
 # 2.6.39
@@ -707,6 +763,7 @@ LIBCFS_ENABLE_CRC32C_ACCEL
 # 3.11
 LIBCFS_KTIME_GET_TS64
 # 3.12
 # 3.11
 LIBCFS_KTIME_GET_TS64
 # 3.12
+LIBCFS_KERNEL_PARAM_OPS
 LIBCFS_KTIME_ADD
 LIBCFS_KTIME_AFTER
 LIBCFS_SHRINKER_COUNT
 LIBCFS_KTIME_ADD
 LIBCFS_KTIME_AFTER
 LIBCFS_SHRINKER_COUNT
@@ -722,6 +779,8 @@ LIBCFS_TIMESPEC64_TO_KTIME
 # 3.19
 LIBCFS_KTIME_GET_SECONDS
 LIBCFS_HAVE_CPUMASK_PRINT_TO_PAGEBUF
 # 3.19
 LIBCFS_KTIME_GET_SECONDS
 LIBCFS_HAVE_CPUMASK_PRINT_TO_PAGEBUF
+# 4.1
+LIBCFS_KERNEL_PARAM_LOCK
 # 4.2
 LIBCFS_HAVE_TOPOLOGY_SIBLING_CPUMASK
 LIBCFS_FPU_API
 # 4.2
 LIBCFS_HAVE_TOPOLOGY_SIBLING_CPUMASK
 LIBCFS_FPU_API
index b33243a..59453fa 100644 (file)
@@ -128,4 +128,12 @@ static inline void *__container_of(const void *ptr, unsigned long shift)
 #define container_of0(ptr, type, member)                               \
        ((type *)__container_of((ptr), offsetof(type, member)))
 
 #define container_of0(ptr, type, member)                               \
        ((type *)__container_of((ptr), offsetof(type, member)))
 
+struct lnet_debugfs_symlink_def {
+       const char *name;
+       const char *target;
+};
+
+void lnet_insert_debugfs(struct ctl_table *table,
+                        const struct lnet_debugfs_symlink_def *symlinks);
+
 #endif /* _LIBCFS_LIBCFS_H_ */
 #endif /* _LIBCFS_LIBCFS_H_ */
index e111193..c3b85fd 100644 (file)
 #define INIT_STRATEGY
 #endif
 
 #define INIT_STRATEGY
 #endif
 
+#ifndef HAVE_MODULE_PARAM_LOCKING
+static DEFINE_MUTEX(param_lock);
+#endif
+
 #ifndef HAVE_UIDGID_HEADER
 
 #ifndef _LINUX_UIDGID_H
 #ifndef HAVE_UIDGID_HEADER
 
 #ifndef _LINUX_UIDGID_H
@@ -105,6 +109,38 @@ static inline bool gid_valid(kgid_t gid)
 
 int cfs_get_environ(const char *key, char *value, int *val_len);
 
 
 int cfs_get_environ(const char *key, char *value, int *val_len);
 
+/*
+ * For RHEL6 struct kernel_parm_ops doesn't exist. Also
+ * the arguments for .set and .get take different
+ * parameters which is handled below
+ */
+#ifdef HAVE_KERNEL_PARAM_OPS
+#define cfs_kernel_param_arg_t const struct kernel_param
+#else
+#define cfs_kernel_param_arg_t struct kernel_param_ops
+#define kernel_param_ops kernel_param
+#endif /* ! HAVE_KERNEL_PARAM_OPS */
+
+#ifndef HAVE_KERNEL_PARAM_LOCK
+static inline void kernel_param_unlock(struct module *mod)
+{
+#ifndef        HAVE_MODULE_PARAM_LOCKING
+       mutex_unlock(&param_lock);
+#else
+       __kernel_param_unlock();
+#endif
+}
+
+static inline void kernel_param_lock(struct module *mod)
+{
+#ifndef        HAVE_MODULE_PARAM_LOCKING
+       mutex_lock(&param_lock);
+#else
+       __kernel_param_lock();
+#endif
+}
+#endif /* ! HAVE_KERNEL_PARAM_LOCK */
+
 #ifndef HAVE_KSTRTOUL
 static inline int kstrtoul(const char *s, unsigned int base, unsigned long *res)
 {
 #ifndef HAVE_KSTRTOUL
 static inline int kstrtoul(const char *s, unsigned int base, unsigned long *res)
 {
index 1d7360a..f923842 100644 (file)
@@ -54,8 +54,58 @@ module_param(libcfs_debug, int, 0644);
 MODULE_PARM_DESC(libcfs_debug, "Lustre kernel debug mask");
 EXPORT_SYMBOL(libcfs_debug);
 
 MODULE_PARM_DESC(libcfs_debug, "Lustre kernel debug mask");
 EXPORT_SYMBOL(libcfs_debug);
 
+static int libcfs_param_debug_mb_set(const char *val,
+                                    cfs_kernel_param_arg_t *kp)
+{
+       int rc;
+       unsigned int num;
+
+       rc = kstrtouint(val, 0, &num);
+       if (rc < 0)
+               return rc;
+
+/*
+ * RHEL6 does not support any kind of locking so we have to provide
+ * our own
+ */
+#ifndef HAVE_MODULE_PARAM_LOCKING
+       kernel_param_lock(THIS_MODULE);
+#endif
+       if (!*((unsigned int *)kp->arg)) {
+               *((unsigned int *)kp->arg) = num;
+               return 0;
+       }
+
+       rc = cfs_trace_set_debug_mb(num);
+
+       if (!rc)
+               *((unsigned int *)kp->arg) = cfs_trace_get_debug_mb();
+
+#ifndef HAVE_MODULE_PARAM_LOCKING
+       kernel_param_unlock(THIS_MODULE);
+#endif
+       return rc;
+}
+
+/* While debug_mb setting look like unsigned int, in fact
+ * it needs quite a bunch of extra processing, so we define special
+ * debug_mb parameter type with corresponding methods to handle this case
+ */
+static struct kernel_param_ops param_ops_debug_mb = {
+       .set = libcfs_param_debug_mb_set,
+       .get = param_get_uint,
+};
+
+#define param_check_debug_mb(name, p) \
+               __param_check(name, p, unsigned int)
+
 static unsigned int libcfs_debug_mb;
 static unsigned int libcfs_debug_mb;
-module_param(libcfs_debug_mb, uint, 0644);
+#ifdef HAVE_KERNEL_PARAM_OPS
+module_param(libcfs_debug_mb, debug_mb, 0644);
+#else
+module_param_call(libcfs_debug_mb, libcfs_param_debug_mb_set, param_get_uint,
+                 &param_ops_debug_mb, 0644);
+#endif
 MODULE_PARM_DESC(libcfs_debug_mb, "Total debug buffer size.");
 
 unsigned int libcfs_printk = D_CANTMASK;
 MODULE_PARM_DESC(libcfs_debug_mb, "Total debug buffer size.");
 
 unsigned int libcfs_printk = D_CANTMASK;
@@ -66,16 +116,123 @@ unsigned int libcfs_console_ratelimit = 1;
 module_param(libcfs_console_ratelimit, uint, 0644);
 MODULE_PARM_DESC(libcfs_console_ratelimit, "Lustre kernel debug console ratelimit (0 to disable)");
 
 module_param(libcfs_console_ratelimit, uint, 0644);
 MODULE_PARM_DESC(libcfs_console_ratelimit, "Lustre kernel debug console ratelimit (0 to disable)");
 
+static int param_set_delay_minmax(const char *val,
+                                 cfs_kernel_param_arg_t *kp,
+                                 long min, long max)
+{
+       long d;
+       int sec;
+       int rc;
+
+       rc = kstrtoint(val, 0, &sec);
+       if (rc)
+               return -EINVAL;
+
+       /* The sysfs setting is in centiseconds */
+       d = cfs_time_seconds(sec) / 100;
+       if (d < min || d > max)
+               return -EINVAL;
+
+       *((unsigned int *)kp->arg) = d;
+
+       return 0;
+}
+
+static int param_get_delay(char *buffer, cfs_kernel_param_arg_t *kp)
+{
+       unsigned int d = *(unsigned int *)kp->arg;
+
+       return sprintf(buffer, "%u", (unsigned int)cfs_duration_sec(d * 100));
+}
+
 unsigned int libcfs_console_max_delay;
 unsigned int libcfs_console_max_delay;
-module_param(libcfs_console_max_delay, uint, 0644);
+unsigned int libcfs_console_min_delay;
+
+static int param_set_console_max_delay(const char *val,
+                                      cfs_kernel_param_arg_t *kp)
+{
+       return param_set_delay_minmax(val, kp,
+                                     libcfs_console_min_delay, INT_MAX);
+}
+
+static struct kernel_param_ops param_ops_console_max_delay = {
+       .set = param_set_console_max_delay,
+       .get = param_get_delay,
+};
+
+#define param_check_console_max_delay(name, p) \
+               __param_check(name, p, unsigned int)
+
+#ifdef HAVE_KERNEL_PARAM_OPS
+module_param(libcfs_console_max_delay, console_max_delay, 0644);
+#else
+module_param_call(libcfs_console_max_delay, param_set_console_max_delay,
+                 param_get_delay, &param_ops_console_max_delay, 0644);
+#endif
 MODULE_PARM_DESC(libcfs_console_max_delay, "Lustre kernel debug console max delay (jiffies)");
 
 MODULE_PARM_DESC(libcfs_console_max_delay, "Lustre kernel debug console max delay (jiffies)");
 
-unsigned int libcfs_console_min_delay;
-module_param(libcfs_console_min_delay, uint, 0644);
+static int param_set_console_min_delay(const char *val,
+                                      cfs_kernel_param_arg_t *kp)
+{
+       return param_set_delay_minmax(val, kp,
+                                     1, libcfs_console_max_delay);
+}
+
+static struct kernel_param_ops param_ops_console_min_delay = {
+       .set = param_set_console_min_delay,
+       .get = param_get_delay,
+};
+
+#define param_check_console_min_delay(name, p) \
+               __param_check(name, p, unsigned int)
+
+#ifdef HAVE_KERNEL_PARAM_OPS
+module_param(libcfs_console_min_delay, console_min_delay, 0644);
+#else
+module_param_call(libcfs_console_min_delay, param_set_console_min_delay,
+                 param_get_delay, &param_ops_console_min_delay, 0644);
+#endif
 MODULE_PARM_DESC(libcfs_console_min_delay, "Lustre kernel debug console min delay (jiffies)");
 
 MODULE_PARM_DESC(libcfs_console_min_delay, "Lustre kernel debug console min delay (jiffies)");
 
+static int param_set_uint_minmax(const char *val,
+                                cfs_kernel_param_arg_t *kp,
+                                unsigned int min, unsigned int max)
+{
+       unsigned int num;
+       int ret;
+
+       if (!val)
+               return -EINVAL;
+
+       ret = kstrtouint(val, 0, &num);
+       if (ret < 0 || num < min || num > max)
+               return -EINVAL;
+
+       *((unsigned int *)kp->arg) = num;
+       return 0;
+}
+
+static int param_set_uintpos(const char *val,
+                            cfs_kernel_param_arg_t *kp)
+{
+       return param_set_uint_minmax(val, kp, 1, -1);
+}
+
+static struct kernel_param_ops param_ops_uintpos = {
+       .set = param_set_uintpos,
+       .get = param_get_uint,
+};
+
+#define param_check_uintpos(name, p) \
+               __param_check(name, p, unsigned int)
+
 unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF;
 unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF;
-module_param(libcfs_console_backoff, uint, 0644);
+#ifdef HAVE_KERNEL_PARAM_OPS
+module_param(libcfs_console_backoff, uintpos, 0644);
+#else
+module_param_call(libcfs_console_backoff, param_set_uintpos, param_get_uint,
+                 &param_ops_uintpos, 0644);
+#endif
 MODULE_PARM_DESC(libcfs_console_backoff, "Lustre kernel debug console backoff factor");
 
 unsigned int libcfs_debug_binary = 1;
 MODULE_PARM_DESC(libcfs_console_backoff, "Lustre kernel debug console backoff factor");
 
 unsigned int libcfs_debug_binary = 1;
@@ -101,7 +258,7 @@ char libcfs_debug_file_path_arr[PATH_MAX] = LIBCFS_DEBUG_FILE_PATH_DEFAULT;
 EXPORT_SYMBOL(libcfs_debug_file_path_arr);
 
 /* We need to pass a pointer here, but elsewhere this must be a const */
 EXPORT_SYMBOL(libcfs_debug_file_path_arr);
 
 /* We need to pass a pointer here, but elsewhere this must be a const */
-static char *libcfs_debug_file_path;
+static char *libcfs_debug_file_path = LIBCFS_DEBUG_FILE_PATH_DEFAULT;
 module_param(libcfs_debug_file_path, charp, 0644);
 MODULE_PARM_DESC(libcfs_debug_file_path,
                 "Path for dumping debug logs, set 'NONE' to prevent log dumping");
 module_param(libcfs_debug_file_path, charp, 0644);
 MODULE_PARM_DESC(libcfs_debug_file_path,
                 "Path for dumping debug logs, set 'NONE' to prevent log dumping");
@@ -300,19 +457,25 @@ int libcfs_debug_init(unsigned long bufsize)
                max = (max / num_possible_cpus());
                max = (max << (20 - PAGE_SHIFT));
        }
                max = (max / num_possible_cpus());
                max = (max << (20 - PAGE_SHIFT));
        }
-       rc = cfs_tracefile_init(max);
 
 
-        if (rc == 0)
-                libcfs_register_panic_notifier();
-
-        return rc;
+       rc = cfs_tracefile_init(max);
+       if (rc)
+               return rc;
+
+       libcfs_register_panic_notifier();
+       kernel_param_lock(THIS_MODULE);
+       libcfs_debug_mb = cfs_trace_get_debug_mb();
+       kernel_param_unlock(THIS_MODULE);
+       return rc;
 }
 
 int libcfs_debug_cleanup(void)
 {
 }
 
 int libcfs_debug_cleanup(void)
 {
-        libcfs_unregister_panic_notifier();
-        cfs_tracefile_exit();
-        return 0;
+       libcfs_unregister_panic_notifier();
+       kernel_param_lock(THIS_MODULE);
+       cfs_tracefile_exit();
+       kernel_param_unlock(THIS_MODULE);
+       return 0;
 }
 
 int libcfs_debug_clear_buffer(void)
 }
 
 int libcfs_debug_clear_buffer(void)
index e8080f3..2018789 100644 (file)
@@ -45,7 +45,7 @@
 #include <linux/list.h>
 
 #include <linux/sysctl.h>
 #include <linux/list.h>
 
 #include <linux/sysctl.h>
-#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
 #include <asm/div64.h>
 
 #define DEBUG_SUBSYSTEM S_LNET
 #include <asm/div64.h>
 
 #define DEBUG_SUBSYSTEM S_LNET
@@ -55,9 +55,7 @@
 #include <lnet/lib-lnet.h>
 #include "tracefile.h"
 
 #include <lnet/lib-lnet.h>
 #include "tracefile.h"
 
-#ifdef CONFIG_SYSCTL
-static struct ctl_table_header *lnet_table_header;
-#endif
+static struct dentry *lnet_debugfs_root;
 
 static DECLARE_RWSEM(ioctl_list_sem);
 static LIST_HEAD(ioctl_list);
 
 static DECLARE_RWSEM(ioctl_list_sem);
 static LIST_HEAD(ioctl_list);
@@ -156,11 +154,10 @@ out:
        RETURN(err);
 }
 
        RETURN(err);
 }
 
-int
-lprocfs_call_handler(void *data, int write, loff_t *ppos,
-                    void __user *buffer, size_t *lenp,
-                    int (*handler)(void *data, int write, loff_t pos,
-                                   void __user *buffer, int len))
+int lprocfs_call_handler(void *data, int write, loff_t *ppos,
+                        void __user *buffer, size_t *lenp,
+                        int (*handler)(void *data, int write, loff_t pos,
+                                       void __user *buffer, int len))
 {
        int rc = handler(data, write, *ppos, buffer, *lenp);
 
 {
        int rc = handler(data, write, *ppos, buffer, *lenp);
 
@@ -218,9 +215,8 @@ static int __proc_dobitmasks(void *data, int write,
        return rc;
 }
 
        return rc;
 }
 
-static int
-proc_dobitmasks(struct ctl_table *table, int write,
-               void __user *buffer, size_t *lenp, loff_t *ppos)
+static int proc_dobitmasks(struct ctl_table *table, int write,
+                          void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                    __proc_dobitmasks);
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                    __proc_dobitmasks);
@@ -238,9 +234,8 @@ static int __proc_dump_kernel(void *data, int write,
        return cfs_trace_dump_debug_buffer_usrstr(buffer, nob);
 }
 
        return cfs_trace_dump_debug_buffer_usrstr(buffer, nob);
 }
 
-static int
-proc_dump_kernel(struct ctl_table *table, int write, void __user *buffer,
-                size_t *lenp, loff_t *ppos)
+static int proc_dump_kernel(struct ctl_table *table, int write,
+                           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                    __proc_dump_kernel);
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                    __proc_dump_kernel);
@@ -262,148 +257,24 @@ static int __proc_daemon_file(void *data, int write,
        return cfs_trace_daemon_command_usrstr(buffer, nob);
 }
 
        return cfs_trace_daemon_command_usrstr(buffer, nob);
 }
 
-static int
-proc_daemon_file(struct ctl_table *table, int write, void __user *buffer,
-                size_t *lenp, loff_t *ppos)
+static int proc_daemon_file(struct ctl_table *table, int write,
+                           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                    __proc_daemon_file);
 }
 
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                    __proc_daemon_file);
 }
 
-static int __proc_debug_mb(void *data, int write,
-                          loff_t pos, void __user *buffer, int nob)
-{
-       if (!write) {
-               char tmpstr[32];
-               int  len = snprintf(tmpstr, sizeof(tmpstr), "%d",
-                                   cfs_trace_get_debug_mb());
-
-               if (pos >= len)
-                       return 0;
-
-               return cfs_trace_copyout_string(buffer, nob, tmpstr + pos,
-                                               "\n");
-       }
-
-       return cfs_trace_set_debug_mb_usrstr(buffer, nob);
-}
-
-static int
-proc_debug_mb(struct ctl_table *table, int write, void __user *buffer,
-             size_t *lenp, loff_t *ppos)
-{
-       return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
-                                   __proc_debug_mb);
-}
-
-static int
-proc_console_max_delay_cs(struct ctl_table *table, int write,
-                         void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-       int rc, max_delay_cs;
-       struct ctl_table dummy = *table;
-       cfs_duration_t d;
-
-       dummy.data = &max_delay_cs;
-       dummy.proc_handler = &proc_dointvec;
-
-       if (!write) { /* read */
-               max_delay_cs = cfs_duration_sec(libcfs_console_max_delay * 100);
-               rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
-               return rc;
-       }
-
-       /* write */
-       max_delay_cs = 0;
-       rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
-       if (rc < 0)
-               return rc;
-       if (max_delay_cs <= 0)
-               return -EINVAL;
-
-       d = cfs_time_seconds(max_delay_cs) / 100;
-       if (d == 0 || d < libcfs_console_min_delay)
-               return -EINVAL;
-       libcfs_console_max_delay = d;
-
-       return rc;
-}
-
-static int
-proc_console_min_delay_cs(struct ctl_table *table, int write,
-                         void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-       int rc, min_delay_cs;
-       struct ctl_table dummy = *table;
-       cfs_duration_t d;
-
-       dummy.data = &min_delay_cs;
-       dummy.proc_handler = &proc_dointvec;
-
-       if (!write) { /* read */
-               min_delay_cs = cfs_duration_sec(libcfs_console_min_delay * 100);
-               rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
-               return rc;
-       }
-
-       /* write */
-       min_delay_cs = 0;
-       rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
-       if (rc < 0)
-               return rc;
-       if (min_delay_cs <= 0)
-               return -EINVAL;
-
-       d = cfs_time_seconds(min_delay_cs) / 100;
-       if (d == 0 || d > libcfs_console_max_delay)
-               return -EINVAL;
-       libcfs_console_min_delay = d;
-
-       return rc;
-}
-
-static int
-proc_console_backoff(struct ctl_table *table, int write, void __user *buffer,
-                    size_t *lenp, loff_t *ppos)
-{
-       int rc, backoff;
-       struct ctl_table dummy = *table;
-
-       dummy.data = &backoff;
-       dummy.proc_handler = &proc_dointvec;
-
-       if (!write) { /* read */
-               backoff = libcfs_console_backoff;
-               rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
-               return rc;
-       }
-
-       /* write */
-       backoff = 0;
-       rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
-       if (rc < 0)
-               return rc;
-
-       if (backoff <= 0)
-               return -EINVAL;
-
-       libcfs_console_backoff = backoff;
-
-       return rc;
-}
-
-static int
-libcfs_force_lbug(struct ctl_table *table, int write, void __user *buffer,
-                 size_t *lenp, loff_t *ppos)
+static int libcfs_force_lbug(struct ctl_table *table, int write,
+                            void __user *buffer,
+                            size_t *lenp, loff_t *ppos)
 {
        if (write)
                LBUG();
        return 0;
 }
 
 {
        if (write)
                LBUG();
        return 0;
 }
 
-static int
-proc_fail_loc(struct ctl_table *table, int write, void __user *buffer,
-             size_t *lenp, loff_t *ppos)
+static int proc_fail_loc(struct ctl_table *table, int write,
+                        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        int rc;
        long old_fail_loc = cfs_fail_loc;
 {
        int rc;
        long old_fail_loc = cfs_fail_loc;
@@ -455,9 +326,8 @@ out:
        return rc;
 }
 
        return rc;
 }
 
-static int
-proc_cpt_table(struct ctl_table *table, int write, void __user *buffer,
-              size_t *lenp, loff_t *ppos)
+static int proc_cpt_table(struct ctl_table *table, int write,
+                         void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                    __proc_cpt_table);
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                    __proc_cpt_table);
@@ -504,19 +374,14 @@ static int __proc_cpt_distance(void *data, int write,
        return rc;
 }
 
        return rc;
 }
 
-static int
-proc_cpt_distance(struct ctl_table *table, int write, void __user *buffer,
-              size_t *lenp, loff_t *ppos)
+static int proc_cpt_distance(struct ctl_table *table, int write,
+                            void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                     __proc_cpt_distance);
 }
 
 static struct ctl_table lnet_table[] = {
 {
        return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
                                     __proc_cpt_distance);
 }
 
 static struct ctl_table lnet_table[] = {
-       /*
-        * NB No .strategy entries have been provided since sysctl(8) prefers
-        * to go via /proc for portability.
-        */
        {
                INIT_CTL_NAME
                .procname       = "debug",
        {
                INIT_CTL_NAME
                .procname       = "debug",
@@ -543,43 +408,6 @@ static struct ctl_table lnet_table[] = {
        },
        {
                INIT_CTL_NAME
        },
        {
                INIT_CTL_NAME
-               .procname       = "console_ratelimit",
-               .data           = &libcfs_console_ratelimit,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec
-       },
-       {
-               INIT_CTL_NAME
-               .procname       = "console_max_delay_centisecs",
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_console_max_delay_cs
-       },
-       {
-               INIT_CTL_NAME
-               .procname       = "console_min_delay_centisecs",
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_console_min_delay_cs
-       },
-       {
-               INIT_CTL_NAME
-               .procname       = "console_backoff",
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_console_backoff
-       },
-       {
-               INIT_CTL_NAME
-               .procname       = "debug_path",
-               .data           = libcfs_debug_file_path_arr,
-               .maxlen         = sizeof(libcfs_debug_file_path_arr),
-               .mode           = 0644,
-               .proc_handler   = &proc_dostring,
-       },
-       {
-               INIT_CTL_NAME
                .procname       = "cpu_partition_table",
                .maxlen         = 128,
                .mode           = 0444,
                .procname       = "cpu_partition_table",
                .maxlen         = 128,
                .mode           = 0444,
@@ -618,14 +446,6 @@ static struct ctl_table lnet_table[] = {
        },
        {
                INIT_CTL_NAME
        },
        {
                INIT_CTL_NAME
-               .procname       = "panic_on_lbug",
-               .data           = &libcfs_panic_on_lbug,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-       },
-       {
-               INIT_CTL_NAME
                .procname       = "dump_kernel",
                .maxlen         = 256,
                .mode           = 0200,
                .procname       = "dump_kernel",
                .maxlen         = 256,
                .mode           = 0200,
@@ -640,12 +460,6 @@ static struct ctl_table lnet_table[] = {
        },
        {
                INIT_CTL_NAME
        },
        {
                INIT_CTL_NAME
-               .procname       = "debug_mb",
-               .mode           = 0644,
-               .proc_handler   = &proc_debug_mb,
-       },
-       {
-               INIT_CTL_NAME
                .procname       = "watchdog_ratelimit",
                .data           = &libcfs_watchdog_ratelimit,
                .maxlen         = sizeof(int),
                .procname       = "watchdog_ratelimit",
                .data           = &libcfs_watchdog_ratelimit,
                .maxlen         = sizeof(int),
@@ -690,37 +504,109 @@ static struct ctl_table lnet_table[] = {
        }
 };
 
        }
 };
 
-#ifdef CONFIG_SYSCTL
-static struct ctl_table top_table[] = {
-       {
-               INIT_CTL_NAME
-               .procname       = "lnet",
-               .mode           = 0555,
-               .data           = NULL,
-               .maxlen         = 0,
-               .child          = lnet_table,
-       },
-       { 0 }
+static const struct lnet_debugfs_symlink_def lnet_debugfs_symlinks[] = {
+       { .name         = "console_ratelimit",
+         .target       = "../../../module/libcfs/parameters/libcfs_console_ratelimit" },
+       { .name         = "debug_path",
+         .target       = "../../../module/libcfs/parameters/libcfs_debug_file_path" },
+       { .name         = "panic_on_lbug",
+         .target       = "../../../module/libcfs/parameters/libcfs_panic_on_lbug" },
+       { .name         = "console_backoff",
+         .target       = "../../../module/libcfs/parameters/libcfs_console_backoff" },
+       { .name         = "debug_mb",
+         .target       = "../../../module/libcfs/parameters/libcfs_debug_mb" },
+       { .name         = "console_min_delay_centisecs",
+         .target       = "../../../module/libcfs/parameters/libcfs_console_min_delay" },
+       { .name         = "console_max_delay_centisecs",
+         .target       = "../../../module/libcfs/parameters/libcfs_console_max_delay" },
+       { .name         = NULL },
 };
 };
-#endif
 
 
-static int insert_proc(void)
+static ssize_t lnet_debugfs_read(struct file *filp, char __user *buf,
+                                size_t count, loff_t *ppos)
 {
 {
-#ifdef CONFIG_SYSCTL
-       if (lnet_table_header == NULL)
-               lnet_table_header = register_sysctl_table(top_table);
-#endif
-       return 0;
+       struct ctl_table *table = filp->private_data;
+       ssize_t rc;
+
+       rc = table->proc_handler(table, 0, buf, &count, ppos);
+       if (!rc)
+               rc = count;
+
+       return rc;
+}
+
+static ssize_t lnet_debugfs_write(struct file *filp, const char __user *buf,
+                                 size_t count, loff_t *ppos)
+{
+       struct ctl_table *table = filp->private_data;
+       ssize_t rc;
+
+       rc = table->proc_handler(table, 1, (void __user *)buf, &count, ppos);
+       if (!rc)
+               rc = count;
+
+       return rc;
+}
+
+static const struct file_operations lnet_debugfs_file_operations_rw = {
+       .open           = simple_open,
+       .read           = lnet_debugfs_read,
+       .write          = lnet_debugfs_write,
+       .llseek         = default_llseek,
+};
+
+static const struct file_operations lnet_debugfs_file_operations_ro = {
+       .open           = simple_open,
+       .read           = lnet_debugfs_read,
+       .llseek         = default_llseek,
+};
+
+static const struct file_operations lnet_debugfs_file_operations_wo = {
+       .open           = simple_open,
+       .write          = lnet_debugfs_write,
+       .llseek         = default_llseek,
+};
+
+static const struct file_operations *lnet_debugfs_fops_select(umode_t mode)
+{
+       if (!(mode & S_IWUGO))
+               return &lnet_debugfs_file_operations_ro;
+
+       if (!(mode & S_IRUGO))
+               return &lnet_debugfs_file_operations_wo;
+
+       return &lnet_debugfs_file_operations_rw;
+}
+
+void lnet_insert_debugfs(struct ctl_table *table,
+                        const struct lnet_debugfs_symlink_def *symlinks)
+{
+       if (!lnet_debugfs_root)
+               lnet_debugfs_root = debugfs_create_dir("lnet", NULL);
+
+       /* Even if we cannot create, just ignore it altogether) */
+       if (IS_ERR_OR_NULL(lnet_debugfs_root))
+               return;
+
+       /* We don't save the dentry returned in next two calls, because
+        * we don't call debugfs_remove() but rather remove_recursive()
+        */
+       for (; table && table->procname; table++)
+               debugfs_create_file(table->procname, table->mode,
+                                   lnet_debugfs_root, table,
+                                   lnet_debugfs_fops_select(table->mode));
+
+       for (; symlinks && symlinks->name; symlinks++)
+               debugfs_create_symlink(symlinks->name, lnet_debugfs_root,
+                                      symlinks->target);
 }
 }
+EXPORT_SYMBOL_GPL(lnet_insert_debugfs);
 
 
-static void remove_proc(void)
+static void lnet_remove_debugfs(void)
 {
 {
-#ifdef CONFIG_SYSCTL
-       if (lnet_table_header != NULL)
-               unregister_sysctl_table(lnet_table_header);
+       debugfs_remove_recursive(lnet_debugfs_root);
 
 
-       lnet_table_header = NULL;
-#endif
+       lnet_debugfs_root = NULL;
 }
 
 static int __init libcfs_init(void)
 }
 
 static int __init libcfs_init(void)
@@ -764,17 +650,10 @@ static int __init libcfs_init(void)
                goto cleanup_wi;
        }
 
                goto cleanup_wi;
        }
 
-
-       rc = insert_proc();
-       if (rc) {
-               CERROR("insert_proc: error %d\n", rc);
-               goto cleanup_crypto;
-       }
+       lnet_insert_debugfs(lnet_table, lnet_debugfs_symlinks);
 
        CDEBUG (D_OTHER, "portals setup OK\n");
        return 0;
 
        CDEBUG (D_OTHER, "portals setup OK\n");
        return 0;
-cleanup_crypto:
-       cfs_crypto_unregister();
 cleanup_wi:
        cfs_wi_shutdown();
 cleanup_deregister:
 cleanup_wi:
        cfs_wi_shutdown();
 cleanup_deregister:
@@ -790,7 +669,7 @@ static void __exit libcfs_exit(void)
 {
        int rc;
 
 {
        int rc;
 
-       remove_proc();
+       lnet_remove_debugfs();
 
        CDEBUG(D_MALLOC, "before Portals cleanup: kmem %d\n",
               atomic_read(&libcfs_kmemory));
 
        CDEBUG(D_MALLOC, "before Portals cleanup: kmem %d\n",
               atomic_read(&libcfs_kmemory));
index 8dba1da..805cb8c 100644 (file)
@@ -911,18 +911,6 @@ int cfs_trace_set_debug_mb(int mb)
        return 0;
 }
 
        return 0;
 }
 
-int cfs_trace_set_debug_mb_usrstr(void __user *usr_str, int usr_str_nob)
-{
-        char     str[32];
-        int      rc;
-
-        rc = cfs_trace_copyin_string(str, sizeof(str), usr_str, usr_str_nob);
-        if (rc < 0)
-                return rc;
-
-        return cfs_trace_set_debug_mb(simple_strtoul(str, NULL, 0));
-}
-
 int cfs_trace_get_debug_mb(void)
 {
         int i;
 int cfs_trace_get_debug_mb(void)
 {
         int i;
index 2f5dc4f..14e3311 100644 (file)
@@ -82,7 +82,6 @@ int cfs_trace_dump_debug_buffer_usrstr(void __user *usr_str, int usr_str_nob);
 int cfs_trace_daemon_command(char *str);
 int cfs_trace_daemon_command_usrstr(void __user *usr_str, int usr_str_nob);
 int cfs_trace_set_debug_mb(int mb);
 int cfs_trace_daemon_command(char *str);
 int cfs_trace_daemon_command_usrstr(void __user *usr_str, int usr_str_nob);
 int cfs_trace_set_debug_mb(int mb);
-int cfs_trace_set_debug_mb_usrstr(void __user *usr_str, int usr_str_nob);
 int cfs_trace_get_debug_mb(void);
 
 extern void libcfs_debug_dumplog_internal(void *arg);
 int cfs_trace_get_debug_mb(void);
 
 extern void libcfs_debug_dumplog_internal(void *arg);