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.9
Committed: Sat May 18 18:15:56 2002 UTC (23 years, 7 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.8: +19 -0 lines
Log Message:
i-scream is now licensed under the GPL. I've added the GPL headers to every
source file, and put a full copy of the license in the appropriate places.
I think I've covered everything. This is going to be a mad commit ;)

File Contents

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