Whamcloud - gitweb
a38902aef1215ac2f2ec2d8dc30f51aa3ee7bd02
[fs/lustre-release.git] / lnet / libcfs / darwin / darwin-proc.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
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.
11  *
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.
16  *
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.
20  */
21
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>
27 #include <sys/proc.h>
28 #include <sys/unistd.h>
29 #include <mach/mach_types.h>
30
31 #define DEBUG_SUBSYSTEM S_LNET
32
33 #include <libcfs/libcfs.h>
34
35 #define LIBCFS_SYSCTL           "libcfs"
36 #define LIBCFS_SYSCTL_SPRITE    "sprite"
37 #define LIBCFS_SYSCTL_MAGIC     0xbabeface
38
39 static struct libcfs_sysctl_sprite {
40         int                     ss_magic;
41         struct sysctl_oid_list  *ss_link;
42 } libcfs_sysctl_sprite = { 0, NULL };
43
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;
51
52 extern long max_debug_mb;
53 extern int cfs_trace_daemon SYSCTL_HANDLER_ARGS;
54 extern int cfs_debug_mb SYSCTL_HANDLER_ARGS;
55 /*
56  * sysctl table for lnet
57  */
58
59 SYSCTL_NODE (,                  OID_AUTO,       lnet,   CTLFLAG_RW,
60              0,                 "lnet sysctl top");
61
62 SYSCTL_INT(_lnet,                       OID_AUTO,       debug,
63              CTLTYPE_INT | CTLFLAG_RW ,                 &libcfs_debug,
64              0,         "debug");
65 SYSCTL_INT(_lnet,                       OID_AUTO,       subsystem_debug,
66              CTLTYPE_INT | CTLFLAG_RW,                  &libcfs_subsystem_debug,
67              0,         "subsystem debug");
68 SYSCTL_INT(_lnet,                       OID_AUTO,       printk,
69              CTLTYPE_INT | CTLFLAG_RW,                  &libcfs_printk,
70              0,         "printk");
71 SYSCTL_INT(_lnet,                       OID_AUTO,       console_ratelimit,
72              CTLTYPE_INT | CTLFLAG_RW,                  &libcfs_console_ratelimit,
73              0,         "console_ratelimit");
74 SYSCTL_STRING(_lnet,                    OID_AUTO,       debug_path,
75              CTLTYPE_STRING | CTLFLAG_RW,               debug_file_path,
76              1024,      "debug path");
77 SYSCTL_INT(_lnet,                       OID_AUTO,       memused,
78              CTLTYPE_INT | CTLFLAG_RW,                  (int *)&libcfs_kmemory.counter,
79              0,         "memused");
80 SYSCTL_INT(_lnet,                       OID_AUTO,       catastrophe,
81              CTLTYPE_INT | CTLFLAG_RW,                  (int *)&libcfs_catastrophe,
82              0,         "catastrophe");
83 SYSCTL_PROC(_lnet,                      OID_AUTO,       trace_daemon,
84              CTLTYPE_STRING | CTLFLAG_RW,               0,
85              0,         &cfs_trace_daemon,              "A",    "trace daemon");
86 SYSCTL_PROC(_lnet,                      OID_AUTO,       debug_mb,
87              CTLTYPE_INT | CTLFLAG_RW,                  &max_debug_mb,
88              0,         &cfs_debug_mb,                  "L",    "max debug size");
89
90
91 static cfs_sysctl_table_t       top_table[] = {
92         &sysctl__lnet,
93         &sysctl__lnet_debug,
94         &sysctl__lnet_subsystem_debug,
95         &sysctl__lnet_printk,
96         &sysctl__lnet_console_ratelimit,
97         &sysctl__lnet_debug_path,
98         &sysctl__lnet_memused,
99         &sysctl__lnet_catastrophe,
100         &sysctl__lnet_trace_daemon,
101         &sysctl__lnet_debug_mb,
102         NULL
103 };
104
105 /*
106  * Register sysctl table
107  */
108 cfs_sysctl_table_header_t *
109 cfs_register_sysctl_table (cfs_sysctl_table_t *table, int arg)
110 {
111         cfs_sysctl_table_t      item;
112         int i = 0;
113
114         while ((item = table[i++]) != NULL) 
115                 sysctl_register_oid(item);
116         return table;
117 }
118
119 /*
120  * Unregister sysctl table
121  */
122 void
123 cfs_unregister_sysctl_table (cfs_sysctl_table_header_t *table) {
124         int i = 0;
125         cfs_sysctl_table_t      item;
126
127         while ((item = table[i++]) != NULL) 
128                 sysctl_unregister_oid(item);
129         return;
130 }
131
132 /*
133  * Allocate a sysctl oid. 
134  */
135 static struct sysctl_oid *
136 cfs_alloc_sysctl(struct sysctl_oid_list *parent, int nbr, int access,
137                  const char *name, void *arg1, int arg2, const char *fmt,
138                  int (*handler) SYSCTL_HANDLER_ARGS)
139 {
140         struct sysctl_oid *oid;
141         char    *sname = NULL;
142         char    *sfmt = NULL;
143
144         if (strlen(name) + 1 > CTL_MAXNAME) {
145                 printf("libcfs: sysctl name: %s is too long.\n", name);
146                 return NULL;
147         }
148         oid = (struct sysctl_oid*)_MALLOC(sizeof(struct sysctl_oid), 
149                                           M_TEMP, M_WAITOK | M_ZERO);
150         if (oid == NULL) 
151                 return NULL;
152
153         sname = (char *)_MALLOC(sizeof(CTL_MAXNAME), 
154                                 M_TEMP, M_WAITOK | M_ZERO);
155         if (sname == NULL) 
156                 goto error;
157         strcpy(sname, name);
158
159         sfmt = (char *)_MALLOC(4, M_TEMP, M_WAITOK | M_ZERO);
160         if (sfmt == NULL) 
161                 goto error;
162         strcpy(sfmt, fmt);
163
164         if (parent == NULL)
165                 oid->oid_parent = &sysctl__children;
166         else
167                 oid->oid_parent = parent;
168         oid->oid_number = nbr;
169         oid->oid_kind = access;
170         oid->oid_name = sname;
171         oid->oid_handler = handler;
172         oid->oid_fmt = sfmt;
173
174         if ((access & CTLTYPE) == CTLTYPE_NODE){
175                 /* It's a sysctl node */
176                 struct sysctl_oid_list *link;
177
178                 link = (struct sysctl_oid_list *)_MALLOC(sizeof(struct sysctl_oid_list), 
179                                                          M_TEMP, M_WAITOK | M_ZERO);
180                 if (link == NULL)
181                         goto error;
182                 oid->oid_arg1 = link;
183                 oid->oid_arg2 = 0;
184         } else {
185                 oid->oid_arg1 = arg1;
186                 oid->oid_arg2 = arg2;
187         }
188
189         return oid;
190 error:
191         if (sfmt != NULL)
192                 _FREE(sfmt, M_TEMP);
193         if (sname != NULL)
194                 _FREE(sname, M_TEMP);
195         if (oid != NULL)
196                 _FREE(oid, M_TEMP);
197         return NULL;
198 }
199
200 void cfs_free_sysctl(struct sysctl_oid *oid)
201 {
202         if (oid->oid_name != NULL)
203                 _FREE((void *)oid->oid_name, M_TEMP);
204         if (oid->oid_fmt != NULL)
205                 _FREE((void *)oid->oid_fmt, M_TEMP);
206         if ((oid->oid_kind & CTLTYPE_NODE != 0) && oid->oid_arg1)
207                 /* XXX Liang: need to assert the list is empty */
208                 _FREE(oid->oid_arg1, M_TEMP);
209         _FREE(oid, M_TEMP);
210 }
211
212 #define CFS_SYSCTL_ISVALID ((libcfs_sysctl_sprite.ss_magic == LIBCFS_SYSCTL_MAGIC) && \
213                             (libcfs_sysctl_sprite.ss_link != NULL))       
214
215 int
216 cfs_sysctl_isvalid(void)
217 {
218         return CFS_SYSCTL_ISVALID;
219 }
220
221 struct sysctl_oid *
222 cfs_alloc_sysctl_node(struct sysctl_oid_list *parent, int nbr, int access,
223                       const char *name, int (*handler) SYSCTL_HANDLER_ARGS)
224 {
225         if (parent == NULL && CFS_SYSCTL_ISVALID)
226                 parent = libcfs_sysctl_sprite.ss_link;
227         return cfs_alloc_sysctl(parent, nbr, CTLTYPE_NODE | access, name,
228                                 NULL, 0, "N", handler);
229 }
230
231 struct sysctl_oid *
232 cfs_alloc_sysctl_int(struct sysctl_oid_list *parent, int nbr, int access,
233                      const char *name, int *ptr, int val)
234 {
235         if (parent == NULL && CFS_SYSCTL_ISVALID)
236                 parent = libcfs_sysctl_sprite.ss_link;
237         return cfs_alloc_sysctl(parent, nbr, CTLTYPE_INT | access, name, 
238                                 ptr, val, "I", sysctl_handle_int);
239 }
240
241 struct sysctl_oid *
242 cfs_alloc_sysctl_long(struct sysctl_oid_list *parent, int nbr, int access,
243                       const char *name, int *ptr, int val)
244 {
245         if (parent == NULL && CFS_SYSCTL_ISVALID)
246                 parent = libcfs_sysctl_sprite.ss_link;
247         return cfs_alloc_sysctl(parent, nbr, CTLTYPE_INT | access, name, 
248                                 ptr, val, "L", sysctl_handle_long);
249 }
250
251 struct sysctl_oid *
252 cfs_alloc_sysctl_string(struct sysctl_oid_list *parent, int nbr, int access,
253                         const char *name, char *ptr, int len)
254 {
255         if (parent == NULL && CFS_SYSCTL_ISVALID)
256                 parent = libcfs_sysctl_sprite.ss_link;
257         return cfs_alloc_sysctl(parent, nbr, CTLTYPE_STRING | access, name, 
258                                 ptr, len, "A", sysctl_handle_string);
259 }
260
261 struct sysctl_oid *
262 cfs_alloc_sysctl_struct(struct sysctl_oid_list *parent, int nbr, int access,
263                         const char *name, void *ptr, int size)
264 {
265         if (parent == NULL && CFS_SYSCTL_ISVALID)
266                 parent = libcfs_sysctl_sprite.ss_link;
267         return cfs_alloc_sysctl(parent, nbr, CTLTYPE_OPAQUE | access, name,
268                                 ptr, size, "S", sysctl_handle_opaque);
269 }
270
271 /* no proc in osx */
272 cfs_proc_dir_entry_t *
273 cfs_create_proc_entry(char *name, int mod, cfs_proc_dir_entry_t *parent)
274 {
275         cfs_proc_dir_entry_t *entry;
276         MALLOC(entry, cfs_proc_dir_entry_t *, sizeof(cfs_proc_dir_entry_t), M_TEMP, M_WAITOK|M_ZERO);
277
278         return  entry;
279 }
280
281 void
282 cfs_free_proc_entry(cfs_proc_dir_entry_t *de){
283         FREE(de, M_TEMP);
284         return;
285 };
286
287 void
288 cfs_remove_proc_entry(char *name, cfs_proc_dir_entry_t *entry)
289 {
290         cfs_free_proc_entry(entry);
291         return;
292 }
293
294 int
295 insert_proc(void)
296 {
297 #if 1
298         if (!libcfs_table_header) 
299                 libcfs_table_header = cfs_register_sysctl_table(top_table, 0);
300 #endif
301         return 0;
302 }
303
304 void
305 remove_proc(void)
306 {
307 #if 1
308         if (libcfs_table_header != NULL) 
309                 cfs_unregister_sysctl_table(libcfs_table_header); 
310         libcfs_table_header = NULL;
311 #endif
312         return;
313 }
314
315 int
316 cfs_sysctl_init(void)
317 {
318         struct sysctl_oid               *oid_root;
319         struct sysctl_oid               *oid_sprite;
320         struct libcfs_sysctl_sprite     *sprite;
321         size_t  len; 
322         int     rc;
323
324         len = sizeof(struct libcfs_sysctl_sprite);
325         rc = sysctlbyname("libcfs.sprite", 
326                           (void *)&libcfs_sysctl_sprite, &len, NULL, 0);
327         if (rc == 0) {
328                 /* 
329                  * XXX Liang: assert (rc == 0 || rc == ENOENT)
330                  *
331                  * libcfs.sprite has been registered by previous 
332                  * loading of libcfs 
333                  */
334                 if (libcfs_sysctl_sprite.ss_magic != LIBCFS_SYSCTL_MAGIC) {
335                         printf("libcfs: magic number of libcfs.sprite "
336                                "is not right (%lx, %lx)\n", 
337                                libcfs_sysctl_sprite.ss_magic,
338                                LIBCFS_SYSCTL_MAGIC);
339                         return -1;
340                 }
341                 assert(libcfs_sysctl_sprite.ss_link != NULL);
342                 printf("libcfs: registered libcfs.sprite found.\n");
343                 return 0;
344         }
345         oid_root = cfs_alloc_sysctl_node(NULL, OID_AUTO, CTLFLAG_RD | CTLFLAG_KERN,
346                                          LIBCFS_SYSCTL, 0);
347         if (oid_root == NULL)
348                 return -1;
349         sysctl_register_oid(oid_root);
350
351         sprite = (struct libcfs_sysctl_sprite *)_MALLOC(sizeof(struct libcfs_sysctl_sprite), 
352                                                         M_TEMP, M_WAITOK | M_ZERO);
353         if (sprite == NULL) {
354                 sysctl_unregister_oid(oid_root);
355                 cfs_free_sysctl(oid_root);
356                 return -1;
357         }
358         sprite->ss_magic = LIBCFS_SYSCTL_MAGIC;
359         sprite->ss_link = (struct sysctl_oid_list *)oid_root->oid_arg1;
360         oid_sprite = cfs_alloc_sysctl_struct((struct sysctl_oid_list *)oid_root->oid_arg1, 
361                                              OID_AUTO, CTLFLAG_RD | CTLFLAG_KERN, 
362                                              LIBCFS_SYSCTL_SPRITE, sprite, 
363                                              sizeof(struct libcfs_sysctl_sprite));
364         if (oid_sprite == NULL) {
365                 cfs_free_sysctl(oid_sprite);
366                 sysctl_unregister_oid(oid_root);
367                 cfs_free_sysctl(oid_root);
368                 return -1;
369         }
370         sysctl_register_oid(oid_sprite);
371
372         libcfs_sysctl_sprite.ss_magic = sprite->ss_magic;
373         libcfs_sysctl_sprite.ss_link = sprite->ss_link;
374
375         return 0;
376 }
377
378 void
379 cfs_sysctl_fini(void)
380 {
381         libcfs_sysctl_sprite.ss_magic = 0;
382         libcfs_sysctl_sprite.ss_link = NULL;
383 }
384