# define EXPORT_SYMTAB
#endif
-#ifdef HAVE_KERNEL_CONFIG_H
+#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <asm/div64.h>
#include "tracefile.h"
-static struct ctl_table_header *lnet_table_header = NULL;
+static cfs_sysctl_table_header_t *lnet_table_header = NULL;
extern char lnet_upcall[1024];
#define PSDEV_LNET (0x100)
PSDEV_LNET_UPCALL, /* User mode upcall script */
PSDEV_LNET_MEMUSED, /* bytes currently PORTAL_ALLOCated */
PSDEV_LNET_CATASTROPHE, /* if we have LBUGged or panic'd */
+ PSDEV_LNET_PANIC_ON_LBUG, /* flag to panic on LBUG */
+ PSDEV_LNET_DUMP_KERNEL, /* snapshot kernel debug buffer to file */
+ PSDEV_LNET_DAEMON_FILE, /* spool kernel debug buffer to file */
+ PSDEV_LNET_DEBUG_MB, /* size of debug buffer */
};
-int LL_PROC_PROTO(proc_dobitmasks);
-
-static struct ctl_table lnet_table[] = {
- {PSDEV_DEBUG, "debug", &libcfs_debug, sizeof(int), 0644, NULL,
- &proc_dobitmasks},
- {PSDEV_SUBSYSTEM_DEBUG, "subsystem_debug", &libcfs_subsystem_debug,
- sizeof(int), 0644, NULL, &proc_dobitmasks},
- {PSDEV_PRINTK, "printk", &libcfs_printk, sizeof(int), 0644, NULL,
- &proc_dobitmasks},
- {PSDEV_CONSOLE_RATELIMIT, "console_ratelimit",&libcfs_console_ratelimit,
- sizeof(int), 0644, NULL, &proc_dointvec},
- {PSDEV_DEBUG_PATH, "debug_path", debug_file_path,
- sizeof(debug_file_path), 0644, NULL, &proc_dostring, &sysctl_string},
- {PSDEV_LNET_UPCALL, "upcall", lnet_upcall,
- sizeof(lnet_upcall), 0644, NULL, &proc_dostring,
- &sysctl_string},
- {PSDEV_LNET_MEMUSED, "memused", (int *)&libcfs_kmemory.counter,
- sizeof(int), 0444, NULL, &proc_dointvec},
- {PSDEV_LNET_CATASTROPHE, "catastrophe", &libcfs_catastrophe,
- sizeof(int), 0444, NULL, &proc_dointvec},
- {0}
-};
-
-static struct ctl_table top_table[2] = {
- {PSDEV_LNET, "lnet", NULL, 0, 0555, lnet_table},
- {0}
-};
-
-int LL_PROC_PROTO(proc_dobitmasks)
+static int
+proc_call_handler(void *data, int write,
+ loff_t *ppos, void *buffer, size_t *lenp,
+ int (*handler)(void *data, int write,
+ loff_t pos, void *buffer, int len))
{
- const int tmpstrlen = 512;
- char *str;
- int rc = 0;
- /* the proc filling api stumps me always, coax proc_dointvec
- * and proc_dostring into doing the drudgery by cheating
- * with a dummy ctl_table
- */
- struct ctl_table dummy = *table;
- unsigned int *mask = (unsigned int *)table->data;
- int is_subsys = (mask == &libcfs_subsystem_debug) ? 1 : 0;
+ int rc = handler(data, write, *ppos, buffer, *lenp);
- str = kmalloc(tmpstrlen, GFP_USER);
- if (str == NULL)
- return -ENOMEM;
+ if (rc < 0)
+ return rc;
if (write) {
- size_t oldlen = *lenp;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
- loff_t oldpos = *ppos;
-#endif
-
- dummy.proc_handler = &proc_dointvec;
-
- /* old proc interface allows user to specify just an int
- * value; be compatible and don't break userland.
- */
- rc = ll_proc_dointvec(&dummy, write, filp, buffer, lenp, ppos);
-
- if (rc != -EINVAL)
- goto out;
-
- /* using new interface */
- dummy.data = str;
- dummy.maxlen = tmpstrlen;
- dummy.proc_handler = &proc_dostring;
-
- /* proc_dointvec might have changed these */
- *lenp = oldlen;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
- *ppos = oldpos;
-#endif
+ *ppos += *lenp;
+ } else {
+ *lenp = rc;
+ *ppos += rc;
+ }
+ return 0;
+}
- rc = ll_proc_dostring(&dummy, write, filp, buffer, lenp, ppos);
+#define DECLARE_PROC_HANDLER(name) \
+static int \
+LL_PROC_PROTO(name) \
+{ \
+ DECLARE_LL_PROC_PPOS_DECL; \
+ \
+ return proc_call_handler(table->data, write, \
+ ppos, buffer, lenp, \
+ __##name); \
+}
- if (rc != 0)
- goto out;
+static int __proc_dobitmasks(void *data, int write,
+ loff_t pos, void *buffer, int nob)
+{
+ const int tmpstrlen = 512;
+ char *tmpstr;
+ int rc;
+ unsigned int *mask = data;
+ int is_subsys = (mask == &libcfs_subsystem_debug) ? 1 : 0;
- rc = libcfs_debug_str2mask(mask, dummy.data, is_subsys);
+ rc = trace_allocate_string_buffer(&tmpstr, tmpstrlen);
+ if (rc < 0)
+ return rc;
+
+ if (!write) {
+ libcfs_debug_mask2str(tmpstr, tmpstrlen, *mask, is_subsys);
+ rc = strlen(tmpstr);
+
+ if (pos >= rc) {
+ rc = 0;
+ } else {
+ rc = trace_copyout_string(buffer, nob,
+ tmpstr + pos, "\n");
+ }
} else {
- dummy.data = str;
- dummy.maxlen = tmpstrlen;
- dummy.proc_handler = &proc_dostring;
-
- libcfs_debug_mask2str(dummy.data, dummy.maxlen,*mask,is_subsys);
-
- rc = ll_proc_dostring(&dummy, write, filp, buffer, lenp, ppos);
+ rc = trace_copyin_string(tmpstr, tmpstrlen, buffer, nob);
+ if (rc < 0)
+ return rc;
+
+ rc = libcfs_debug_str2mask(mask, tmpstr, is_subsys);
}
-out:
- kfree(str);
+ trace_free_string_buffer(tmpstr, tmpstrlen);
return rc;
}
-int insert_proc(void)
+DECLARE_PROC_HANDLER(proc_dobitmasks)
+
+static int __proc_dump_kernel(void *data, int write,
+ loff_t pos, void *buffer, int nob)
{
- struct proc_dir_entry *ent;
+ if (!write)
+ return 0;
+
+ return trace_dump_debug_buffer_usrstr(buffer, nob);
+}
-#ifdef CONFIG_SYSCTL
- if (!lnet_table_header)
- lnet_table_header = register_sysctl_table(top_table, 0);
-#endif
+DECLARE_PROC_HANDLER(proc_dump_kernel)
- ent = create_proc_entry("sys/lnet/dump_kernel", 0, NULL);
- if (ent == NULL) {
- CERROR("couldn't register dump_kernel\n");
- return -1;
+static int __proc_daemon_file(void *data, int write,
+ loff_t pos, void *buffer, int nob)
+{
+ if (!write) {
+ int len = strlen(tracefile);
+
+ if (pos >= len)
+ return 0;
+
+ return trace_copyout_string(buffer, nob,
+ tracefile + pos, "\n");
}
- ent->write_proc = trace_dk;
+
+ return trace_daemon_command_usrstr(buffer, nob);
+}
- ent = create_proc_entry("sys/lnet/daemon_file", 0, NULL);
- if (ent == NULL) {
- CERROR("couldn't register daemon_file\n");
- return -1;
- }
- ent->write_proc = trace_write_daemon_file;
- ent->read_proc = trace_read_daemon_file;
+DECLARE_PROC_HANDLER(proc_daemon_file)
- ent = create_proc_entry("sys/lnet/debug_mb", 0, NULL);
- if (ent == NULL) {
- CERROR("couldn't register debug_mb\n");
- return -1;
+static int __proc_debug_mb(void *data, int write,
+ loff_t pos, void *buffer, int nob)
+{
+ if (!write) {
+ char tmpstr[32];
+ int len = snprintf(tmpstr, sizeof(tmpstr), "%d",
+ trace_get_debug_mb());
+
+ if (pos >= len)
+ return 0;
+
+ return trace_copyout_string(buffer, nob, tmpstr + pos, "\n");
}
- ent->write_proc = trace_write_debug_mb;
- ent->read_proc = trace_read_debug_mb;
+
+ return trace_set_debug_mb_usrstr(buffer, nob);
+}
+
+DECLARE_PROC_HANDLER(proc_debug_mb)
+static cfs_sysctl_table_t lnet_table[] = {
+ /*
+ * NB No .strategy entries have been provided since sysctl(8) prefers
+ * to go via /proc for portability.
+ */
+ {
+ .ctl_name = PSDEV_DEBUG,
+ .procname = "debug",
+ .data = &libcfs_debug,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dobitmasks
+ },
+ {
+ .ctl_name = PSDEV_SUBSYSTEM_DEBUG,
+ .procname = "subsystem_debug",
+ .data = &libcfs_subsystem_debug,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dobitmasks
+ },
+ {
+ .ctl_name = PSDEV_PRINTK,
+ .procname = "printk",
+ .data = &libcfs_printk,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dobitmasks
+ },
+ {
+ .ctl_name = PSDEV_CONSOLE_RATELIMIT,
+ .procname = "console_ratelimit",
+ .data = &libcfs_console_ratelimit,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+
+ {
+ .ctl_name = PSDEV_DEBUG_PATH,
+ .procname = "debug_path",
+ .data = debug_file_path,
+ .maxlen = sizeof(debug_file_path),
+ .mode = 0644,
+ .proc_handler = &proc_dostring,
+ },
+
+ {
+ .ctl_name = PSDEV_LNET_UPCALL,
+ .procname = "upcall",
+ .data = lnet_upcall,
+ .maxlen = sizeof(lnet_upcall),
+ .mode = 0644,
+ .proc_handler = &proc_dostring,
+ },
+ {
+ .ctl_name = PSDEV_LNET_MEMUSED,
+ .procname = "memused",
+ .data = (int *)&libcfs_kmemory.counter,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec
+ },
+ {
+ .ctl_name = PSDEV_LNET_CATASTROPHE,
+ .procname = "catastrophe",
+ .data = &libcfs_catastrophe,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec
+ },
+ {
+ .ctl_name = PSDEV_LNET_PANIC_ON_LBUG,
+ .procname = "panic_on_lbug",
+ .data = &libcfs_panic_on_lbug,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+ {
+ .ctl_name = PSDEV_LNET_DUMP_KERNEL,
+ .procname = "dump_kernel",
+ .mode = 0200,
+ .proc_handler = &proc_dump_kernel,
+ },
+ {
+ .ctl_name = PSDEV_LNET_DAEMON_FILE,
+ .procname = "daemon_file",
+ .mode = 0644,
+ .proc_handler = &proc_daemon_file,
+ },
+ {
+ .ctl_name = PSDEV_LNET_DEBUG_MB,
+ .procname = "debug_mb",
+ .mode = 0644,
+ .proc_handler = &proc_debug_mb,
+ },
+ {0}
+};
+
+static cfs_sysctl_table_t top_table[2] = {
+ {
+ .ctl_name = PSDEV_LNET,
+ .procname = "lnet",
+ .data = NULL,
+ .maxlen = 0,
+ .mode = 0555,
+ .child = lnet_table
+ },
+ {0}
+};
+
+int insert_proc(void)
+{
+#ifdef CONFIG_SYSCTL
+ if (lnet_table_header == NULL)
+ lnet_table_header = cfs_register_sysctl_table(top_table, 0);
+#endif
return 0;
}
void remove_proc(void)
{
- remove_proc_entry("sys/lnet/dump_kernel", NULL);
- remove_proc_entry("sys/lnet/daemon_file", NULL);
- remove_proc_entry("sys/lnet/debug_mb", NULL);
-
#ifdef CONFIG_SYSCTL
- if (lnet_table_header)
- unregister_sysctl_table(lnet_table_header);
+ if (lnet_table_header != NULL)
+ cfs_unregister_sysctl_table(lnet_table_header);
+
lnet_table_header = NULL;
#endif
}