Whamcloud - gitweb
d4c65e7887b8e01d007db79710a60b0ab7905f2e
[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 const char tok[] = {'/', '\0'};
45
46 /*
47  * Externs
48  */
49 extern struct proc_dir_entry proc_root; /* Defined in proc/root.c */
50
51 /*
52  * Globals
53  */
54 struct proc_dir_entry *proc_lustre_root;
55 struct proc_dir_entry *proc_lustre_dev_root;
56 struct proc_dir_entry *proc_lustre_fs_root;
57
58 struct proc_dir_entry* lprocfs_mkdir(const char* dname,
59                                      struct proc_dir_entry *parent)
60 {
61         struct proc_dir_entry *child_dir_entry;
62
63         child_dir_entry = proc_mkdir(dname, parent);
64
65         if (!child_dir_entry)
66                 CERROR("lustre: failed to create /proc entry %s\n", dname);
67
68         return child_dir_entry;
69 }
70
71 struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry* head,
72                                     const char* name)
73 {
74         struct proc_dir_entry* temp;
75
76         if (!head)
77                 return NULL;
78
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 NULL;
87 }
88
89 void lprocfs_remove_all(struct proc_dir_entry* root)
90 {
91         struct proc_dir_entry *temp = root;
92         struct proc_dir_entry *rm_entry;
93         struct proc_dir_entry *parent = root->parent;
94
95         while (1) {
96                 while (temp->subdir)
97                         temp = temp->subdir;
98
99                 rm_entry = temp;
100                 temp = temp->parent;
101                 remove_proc_entry(rm_entry->name, rm_entry->parent);
102                 if (temp == parent) break;
103         }
104 }
105
106 struct proc_dir_entry* lprocfs_new_dir(struct proc_dir_entry* root,
107                                        const char* string, const char* tok)
108 {
109         struct proc_dir_entry* new_root = 0;
110         struct proc_dir_entry* temp_entry = 0;
111         char temp_string[MAX_STRING_SIZE];
112         char* my_str;
113         char* mover_str;
114
115         strncpy(temp_string, string, MAX_STRING_SIZE-1);
116         temp_string[strlen(string) + 1] = '\0';
117
118         new_root = root;
119         mover_str = temp_string;
120         while ((my_str = strsep(&mover_str, tok))) {
121                 if(!*my_str)
122                         continue;
123                 CDEBUG(D_OTHER, "SEARCH= %s\t, ROOT=%s\n", my_str,
124                        new_root->name);
125                 temp_entry = lprocfs_srch(new_root, my_str);
126                 if (temp_entry == 0) {
127                         CDEBUG(D_OTHER, "Adding: %s\n", my_str);
128                         temp_entry = lprocfs_mkdir(my_str, new_root);
129                         if (temp_entry == 0) {
130                                 CDEBUG(D_OTHER, 
131                                        "! Did not create new dir %s !!\n",
132                                        my_str);
133                                 return 0;
134                         }
135                 }
136                 new_root = temp_entry;
137         }
138
139         return new_root;
140 }
141
142 int lprocfs_new_vars(struct proc_dir_entry* root, struct lprocfs_vars* list,
143                      const char* tok, void* data)
144 {
145         struct proc_dir_entry *temp_root;
146         struct proc_dir_entry *new_leaf;
147         struct proc_dir_entry *new_parent;
148         char temp_string[MAX_STRING_SIZE];
149
150         if (!list)
151                 return 0;
152
153         while (list->name) {
154                 temp_root = lprocfs_new_dir(root, list->name, tok);
155
156                 if (!temp_root) {
157                         CDEBUG(D_OTHER, "!LProcFS: Mods: No root!");
158                         return -EINVAL;
159                 }
160
161                 /* Convert the last element into a leaf-node */
162                 strncpy(temp_string, temp_root->name, MAX_STRING_SIZE-1);
163                 temp_string[strlen(temp_root->name) + 1] = '\0';
164                 new_parent = temp_root->parent;
165                 remove_proc_entry(temp_root->name, new_parent);
166
167                 new_leaf = create_proc_entry(temp_string, DEFAULT_MODE,
168                                              new_parent);
169                 new_leaf->read_proc = list->read_fptr;
170                 new_leaf->write_proc = list->write_fptr;
171                 new_leaf->data = data;
172                 list++;
173         }
174         return 0;
175 }
176
177 /*
178  *  API implementations
179  */
180 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *var,
181                      void *data)
182 {
183         return lprocfs_new_vars(root, var, (const char*) tok, data);
184 }
185
186 int lprocfs_reg_obd(struct obd_device *device, struct lprocfs_vars *list,
187                     void *data)
188 {
189         int retval = 0;
190         struct proc_dir_entry* this_dev_root = 0;
191
192         /* Obtain this device root */
193         this_dev_root = lprocfs_mkdir(device->obd_name,
194                                       device->obd_type->typ_procroot);
195
196         device->obd_proc_entry = this_dev_root;
197         retval = lprocfs_add_vars(this_dev_root, list, data);
198
199         return retval;
200 }
201
202 int lprocfs_dereg_obd(struct obd_device* device)
203 {
204         CDEBUG(D_OTHER, "LPROCFS removing device = %s\n", device->obd_name);
205
206         if (!device) {
207                 CDEBUG(D_OTHER, "! LProcfs:  Null pointer !\n");
208                 return 0;
209         }
210
211         lprocfs_remove_all(device->obd_proc_entry);
212
213         if (device->counters)
214                 OBD_FREE(device->counters, device->cntr_mem_size);
215
216         return 0;
217 }
218
219 struct proc_dir_entry* lprocfs_reg_mnt(char* mnt_name)
220 {
221         return lprocfs_mkdir(mnt_name, proc_lustre_fs_root);
222 }
223
224 int lprocfs_dereg_mnt(struct proc_dir_entry* root)
225 {
226         lprocfs_remove_all(root);
227         return 0;
228 }
229
230 int lprocfs_reg_class(struct obd_type* type, struct lprocfs_vars* list,
231                       void* data)
232 {
233         struct proc_dir_entry* root;
234         int retval;
235
236         root = lprocfs_mkdir(type->typ_name, proc_lustre_dev_root);
237
238         type->typ_procroot = root;
239
240         retval = lprocfs_add_vars(root, list, data);
241
242         return retval;
243 }
244
245 int lprocfs_dereg_class(struct obd_type* class)
246 {
247         if(!class){
248                 CDEBUG(D_OTHER, "Non-existent class",
249                        class->typ_name);
250                 return 0;
251         }
252
253         lprocfs_remove_all(class->typ_procroot);
254
255         CDEBUG(D_OTHER, "LPROCFS removed = %s\n", class->typ_name);
256
257         return 0;
258
259 }
260 int lprocfs_reg_main()
261 {
262         proc_lustre_root = lprocfs_mkdir("lustre", &proc_root);
263         if (!proc_lustre_root) {
264                 CERROR(" !! Cannot create /proc/lustre !! \n");
265                 return -EINVAL;
266         }
267
268         proc_lustre_dev_root = lprocfs_mkdir("devices", proc_lustre_root);
269         if (!proc_lustre_dev_root) {
270                 CERROR(" !! Cannot create /proc/lustre/devices !! \n");
271                 return -EINVAL;
272         }
273         proc_lustre_fs_root = lprocfs_mkdir("mnt_pnt", proc_lustre_root);
274
275         if (!proc_lustre_fs_root) {
276                 CERROR(" !! Cannot create /proc/lustre/mnt_pnt !! \n");
277                 return -EINVAL;
278         }
279
280         return 0;
281 }
282
283 int lprocfs_dereg_main()
284 {
285         lprocfs_remove_all(proc_lustre_root);
286         proc_lustre_root = 0;
287         proc_lustre_dev_root = 0;
288         proc_lustre_fs_root = 0;
289
290         return 0;
291 }
292
293
294 /*
295  * Needs to go...
296  */
297 int lprocfs_ll_rd(char *page, char **start, off_t off,
298                   int count, int *eof, void *data)
299 {
300         __u64 *temp = (__u64 *)data;
301         int len;
302
303         len = snprintf(page, count, LPU64"\n", *temp);
304
305         return len;
306 }
307
308 #endif /* LPROC_SNMP */
309
310 EXPORT_SYMBOL(lprocfs_reg_obd);
311 EXPORT_SYMBOL(lprocfs_dereg_obd);
312 EXPORT_SYMBOL(lprocfs_reg_main);
313 EXPORT_SYMBOL(lprocfs_dereg_main);
314 EXPORT_SYMBOL(lprocfs_reg_mnt);
315 EXPORT_SYMBOL(lprocfs_dereg_mnt);
316 EXPORT_SYMBOL(lprocfs_add_vars);
317 EXPORT_SYMBOL(lprocfs_reg_class);
318 EXPORT_SYMBOL(lprocfs_dereg_class);
319 EXPORT_SYMBOL(lprocfs_ll_rd);
320
321