Whamcloud - gitweb
- merge 0.7rc1 from b_devel to HEAD (20030612 merge point)
[fs/lustre-release.git] / lustre / include / linux / lprocfs_status.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2002 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
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.
11  *
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.
16  *
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.
20  *
21  *   Top level header file for LProc SNMP
22  *   Author: Hariharan Thantry thantry@users.sourceforge.net
23  */
24 #ifndef _LPROCFS_SNMP_H
25 #define _LPROCFS_SNMP_H
26
27 #ifdef __KERNEL__
28 #include <linux/autoconf.h>
29 #include <linux/proc_fs.h>
30 #endif
31
32 #ifndef LPROCFS
33 #ifdef  CONFIG_PROC_FS  /* Ensure that /proc is configured */
34 #define LPROCFS
35 #endif
36 #endif
37
38 struct lprocfs_vars {
39         const char   *name;
40         read_proc_t *read_fptr;
41         write_proc_t *write_fptr;
42         void *data;
43 };
44
45 struct lprocfs_static_vars {
46         struct lprocfs_vars *module_vars;
47         struct lprocfs_vars *obd_vars;
48 };
49
50 /* Lprocfs counters are can be configured using the enum bit masks below.
51  *
52  * LPROCFS_CNTR_EXTERNALLOCK indicates that an external lock already
53  * protects this counter from concurrent updates. If not specified,
54  * lprocfs an internal per-counter lock variable. External locks are
55  * not used to protect counter increments, but are used to protect
56  * counter readout and resets.
57  *
58  * LPROCFS_CNTR_AVGMINMAX indicates a multi-valued counter samples,
59  * (i.e. counter can be incremented by more than "1"). When specified,
60  * the counter maintains min, max and sum in addition to a simple
61  * invocation count. This allows averages to be be computed.
62  * If not specified, the counter is an increment-by-1 counter.
63  * min, max, sum, etc. are not maintained.
64  *
65  * LPROCFS_CNTR_STDDEV indicates that the counter should track sum of
66  * squares (for multi-valued counter samples only). This allows
67  * external computation of standard deviation, but involves a 64-bit
68  * multiply per counter increment.
69  */
70
71 enum {
72         LPROCFS_CNTR_EXTERNALLOCK = 1,
73         LPROCFS_CNTR_AVGMINMAX    = 2,
74         LPROCFS_CNTR_STDDEV       = 4,
75 };
76
77 struct lprocfs_counter {
78         union {
79                 spinlock_t    internal; /* when there is no external lock */
80                 spinlock_t   *external; /* external lock, when available */
81         } l;
82         unsigned int  config;
83         __u64         count;
84         __u64         sum;
85         __u64         min;
86         __u64         max;
87         __u64         sumsquare;
88         const char    *name;   /* must be static */
89         const char    *units;  /* must be static */
90 };
91
92
93 struct lprocfs_counters {
94         unsigned int           num;
95         unsigned int           padto8byteboundary;
96         struct lprocfs_counter cntr[0];
97 };
98
99
100 /* class_obd.c */
101 extern struct proc_dir_entry *proc_lustre_root;
102 struct obd_device;
103
104 #ifdef LPROCFS
105
106 /* Two optimized LPROCFS counter increment macros are provided:
107  *     LPROCFS_COUNTER_INCR(cntr, value) - use for multi-valued counters
108  *     LPROCFS_COUNTER_INCBY1(cntr) - optimized for by-one counters
109  * Counter data layout allows config flag, counter lock and the
110  * count itself to reside within a single cache line.
111  */
112
113 #define LPROCFS_COUNTER_INCR(cntr, value)                         \
114         do {                                                      \
115                struct lprocfs_counter *c = (cntr);                \
116                LASSERT(c != NULL);                                \
117                if (!(c->config & LPROCFS_CNTR_EXTERNALLOCK))      \
118                      spin_lock(&c->l.internal);                   \
119                c->count++;                                        \
120                if (c->config & LPROCFS_CNTR_AVGMINMAX) {          \
121                       __u64 val = (__u64) (value);                \
122                       c->sum += val;                              \
123                       if (c->config & LPROCFS_CNTR_STDDEV)        \
124                          c->sumsquare += (val*val);               \
125                       if (val < c->min) c->min = val;             \
126                       if (val > c->max) c->max = val;             \
127                }                                                  \
128                if (!(c->config & LPROCFS_CNTR_EXTERNALLOCK))      \
129                       spin_unlock(&c->l.internal);                \
130       } while (0)
131
132 #define LPROCFS_COUNTER_INCBY1(cntr)                              \
133         do {                                                      \
134                struct lprocfs_counter *c = (cntr);                \
135                LASSERT(c != NULL);                                \
136                if (!(c->config & LPROCFS_CNTR_EXTERNALLOCK))      \
137                      spin_lock(&c->l.internal);                   \
138                c->count++;                                        \
139                if (!(c->config & LPROCFS_CNTR_EXTERNALLOCK))      \
140                       spin_unlock(&c->l.internal);                \
141       } while (0)
142
143 #define LPROCFS_COUNTER_INIT(cntr, conf, lck, nam, un)                 \
144         do {                                                           \
145                struct lprocfs_counter *c = (cntr);                     \
146                LASSERT(c != NULL);                                     \
147                memset(c, 0, sizeof(struct lprocfs_counter));           \
148                if (conf & LPROCFS_CNTR_EXTERNALLOCK) c->l.external = (lck); \
149                else spin_lock_init(&c->l.internal);                    \
150                c->config = conf;                                       \
151                c->min = (~(__u64)0);                                   \
152                c->name = (nam);                                        \
153                c->units = (un);                                        \
154         } while (0)
155
156 extern struct lprocfs_counters* lprocfs_alloc_counters(unsigned int num);
157 extern void lprocfs_free_counters(struct lprocfs_counters* cntrs);
158 extern int lprocfs_alloc_obd_counters(struct obd_device *obddev,
159                                       unsigned int num_private_counters);
160 extern void lprocfs_free_obd_counters(struct obd_device *obddev);
161 extern int lprocfs_register_counters(struct proc_dir_entry *root,
162                                      const char* name,
163                                      struct lprocfs_counters *cntrs);
164
165 #define LPROCFS_INIT_MULTI_VARS(array, size)                              \
166 void lprocfs_init_multi_vars(unsigned int idx,                            \
167                              struct lprocfs_static_vars *x)               \
168 {                                                                         \
169    struct lprocfs_static_vars *glob = (struct lprocfs_static_vars*)array; \
170    LASSERT(glob != 0);                                                    \
171    LASSERT(idx < (unsigned int)(size));                                   \
172    x->module_vars = glob[idx].module_vars;                                \
173    x->obd_vars = glob[idx].obd_vars;                                      \
174 }                                                                         \
175
176 #define LPROCFS_INIT_VARS(vclass, vinstance)           \
177 void lprocfs_init_vars(struct lprocfs_static_vars *x)  \
178 {                                                      \
179         x->module_vars = vclass;                       \
180         x->obd_vars = vinstance;                       \
181 }                                                      \
182
183 extern void lprocfs_init_vars(struct lprocfs_static_vars *var);
184 extern void lprocfs_init_multi_vars(unsigned int idx,
185                                     struct lprocfs_static_vars *var);
186 /* lprocfs_status.c */
187 extern int lprocfs_add_vars(struct proc_dir_entry *root,
188                             struct lprocfs_vars *var,
189                             void *data);
190
191 extern struct proc_dir_entry *lprocfs_register(const char *name,
192                                                struct proc_dir_entry *parent,
193                                                struct lprocfs_vars *list,
194                                                void *data);
195
196 extern void lprocfs_remove(struct proc_dir_entry *root);
197
198 extern int lprocfs_obd_attach(struct obd_device *dev, struct lprocfs_vars *list);
199 extern int lprocfs_obd_detach(struct obd_device *dev);
200
201 /* Generic callbacks */
202
203 extern int lprocfs_rd_u64(char *page, char **start, off_t off,
204                           int count, int *eof, void *data);
205 extern int lprocfs_rd_uuid(char *page, char **start, off_t off,
206                            int count, int *eof, void *data);
207 extern int lprocfs_rd_name(char *page, char **start, off_t off,
208                            int count, int *eof, void *data);
209 extern int lprocfs_rd_server_uuid(char *page, char **start, off_t off,
210                                   int count, int *eof, void *data);
211 extern int lprocfs_rd_conn_uuid(char *page, char **start, off_t off,
212                                 int count, int *eof, void *data);
213 extern int lprocfs_rd_numrefs(char *page, char **start, off_t off,
214                               int count, int *eof, void *data);
215
216 /* Statfs helpers */
217 struct statfs;
218 extern int lprocfs_rd_blksize(char *page, char **start, off_t off,
219                               int count, int *eof, struct statfs *sfs);
220 extern int lprocfs_rd_kbytestotal(char *page, char **start, off_t off,
221                                   int count, int *eof, struct statfs *sfs);
222 extern int lprocfs_rd_kbytesfree(char *page, char **start, off_t off,
223                                  int count, int *eof, struct statfs *sfs);
224 extern int lprocfs_rd_filestotal(char *page, char **start, off_t off,
225                                  int count, int *eof, struct statfs *sfs);
226 extern int lprocfs_rd_filesfree(char *page, char **start, off_t off,
227                                 int count, int *eof, struct statfs *sfs);
228 extern int lprocfs_rd_filegroups(char *page, char **start, off_t off,
229                                  int count, int *eof, struct statfs *sfs);
230
231 /* lprocfs_status.c: counter read/write functions */
232 struct file;
233 extern int lprocfs_counter_read(char *page, char **start, off_t off,
234                                 int count, int *eof, void *data);
235 extern int lprocfs_counter_write(struct file *file, const char *buffer,
236                                  unsigned long count, void *data);
237
238 #define DEFINE_LPROCFS_STATFS_FCT(fct_name, get_statfs_fct)               \
239 int fct_name(char *page, char **start, off_t off,                         \
240              int count, int *eof, void *data)                             \
241 {                                                                         \
242         struct statfs sfs;                                                \
243         int rc = get_statfs_fct((struct obd_device*)data, &sfs);          \
244         return (rc == 0 ?                                                 \
245                 lprocfs_##fct_name (page, start, off, count, eof, &sfs) : \
246                 rc);                                                      \
247 }
248
249 #else
250 /* LPROCFS is not defined */
251 #define LPROCFS_COUNTER_INCR(cntr, value)
252 #define LPROCFS_COUNTER_INCBY1(cntr)
253 #define LPROCFS_COUNTER_INIT(cntr, conf, lock, nam, un)
254
255 static inline struct lprocfs_counters* lprocfs_alloc_counters(unsigned int num)
256 { return NULL; }
257 static inline void lprocfs_free_counters(struct lprocfs_counters* cntrs)
258 { return; }
259
260 static inline int lprocfs_register_counters(struct proc_dir_entry *root,
261                                             const char* name,
262                                             struct lprocfs_counters *cntrs)
263 { return 0; }
264 static inline int lprocfs_alloc_obd_counters(struct obd_device *obddev,
265                                              unsigned int num_private_counters)
266 { return 0; }
267 static inline void lprocfs_free_obd_counters(struct obd_device *obddev)
268 { return; }
269
270 static inline struct proc_dir_entry *
271 lprocfs_register(const char *name, struct proc_dir_entry *parent,
272                  struct lprocfs_vars *list, void *data) { return NULL; }
273 #define LPROCFS_INIT_MULTI_VARS(array, size)
274 static inline void lprocfs_init_multi_vars(unsigned int idx,
275                                            struct lprocfs_static_vars *x) { return; }
276 #define LPROCFS_INIT_VARS(vclass, vinstance)
277 static inline void lprocfs_init_vars(struct lprocfs_static_vars *x) { return; }
278 static inline int lprocfs_add_vars(struct proc_dir_entry *root,
279                                    struct lprocfs_vars *var,
280                                    void *data) { return 0; }
281 static inline void lprocfs_remove(struct proc_dir_entry *root) {};
282 struct obd_device;
283 static inline int lprocfs_obd_attach(struct obd_device *dev,
284                                      struct lprocfs_vars *list) { return 0; }
285 static inline int lprocfs_obd_detach(struct obd_device *dev)  { return 0; }
286 static inline int lprocfs_rd_u64(char *page, char **start, off_t off,
287                                  int count, int *eof, void *data) { return 0; }
288 static inline int lprocfs_rd_uuid(char *page, char **start, off_t off,
289                                   int count, int *eof, void *data) { return 0; }
290 static inline int lprocfs_rd_name(char *page, char **start, off_t off,
291                                   int count, int *eof, void *data) { return 0; }
292 static inline int lprocfs_rd_server_uuid(char *page, char **start, off_t off,
293                                          int count, int *eof, void *data) { return 0; }
294 static inline int lprocfs_rd_conn_uuid(char *page, char **start, off_t off,
295                                        int count, int *eof, void *data) { return 0; }
296 static inline int lprocfs_rd_numrefs(char *page, char **start, off_t off,
297                                      int count, int *eof, void *data) { return 0; }
298
299 /* Statfs helpers */
300 struct statfs;
301 static inline
302 int lprocfs_rd_blksize(char *page, char **start, off_t off,
303                        int count, int *eof, struct statfs *sfs) { return 0; }
304 static inline
305 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off,
306                            int count, int *eof, struct statfs *sfs) { return 0; }
307 static inline
308 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off,
309                           int count, int *eof, struct statfs *sfs) { return 0; }
310 static inline
311 int lprocfs_rd_filestotal(char *page, char **start, off_t off,
312                           int count, int *eof, struct statfs *sfs) { return 0; }
313 static inline
314 int lprocfs_rd_filesfree(char *page, char **start, off_t off,
315                          int count, int *eof, struct statfs *sfs)  { return 0; }
316 static inline
317 int lprocfs_rd_filegroups(char *page, char **start, off_t off,
318                           int count, int *eof, struct statfs *sfs) { return 0; }
319 static inline
320 int lprocfs_counter_read(char *page, char **start, off_t off,
321                          int count, int *eof, void *data) { return 0; }
322 struct file;
323 static inline
324 int lprocfs_counter_write(struct file *file, const char *buffer,
325                           unsigned long count, void *data) { return 0; }
326
327 #define DEFINE_LPROCFS_STATFS_FCT(fct_name, get_statfs_fct)  \
328 int fct_name(char *page, char **start, off_t off,            \
329              int count, int *eof, void *data) { *eof = 1; return 0; }
330
331 #endif /* LPROCFS */
332
333 #endif /* LPROCFS_SNMP_H */