r11936: Fix bug in returning remote time found by Thomas Bork <tombork@web.de>.
[Samba.git] / pcp / samba.c
blob07a6ce2e169ed7a03a0f66405c27bca69993c037
1 /*
2 * Samba, configurable PMDA
4 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
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.
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.
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.
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.
25 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
26 * Mountain View, CA 94043, or:
28 * http://www.sgi.com
30 * For further information regarding this notice, see:
32 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
35 typedef int BOOL;
37 #define IRIX 1
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"
50 static pmdaInstid *counttime = NULL;
51 static pmdaInstid *bytes = NULL;
54 * List of instance domains
57 static pmdaIndom indomtab[] = {
58 {COUNT_TIME_INDOM,0,NULL},
59 {BYTE_INDOM,0,NULL}
62 * all metrics supported in this PMDA - one table entry for each
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} }, }
144 extern int errno;
145 struct profile_stats *stats;
146 struct profile_header *shmheader;
147 int shmid = -1;
151 samba_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
153 __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
156 if (inst != PM_IN_NULL && mdesc->m_desc.indom == PM_INDOM_NULL)
157 return PM_ERR_INST;
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;
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;
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;
243 else if (idp->cluster == 3) { /* counts */
244 if (idp->item == 0) {
245 if (inst < indomtab[COUNT_TIME_INDOM].it_numinst) {
246 unsigned *p;
248 p = (unsigned *)((unsigned)stats + samba_counts[inst].offset);
249 atom->ul = *p;
251 else
252 return PM_ERR_INST;
254 else
255 return PM_ERR_PMID;
257 else if (idp->cluster == 4) { /* times */
258 if (idp->item == 0) {
259 if (inst < indomtab[COUNT_TIME_INDOM].it_numinst) {
260 unsigned *p;
262 p = (unsigned *)((unsigned)stats + samba_times[inst].offset);
263 atom->ul = *p;
265 else
266 return PM_ERR_INST;
268 else
269 return PM_ERR_PMID;
271 else if (idp->cluster == 5) { /* bytes */
272 if (idp->item == 0) {
273 if (inst < indomtab[BYTE_INDOM].it_numinst) {
274 unsigned *p;
276 p = (unsigned *)((unsigned)stats + samba_bytes[inst].offset);
277 atom->ul = *p;
279 else
280 return PM_ERR_INST;
282 else
283 return PM_ERR_PMID;
285 else
286 return PM_ERR_PMID;
287 return 0;
291 void
292 samba_init(pmdaInterface *dp)
294 int inst_count, i;
296 if (dp->status != 0)
297 return;
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);
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);
311 * Initialize lists of instances
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*/
320 for (i = 0; i < inst_count; i++) {
321 counttime[i].i_inst = i;
322 counttime[i].i_name = samba_counts[i].name;
324 indomtab[COUNT_TIME_INDOM].it_numinst = inst_count;
325 indomtab[COUNT_TIME_INDOM].it_set = counttime;
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*/
333 for (i = 0; i < inst_count; i++) {
334 bytes[i].i_inst = i;
335 bytes[i].i_name = samba_bytes[i].name;
337 indomtab[BYTE_INDOM].it_numinst = inst_count;
338 indomtab[BYTE_INDOM].it_set = bytes;
341 pmdaSetFetchCallBack(dp, samba_fetchCallBack);
342 pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]),
343 metrictab, sizeof(metrictab)/sizeof(metrictab[0]));
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 */
357 exit(1);
362 main(int argc, char **argv)
364 int err = 0;
365 char *p;
366 pmdaInterface dispatch;
368 for (p = pmProgname = argv[0]; *p; p++)
369 if (*p == '/') pmProgname = p+1;
371 pmdaDaemon(&dispatch, PMDA_INTERFACE_2, pmProgname, SAMBA,
372 "samba.log", "/var/pcp/pmdas/samba/help");
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);
383 pmdaOpenLog(&dispatch);
384 samba_init(&dispatch);
385 pmdaConnect(&dispatch);
386 pmdaMain(&dispatch);
388 exit(0);
389 /*NOTREACHED*/