Whamcloud - gitweb
ea2b9c47240ecdf85bc8d07fc020b731598c5703
[fs/lustre-release.git] / lustre / obdclass / lprocfs_status.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 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
23 #define EXPORT_SYMTAB
24 #include <linux/config.h>
25 #include <linux/module.h>
26 #include <linux/version.h>
27 #include <linux/proc_fs.h>
28 #include <linux/slab.h>
29 #include <linux/types.h>
30
31 #define DEBUG_SUBSYSTEM S_CLASS
32 #define MAX_STRING_SIZE 100
33
34 #include <linux/lustre_lite.h>
35 #include <linux/lprocfs_status.h>
36
37 #ifdef LPROC_SNMP
38
39 #define DEFAULT_MODE 0444
40 /*
41  * Tokenizer array. Change this array to include special
42  * characters for string tokenizing
43  */
44 char tok[] = {'/', (char)0};
45
46
47
48 /*
49  * Externs
50  */
51 extern struct proc_dir_entry proc_root; /* Defined in proc/root.c */
52
53 /*
54  * Globals
55  */
56 struct proc_dir_entry *proc_lustre_root = 0;
57 struct proc_dir_entry *proc_lustre_dev_root = 0;
58 struct proc_dir_entry *proc_lustre_fs_root=0;
59
60 struct proc_dir_entry* lprocfs_mkdir(const char* dname,
61                                      struct proc_dir_entry *parent)
62 {
63         struct proc_dir_entry *child_dir_entry;
64
65         child_dir_entry = proc_mkdir(dname, parent);
66
67         if (!child_dir_entry)
68                 CERROR("lustre: failed to create /proc entry %s\n", dname);
69
70         return child_dir_entry;
71 }
72 struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry* head,
73                                     const char* name)
74 {
75         struct proc_dir_entry* temp;
76         
77         if (!head)
78                 return 0;
79         temp = head->subdir;
80         while (temp != NULL) {
81                 if (!strcmp(temp->name, name))
82                         return temp;
83                 temp = temp->next;
84         }
85         
86         return 0;
87 }
88
89
90 void lprocfs_remove_all(struct proc_dir_entry* root)
91 {
92
93         struct proc_dir_entry *temp=root;
94         struct proc_dir_entry* rm_entry;
95
96         while(1){
97
98                 while(temp->subdir){
99                         temp=temp->subdir;
100         }
101                 rm_entry=temp;
102                 temp=temp->parent;
103                 remove_proc_entry(rm_entry->name, rm_entry->parent);
104                 if(temp==root->parent) break;
105
106         }
107
108
109 }
110
111 struct proc_dir_entry* lprocfs_new_dir(struct proc_dir_entry* root,
112                                        const char* string, 
113                                        const char* tok)
114 {
115         struct proc_dir_entry* new_root = 0;
116         struct proc_dir_entry* temp_entry = 0;
117         
118         char temp_string[MAX_STRING_SIZE];
119         char* my_str;
120         char* mover_str;
121
122         /*
123          * Remove trailing escaping character
124          */
125         memset(temp_string, 0, MAX_STRING_SIZE);
126         if (strlen(string) >= MAX_STRING_SIZE) {
127                 CDEBUG(D_OTHER, "Directory namespace too long");
128                 return 0;
129         }
130        
131         strcpy(temp_string, string);
132         temp_string[strlen(string) + 1] = '\0';
133         
134         new_root=root;
135         mover_str=temp_string;
136         while ((my_str = strsep(&mover_str, tok))) {
137                 if(!*my_str)
138                         continue;
139                 CDEBUG(D_OTHER, "SEARCH= %s\t, ROOT=%s\n", my_str, 
140                        new_root->name);
141                 temp_entry = lprocfs_srch(new_root, my_str);
142                 if (temp_entry == 0) {
143                         CDEBUG(D_OTHER, "Adding: %s\n", my_str);
144                         temp_entry = lprocfs_mkdir(my_str, new_root);
145                         if (temp_entry == 0) {
146                                 CDEBUG(D_OTHER, 
147                                        "! Did not create new dir %s !!\n",
148                                        my_str);
149                                 return 0;
150                         }
151                 }
152                 new_root = temp_entry;
153         }
154
155         return new_root;
156 }
157
158 int lprocfs_new_vars(struct proc_dir_entry* root,
159                      lprocfs_vars_t* list,
160                      const char* tok, 
161                      void* data)
162 {
163         struct proc_dir_entry* temp_root=0;
164         struct proc_dir_entry* new_leaf=0;
165         struct proc_dir_entry* new_parent=0;
166         char temp_string[MAX_STRING_SIZE];
167         
168         if(!list)
169                 return 0;
170
171         while(list->name){
172                 temp_root=lprocfs_new_dir(root, list->name, tok);
173                 
174                 if(!temp_root){
175                         CDEBUG(D_OTHER, "!LProcFS: Mods: No root!");
176                         return -EINVAL;
177                 }
178                 /* Convert the last element into a leaf-node */
179                 memset(temp_string, 0, MAX_STRING_SIZE);
180                 strcpy(temp_string, temp_root->name);
181                 temp_string[strlen(temp_root->name) + 1] = '\0';
182                 new_parent=temp_root->parent;
183                 if (new_parent != 0){
184                         remove_proc_entry(temp_root->name, new_parent);
185                 } else {
186                         remove_proc_entry(temp_root->name, NULL);
187                 }
188                 new_leaf = create_proc_entry(temp_string, DEFAULT_MODE, 
189                                              new_parent);
190                 new_leaf->read_proc = list->read_fptr;
191                 new_leaf->write_proc = list->write_fptr;
192                 new_leaf->data=data;
193                 list++;
194         }
195         return 0;
196
197 }
198
199 /*
200  *  API implementations
201  */
202
203 int lprocfs_add_vars(struct proc_dir_entry* root,
204                      lprocfs_vars_t* var, 
205                      void* data)
206 {
207             
208         return lprocfs_new_vars(root, var, 
209                                 (const char*) tok, data);
210
211         
212 }
213
214 int lprocfs_reg_obd(struct obd_device* device, 
215                     lprocfs_vars_t* list, 
216                     void* data)
217 {
218         
219         int retval = 0;
220         struct proc_dir_entry* this_dev_root=0;
221         
222         /* Obtain this device root */
223         this_dev_root = lprocfs_mkdir(device->obd_name, 
224                                       device->obd_type->typ_procroot);
225             
226         device->obd_proc_entry=this_dev_root;
227         retval=lprocfs_add_vars(this_dev_root, list, 
228                                 data);
229                 
230         return retval;
231 }
232
233 int lprocfs_dereg_obd(struct obd_device* device)
234 {
235
236         CDEBUG(D_OTHER, "LPROCFS removing device = %s\n", device->obd_name);
237
238         if (!device) {
239                 CDEBUG(D_OTHER, "! LProcfs:  Null pointer !\n");
240                 return 0;
241         }
242
243         lprocfs_remove_all(device->obd_proc_entry);
244
245         if (device->counters)
246                 OBD_FREE(device->counters, device->cntr_mem_size);
247
248         return 0;
249 }
250
251 struct proc_dir_entry* lprocfs_reg_mnt(char* mnt_name)
252 {
253         return lprocfs_mkdir(mnt_name, proc_lustre_fs_root);
254                        
255 }
256
257 int lprocfs_dereg_mnt(struct proc_dir_entry* root)
258 {
259         lprocfs_remove_all(root);
260          return 0;
261         
262 }
263
264 int lprocfs_reg_class(struct obd_type* type,
265                       lprocfs_vars_t* list, 
266                       void* data)
267 {
268         struct proc_dir_entry* root;
269         int retval;
270
271         root=lprocfs_mkdir(type->typ_name, proc_lustre_dev_root);        
272         
273         type->typ_procroot=root;
274
275         retval=lprocfs_add_vars(root, list, data);
276
277         return retval;
278 }
279
280 int lprocfs_dereg_class(struct obd_type* class)
281 {
282         if(!class){
283                 CDEBUG(D_OTHER, "Non-existent class",
284                        class->typ_name);
285                 return 0;
286         }
287                 
288         lprocfs_remove_all(class->typ_procroot);
289       
290         CDEBUG(D_OTHER, "LPROCFS removed = %s\n", class->typ_name);
291
292         return 0;
293
294 }
295 int lprocfs_reg_main()
296 {
297         proc_lustre_root = lprocfs_mkdir("lustre", &proc_root);
298         if (!proc_lustre_root) {
299                 CERROR(" !! Cannot create /proc/lustre !! \n");
300                 return -EINVAL;
301         }
302                 
303         proc_lustre_dev_root =lprocfs_mkdir("devices", proc_lustre_root);
304         
305         if (!proc_lustre_dev_root) {
306                 CERROR(" !! Cannot create /proc/lustre/devices !! \n");
307                 return -EINVAL;
308         }
309         proc_lustre_fs_root=lprocfs_mkdir("mnt_pnt", proc_lustre_root);
310         
311         if (!proc_lustre_fs_root) {
312                 CERROR(" !! Cannot create /proc/lustre/mnt_pnt !! \n");
313                 return -EINVAL;
314         }
315         
316         return 0;
317
318 }
319
320 int lprocfs_dereg_main()
321 {
322         lprocfs_remove_all(proc_lustre_root);
323         proc_lustre_root=0;
324         proc_lustre_dev_root=0;
325         proc_lustre_fs_root=0;
326         return 0;
327
328 }
329
330
331 /* 
332  * Needs to go...
333  */
334
335 int lprocfs_ll_rd(char *page, char **start, off_t off,
336                   int count, int *eof, void *data)
337 {
338         __u64 *temp = (__u64 *)data;
339         int len;
340
341         len = snprintf(page, count, LPU64"\n", *temp);
342
343         return len;
344 }
345
346 #endif /* LPROC_SNMP */
347
348
349 EXPORT_SYMBOL(lprocfs_reg_obd);
350 EXPORT_SYMBOL(lprocfs_dereg_obd);
351 EXPORT_SYMBOL(lprocfs_reg_main);
352 EXPORT_SYMBOL(lprocfs_dereg_main);
353 EXPORT_SYMBOL(lprocfs_reg_mnt);
354 EXPORT_SYMBOL(lprocfs_dereg_mnt);
355 EXPORT_SYMBOL(lprocfs_add_vars);
356 EXPORT_SYMBOL(lprocfs_reg_class);
357 EXPORT_SYMBOL(lprocfs_dereg_class);
358 EXPORT_SYMBOL(lprocfs_ll_rd);
359
360