This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[samba.git] / pcp / samba.c
1 /*
2  * Samba, configurable PMDA
3  *
4  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 of the GNU General Public License as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it would be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * Further, this software is distributed without any warranty that it is
15  * free of the rightful claim of any third person regarding infringement
16  * or the like.  Any license provided herein, whether implied or
17  * otherwise, applies only to this software file.  Patent licenses, if
18  * any, provided herein do not apply to combinations of this program with
19  * other software, or any other product whatsoever.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write the Free Software Foundation, Inc., 59
23  * Temple Place - Suite 330, Boston MA 02111-1307, USA.
24  *
25  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
26  * Mountain View, CA  94043, or:
27  *
28  * http://www.sgi.com
29  *
30  * For further information regarding this notice, see:
31  *
32  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
33  */
34
35 typedef int BOOL;
36
37 #define IRIX 1
38
39 #include <stdio.h>
40 #include <sys/shm.h>
41 #include <pcp/pmapi.h>
42 #ifdef IRIX
43 #include <pcp/impl.h>
44 #endif
45 #include <pcp/pmda.h>
46 #include "domain.h"
47 #include "profile.h"
48 #include "metrics.h"
49
50 static pmdaInstid *counttime = NULL;
51 static pmdaInstid *bytes = NULL;
52
53 /*
54  * List of instance domains
55  */
56
57 static pmdaIndom indomtab[] = {
58         {COUNT_TIME_INDOM,0,NULL},
59         {BYTE_INDOM,0,NULL}
60 };
61 /*
62  * all metrics supported in this PMDA - one table entry for each
63  */
64
65 static pmdaMetric metrictab[] = {
66 /* smbd.smb_count */
67     { NULL, { PMDA_PMID(0,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
68                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
69 /* smbd.uid_changes */
70     { NULL, { PMDA_PMID(0,1), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
71                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
72 /* statcache.lookups */
73     { NULL, { PMDA_PMID(1,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
74                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
75 /* statcache.misses */
76     { NULL, { PMDA_PMID(1,1), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
77                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
78 /* statcache.hits */
79     { NULL, { PMDA_PMID(1,2), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
80                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
81 /* writecache.num_caches */
82     { NULL, { PMDA_PMID(2,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT, 
83                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
84 /* writecache.allocated_caches */
85     { NULL, { PMDA_PMID(2,1), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT, 
86                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
87 /* writecache.read_hits */
88     { NULL, { PMDA_PMID(2,2), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
89                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
90 /* writecache.total_writes */
91     { NULL, { PMDA_PMID(2,3), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
92                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
93 /* writecache.init_writes */
94     { NULL, { PMDA_PMID(2,4), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
95                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
96 /* writecache.abutted_writes */
97     { NULL, { PMDA_PMID(2,5), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
98                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
99 /* writecache.perfect_writes */
100     { NULL, { PMDA_PMID(2,6), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
101                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
102 /* writecache.direct_writes */
103     { NULL, { PMDA_PMID(2,7), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
104                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
105 /* writecache.non_oplock_writes */
106     { NULL, { PMDA_PMID(2,8), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
107                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
108 /* writecache.seek_flush */
109     { NULL, { PMDA_PMID(2,9), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
110                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
111 /* writecache.read_flush */
112     { NULL, { PMDA_PMID(2,10), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
113                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
114 /* writecache.write_flush */
115     { NULL, { PMDA_PMID(2,11), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
116                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
117 /* writecache.readraw_flush */
118     { NULL, { PMDA_PMID(2,12), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
119                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
120 /* writecache.oplock_rel_flush */
121     { NULL, { PMDA_PMID(2,13), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
122                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
123 /* writecache.close_flush */
124     { NULL, { PMDA_PMID(2,14), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
125                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
126 /* writecache.sync_flush */
127     { NULL, { PMDA_PMID(2,15), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
128                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
129 /* writecache.size_change_flush */
130     { NULL, { PMDA_PMID(2,16), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, 
131                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
132 /* counts instance domain */
133     { NULL, { PMDA_PMID(3,0), PM_TYPE_U32, COUNT_TIME_INDOM, PM_SEM_COUNTER, 
134                 { 0,0,1,0,0,PM_COUNT_ONE} }, },
135 /* times instance domain */
136     { NULL, { PMDA_PMID(4,0), PM_TYPE_U32, COUNT_TIME_INDOM, PM_SEM_COUNTER, 
137                 { 0,1,0,0,PM_TIME_USEC,0} }, },
138 /* bytes instance domain */
139     { NULL, { PMDA_PMID(5,0), PM_TYPE_U32, BYTE_INDOM, PM_SEM_COUNTER, 
140                 { 1,0,0,PM_SPACE_BYTE,0,0} }, }
141
142 };
143
144 extern int      errno;
145 struct profile_stats    *stats;
146 struct profile_header   *shmheader;
147 int             shmid = -1;
148
149
150 int
151 samba_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
152 {
153     __pmID_int          *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
154     
155
156     if (inst != PM_IN_NULL && mdesc->m_desc.indom == PM_INDOM_NULL)
157         return PM_ERR_INST;
158
159     if (idp->cluster == 0) {
160         switch (idp->item) {
161             case 0:                     /* smbd.smb_count */
162                 atom->ul = stats->smb_count;
163                 break;
164             case 1:                     /* smb.uid_changes */
165                 atom->ul = stats->uid_changes;
166                 break;
167             default:
168                 return PM_ERR_PMID;
169         }
170     }
171     else if (idp->cluster == 1) {       /* statcache */
172         switch (idp->item) {
173             case 0:                     /* statcache.lookups */
174                 atom->ul = stats->statcache_lookups;
175                 break;
176             case 1:                     /* statcache.misses */
177                 atom->ul = stats->statcache_misses;
178                 break;
179             case 2:                     /* statcache.hits */
180                 atom->ul = stats->statcache_hits;
181                 break;
182             default:
183                 return PM_ERR_PMID;
184         }
185     }
186     else if (idp->cluster == 2) {       /* writecache */
187         switch (idp->item) {
188             case 0:                     /* writecache.num_caches */
189                 atom->ul = stats->writecache_num_write_caches;
190                 break;
191             case 1:                     /* writecache.allocated_caches */
192                 atom->ul = stats->writecache_allocated_write_caches;
193                 break;
194             case 2:                     /* writecache.read_hits */
195                 atom->ul = stats->writecache_read_hits;
196                 break;
197             case 3:                     /* writecache.total_writes */
198                 atom->ul = stats->writecache_total_writes;
199                 break;
200             case 4:                     /* writecache.init_writes */
201                 atom->ul = stats->writecache_init_writes;
202                 break;
203             case 5:                     /* writecache.abutted_writes */
204                 atom->ul = stats->writecache_abutted_writes;
205                 break;
206             case 6:                     /* writecache.perfect_writes */
207                 atom->ul = stats->writecache_num_perfect_writes;
208                 break;
209             case 7:                     /* writecache.direct_writes */
210                 atom->ul = stats->writecache_direct_writes;
211                 break;
212             case 8:                     /* writecache.non_oplock_writes */
213                 atom->ul = stats->writecache_non_oplock_writes;
214                 break;
215             case 9:                     /* writecache.seek_flush */
216                 atom->ul = stats->writecache_flushed_writes[SEEK_FLUSH];
217                 break;
218             case 10:                    /* writecache.read_flush */
219                 atom->ul = stats->writecache_flushed_writes[READ_FLUSH];
220                 break;
221             case 11:                    /* writecache.write_flush */
222                 atom->ul = stats->writecache_flushed_writes[WRITE_FLUSH];
223                 break;
224             case 12:                    /* writecache.readraw_flush */
225                 atom->ul = stats->writecache_flushed_writes[READRAW_FLUSH];
226                 break;
227             case 13:                    /* writecache.oplock_rel_flush */
228                 atom->ul = stats->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH];
229                 break;
230             case 14:                    /* writecache.close_flush */
231                 atom->ul = stats->writecache_flushed_writes[CLOSE_FLUSH];
232                 break;
233             case 15:                    /* writecache.sync_flush */
234                 atom->ul = stats->writecache_flushed_writes[SYNC_FLUSH];
235                 break;
236             case 16:                    /* writecache.size_change_flush */
237                 atom->ul = stats->writecache_flushed_writes[SIZECHANGE_FLUSH];
238                 break;
239             default:
240                 return PM_ERR_PMID;
241         }
242     }
243     else if (idp->cluster == 3) {       /* counts */
244         if (idp->item == 0) {
245             if (inst < indomtab[COUNT_TIME_INDOM].it_numinst) {
246                 unsigned *p;
247
248                 p = (unsigned *)((unsigned)stats + samba_counts[inst].offset);
249                 atom->ul = *p;
250             }
251             else
252                 return PM_ERR_INST;
253         }
254         else
255             return PM_ERR_PMID;
256     }
257     else if (idp->cluster == 4) {       /* times */
258         if (idp->item == 0) {
259             if (inst < indomtab[COUNT_TIME_INDOM].it_numinst) {
260                 unsigned *p;
261
262                 p = (unsigned *)((unsigned)stats + samba_times[inst].offset);
263                 atom->ul = *p;
264             }
265             else
266                 return PM_ERR_INST;
267         }
268         else
269             return PM_ERR_PMID;
270     }
271     else if (idp->cluster == 5) {       /* bytes */
272         if (idp->item == 0) {
273             if (inst < indomtab[BYTE_INDOM].it_numinst) {
274                 unsigned *p;
275
276                 p = (unsigned *)((unsigned)stats + samba_bytes[inst].offset);
277                 atom->ul = *p;
278             }
279             else
280                 return PM_ERR_INST;
281         }
282         else
283             return PM_ERR_PMID;
284     }
285     else
286         return PM_ERR_PMID;
287     return 0;
288 }
289
290
291 void 
292 samba_init(pmdaInterface *dp)
293 {
294     int inst_count, i;
295
296     if (dp->status != 0)
297         return;
298
299     if ((shmid = shmget(PROF_SHMEM_KEY, 0, 0)) == -1) {
300         fprintf(stderr, "shmid: %s\n", strerror(errno));
301         fprintf(stderr, "samba not compiled with profile support or not running\n");
302         exit(1);
303     }
304     shmheader = (struct profile_header *)shmat(shmid, NULL, SHM_RDONLY);
305     if ((int)shmheader == -1) {
306         fprintf(stderr, "shmat: %s\n", strerror(errno));
307         exit(1);
308     }
309
310 /*
311  * Initialize lists of instances
312  */
313
314     inst_count = sizeof(samba_counts)/sizeof(samba_counts[0]);
315     counttime = (pmdaInstid *)malloc(inst_count * sizeof(pmdaInstid));
316     if (counttime == NULL) {
317         __pmNoMem("count&time",inst_count * sizeof(pmdaInstid),PM_FATAL_ERR);
318         /* NOTREACHED*/
319     }
320     for (i = 0; i < inst_count; i++) {
321         counttime[i].i_inst = i;
322         counttime[i].i_name = samba_counts[i].name;
323     }
324     indomtab[COUNT_TIME_INDOM].it_numinst = inst_count;
325     indomtab[COUNT_TIME_INDOM].it_set = counttime;
326
327     inst_count = sizeof(samba_bytes)/sizeof(samba_bytes[0]);
328     bytes = (pmdaInstid *)malloc(inst_count * sizeof(pmdaInstid));
329     if (bytes == NULL) {
330         __pmNoMem("bytes",inst_count * sizeof(pmdaInstid),PM_FATAL_ERR);
331         /* NOTREACHED*/
332     }
333     for (i = 0; i < inst_count; i++) {
334         bytes[i].i_inst = i;
335         bytes[i].i_name = samba_bytes[i].name;
336     }
337     indomtab[BYTE_INDOM].it_numinst = inst_count;
338     indomtab[BYTE_INDOM].it_set = bytes;
339
340
341     pmdaSetFetchCallBack(dp, samba_fetchCallBack);
342     pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]), 
343              metrictab, sizeof(metrictab)/sizeof(metrictab[0]));
344
345     /* validate the data */
346     if (!shmheader)     /* not mapped yet */
347         fprintf(stderr, "samba_init: shmem not mapped\n");
348     else if (shmheader->prof_shm_magic != PROF_SHM_MAGIC)
349         fprintf(stderr, "samba_init: bad magic\n");
350     else if (shmheader->prof_shm_version != PROF_SHM_VERSION)
351         fprintf(stderr, "samba_init: bad version %X\n",
352                         shmheader->prof_shm_version);
353     else {
354         stats = &shmheader->stats;
355         return;         /* looks OK */
356     }
357     exit(1);
358 }
359
360
361 int
362 main(int argc, char **argv)
363 {
364     int                 err = 0;
365     char                *p;
366     pmdaInterface       dispatch;
367
368     for (p = pmProgname = argv[0]; *p; p++)
369         if (*p == '/') pmProgname = p+1;
370
371     pmdaDaemon(&dispatch, PMDA_INTERFACE_2, pmProgname, SAMBA,
372                 "samba.log", "/var/pcp/pmdas/samba/help");
373
374     if (pmdaGetOpt(argc, argv, "D:d:l:?", &dispatch, &err) != EOF) {
375         fprintf(stderr, "Usage: %s [options]\n\n\
376 Options:\n\
377   -d domain    use domain (numeric) for metrics domain of PMDA\n\
378   -l logfile   write log into logfile rather than using default log name\n",
379         pmProgname);
380         exit(1);
381     }
382
383     pmdaOpenLog(&dispatch);
384     samba_init(&dispatch);
385     pmdaConnect(&dispatch);
386     pmdaMain(&dispatch);
387
388     exit(0);
389     /*NOTREACHED*/
390 }