1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5 * Author: Zach Brown <zab@zabbo.net>
6 * Author: Peter J. Braam <braam@clusterfs.com>
7 * Author: Phil Schwan <phil@clusterfs.com>
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 # define EXPORT_SYMTAB
29 #ifdef HAVE_KERNEL_CONFIG_H
30 #include <linux/config.h>
32 #include <linux/module.h>
33 #include <linux/kernel.h>
35 #include <linux/string.h>
36 #include <linux/stat.h>
37 #include <linux/errno.h>
38 #include <linux/smp_lock.h>
39 #include <linux/unistd.h>
41 #include <linux/uio.h>
43 #include <asm/system.h>
44 #include <asm/uaccess.h>
47 #include <linux/file.h>
48 #include <linux/stat.h>
49 #include <linux/list.h>
50 #include <asm/uaccess.h>
51 #include <asm/segment.h>
53 #include <linux/proc_fs.h>
54 #include <linux/sysctl.h>
56 # define DEBUG_SUBSYSTEM S_LNET
58 #include <libcfs/kp30.h>
59 #include <asm/div64.h>
60 #include "tracefile.h"
62 static struct ctl_table_header *lnet_table_header = NULL;
63 extern char lnet_upcall[1024];
65 #define PSDEV_LNET (0x100)
67 PSDEV_DEBUG = 1, /* control debugging */
68 PSDEV_SUBSYSTEM_DEBUG, /* control debugging */
69 PSDEV_PRINTK, /* force all messages to console */
70 PSDEV_CONSOLE_RATELIMIT, /* ratelimit console messages */
71 PSDEV_DEBUG_PATH, /* crashdump log location */
72 PSDEV_DEBUG_DUMP_PATH, /* crashdump tracelog location */
73 PSDEV_LNET_UPCALL, /* User mode upcall script */
74 PSDEV_LNET_MEMUSED, /* bytes currently PORTAL_ALLOCated */
75 PSDEV_LNET_CATASTROPHE, /* if we have LBUGged or panic'd */
78 int LL_PROC_PROTO(proc_dobitmasks);
80 static struct ctl_table lnet_table[] = {
82 .ctl_name = PSDEV_DEBUG,
84 .data = &libcfs_debug,
85 .maxlen = sizeof(int),
87 .proc_handler = &proc_dobitmasks
90 .ctl_name = PSDEV_SUBSYSTEM_DEBUG,
91 .procname = "subsystem_debug",
92 .data = &libcfs_subsystem_debug,
93 .maxlen = sizeof(int),
95 .proc_handler = &proc_dobitmasks
98 .ctl_name = PSDEV_PRINTK,
100 .data = &libcfs_printk,
101 .maxlen = sizeof(int),
103 .proc_handler = &proc_dobitmasks
106 .ctl_name = PSDEV_CONSOLE_RATELIMIT,
107 .procname = "console_ratelimit",
108 .data = &libcfs_console_ratelimit,
109 .maxlen = sizeof(int),
111 .proc_handler = &proc_dointvec
115 .ctl_name = PSDEV_DEBUG_PATH,
116 .procname = "debug_path",
117 .data = debug_file_path,
118 .maxlen = sizeof(debug_file_path),
120 .proc_handler = &proc_dostring,
121 .strategy = &sysctl_string
125 .ctl_name = PSDEV_LNET_UPCALL,
126 .procname = "upcall",
128 .maxlen = sizeof(lnet_upcall),
130 .proc_handler = &proc_dostring,
131 .strategy = &sysctl_string
134 .ctl_name = PSDEV_LNET_MEMUSED,
135 .procname = "memused",
136 .data = (int *)&libcfs_kmemory.counter,
137 .maxlen = sizeof(int),
139 .proc_handler = &proc_dointvec
142 .ctl_name = PSDEV_LNET_CATASTROPHE,
143 .procname = "catastrophe",
144 .data = &libcfs_catastrophe,
145 .maxlen = sizeof(int),
147 .proc_handler = &proc_dointvec
152 static struct ctl_table top_table[2] = {
154 .ctl_name = PSDEV_LNET,
164 int LL_PROC_PROTO(proc_dobitmasks)
166 const int tmpstrlen = 512;
169 /* the proc filling api stumps me always, coax proc_dointvec
170 * and proc_dostring into doing the drudgery by cheating
171 * with a dummy ctl_table
173 struct ctl_table dummy = *table;
174 unsigned int *mask = (unsigned int *)table->data;
175 int is_subsys = (mask == &libcfs_subsystem_debug) ? 1 : 0;
177 str = kmalloc(tmpstrlen, GFP_USER);
182 size_t oldlen = *lenp;
183 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
184 loff_t oldpos = *ppos;
187 dummy.proc_handler = &proc_dointvec;
189 /* old proc interface allows user to specify just an int
190 * value; be compatible and don't break userland.
192 rc = ll_proc_dointvec(&dummy, write, filp, buffer, lenp, ppos);
197 /* using new interface */
199 dummy.maxlen = tmpstrlen;
200 dummy.proc_handler = &proc_dostring;
202 /* proc_dointvec might have changed these */
204 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
208 rc = ll_proc_dostring(&dummy, write, filp, buffer, lenp, ppos);
213 rc = libcfs_debug_str2mask(mask, dummy.data, is_subsys);
216 dummy.maxlen = tmpstrlen;
217 dummy.proc_handler = &proc_dostring;
219 libcfs_debug_mask2str(dummy.data, dummy.maxlen,*mask,is_subsys);
221 rc = ll_proc_dostring(&dummy, write, filp, buffer, lenp, ppos);
229 int insert_proc(void)
231 struct proc_dir_entry *ent;
234 if (!lnet_table_header)
235 lnet_table_header = cfs_register_sysctl_table(top_table, 0);
238 ent = create_proc_entry("sys/lnet/dump_kernel", 0, NULL);
240 CERROR("couldn't register dump_kernel\n");
243 ent->write_proc = trace_dk;
245 ent = create_proc_entry("sys/lnet/daemon_file", 0, NULL);
247 CERROR("couldn't register daemon_file\n");
250 ent->write_proc = trace_write_daemon_file;
251 ent->read_proc = trace_read_daemon_file;
253 ent = create_proc_entry("sys/lnet/debug_mb", 0, NULL);
255 CERROR("couldn't register debug_mb\n");
258 ent->write_proc = trace_write_debug_mb;
259 ent->read_proc = trace_read_debug_mb;
264 void remove_proc(void)
266 remove_proc_entry("sys/lnet/dump_kernel", NULL);
267 remove_proc_entry("sys/lnet/daemon_file", NULL);
268 remove_proc_entry("sys/lnet/debug_mb", NULL);
271 if (lnet_table_header)
272 cfs_unregister_sysctl_table(lnet_table_header);
273 lnet_table_header = NULL;