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:
30 * For further information regarding this notice, see:
32 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
41 #include <pcp/pmapi.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
},
62 * all metrics supported in this PMDA - one table entry for each
65 static pmdaMetric metrictab
[] = {
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
} }, },
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} }, }
145 struct profile_stats
*stats
;
146 struct profile_header
*shmheader
;
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
)
159 if (idp
->cluster
== 0) {
161 case 0: /* smbd.smb_count */
162 atom
->ul
= stats
->smb_count
;
164 case 1: /* smb.uid_changes */
165 atom
->ul
= stats
->uid_changes
;
171 else if (idp
->cluster
== 1) { /* statcache */
173 case 0: /* statcache.lookups */
174 atom
->ul
= stats
->statcache_lookups
;
176 case 1: /* statcache.misses */
177 atom
->ul
= stats
->statcache_misses
;
179 case 2: /* statcache.hits */
180 atom
->ul
= stats
->statcache_hits
;
186 else if (idp
->cluster
== 2) { /* writecache */
188 case 0: /* writecache.num_caches */
189 atom
->ul
= stats
->writecache_num_write_caches
;
191 case 1: /* writecache.allocated_caches */
192 atom
->ul
= stats
->writecache_allocated_write_caches
;
194 case 2: /* writecache.read_hits */
195 atom
->ul
= stats
->writecache_read_hits
;
197 case 3: /* writecache.total_writes */
198 atom
->ul
= stats
->writecache_total_writes
;
200 case 4: /* writecache.init_writes */
201 atom
->ul
= stats
->writecache_init_writes
;
203 case 5: /* writecache.abutted_writes */
204 atom
->ul
= stats
->writecache_abutted_writes
;
206 case 6: /* writecache.perfect_writes */
207 atom
->ul
= stats
->writecache_num_perfect_writes
;
209 case 7: /* writecache.direct_writes */
210 atom
->ul
= stats
->writecache_direct_writes
;
212 case 8: /* writecache.non_oplock_writes */
213 atom
->ul
= stats
->writecache_non_oplock_writes
;
215 case 9: /* writecache.seek_flush */
216 atom
->ul
= stats
->writecache_flushed_writes
[SEEK_FLUSH
];
218 case 10: /* writecache.read_flush */
219 atom
->ul
= stats
->writecache_flushed_writes
[READ_FLUSH
];
221 case 11: /* writecache.write_flush */
222 atom
->ul
= stats
->writecache_flushed_writes
[WRITE_FLUSH
];
224 case 12: /* writecache.readraw_flush */
225 atom
->ul
= stats
->writecache_flushed_writes
[READRAW_FLUSH
];
227 case 13: /* writecache.oplock_rel_flush */
228 atom
->ul
= stats
->writecache_flushed_writes
[OPLOCK_RELEASE_FLUSH
];
230 case 14: /* writecache.close_flush */
231 atom
->ul
= stats
->writecache_flushed_writes
[CLOSE_FLUSH
];
233 case 15: /* writecache.sync_flush */
234 atom
->ul
= stats
->writecache_flushed_writes
[SYNC_FLUSH
];
236 case 16: /* writecache.size_change_flush */
237 atom
->ul
= stats
->writecache_flushed_writes
[SIZECHANGE_FLUSH
];
243 else if (idp
->cluster
== 3) { /* counts */
244 if (idp
->item
== 0) {
245 if (inst
< indomtab
[COUNT_TIME_INDOM
].it_numinst
) {
248 p
= (unsigned *)((unsigned)stats
+ samba_counts
[inst
].offset
);
257 else if (idp
->cluster
== 4) { /* times */
258 if (idp
->item
== 0) {
259 if (inst
< indomtab
[COUNT_TIME_INDOM
].it_numinst
) {
262 p
= (unsigned *)((unsigned)stats
+ samba_times
[inst
].offset
);
271 else if (idp
->cluster
== 5) { /* bytes */
272 if (idp
->item
== 0) {
273 if (inst
< indomtab
[BYTE_INDOM
].it_numinst
) {
276 p
= (unsigned *)((unsigned)stats
+ samba_bytes
[inst
].offset
);
292 samba_init(pmdaInterface
*dp
)
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");
304 shmheader
= (struct profile_header
*)shmat(shmid
, NULL
, SHM_RDONLY
);
305 if ((int)shmheader
== -1) {
306 fprintf(stderr
, "shmat: %s\n", strerror(errno
));
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
);
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
));
330 __pmNoMem("bytes",inst_count
* sizeof(pmdaInstid
),PM_FATAL_ERR
);
333 for (i
= 0; i
< inst_count
; 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
);
354 stats
= &shmheader
->stats
;
355 return; /* looks OK */
362 main(int argc
, char **argv
)
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\
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",
383 pmdaOpenLog(&dispatch
);
384 samba_init(&dispatch
);
385 pmdaConnect(&dispatch
);