Whamcloud - gitweb
Fix a few compiler warnings.
[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()
23  *               proc_lustre_release_obd_device()
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: ", obddev->obd_minor);
63         
64         if  (obddev->obd_flags & OBD_ATTACHED) {
65                 p += sprintf(&page[p], ", attached(%s)", 
66                              obddev->obd_type->typ_name);
67         }
68         
69         if  (obddev->obd_flags & OBD_SET_UP) {
70                 struct dentry   *my_dentry;
71                 struct vfsmount *root_mnt;
72                 char *path;
73                 char *pathpage;
74                 
75                 if (!(pathpage = (char*) __get_free_page(GFP_KERNEL)))
76                         return -ENOMEM;
77                 
78                 my_dentry = NULL;
79                 root_mnt = mntget(current->fs->rootmnt);
80                 path = d_path(my_dentry,root_mnt,pathpage,PAGE_SIZE);
81                 
82                 p += sprintf(&page[p], ", setup(%s)", path);
83                 
84                 free_page((unsigned long) pathpage);
85         }
86         
87         /* print exports */
88         {
89                 struct list_head * lh;
90                 struct obd_export * export=0;
91                 
92                 lh = &obddev->obd_exports;
93                 while ((lh = lh->next) != &obddev->obd_exports) {
94                         p += sprintf(&page[p],
95                                      ((export==0) ? ", connections(" : ",") );
96                         export = list_entry(lh, struct obd_export, export_chain);
97                         p += sprintf(&page[p], "%p", export);
98                 } 
99                 if (export!=0) { /* there was at least one export */
100                         p += sprintf(&page[p], ")");
101                 }
102         }
103         
104         p += sprintf(&page[p], "\n");
105
106         /* Compute eof and return value */
107
108         if (offset + count >= p) {
109                 *eof=1;
110                 return (p - offset);
111         }
112         return count;
113 }
114
115 struct proc_dir_entry *
116 proc_lustre_register_obd_device(struct obd_device *obd)
117 {
118         char obdname[32];
119         struct proc_dir_entry *obd_dir;
120         struct proc_dir_entry *obd_status = 0;
121
122         if (!proc_lustre_dir_entry) {
123                 proc_lustre_dir_entry = proc_mkdir("lustre", &proc_root);
124                 if (IS_ERR(proc_lustre_dir_entry))
125                         return 0;
126         
127                 proc_lustre_obd_dir_entry = 
128                         proc_mkdir("obd", proc_lustre_dir_entry);
129                 if (IS_ERR(proc_lustre_obd_dir_entry))
130                         return 0;
131         }
132
133         sprintf(obdname, "%d", obd->obd_minor);
134
135
136         obd_dir =  proc_mkdir(obdname, proc_lustre_obd_dir_entry);
137         if (obd_dir) 
138                 obd_status = create_proc_entry("status", S_IRUSR | S_IFREG, obd_dir);
139
140         if (obd_status) {
141                 obd_status->read_proc = read_lustre_status;
142                 obd_status->data = (void*) obd;
143         }
144
145         return obd_dir;
146 }
147
148 void proc_lustre_remove_obd_entry(const char* name, struct obd_device *obd)
149 {
150         struct proc_dir_entry *obd_entry = 0;
151         struct proc_dir_entry *obd_dir = obd->obd_proc_entry;
152         
153         remove_proc_entry(name, obd_dir);
154
155         while (obd_dir->subdir==0) {
156                 /* if we removed last entry in this directory,
157                  * then remove parent directory unless this
158                  * is /proc itself
159                  */
160                 if (obd_dir == &proc_root) 
161                         break;
162                         
163                 obd_entry = obd_dir;
164                 obd_dir = obd_dir->parent;
165
166                 /* If /proc/lustre/obd/foo or /proc/lustre/obd or
167                  * /proc/lustre is being removed, then reset
168                  * internal variables
169                  */
170
171                 if (obd_entry == obd->obd_proc_entry)
172                         obd->obd_proc_entry=0; /* /proc/lustre/obd/foo */
173                 else 
174                         if (obd_entry == proc_lustre_obd_dir_entry)
175                                 proc_lustre_obd_dir_entry=0;
176                         else 
177                                 if (obd_entry == proc_lustre_dir_entry) 
178                                         proc_lustre_dir_entry=0;
179
180                 remove_proc_entry(obd_entry->name, obd_dir);
181         }
182 }
183
184 void proc_lustre_release_obd_device(struct obd_device *obd)
185 {
186         proc_lustre_remove_obd_entry("status", obd);
187 }
188
189
190 #else  /* CONFIG_PROC_FS */
191
192 struct proc_dir_entry *proc_lustre_register_obd_device(struct obd_device *obd)
193 {
194         return 0;
195 }
196
197 void proc_lustre_remove_obd_entry(const char* name, struct obd_device *obd) {}
198 void proc_lustre_release_obd_device(struct obd_device *obd) {}
199
200 #endif   /* CONFIG_PROC_FS */
201                                    
202 EXPORT_SYMBOL(proc_lustre_remove_obd_entry);
203
204
205
206
207
208
209
210
211
212
213