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.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <sys/param.h>
23 #include <sys/kernel.h>
24 #include <sys/malloc.h>
25 #include <sys/systm.h>
26 #include <sys/sysctl.h>
28 #include <sys/unistd.h>
29 #include <mach/mach_types.h>
31 #define DEBUG_SUBSYSTEM S_LNET
33 #include <libcfs/libcfs.h>
35 #define LIBCFS_SYSCTL "libcfs"
36 #define LIBCFS_SYSCTL_SPRITE "sprite"
37 #define LIBCFS_SYSCTL_MAGIC 0xbabeface
39 static struct libcfs_sysctl_sprite {
41 struct sysctl_oid_list *ss_link;
42 } libcfs_sysctl_sprite = { 0, NULL };
44 static cfs_sysctl_table_header_t *libcfs_table_header = NULL;
45 extern unsigned int libcfs_debug;
46 extern unsigned int libcfs_subsystem_debug;
47 extern unsigned int libcfs_printk;
48 extern unsigned int libcfs_console_ratelimit;
49 extern unsigned int libcfs_catastrophe;
50 extern atomic_t libcfs_kmemory;
52 static int sysctl_debug_kernel SYSCTL_HANDLER_ARGS
55 const int maxstr = 1024;
59 if (req->newptr == USER_ADDR_NULL) {
65 error = trace_allocate_string_buffer(&str, maxstr + 1);
69 error = SYSCTL_IN(req, str, maxstr);
71 /* NB str guaranteed terminted */
73 error = tracefile_dump_all_pages(str);
75 trace_free_string_buffer(str, maxstr + 1);
79 static int sysctl_daemon_file SYSCTL_HANDLER_ARGS
85 if (req->newptr == USER_ADDR_NULL) {
87 tracefile_read_lock();
89 /* include terminating '\0' */
90 error = SYSCTL_OUT(req, tracefile, strlen(tracefile) + 1);
92 tracefile_read_unlock();
97 error = trace_allocate_string_buffer(&str, TRACEFILE_NAME_SIZE);
101 error = SYSCTL_IN(req, str, TRACEFILE_NAME_SIZE - 1);
103 /* NB str guaranteed terminted */
105 error = trace_daemon_command(str);
107 trace_free_string_buffer(str, TRACEFILE_NAME_SIZE);
112 static int sysctl_debug_mb SYSCTL_HANDLER_ARGS
118 if (req->newptr == USER_ADDR_NULL) {
120 mb = trace_get_debug_mb();
121 error = SYSCTL_OUT(req, &mb, sizeof(mb));
124 error = SYSCTL_IN(req, &mb, sizeof(mb));
126 error = trace_set_debug_mb(mb);
133 * sysctl table for lnet
136 SYSCTL_NODE (, OID_AUTO, lnet, CTLFLAG_RW,
137 0, "lnet sysctl top");
139 SYSCTL_INT(_lnet, OID_AUTO, debug,
140 CTLTYPE_INT | CTLFLAG_RW , &libcfs_debug,
142 SYSCTL_INT(_lnet, OID_AUTO, subsystem_debug,
143 CTLTYPE_INT | CTLFLAG_RW, &libcfs_subsystem_debug,
144 0, "subsystem debug");
145 SYSCTL_INT(_lnet, OID_AUTO, printk,
146 CTLTYPE_INT | CTLFLAG_RW, &libcfs_printk,
148 SYSCTL_INT(_lnet, OID_AUTO, console_ratelimit,
149 CTLTYPE_INT | CTLFLAG_RW, &libcfs_console_ratelimit,
150 0, "console_ratelimit");
151 SYSCTL_STRING(_lnet, OID_AUTO, debug_path,
152 CTLTYPE_STRING | CTLFLAG_RW, debug_file_path,
154 SYSCTL_INT(_lnet, OID_AUTO, memused,
155 CTLTYPE_INT | CTLFLAG_RW, (int *)&libcfs_kmemory.counter,
157 SYSCTL_INT(_lnet, OID_AUTO, catastrophe,
158 CTLTYPE_INT | CTLFLAG_RW, (int *)&libcfs_catastrophe,
162 SYSCTL_PROC(_lnet, OID_AUTO, debug_kernel,
163 CTLTYPE_STRING | CTLFLAG_W, 0,
164 0, &sysctl_debug_kernel, "A", "debug_kernel");
165 SYSCTL_PROC(_lnet, OID_AUTO, daemon_file,
166 CTLTYPE_STRING | CTLFLAG_RW, 0,
167 0, &sysctl_daemon_file, "A", "daemon_file");
168 SYSCTL_PROC(_lnet, OID_AUTO, debug_mb,
169 CTLTYPE_INT | CTLFLAG_RW, 0,
170 0, &sysctl_debug_mb, "L", "debug_mb");
173 static cfs_sysctl_table_t top_table[] = {
176 &sysctl__lnet_subsystem_debug,
177 &sysctl__lnet_printk,
178 &sysctl__lnet_console_ratelimit,
179 &sysctl__lnet_debug_path,
180 &sysctl__lnet_memused,
181 &sysctl__lnet_catastrophe,
182 &sysctl__lnet_debug_kernel,
183 &sysctl__lnet_daemon_file,
184 &sysctl__lnet_debug_mb,
189 * Register sysctl table
191 cfs_sysctl_table_header_t *
192 cfs_register_sysctl_table (cfs_sysctl_table_t *table, int arg)
194 cfs_sysctl_table_t item;
197 while ((item = table[i++]) != NULL)
198 sysctl_register_oid(item);
203 * Unregister sysctl table
206 cfs_unregister_sysctl_table (cfs_sysctl_table_header_t *table) {
208 cfs_sysctl_table_t item;
210 while ((item = table[i++]) != NULL)
211 sysctl_unregister_oid(item);
216 * Allocate a sysctl oid.
218 static struct sysctl_oid *
219 cfs_alloc_sysctl(struct sysctl_oid_list *parent, int nbr, int access,
220 const char *name, void *arg1, int arg2, const char *fmt,
221 int (*handler) SYSCTL_HANDLER_ARGS)
223 struct sysctl_oid *oid;
227 if (strlen(name) + 1 > CTL_MAXNAME) {
228 printf("libcfs: sysctl name: %s is too long.\n", name);
231 oid = (struct sysctl_oid*)_MALLOC(sizeof(struct sysctl_oid),
232 M_TEMP, M_WAITOK | M_ZERO);
236 sname = (char *)_MALLOC(sizeof(CTL_MAXNAME),
237 M_TEMP, M_WAITOK | M_ZERO);
242 sfmt = (char *)_MALLOC(4, M_TEMP, M_WAITOK | M_ZERO);
248 oid->oid_parent = &sysctl__children;
250 oid->oid_parent = parent;
251 oid->oid_number = nbr;
252 oid->oid_kind = access;
253 oid->oid_name = sname;
254 oid->oid_handler = handler;
257 if ((access & CTLTYPE) == CTLTYPE_NODE){
258 /* It's a sysctl node */
259 struct sysctl_oid_list *link;
261 link = (struct sysctl_oid_list *)_MALLOC(sizeof(struct sysctl_oid_list),
262 M_TEMP, M_WAITOK | M_ZERO);
265 oid->oid_arg1 = link;
268 oid->oid_arg1 = arg1;
269 oid->oid_arg2 = arg2;
277 _FREE(sname, M_TEMP);
283 void cfs_free_sysctl(struct sysctl_oid *oid)
285 if (oid->oid_name != NULL)
286 _FREE((void *)oid->oid_name, M_TEMP);
287 if (oid->oid_fmt != NULL)
288 _FREE((void *)oid->oid_fmt, M_TEMP);
289 if ((oid->oid_kind & CTLTYPE_NODE != 0) && oid->oid_arg1)
290 /* XXX Liang: need to assert the list is empty */
291 _FREE(oid->oid_arg1, M_TEMP);
295 #define CFS_SYSCTL_ISVALID ((libcfs_sysctl_sprite.ss_magic == LIBCFS_SYSCTL_MAGIC) && \
296 (libcfs_sysctl_sprite.ss_link != NULL))
299 cfs_sysctl_isvalid(void)
301 return CFS_SYSCTL_ISVALID;
305 cfs_alloc_sysctl_node(struct sysctl_oid_list *parent, int nbr, int access,
306 const char *name, int (*handler) SYSCTL_HANDLER_ARGS)
308 if (parent == NULL && CFS_SYSCTL_ISVALID)
309 parent = libcfs_sysctl_sprite.ss_link;
310 return cfs_alloc_sysctl(parent, nbr, CTLTYPE_NODE | access, name,
311 NULL, 0, "N", handler);
315 cfs_alloc_sysctl_int(struct sysctl_oid_list *parent, int nbr, int access,
316 const char *name, int *ptr, int val)
318 if (parent == NULL && CFS_SYSCTL_ISVALID)
319 parent = libcfs_sysctl_sprite.ss_link;
320 return cfs_alloc_sysctl(parent, nbr, CTLTYPE_INT | access, name,
321 ptr, val, "I", sysctl_handle_int);
325 cfs_alloc_sysctl_long(struct sysctl_oid_list *parent, int nbr, int access,
326 const char *name, int *ptr, int val)
328 if (parent == NULL && CFS_SYSCTL_ISVALID)
329 parent = libcfs_sysctl_sprite.ss_link;
330 return cfs_alloc_sysctl(parent, nbr, CTLTYPE_INT | access, name,
331 ptr, val, "L", sysctl_handle_long);
335 cfs_alloc_sysctl_string(struct sysctl_oid_list *parent, int nbr, int access,
336 const char *name, char *ptr, int len)
338 if (parent == NULL && CFS_SYSCTL_ISVALID)
339 parent = libcfs_sysctl_sprite.ss_link;
340 return cfs_alloc_sysctl(parent, nbr, CTLTYPE_STRING | access, name,
341 ptr, len, "A", sysctl_handle_string);
345 cfs_alloc_sysctl_struct(struct sysctl_oid_list *parent, int nbr, int access,
346 const char *name, void *ptr, int size)
348 if (parent == NULL && CFS_SYSCTL_ISVALID)
349 parent = libcfs_sysctl_sprite.ss_link;
350 return cfs_alloc_sysctl(parent, nbr, CTLTYPE_OPAQUE | access, name,
351 ptr, size, "S", sysctl_handle_opaque);
355 cfs_proc_dir_entry_t *
356 cfs_create_proc_entry(char *name, int mod, cfs_proc_dir_entry_t *parent)
358 cfs_proc_dir_entry_t *entry;
359 MALLOC(entry, cfs_proc_dir_entry_t *, sizeof(cfs_proc_dir_entry_t), M_TEMP, M_WAITOK|M_ZERO);
365 cfs_free_proc_entry(cfs_proc_dir_entry_t *de){
371 cfs_remove_proc_entry(char *name, cfs_proc_dir_entry_t *entry)
373 cfs_free_proc_entry(entry);
381 if (!libcfs_table_header)
382 libcfs_table_header = cfs_register_sysctl_table(top_table, 0);
391 if (libcfs_table_header != NULL)
392 cfs_unregister_sysctl_table(libcfs_table_header);
393 libcfs_table_header = NULL;
399 cfs_sysctl_init(void)
401 struct sysctl_oid *oid_root;
402 struct sysctl_oid *oid_sprite;
403 struct libcfs_sysctl_sprite *sprite;
407 len = sizeof(struct libcfs_sysctl_sprite);
408 rc = sysctlbyname("libcfs.sprite",
409 (void *)&libcfs_sysctl_sprite, &len, NULL, 0);
412 * XXX Liang: assert (rc == 0 || rc == ENOENT)
414 * libcfs.sprite has been registered by previous
417 if (libcfs_sysctl_sprite.ss_magic != LIBCFS_SYSCTL_MAGIC) {
418 printf("libcfs: magic number of libcfs.sprite "
419 "is not right (%lx, %lx)\n",
420 libcfs_sysctl_sprite.ss_magic,
421 LIBCFS_SYSCTL_MAGIC);
424 assert(libcfs_sysctl_sprite.ss_link != NULL);
425 printf("libcfs: registered libcfs.sprite found.\n");
428 oid_root = cfs_alloc_sysctl_node(NULL, OID_AUTO, CTLFLAG_RD | CTLFLAG_KERN,
430 if (oid_root == NULL)
432 sysctl_register_oid(oid_root);
434 sprite = (struct libcfs_sysctl_sprite *)_MALLOC(sizeof(struct libcfs_sysctl_sprite),
435 M_TEMP, M_WAITOK | M_ZERO);
436 if (sprite == NULL) {
437 sysctl_unregister_oid(oid_root);
438 cfs_free_sysctl(oid_root);
441 sprite->ss_magic = LIBCFS_SYSCTL_MAGIC;
442 sprite->ss_link = (struct sysctl_oid_list *)oid_root->oid_arg1;
443 oid_sprite = cfs_alloc_sysctl_struct((struct sysctl_oid_list *)oid_root->oid_arg1,
444 OID_AUTO, CTLFLAG_RD | CTLFLAG_KERN,
445 LIBCFS_SYSCTL_SPRITE, sprite,
446 sizeof(struct libcfs_sysctl_sprite));
447 if (oid_sprite == NULL) {
448 cfs_free_sysctl(oid_sprite);
449 sysctl_unregister_oid(oid_root);
450 cfs_free_sysctl(oid_root);
453 sysctl_register_oid(oid_sprite);
455 libcfs_sysctl_sprite.ss_magic = sprite->ss_magic;
456 libcfs_sysctl_sprite.ss_link = sprite->ss_link;
462 cfs_sysctl_fini(void)
464 libcfs_sysctl_sprite.ss_magic = 0;
465 libcfs_sysctl_sprite.ss_link = NULL;