Whamcloud - gitweb
tidy runfailure-ost a touch
[fs/lustre-release.git] / lustre / obdclass / proc_lustre.c
1 /* proc_lustre.c manages /proc/lustre/obd. 
2  *
3  * Copyright (c) 2001 Rumi Zahir <rumi.zahir@intel.com>
4  *
5  * This code is issued under the GNU General Public License.
6  * See the file COPYING in this distribution
7  *
8  * OBD devices materialize in /proc as a directory:
9  *              /proc/lustre/obd/<number>
10  * when /dev/obd<number> is opened. When the device is closed, the 
11  * directory entry disappears. 
12  * 
13  * For each open OBD device, code in this file also creates a file
14  * named <status>. "cat /proc/lustre/obd/<number>/status" gives 
15  * information about the OBD device's configuration.
16  * The class driver manages the "status" entry.
17  *
18  * Other logical drivers can create their own entries. For example,
19  * the obdtrace driver creates /proc/lustre/obd/<obdid>/stats entry.
20  *
21  * This file defines three functions 
22  *   proc_lustre_register_obd_device() - called at device attach time
23  *   proc_lustre_release_obd_device() - called at detach
24  *               proc_lustre_remove_obd_entry() 
25  * that dynamically create/delete /proc/lustre/obd entries:
26  *
27  *     proc_lustre_register_obd_device() registers an obd device,
28  *     and, if this is the first OBD device, creates /proc/lustre/obd.
29  *
30  *     proc_lustre_release_obd_device() removes device information
31  *     from /proc/lustre/obd, and if this is the last OBD device
32  *     removes  /proc/lustre/obd.
33  *
34  *     proc_lustre_remove_obd_entry() removes a
35  *     /proc/lustre/obd/<obdid>/ entry by name. This is the only
36  *     function that is exported to other modules. 
37  */
38
39 #define EXPORT_SYMTAB
40 #include <linux/config.h>
41 #include <linux/module.h>
42 #include <linux/version.h>
43 #include <linux/proc_fs.h>
44
45 #define DEBUG_SUBSYSTEM S_CLASS
46
47 #include <linux/obd_support.h>
48 #include <linux/obd_class.h>
49
50 #ifdef CONFIG_PROC_FS
51 extern struct proc_dir_entry proc_root;
52 static struct proc_dir_entry *proc_lustre_dir_entry = 0;
53 static struct proc_dir_entry *proc_lustre_obd_dir_entry = 0;
54
55
56 static int read_lustre_status(char *page, char **start, off_t offset,
57                               int count, int *eof, void *data)
58 {
59         struct obd_device * obddev = (struct obd_device *) data;
60         int p;
61
62         p = sprintf(&page[0], "device=%d\n", obddev->obd_minor);
63         p += sprintf(&page[0], "name=%s\n", MKSTR(obddev->obd_name));
64         p += sprintf(&page[0], "uuid=%s\n", obddev->obd_uuid); 
65         p += sprintf(&page[p], "attached=1\n");
66         p += sprintf(&page[0], "type=%s\n", MKSTR(obddev->obd_type->typ_name));
67         
68         if  (obddev->obd_flags & OBD_SET_UP) {
69                 p += sprintf(&page[p], "setup=1\n");
70         }
71         
72         /* print exports */
73         {
74                 struct list_head * lh;
75                 struct obd_export * export=0;
76                 
77                 lh = &obddev->obd_exports;
78                 while ((lh = lh->next) != &obddev->obd_exports) {
79                         p += sprintf(&page[p],
80                                      ((export==0) ? ", connections(" : ",") );
81                         export = list_entry(lh, struct obd_export, export_chain);
82                         p += sprintf(&page[p], "%p", export);
83                 } 
84                 if (export!=0) { /* there was at least one export */
85                         p += sprintf(&page[p], ")");
86                 }
87         }
88         
89         p += sprintf(&page[p], "\n");
90
91         /* Compute eof and return value */
92         if (offset + count >= p) {
93                 *eof=1;
94                 return (p - offset);
95         }
96         return count;
97 }
98
99 struct proc_dir_entry *
100 proc_lustre_register_obd_device(struct obd_device *obd)
101 {
102         char obdname[32];
103         struct proc_dir_entry *obd_dir;
104         struct proc_dir_entry *obd_status = 0;
105
106         if (!proc_lustre_dir_entry) {
107                 proc_lustre_dir_entry = proc_mkdir("lustre", &proc_root);
108                 if (IS_ERR(proc_lustre_dir_entry))
109                         return 0;
110         
111                 proc_lustre_obd_dir_entry = 
112                         proc_mkdir("devices", proc_lustre_dir_entry);
113                 if (IS_ERR(proc_lustre_obd_dir_entry))
114                         return 0;
115         }
116         sprintf(obdname, "%s", obd->obd_name);
117         obd_dir =  proc_mkdir(obdname, proc_lustre_obd_dir_entry);
118
119         if (obd_dir) 
120                 obd_status = create_proc_entry("status", S_IRUSR | S_IFREG, 
121                                                obd_dir);
122
123         if (obd_status) {
124                 obd_status->read_proc = read_lustre_status;
125                 obd_status->data = (void*) obd;
126         }
127
128         return obd_dir;
129 }
130
131 void proc_lustre_remove_obd_entry(const char* name, struct obd_device *obd)
132 {
133         struct proc_dir_entry *obd_entry = 0;
134         struct proc_dir_entry *obd_dir = obd->obd_proc_entry;
135         
136         remove_proc_entry(name, obd_dir);
137
138         while (obd_dir->subdir==0) {
139                 /* if we removed last entry in this directory,
140                  * then remove parent directory unless this
141                  * is /proc itself
142                  */
143                 if (obd_dir == &proc_root) 
144                         break;
145                         
146                 obd_entry = obd_dir;
147                 obd_dir = obd_dir->parent;
148
149                 /* If /proc/lustre/obd/foo or /proc/lustre/obd or
150                  * /proc/lustre is being removed, then reset
151                  * internal variables
152                  */
153
154                 if (obd_entry == obd->obd_proc_entry)
155                         obd->obd_proc_entry=0; /* /proc/lustre/obd/foo */
156                 else 
157                         if (obd_entry == proc_lustre_obd_dir_entry)
158                                 proc_lustre_obd_dir_entry=0;
159                         else 
160                                 if (obd_entry == proc_lustre_dir_entry) 
161                                         proc_lustre_dir_entry=0;
162
163                 remove_proc_entry(obd_entry->name, obd_dir);
164         }
165 }
166
167 void proc_lustre_release_obd_device(struct obd_device *obd)
168 {
169         proc_lustre_remove_obd_entry("status", obd);
170 }
171
172
173 #else  /* CONFIG_PROC_FS */
174
175 struct proc_dir_entry *proc_lustre_register_obd_device(struct obd_device *obd)
176 {
177         return 0;
178 }
179
180 void proc_lustre_remove_obd_entry(const char* name, struct obd_device *obd) {}
181 void proc_lustre_release_obd_device(struct obd_device *obd) {}
182
183 #endif   /* CONFIG_PROC_FS */
184                                    
185 EXPORT_SYMBOL(proc_lustre_remove_obd_entry);
186
187
188
189
190
191
192
193
194
195
196