1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 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.
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>
31 #define DEBUG_SUBSYSTEM S_CLASS
32 #define MAX_STRING_SIZE 100
34 #include <linux/lustre_lite.h>
35 #include <linux/lprocfs_status.h>
39 #define DEFAULT_MODE 0444
41 * Tokenizer array. Change this array to include special
42 * characters for string tokenizing
44 char tok[] = {'/', (char)0};
51 extern struct proc_dir_entry proc_root; /* Defined in proc/root.c */
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;
60 struct proc_dir_entry* lprocfs_mkdir(const char* dname,
61 struct proc_dir_entry *parent)
63 struct proc_dir_entry *child_dir_entry;
65 child_dir_entry = proc_mkdir(dname, parent);
68 CERROR("lustre: failed to create /proc entry %s\n", dname);
70 return child_dir_entry;
72 struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry* head,
75 struct proc_dir_entry* temp;
80 while (temp != NULL) {
81 if (!strcmp(temp->name, name))
90 void lprocfs_remove_all(struct proc_dir_entry* root)
93 struct proc_dir_entry *temp=root;
94 struct proc_dir_entry* rm_entry;
103 remove_proc_entry(rm_entry->name, rm_entry->parent);
104 if(temp==root->parent) break;
111 struct proc_dir_entry* lprocfs_new_dir(struct proc_dir_entry* root,
115 struct proc_dir_entry* new_root = 0;
116 struct proc_dir_entry* temp_entry = 0;
118 char temp_string[MAX_STRING_SIZE];
123 * Remove trailing escaping character
125 memset(temp_string, 0, MAX_STRING_SIZE);
126 if (strlen(string) >= MAX_STRING_SIZE) {
127 CDEBUG(D_OTHER, "Directory namespace too long");
131 strcpy(temp_string, string);
132 temp_string[strlen(string) + 1] = '\0';
135 mover_str=temp_string;
136 while ((my_str = strsep(&mover_str, tok))) {
139 CDEBUG(D_OTHER, "SEARCH= %s\t, ROOT=%s\n", my_str,
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) {
147 "! Did not create new dir %s !!\n",
152 new_root = temp_entry;
158 int lprocfs_new_vars(struct proc_dir_entry* root,
159 lprocfs_vars_t* list,
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];
172 temp_root=lprocfs_new_dir(root, list->name, tok);
175 CDEBUG(D_OTHER, "!LProcFS: Mods: No root!");
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);
186 remove_proc_entry(temp_root->name, NULL);
188 new_leaf = create_proc_entry(temp_string, DEFAULT_MODE,
190 new_leaf->read_proc = list->read_fptr;
191 new_leaf->write_proc = list->write_fptr;
200 * API implementations
203 int lprocfs_add_vars(struct proc_dir_entry* root,
208 return lprocfs_new_vars(root, var,
209 (const char*) tok, data);
214 int lprocfs_reg_obd(struct obd_device* device,
215 lprocfs_vars_t* list,
220 struct proc_dir_entry* this_dev_root=0;
222 /* Obtain this device root */
223 this_dev_root = lprocfs_mkdir(device->obd_name,
224 device->obd_type->typ_procroot);
226 device->obd_proc_entry=this_dev_root;
227 retval=lprocfs_add_vars(this_dev_root, list,
233 int lprocfs_dereg_obd(struct obd_device* device)
236 CDEBUG(D_OTHER, "LPROCFS removing device = %s\n", device->obd_name);
239 CDEBUG(D_OTHER, "! LProcfs: Null pointer !\n");
243 lprocfs_remove_all(device->obd_proc_entry);
245 if (device->counters)
246 OBD_FREE(device->counters, device->cntr_mem_size);
251 struct proc_dir_entry* lprocfs_reg_mnt(char* mnt_name)
253 return lprocfs_mkdir(mnt_name, proc_lustre_fs_root);
257 int lprocfs_dereg_mnt(struct proc_dir_entry* root)
259 lprocfs_remove_all(root);
264 int lprocfs_reg_class(struct obd_type* type,
265 lprocfs_vars_t* list,
268 struct proc_dir_entry* root;
271 root=lprocfs_mkdir(type->typ_name, proc_lustre_dev_root);
273 type->typ_procroot=root;
275 retval=lprocfs_add_vars(root, list, data);
280 int lprocfs_dereg_class(struct obd_type* class)
283 CDEBUG(D_OTHER, "Non-existent class",
288 lprocfs_remove_all(class->typ_procroot);
290 CDEBUG(D_OTHER, "LPROCFS removed = %s\n", class->typ_name);
295 int lprocfs_reg_main()
297 proc_lustre_root = lprocfs_mkdir("lustre", &proc_root);
298 if (!proc_lustre_root) {
299 CERROR(" !! Cannot create /proc/lustre !! \n");
303 proc_lustre_dev_root =lprocfs_mkdir("devices", proc_lustre_root);
305 if (!proc_lustre_dev_root) {
306 CERROR(" !! Cannot create /proc/lustre/devices !! \n");
309 proc_lustre_fs_root=lprocfs_mkdir("mnt_pnt", proc_lustre_root);
311 if (!proc_lustre_fs_root) {
312 CERROR(" !! Cannot create /proc/lustre/mnt_pnt !! \n");
320 int lprocfs_dereg_main()
322 lprocfs_remove_all(proc_lustre_root);
324 proc_lustre_dev_root=0;
325 proc_lustre_fs_root=0;
335 int lprocfs_ll_rd(char *page, char **start, off_t off,
336 int count, int *eof, void *data)
338 __u64 *temp = (__u64 *)data;
341 len = snprintf(page, count, LPU64"\n", *temp);
346 #endif /* LPROC_SNMP */
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);