1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Intel Corporation
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.
23 * Author: Hariharan Thantry
24 * File Name: lprocfs.c
26 * During initialization (of lustre), the following directory materializes
28 * When the first OBD device of a class is created (due to insmod)
30 * /proc/lustre/devices/<device-class> is created.
31 * When an instance of a device is created (during attach) the
32 * directory entry for that instance along with the variables for
33 * that entry gets created. These variables could be counters, string
35 * Each API further describes the functionality offered.
40 #include <linux/config.h>
41 #include <linux/module.h>
42 #include <linux/version.h>
43 #include <linux/proc_fs.h>
44 #include <linux/slab.h>
45 #include <linux/types.h>
46 #include <linux/string.h>
48 #define DEBUG_SUBSYSTEM S_CLASS
49 #define MAX_STRING_SIZE 100
52 #include <linux/obd_support.h>
53 #include <linux/obd_class.h>
54 #include <linux/lprocfs.h>
55 #include <linux/string.h>
56 #include <linux/lustre_lib.h>
60 #define DEFAULT_MODE 0644
62 * Tokenizer array. Change this array to include special
63 * characters for string tokenizing
65 char tok[] = {'/', (char)0};
68 * Escape character. To be used in directories that
69 * should not have any counter/variable entries under
70 * them. Used for hierarchical directories
73 char escape_char = '%';
78 extern struct proc_dir_entry proc_root; /* Defined in proc/root.c */
85 static struct proc_dir_entry *proc_lustre_root = 0;
86 static struct proc_dir_entry *proc_lustre_dev_root = 0;
88 /* struct lustre_lock proc_lustre_lock; */
89 /* static struct proc_dir_entry *proc_lustre_conn_root = 0; */
90 char *testStr = "General..";
93 * Link the namespace with the internal array indices for
94 * each device class, only if proc lustre is defined
97 struct namespace_index dir_mdc_index[] = {
98 LPROCFS_DIR_INDEX(mdc, mgmt_setup),
99 LPROCFS_DIR_INDEX(mdc, mgmt_cleanup),
100 LPROCFS_DIR_INDEX(mdc, mgmt_connect),
101 LPROCFS_DIR_INDEX(mdc, mgmt_disconnect),
102 LPROCFS_DIR_INDEX(mdc, reint),
103 LPROCFS_DIR_INDEX(mdc, getstatus),
104 LPROCFS_DIR_INDEX(mdc, getattr),
105 LPROCFS_DIR_INDEX(mdc, setattr),
106 LPROCFS_DIR_INDEX(mdc, open),
107 LPROCFS_DIR_INDEX(mdc, readpage),
108 LPROCFS_DIR_INDEX(mdc, create),
109 LPROCFS_DIR_INDEX(mdc, unlink),
110 LPROCFS_DIR_INDEX(mdc, link),
111 LPROCFS_DIR_INDEX(mdc, rename),
114 struct namespace_index dir_mds_index[] = {
115 LPROCFS_DIR_INDEX(mds, mgmt_setup),
116 LPROCFS_DIR_INDEX(mds, mgmt_cleanup),
117 LPROCFS_DIR_INDEX(mds, mgmt_connect),
118 LPROCFS_DIR_INDEX(mds, mgmt_disconnect),
119 LPROCFS_DIR_INDEX(mds, getstatus),
120 LPROCFS_DIR_INDEX(mds, connect),
121 LPROCFS_DIR_INDEX(mds, disconnect_callback),
122 LPROCFS_DIR_INDEX(mds, getattr),
123 LPROCFS_DIR_INDEX(mds, readpage),
124 LPROCFS_DIR_INDEX(mds, open),
125 LPROCFS_DIR_INDEX(mds, close),
126 LPROCFS_DIR_INDEX(mds, create),
127 LPROCFS_DIR_INDEX(mds, unlink),
128 LPROCFS_DIR_INDEX(mds, link),
129 LPROCFS_DIR_INDEX(mds, rename),
130 LPROCFS_DIR_INDEX(mds, reint_summary),
131 LPROCFS_DIR_INDEX(mds, reint_setattr),
132 LPROCFS_DIR_INDEX(mds, reint_create),
133 LPROCFS_DIR_INDEX(mds, reint_unlink),
134 LPROCFS_DIR_INDEX(mds, reint_link),
135 LPROCFS_DIR_INDEX(mds, reint_rename),
136 LPROCFS_DIR_INDEX(mds, reint_recreate),
139 struct namespace_index dir_mdt_index[] = {
140 LPROCFS_DIR_INDEX(mdt, mgmt_setup),
141 LPROCFS_DIR_INDEX(mdt, mgmt_cleanup),
142 LPROCFS_DIR_INDEX(mdt, mgmt_connect),
143 LPROCFS_DIR_INDEX(mdt, mgmt_disconnect),
146 struct namespace_index dir_osc_index[] = {
147 LPROCFS_DIR_INDEX(osc, mgmt_setup),
148 LPROCFS_DIR_INDEX(osc, mgmt_cleanup),
149 LPROCFS_DIR_INDEX(osc, mgmt_connect),
150 LPROCFS_DIR_INDEX(osc, mgmt_disconnect),
151 LPROCFS_DIR_INDEX(osc, create),
152 LPROCFS_DIR_INDEX(osc, destroy),
153 LPROCFS_DIR_INDEX(osc, getattr),
154 LPROCFS_DIR_INDEX(osc, setattr),
155 LPROCFS_DIR_INDEX(osc, open),
156 LPROCFS_DIR_INDEX(osc, close),
157 LPROCFS_DIR_INDEX(osc, brw),
158 LPROCFS_DIR_INDEX(osc, punch),
159 LPROCFS_DIR_INDEX(osc, summary),
160 LPROCFS_DIR_INDEX(osc, cancel),
163 struct namespace_index dir_ost_index[] = {
164 LPROCFS_DIR_INDEX(ost, mgmt_setup),
165 LPROCFS_DIR_INDEX(ost, mgmt_cleanup),
166 LPROCFS_DIR_INDEX(ost, mgmt_connect),
167 LPROCFS_DIR_INDEX(ost, mgmt_disconnect),
168 LPROCFS_DIR_INDEX(ost, create),
169 LPROCFS_DIR_INDEX(ost, destroy),
170 LPROCFS_DIR_INDEX(ost, getattr),
171 LPROCFS_DIR_INDEX(ost, setattr),
172 LPROCFS_DIR_INDEX(ost, open),
173 LPROCFS_DIR_INDEX(ost, close),
174 LPROCFS_DIR_INDEX(ost, brw),
175 LPROCFS_DIR_INDEX(ost, punch),
176 LPROCFS_DIR_INDEX(ost, summary),
177 LPROCFS_DIR_INDEX(ost, cancel),
178 LPROCFS_DIR_INDEX(ost, getinfo),
181 struct namespace_index dir_lov_index[] = {
182 LPROCFS_DIR_INDEX(lov, mgmt_setup),
183 LPROCFS_DIR_INDEX(lov, mgmt_cleanup),
184 LPROCFS_DIR_INDEX(lov, mgmt_connect),
185 LPROCFS_DIR_INDEX(lov, mgmt_disconnect),
186 LPROCFS_DIR_INDEX(lov, create),
187 LPROCFS_DIR_INDEX(lov, destroy),
188 LPROCFS_DIR_INDEX(lov, getattr),
189 LPROCFS_DIR_INDEX(lov, setattr),
190 LPROCFS_DIR_INDEX(lov, open),
191 LPROCFS_DIR_INDEX(lov, close),
192 LPROCFS_DIR_INDEX(lov, brw),
193 LPROCFS_DIR_INDEX(lov, punch),
194 LPROCFS_DIR_INDEX(lov, summary),
195 LPROCFS_DIR_INDEX(lov, cancel),
196 LPROCFS_DIR_INDEX(lov, getinfo),
199 struct namespace_index dir_obdfilter_index[] = {
200 LPROCFS_DIR_INDEX(obdfilter, mgmt_setup),
201 LPROCFS_DIR_INDEX(obdfilter, mgmt_cleanup),
202 LPROCFS_DIR_INDEX(obdfilter, mgmt_connect),
203 LPROCFS_DIR_INDEX(obdfilter, mgmt_disconnect),
204 LPROCFS_DIR_INDEX(obdfilter, create),
205 LPROCFS_DIR_INDEX(obdfilter, destroy),
206 LPROCFS_DIR_INDEX(obdfilter, getattr),
207 LPROCFS_DIR_INDEX(obdfilter, setattr),
208 LPROCFS_DIR_INDEX(obdfilter, open),
209 LPROCFS_DIR_INDEX(obdfilter, close),
210 LPROCFS_DIR_INDEX(obdfilter, brw),
211 LPROCFS_DIR_INDEX(obdfilter, punch),
212 LPROCFS_DIR_INDEX(obdfilter, summary),
213 LPROCFS_DIR_INDEX(obdfilter, cancel),
214 LPROCFS_DIR_INDEX(obdfilter, getinfo),
217 struct namespace_index dir_ldlm_index[] = {
218 LPROCFS_DIR_INDEX(ldlm, mgmt_setup),
219 LPROCFS_DIR_INDEX(ldlm, mgmt_cleanup),
220 LPROCFS_DIR_INDEX(ldlm, mgmt_connect),
221 LPROCFS_DIR_INDEX(ldlm, mgmt_disconnect),
222 LPROCFS_DIR_INDEX(ldlm, locks_enqueus),
223 LPROCFS_DIR_INDEX(ldlm, locks_cancels),
224 LPROCFS_DIR_INDEX(ldlm, locks_converts),
225 LPROCFS_DIR_INDEX(ldlm, locks_matches),
228 struct namespace_index dir_ptlrpc_index[] = {
229 LPROCFS_DIR_INDEX(ptlrpc, mgmt_setup),
230 LPROCFS_DIR_INDEX(ptlrpc, mgmt_cleanup),
231 LPROCFS_DIR_INDEX(ptlrpc, mgmt_connect),
232 LPROCFS_DIR_INDEX(ptlrpc, mgmt_disconnect),
233 LPROCFS_DIR_INDEX(ptlrpc, counters),
236 struct namespace_index prof_mdc_index[] = {
237 LPROCFS_CNTR_INDEX(mdc, min_time),
238 LPROCFS_CNTR_INDEX(mdc, max_time),
239 LPROCFS_CNTR_INDEX(mdc, sum_time),
240 LPROCFS_CNTR_INDEX(mdc, num_ops),
243 struct namespace_index prof_mds_index[]= {
244 LPROCFS_CNTR_INDEX(mds, min_time),
245 LPROCFS_CNTR_INDEX(mds, max_time),
246 LPROCFS_CNTR_INDEX(mds, sum_time),
247 LPROCFS_CNTR_INDEX(mds, num_ops),
250 struct namespace_index prof_mdt_index[]= {
251 LPROCFS_CNTR_INDEX(mds, min_time),
252 LPROCFS_CNTR_INDEX(mds, max_time),
253 LPROCFS_CNTR_INDEX(mds, sum_time),
254 LPROCFS_CNTR_INDEX(mds, num_ops),
257 struct namespace_index prof_osc_index[]= {
258 LPROCFS_CNTR_INDEX(osc, min_time),
259 LPROCFS_CNTR_INDEX(osc, max_time),
260 LPROCFS_CNTR_INDEX(osc, sum_time),
261 LPROCFS_CNTR_INDEX(osc, num_ops),
264 struct namespace_index prof_ost_index[]= {
265 LPROCFS_CNTR_INDEX(ost, min_time),
266 LPROCFS_CNTR_INDEX(ost, max_time),
267 LPROCFS_CNTR_INDEX(ost, sum_time),
268 LPROCFS_CNTR_INDEX(ost, num_ops),
271 struct namespace_index prof_lov_index[]= {
272 LPROCFS_CNTR_INDEX(lov, min_time),
273 LPROCFS_CNTR_INDEX(lov, max_time),
274 LPROCFS_CNTR_INDEX(lov, sum_time),
275 LPROCFS_CNTR_INDEX(lov, num_ops),
278 struct namespace_index prof_obdfilter_index[]= {
279 LPROCFS_CNTR_INDEX(obdfilter, min_time),
280 LPROCFS_CNTR_INDEX(obdfilter, max_time),
281 LPROCFS_CNTR_INDEX(obdfilter, sum_time),
282 LPROCFS_CNTR_INDEX(obdfilter, num_ops),
285 struct namespace_index prof_ldlm_index[] = {
286 LPROCFS_CNTR_INDEX(ldlm, min_time),
287 LPROCFS_CNTR_INDEX(ldlm, max_time),
288 LPROCFS_CNTR_INDEX(ldlm, sum_time),
289 LPROCFS_CNTR_INDEX(ldlm, num_ops),
290 LPROCFS_CNTR_INDEX(ldlm, num_total),
291 LPROCFS_CNTR_INDEX(ldlm, num_zerolatency),
292 LPROCFS_CNTR_INDEX(ldlm, num_zerolatency_inflight),
293 LPROCFS_CNTR_INDEX(ldlm, num_zerolatency_done),
294 LPROCFS_CNTR_INDEX(ldlm, nonzero_mintime),
295 LPROCFS_CNTR_INDEX(ldlm, nonzero_maxtime),
296 LPROCFS_CNTR_INDEX(ldlm, nonzero_sumtime),
299 struct namespace_index prof_ptlrpc_index[] = {
300 LPROCFS_CNTR_INDEX(ptlrpc, min_time),
301 LPROCFS_CNTR_INDEX(ptlrpc, max_time),
302 LPROCFS_CNTR_INDEX(ptlrpc, sum_time),
303 LPROCFS_CNTR_INDEX(ptlrpc, num_ops),
304 LPROCFS_CNTR_INDEX(ptlrpc, msgs_alloc),
305 LPROCFS_CNTR_INDEX(ptlrpc, msgs_max),
306 LPROCFS_CNTR_INDEX(ptlrpc, recv_count),
307 LPROCFS_CNTR_INDEX(ptlrpc, recv_length),
308 LPROCFS_CNTR_INDEX(ptlrpc, send_count),
309 LPROCFS_CNTR_INDEX(ptlrpc, send_length),
310 LPROCFS_CNTR_INDEX(ptlrpc, portal_kmemory),
314 * Group the device class name, its directory hierarchy and
315 * leaf nodes together
318 struct groupspace_index class_index[] = {
319 LPROCFS_GROUP_CREATE(mdc),
320 LPROCFS_GROUP_CREATE(mds),
321 LPROCFS_GROUP_CREATE(mdt),
322 LPROCFS_GROUP_CREATE(osc),
323 LPROCFS_GROUP_CREATE(ost),
324 LPROCFS_GROUP_CREATE(lov),
325 LPROCFS_GROUP_CREATE(obdfilter),
326 LPROCFS_GROUP_CREATE(ldlm),
327 LPROCFS_GROUP_CREATE(ptlrpc),
332 * API implementations
336 * lprocfs_reg_dev: Registers an instance of the OBD device in the
340 int lprocfs_reg_dev(struct obd_device* device, lprocfs_group_t* namespace,
341 unsigned int cnt_struct_size)
343 unsigned int num_directories = 0;
344 int class_array_index = 0;
346 struct proc_dir_entry* this_dev_root=0;
347 unsigned int i = 0, j = 0;
349 /* Obtain this device root */
350 this_dev_root = lprocfs_mkinitdir(device);
351 if (this_dev_root == 0) {
352 CERROR("Could not create initial directory");
353 return LPROCFS_FAILURE;
356 /* Obtain the class-array index */
357 class_array_index = lprocfs_getclass_idx(class_index,
358 device->obd_type->typ_name);
360 if (class_array_index == LPROCFS_FAILURE) {
361 CERROR("Could not find class for %s\n",
362 device->obd_type->typ_name);
363 return LPROCFS_FAILURE;
366 /* Create the directory namespace */
367 retval = lprocfs_create_dir_namespace(this_dev_root, namespace,
369 if (retval == LPROCFS_FAILURE) {
370 CERROR("!!Could not create proc directory structure !!\n");
371 return LPROCFS_FAILURE;
374 /* Allocate memory managed by LProcFS for the device. */
375 if (cnt_struct_size != 0) {
376 OBD_ALLOC(device->counters, num_directories*cnt_struct_size);
377 device->cntr_mem_size = num_directories*cnt_struct_size;
381 * Iterate the proc-dir-namespace, obtain corresponding
382 * directory(attribute)
383 * entries. Create the proc-counters from namespace, link them into
386 retval=lprocfs_link_dir_counters(device, this_dev_root, namespace,
387 cnt_struct_size, class_array_index);
389 if (retval == LPROCFS_FAILURE) {
390 CERROR("!! Could not link proc counters to device !!");
391 return LPROCFS_FAILURE;
395 * Test code: This goes into individual modules. strcmp is
396 * unnecessary, since device knows its class. To see the values
397 * from the user space, do a cat on the respective variable
399 if (!(strcmp(device->obd_type->typ_name, "mds"))) {
400 DEV_PROF_START(mds, device, gen, mgmt_setup);
402 for (i = 0; i < 100; i++)
403 for (j = 0; j < 100; j++)
406 DEV_PROF_END(mds, device, gen, mgmt_setup);
408 DEV_PROF_START(mds, device, gen, mgmt_setup);
410 for (i = 0; i < 1000; i++)
411 for (j = 0; j < 1000; j++)
414 DEV_PROF_END(mds, device, gen, mgmt_setup);
417 DEV_PROF_START(mds, device, gen, open);
418 for (i = 0; i < 50; i++) {
419 DEV_PROF_START(mds, device, gen, close);
420 for (j = 0; j < 2000; j++)
422 DEV_PROF_END(mds, device, gen, close);
424 DEV_PROF_END(mds, device, gen, open);
427 if (!(strcmp(device->obd_type->typ_name, "ldlm"))) {
428 DEV_PROF_START(ldlm, device, ldlm, mgmt_connect);
429 for (i = 0; i < 200; i++) {
430 DEV_PROF_START(ldlm, device, ldlm, mgmt_disconnect);
431 for (j = 0; j < 2000; j++)
433 DEV_PROF_END(ldlm, device, ldlm, mgmt_disconnect);
435 DEV_PROF_END(ldlm, device, ldlm, mgmt_connect);
438 return LPROCFS_SUCCESS;
441 int lprocfs_link_dir_counters(struct obd_device* device,
442 struct proc_dir_entry* root,
443 lprocfs_group_t* namespace,
447 struct proc_dir_entry* dir_root=0;
448 lprocfs_group_t* temp;
449 lprocfs_vars_t* fn_ctr;
450 struct namespace_index* cntr_names;
454 unsigned int escape = 0;
459 temp = &namespace[i];
461 if (temp->count_func_namespace == 0)
464 while ((temp->dir_namespace)[j] != 0) {
465 dir_root = lprocfs_add_dir(root,
466 (temp->dir_namespace)[j],
467 (const char*)tok, &escape);
473 dir_idx = lprocfs_get_idx(class_index[cl_idx].directory,
474 (temp->dir_namespace)[j]);
477 fn_ctr = &((temp->count_func_namespace)[k]);
478 if (fn_ctr->read_fptr == 0)
480 cntr_names = class_index[cl_idx].counters;
481 cnt_idx = lprocfs_get_idx(cntr_names,
484 if (lprocfs_add_var(device, dir_root, fn_ctr,
485 dir_idx, cnt_idx, sz,
488 CERROR("Could not create leaf node!");
489 return LPROCFS_FAILURE;
505 return LPROCFS_SUCCESS;
508 int lprocfs_create_dir_namespace(struct proc_dir_entry* root,
509 lprocfs_group_t* namespace,
510 unsigned int *num_dirs)
514 struct proc_dir_entry* dir_root=0;
515 lprocfs_group_t* temp;
516 unsigned int escape = 0;
519 temp = &namespace[i];
520 if (temp->count_func_namespace == 0)
522 while ((temp->dir_namespace)[j] != 0){
523 dir_root = lprocfs_add_dir(root,
524 (temp->dir_namespace)[j],
525 (const char*)tok, &escape);
527 CERROR("!! Could not create dir %s !! \n",
528 (temp->dir_namespace)[j]);
529 return LPROCFS_FAILURE;
531 if (temp->prof_type != e_specific && !escape)
539 return LPROCFS_SUCCESS;
543 int lprocfs_getclass_idx(struct groupspace_index* group, const char* classname)
545 unsigned int idx = 0;
547 while (group[idx].name != NULL) {
548 if (!strcmp(group[idx].name, classname))
553 return LPROCFS_FAILURE;
556 struct proc_dir_entry* lprocfs_mkinitdir(struct obd_device* device)
558 struct proc_dir_entry* this_dev_root = 0;
559 struct proc_dir_entry* temp_proc = 0;
562 * First check if /proc/lustre exits. If it does not,
563 * instantiate the same and the devices directory
565 if (!proc_lustre_root) {
566 proc_lustre_root = lprocfs_mkdir("lustre", &proc_root);
567 if (!proc_lustre_root) {
568 CERROR(" !! Cannot create /proc/lustre !! \n");
571 proc_lustre_dev_root =
572 lprocfs_mkdir("devices", proc_lustre_root);
574 if (!proc_lustre_dev_root) {
575 CERROR(" !! Cannot create /proc/lustre/devices !! \n");
581 * Check if this is the first instance for a device of
582 * this class in the lprocfs hierarchy.
584 temp_proc = lprocfs_srch(proc_lustre_dev_root,
585 device->obd_type->typ_name);
588 temp_proc = lprocfs_mkdir(device->obd_type->typ_name,
589 proc_lustre_dev_root);
591 CERROR("! Proc dir for device class %s !!\n",
592 device->obd_type->typ_name);
597 /* Next create the proc_dir_entry for this instance */
598 this_dev_root = lprocfs_mkdir(device->obd_name, temp_proc);
599 if (!this_dev_root) {
600 CERROR("!Can't create proc entry for instance %s !! \n",
605 return this_dev_root;
609 int lprocfs_get_idx(struct namespace_index* class, const char* dir_name)
611 unsigned int index = 0;
612 char temp_string[MAX_STRING_SIZE];
614 /* First replace the string tokenizer with enum character */
615 memset(temp_string, 0, MAX_STRING_SIZE);
616 while (dir_name[index]!='\0' && index < MAX_STRING_SIZE) {
617 if (dir_name[index] != tok[0])
618 temp_string[index] = dir_name[index];
620 temp_string[index] = enum_char;
623 temp_string[index] = '\0';
626 while (class[index].name) {
627 if (!strcmp(class[index].name, temp_string))
632 CDEBUG(D_OTHER, "No profiling for %s\n", temp_string);
636 struct proc_dir_entry* lprocfs_mkdir(const char* dname,
637 struct proc_dir_entry *parent)
639 struct proc_dir_entry *child_dir_entry;
641 child_dir_entry = proc_mkdir(dname, parent);
643 if (!child_dir_entry)
644 CERROR("lustre: failed to create /proc entry %s\n", dname);
646 return child_dir_entry;
650 * Create the variable struct entry for /proc. This will also
651 * register the read/write function pointers with
653 * Returns non-zero on success, zero on failure
655 unsigned int lprocfs_add_var(struct obd_device* device,
656 struct proc_dir_entry* root,
657 lprocfs_vars_t* variable, int dir_idx, int cnt_idx,
658 unsigned int sz, lprofilers_e type)
660 struct proc_dir_entry* new_proc_entry;
662 unsigned int actual_idx;
663 unsigned int blk_size;
665 new_proc_entry = create_proc_entry(variable->name, DEFAULT_MODE, root);
667 return LPROCFS_FAILURE;
669 new_proc_entry->read_proc = variable->read_fptr;
670 new_proc_entry->write_proc = variable->write_fptr;
674 if (device->counters) {
675 if (dir_idx != -1 && cnt_idx != -1) {
676 temp = (__u64*)device->counters;
677 blk_size = ((sz) / (sizeof(__u64)));
678 actual_idx = (dir_idx*blk_size) + cnt_idx;
680 new_proc_entry->data = (__u64*)temp;
685 new_proc_entry->data = device;
689 return LPROCFS_SUCCESS;
694 * Tokenize name, based on tok and end-of-string. Create and return the
695 * new directory entry. Set escape variable if the directory name contained
696 * the escaping character (#)
699 struct proc_dir_entry* lprocfs_add_dir(struct proc_dir_entry *root,
702 unsigned int* escape)
704 struct proc_dir_entry* new_root = 0;
705 struct proc_dir_entry* temp_entry = 0;
706 struct proc_dir_entry* new_entry = 0;
707 char temp_string[MAX_STRING_SIZE];
712 * Remove trailing escaping character
714 memset(temp_string, 0, MAX_STRING_SIZE);
715 if (strlen(string) >= MAX_STRING_SIZE) {
716 CERROR("Directory namespace too long");
720 if (strchr(string, escape_char)) {
722 strncpy(temp_string,string,strlen(string) - 1);
723 temp_string[strlen(string)] = '\0';
726 strcpy(temp_string, string);
727 temp_string[strlen(string) + 1] = '\0';
732 /* Using strsep() instead */
733 mover_str=temp_string;
734 while ((my_str = strsep(&mover_str, tok))) {
737 temp_entry = lprocfs_srch(new_root, my_str);
738 if (temp_entry == 0) {
739 new_entry = lprocfs_mkdir(my_str, new_root);
740 if (new_entry == 0) {
741 CERROR("! Did not create new dir %s !!\n",
747 new_root = temp_entry;
753 struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry* head,
756 struct proc_dir_entry* temp;
761 while (temp != NULL) {
762 if (!strcmp(temp->name, name))
770 #warning FIXME: recursive code is VERY bad in the kernel because of stack limit
771 struct proc_dir_entry* lprocfs_bfs_srch(struct proc_dir_entry* root,
774 struct proc_dir_entry* temp = root;
779 if (!strcmp(temp->name, name))
782 if ((temp = lprocfs_bfs_srch(root->next, name)) != 0)
785 if ((temp = lprocfs_bfs_srch(root->subdir, name)) != 0)
791 int lprocfs_get_nm(char* name, lprocfs_obd_nm_t* collection)
794 while (collection[i].obd_names != 0) {
795 if(!strcmp(collection[i].obd_clname, name))
803 int lprocfs_dereg_dev(struct obd_device* device)
805 struct proc_dir_entry* temp;
807 CDEBUG(D_OTHER, "LPROCFS removing device = %s\n", device->obd_name);
810 CDEBUG(D_OTHER, "! LProcfs: Null pointer !\n");
811 return LPROCFS_SUCCESS;
814 if (!(device->obd_name)) {
815 CERROR(" !! Device does not have a name !! \n");
816 return LPROCFS_FAILURE;
819 temp = lprocfs_bfs_srch(proc_lustre_dev_root->subdir, device->obd_name);
821 CERROR("Device %s not in lprocfs\n", device->obd_name);
822 return LPROCFS_FAILURE;
825 lprocfs_remove_all(temp);
828 * Free the memory held by counters
830 if (device->counters)
831 OBD_FREE(device->counters, device->cntr_mem_size);
833 CDEBUG(D_OTHER, "LPROCFS removed device = %s\n", \
836 return LPROCFS_SUCCESS;
839 void lprocfs_remove_all(struct proc_dir_entry* root)
841 if (root->subdir != 0)
842 lprocfs_remove_all(root->subdir);
845 lprocfs_remove_all(root->next);
847 if (root->parent != 0)
848 remove_proc_entry(root->name, root->parent);
850 remove_proc_entry(root->name, NULL);
853 int rd_uuid(char* page, char **start, off_t off,
854 int count, int *eof, void *data)
857 struct obd_device *temp = (struct obd_device *)data;
859 len = sprintf(page, "%s\n", temp->obd_uuid);
864 int wr_uuid(struct file* file, const char *buffer,
865 unsigned long count, void *data)
871 int rd_blksize(char* page, char **start, off_t off,
872 int count, int *eof, void *data)
875 //struct obd_device *temp = (struct obd_device *)data;
880 int rd_blktotal(char* page, char **start, off_t off,
881 int count, int *eof, void *data)
886 int rd_blkfree(char* page, char **start, off_t off,
887 int count, int *eof, void *data)
892 int rd_kbfree(char* page, char **start, off_t off,
893 int count, int *eof, void *data)
898 int rd_numobjects(char* page, char **start, off_t off,
899 int count, int *eof, void *data)
904 int rd_objfree(char* page, char **start, off_t off,
905 int count, int *eof, void *data)
910 int rd_objgroups(char* page, char **start, off_t off,
911 int count, int *eof, void *data)
917 int lprocfs_ll_rd(char *page, char **start, off_t off,
918 int count, int *eof, void *data)
920 __u64 *temp = (__u64 *)data;
923 len = snprintf(page, count, LPU64"\n", *temp);
928 int rd_fs_type(char* page, char **start, off_t off,
929 int count, int *eof, void *data)
934 int rd_other(char* page, char **start, off_t off, int count, int *eof,
940 int rd_string(char* page, char **start, off_t off, int count, int *eof,
943 printk("Hello string");
947 int lprocfs_ll_wr(struct file* file, const char *buffer, unsigned long count,
953 int wr_other(struct file* file, const char *buffer, unsigned long count,
959 int wr_string(struct file* file, const char *buffer, unsigned long count,
965 int lprocfs_reg_conn(unsigned int conn_number,
966 struct lprocfs_conn_namespace* namespace)
971 int lprocfs_dereg_conn(unsigned int conn_number)
979 int lprocfs_add_export(unsigned int conn_number, struct obd_device* device)
984 int lprocfs_add_import(unsigned int conn_number, struct obd_device* device)
989 int lprocfs_remove_export(unsigned int conn_number, struct obd_device* device)
994 int lprocfs_remove_import(unsigned int conn_number, struct obd_device* device)