ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/host/ihost-perl/plugins/freebsd/freebsd.c
Revision: 1.10
Committed: Tue May 21 16:47:12 2002 UTC (23 years, 7 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.9: +1 -0 lines
Log Message:
Added URL to GPL headers.

File Contents

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org.uk
4 * Copyright (C) 2000-2002 i-scream
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include <stdio.h>
22 #include "ukcprog.h"
23 #include <sys/param.h>
24 #include <sys/ucred.h>
25 #include <sys/mount.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <sys/utsname.h>
29 #include <sys/types.h>
30 #include <utmp.h>
31 #include <sys/dkstat.h>
32 #include <kvm.h>
33 #include <unistd.h>
34 #include <sys/sysctl.h>
35 #include <fcntl.h>
36 #include <limits.h>
37 #include <time.h>
38 #include <sys/time.h>
39
40 uid_t uid;
41 uid_t euid;
42 gid_t gid;
43 gid_t egid;
44
45 void die(){
46 exit(1);
47 }
48
49 void diskStats(){
50 struct statfs *mp;
51 int nummnt;
52 int counter=0;
53 char *mntpnt;
54 char *devicename;
55
56 nummnt=getmntinfo(&mp , MNT_LOCAL);
57 if (nummnt<=0){
58 errf("Failed to get disk stats (%m)");
59 die();
60 }
61
62 mntpnt=malloc(MNAMELEN);
63 devicename=malloc(MNAMELEN);
64
65 for(;counter<nummnt;counter++){
66 strncpy(mntpnt, mp->f_mntonname ,MNAMELEN);
67 strncpy(devicename, mp->f_mntfromname ,MNAMELEN);
68 printf("packet.disk.p%d.attributes.mount %s\n", counter, mntpnt);
69 printf("packet.disk.p%d.attributes.name %s\n", counter, devicename);
70 printf("packet.disk.p%d.attributes.kbytes %lu\n",counter, ((mp->f_bsize/1024) * mp->f_blocks));
71 printf("packet.disk.p%d.attributes.used %lu\n",counter, (((mp->f_bsize/1024) * mp->f_blocks) -((mp->f_bsize/1024) * mp->f_bfree)));
72 printf("packet.disk.p%d.attributes.avail %lu\n",counter, (mp->f_bsize/1024) * mp->f_bavail);
73 printf("packet.disk.p%d.attributes.totalinodes %lu\n", counter, mp->f_files);
74 printf("packet.disk.p%d.attributes.freeinodes %lu\n",counter, mp->f_ffree);
75
76 mp++;
77 }
78
79
80 }
81
82 void osStats(){
83 struct utsname os;
84
85 if((uname(&os)) != 0){
86 errf("Failed to get os stats (%m)");
87 die();
88 }
89
90 printf("packet.os.name %s\n", os.sysname);
91 printf("packet.os.release %s\n" , os.release);
92 printf("packet.os.version %s\n", os.version);
93 printf("packet.os.sysname %s\n" , os.nodename);
94 printf("packet.os.platform %s\n", os.machine);
95
96 }
97 void loadStats(){
98 double loadav[3];
99
100 if((getloadavg(loadav,3)) == -1){
101 errf("Failed to get load averages (%m)");
102 die();
103 }
104
105 printf("packet.load.load1 %.2f\n",loadav[0]);
106 printf("packet.load.load5 %.2f\n",loadav[1]);
107 printf("packet.load.load15 %.2f\n",loadav[2]);
108 }
109
110 void userStats(){
111 struct utmp users;
112 FILE *f;
113 int numusers=0;
114
115 if ((f=fopen(_PATH_UTMP, "r")) == NULL){
116 errf("Failed to get user stats(%m)");
117 die();
118 }
119
120 printf("packet.users.list");
121
122 while((fread(&users, sizeof(users),1,f)) != 0){
123 if (users.ut_name[0] == '\0') continue;
124 printf(" %s",users.ut_name);
125 numusers++;
126 }
127
128 printf("\npacket.users.count %d\n",numusers);
129
130 }
131
132 void systemStats(){
133
134 long cp_time[CPUSTATES];
135 long total, user, idle, kernel, nice;
136 long totalmem, freemem, swaptotal, swapused;
137 float stat;
138
139 static char *uptimename = "kern.boottime";
140 static char *cpname = "kern.cp_time";
141 static char *tmemname = "hw.physmem";
142 static char *fmemname = "vm.stats.vm.v_free_count";
143 int pagesize=-1;
144 size_t size;
145
146 kvm_t *kvmd = NULL;
147 struct kvm_swap swapinfo;
148 char errbuf[_POSIX2_LINE_MAX];
149 time_t current;
150 struct timeval uptime;
151
152 time(&current);
153
154 if (sysctlbyname(uptimename, NULL, &size, NULL, NULL) < 0){
155 errf("sysctlbyname (%m)");
156 die();
157 }
158
159
160 if (sysctlbyname(uptimename, &uptime, &size, NULL, NULL) < 0){
161 errf("Failed to get cpu stats (%m)");
162 die();
163 }
164
165 printf("packet.os.uptime %ld\n",(current-(uptime.tv_sec)));
166
167
168 if (sysctlbyname(cpname, NULL, &size, NULL, NULL) < 0){
169 errf("sysctlbyname (%m)");
170 die();
171 }
172
173 if (size != sizeof cp_time){
174 errf("bailing out, trying to write into something to small");
175 die();
176 }
177
178 if (sysctlbyname(cpname, &cp_time, &size, NULL, NULL) < 0){
179 errf("Failed to get cpu stats (%m)");
180 die();
181 }
182
183 user=cp_time[CP_USER];
184 nice=cp_time[CP_NICE];
185 kernel=cp_time[CP_SYS];
186 idle=cp_time[CP_IDLE];
187
188 sleep(1);
189
190 if (sysctlbyname(cpname, &cp_time, &size, NULL, NULL) < 0){
191 errf("Failed to get cpu stats (%m)");
192 die();
193 }
194
195 user=cp_time[CP_USER]-user;
196 nice=cp_time[CP_NICE]-nice;
197 kernel=cp_time[CP_SYS]-kernel;
198 idle=cp_time[CP_IDLE]-idle;
199
200 total=user+nice+kernel+idle;
201 stat=((float)(user+nice)/(float)total)*100.0;
202 printf("packet.cpu.user %.2f\n",stat);
203 stat=((float)(kernel)/(float)total)*100.0;
204 printf("packet.cpu.kernel %.2f\n",stat);
205 stat=((float)(idle)/(float)total)*100.0;
206 printf("packet.cpu.idle %.2f\n",stat);
207
208 /* Cos i-scream's expects this to be sent :/ */
209 printf("packet.cpu.iowait 0\n");
210 printf("packet.cpu.swap 0\n");
211
212 /* MEMORY STATS */
213 pagesize=getpagesize();
214 if (pagesize==-1){
215 errf("Failed to get pagesize (%m)");
216 die();
217 }
218
219 if (sysctlbyname(tmemname, NULL, &size, NULL, NULL) < 0){
220 errf("sysctlbyname (%m)");
221 die();
222 }
223
224 if (sysctlbyname(tmemname, &totalmem, &size, NULL, NULL) < 0){
225 errf("Failed to get memory stats (%m)");
226 die();
227 }
228
229 if (sysctlbyname(fmemname, NULL, &size, NULL, NULL) < 0){
230 errf("sysctlbyname (%m)");
231 die();
232 }
233
234 if (sysctlbyname(fmemname, &freemem, &size, NULL, NULL) < 0){
235 errf("Failed to get memory stats (%m)");
236 die();
237 }
238
239 totalmem/=(1024*1024);
240 freemem=(freemem*pagesize)/(1024*1024);
241
242 printf("packet.memory.total %ld\n", totalmem);
243 printf("packet.memory.free %ld\n", freemem);
244 printf("packet.memory.used %ld\n", (totalmem-freemem));
245
246 /* Swap stats */
247
248 /* Get sufficent privilages to do this */
249 if (gid!=egid){
250 /* Means we are setgid something, hopefully kmem :) */
251 if ((setegid(egid)) != 0){
252 errf("Failed to gain sufficent privilages (%m)");
253 die();
254 }
255 }
256
257 kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
258 if (kvmd == NULL){
259 errf("Failed to open kvm info to get swap stats (%m)");
260 die();
261 }
262
263 /* Lose our setgid'ness */
264
265 if ((setegid(gid)) != 0){
266 errf("Failed to release permissions, refusing to keep setgid. (%m)");
267 die();
268 }
269
270
271 /* ok, just for proof of concept atm, ideally this will need to handle more
272 than one swap device */
273
274 if ((kvm_getswapinfo(kvmd, &swapinfo, 1,0)) == -1){
275 errf("Failed to get swap info (%m)");
276 die();
277 }
278
279 swaptotal=((((long)swapinfo.ksw_total)*pagesize)/1024)/1024;
280 swapused=((((long)swapinfo.ksw_used)*pagesize)/1024)/1024;
281
282 printf("packet.swap.total %ld\n" , swaptotal);
283 printf("packet.swap.used %ld\n", swapused);
284 printf("packet.swap.free %lu\n", (swaptotal-swapused));
285
286 }
287
288 void processStats(){
289 int sleeping=-1;
290 int zombie=0;
291 int stopped=0;
292 int running=0;
293 char *line;
294 char *line_p;
295
296 FILE *f;
297
298 if((f=popen("/bin/ps -ax" , "r")) == NULL) {
299 errf("Failed to get process stats (%m)");
300 die();
301 }
302
303 while((line=fpgetline(f)) != NULL) {
304 line_p=line;
305 for(; (*line_p == ' ') && (*line_p != '\0'); line_p++);
306 line_p=strchr(line_p, ' ');
307 for(; (*line_p == ' ') && (*line_p != '\0'); line_p++);
308 line_p=strchr(line_p, ' ');
309 for(; (*line_p == ' ') && (*line_p != '\0'); line_p++);
310 if (line_p==NULL) abort();
311
312 if (*line_p=='S') sleeping++;
313 if (*line_p=='I') sleeping++;
314 if (*line_p=='R') running++;
315 if (*line_p=='D') running++;
316 if (*line_p=='Z') zombie++;
317 if (*line_p=='T') stopped++;
318 if (*line_p=='J') running++;
319
320 }
321
322 if((pclose(f)) != 0) {
323 errf("Failed to close process stats (%m)");
324 die();
325 }
326
327 printf("packet.processes.sleeping %d\n",sleeping);
328 printf("packet.processes.cpu %d\n",running);
329 printf("packet.processes.zombie %d\n",zombie);
330 printf("packet.processes.stopped %d\n", stopped);
331 printf("packet.processes.total %d\n", (sleeping+running+zombie+stopped));
332
333
334 }
335
336
337 int main(){
338 uid=getuid();
339 euid=geteuid();
340 gid=getgid();
341 egid=getegid();
342
343 /* We dont want to run with more permissions than we need, until we need em */
344 if ((setegid(gid)) != 0){
345 errf("Failed to release permissions, refusing to keep setgid. (%m)");
346 die();
347 }
348
349 if ((seteuid(uid)) != 0){
350 errf("Failed to release permissions, refusing to keep setuid. (%m)");
351 die();
352 }
353
354 diskStats();
355 osStats();
356 loadStats();
357 userStats();
358 systemStats();
359 processStats();
360 exit(0);
361 }