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.
21 * Author: Hariharan Thantry thantry@users.sourceforge.net
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 #include <linux/lustre_lite.h>
33 #include <linux/lprocfs_status.h>
37 #define DEFAULT_MODE 0444
39 * Tokenizer array. Change this array to include special
40 * characters for string tokenizing
42 const char tok[] = {'/', '\0'};
47 extern struct proc_dir_entry proc_root; /* Defined in proc/root.c */
52 struct proc_dir_entry *proc_lustre_root;
53 struct proc_dir_entry *proc_lustre_dev_root;
54 struct proc_dir_entry *proc_lustre_fs_root;
56 struct proc_dir_entry* lprocfs_mkdir(const char* dname,
57 struct proc_dir_entry *parent)
59 struct proc_dir_entry *child_dir_entry;
60 child_dir_entry = proc_mkdir(dname, parent);
62 CERROR("lustre: failed to create /proc entry %s\n", dname);
63 return child_dir_entry;
66 struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry* head,
69 struct proc_dir_entry* temp;
73 while (temp != NULL) {
74 if (!strcmp(temp->name, name))
81 void lprocfs_remove_all(struct proc_dir_entry* root)
83 struct proc_dir_entry *temp = root;
84 struct proc_dir_entry *rm_entry;
85 struct proc_dir_entry *parent = root->parent;
93 remove_proc_entry(rm_entry->name, rm_entry->parent);
94 if (temp == parent) break;
98 #define MAX_STRING_SIZE 100
99 struct proc_dir_entry* lprocfs_new_dir(struct proc_dir_entry* root,
100 const char* string, const char* tok)
102 struct proc_dir_entry* new_root;
103 struct proc_dir_entry* temp_entry;
104 char temp_string[MAX_STRING_SIZE+1];
108 strncpy(temp_string, string, MAX_STRING_SIZE);
109 temp_string[MAX_STRING_SIZE] = '\0';
112 mover_str = temp_string;
113 while ((my_str = strsep(&mover_str, tok))) {
116 CDEBUG(D_OTHER, "SEARCH= %s\t, ROOT=%s\n", my_str,
118 temp_entry = lprocfs_srch(new_root, my_str);
119 if (temp_entry == NULL) {
120 CDEBUG(D_OTHER, "Adding: %s\n", my_str);
121 temp_entry = lprocfs_mkdir(my_str, new_root);
122 if (temp_entry == NULL) {
124 "! Did not create new dir %s !!\n",
129 new_root = temp_entry;
134 int lprocfs_new_vars(struct proc_dir_entry* root,
135 struct lprocfs_vars* list,
136 const char* tok, void* data)
138 struct proc_dir_entry *temp_root;
139 struct proc_dir_entry *new_leaf;
140 struct proc_dir_entry *new_parent;
141 char temp_string[MAX_STRING_SIZE+1];
147 temp_root = lprocfs_new_dir(root, list->name, tok);
148 if (temp_root == NULL) {
149 CDEBUG(D_OTHER, "!LProcFS: Mods: No root!");
153 /* Convert the last element into a leaf-node */
154 strncpy(temp_string, temp_root->name, MAX_STRING_SIZE);
155 temp_string[MAX_STRING_SIZE] = '\0';
156 new_parent = temp_root->parent;
157 remove_proc_entry(temp_root->name, new_parent);
158 new_leaf = create_proc_entry(temp_string, DEFAULT_MODE,
160 if (new_leaf == NULL) {
161 CERROR("LprocFS: No memory to create /proc entry %s",
165 new_leaf->read_proc = list->read_fptr;
166 new_leaf->write_proc = list->write_fptr;
170 new_leaf->data=list->data;
176 #undef MAX_STRING_SIZE
178 * API implementations
180 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *var,
183 return lprocfs_new_vars(root, var, tok, data);
186 int lprocfs_reg_obd(struct obd_device *device, struct lprocfs_vars *list,
189 struct proc_dir_entry* this_dev_root;
192 if(lprocfs_srch(device->obd_type->typ_procroot, device->obd_name)){
193 CDEBUG(D_OTHER, "Device with name [%s] exists!",
198 /* Obtain this device root */
199 this_dev_root = lprocfs_mkdir(device->obd_name,
200 device->obd_type->typ_procroot);
202 device->obd_proc_entry = this_dev_root;
203 retval = lprocfs_add_vars(this_dev_root, list, data);
208 int lprocfs_dereg_obd(struct obd_device* device)
210 CDEBUG(D_OTHER, "LPROCFS removing device = %s\n", device->obd_name);
212 if (device == NULL) {
213 CDEBUG(D_OTHER, "! LProcfs: Null pointer !\n");
216 if (device->obd_proc_entry == NULL) {
217 CDEBUG(D_OTHER, "! Proc entry non-existent !");
220 lprocfs_remove_all(device->obd_proc_entry);
221 device->obd_proc_entry = NULL;
222 if (device->counters)
223 OBD_FREE(device->counters, device->cntr_mem_size);
228 struct proc_dir_entry* lprocfs_reg_mnt(char* mnt_name)
230 if(lprocfs_srch(proc_lustre_fs_root, mnt_name)){
231 CDEBUG(D_OTHER, "Mount with same name exists!");
234 return lprocfs_mkdir(mnt_name, proc_lustre_fs_root);
237 int lprocfs_dereg_mnt(struct proc_dir_entry* root)
240 CDEBUG(D_OTHER, "Non-existent root!");
243 lprocfs_remove_all(root);
247 int lprocfs_reg_class(struct obd_type* type, struct lprocfs_vars* list,
251 struct proc_dir_entry* root;
253 root = lprocfs_mkdir(type->typ_name, proc_lustre_dev_root);
254 lprocfs_add_vars(root, list, data);
255 type->typ_procroot = root;
256 retval = lprocfs_add_vars(root, list, data);
260 int lprocfs_dereg_class(struct obd_type* class)
263 CDEBUG(D_OTHER, "Non-existent class",
267 lprocfs_remove_all(class->typ_procroot);
268 class->typ_procroot = NULL;
269 CDEBUG(D_OTHER, "LPROCFS removed = %s\n", class->typ_name);
273 int lprocfs_reg_main()
275 proc_lustre_root = lprocfs_mkdir("lustre", &proc_root);
276 if (proc_lustre_root == NULL) {
277 CERROR(" !! Cannot create /proc/lustre !! \n");
281 proc_lustre_dev_root = lprocfs_mkdir("devices", proc_lustre_root);
282 if (proc_lustre_dev_root == NULL) {
283 CERROR(" !! Cannot create /proc/lustre/devices !! \n");
286 proc_lustre_fs_root = lprocfs_mkdir("mnt_pnt", proc_lustre_root);
288 if (proc_lustre_fs_root == NULL) {
289 CERROR(" !! Cannot create /proc/lustre/mnt_pnt !! \n");
296 int lprocfs_dereg_main()
298 lprocfs_remove_all(proc_lustre_root);
299 proc_lustre_root = NULL;
300 proc_lustre_dev_root = NULL;
301 proc_lustre_fs_root = NULL;
309 int lprocfs_ll_rd(char *page, char **start, off_t off,
310 int count, int *eof, void *data)
312 __u64 *temp = (__u64 *)data;
314 len = snprintf(page, count, LPU64"\n", *temp);
318 #endif /* LPROC_SNMP */
320 EXPORT_SYMBOL(lprocfs_reg_obd);
321 EXPORT_SYMBOL(lprocfs_dereg_obd);
322 EXPORT_SYMBOL(lprocfs_reg_main);
323 EXPORT_SYMBOL(lprocfs_dereg_main);
324 EXPORT_SYMBOL(lprocfs_reg_mnt);
325 EXPORT_SYMBOL(lprocfs_dereg_mnt);
326 EXPORT_SYMBOL(lprocfs_add_vars);
327 EXPORT_SYMBOL(lprocfs_reg_class);
328 EXPORT_SYMBOL(lprocfs_dereg_class);
329 EXPORT_SYMBOL(lprocfs_ll_rd);