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 (22 years, 5 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

# User Rev Content
1 tdb 1.9 /*
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 pajs 1.1 #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 pajs 1.2 #include <sys/utsname.h>
28     #include <sys/types.h>
29     #include <utmp.h>
30 pajs 1.4 #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 pajs 1.7 #include <time.h>
37     #include <sys/time.h>
38 pajs 1.4
39     uid_t uid;
40     uid_t euid;
41     gid_t gid;
42     gid_t egid;
43 pajs 1.1
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 pajs 1.2 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 pajs 1.3 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 pajs 1.4 }
130    
131     void systemStats(){
132    
133     long cp_time[CPUSTATES];
134     long total, user, idle, kernel, nice;
135     long totalmem, freemem, swaptotal, swapused;
136 pajs 1.8 float stat;
137 pajs 1.4
138 pajs 1.7 static char *uptimename = "kern.boottime";
139 pajs 1.4 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 pajs 1.7 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 pajs 1.4
164 pajs 1.7 printf("packet.os.uptime %ld\n",(current-(uptime.tv_sec)));
165    
166    
167 pajs 1.4 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 pajs 1.3
194 pajs 1.8 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 pajs 1.4
199     total=user+nice+kernel+idle;
200 pajs 1.8 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 pajs 1.4
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 pajs 1.3
223 pajs 1.4 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 pajs 1.8 /* Lose our setgid'ness */
263 pajs 1.5
264     if ((setegid(gid)) != 0){
265     errf("Failed to release permissions, refusing to keep setgid. (%m)");
266     die();
267     }
268    
269 pajs 1.4
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 pajs 1.3 }
286    
287 pajs 1.6 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 pajs 1.1 int main(){
337 pajs 1.4 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 pajs 1.5 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 pajs 1.4
353 pajs 1.1 diskStats();
354 pajs 1.2 osStats();
355     loadStats();
356 pajs 1.3 userStats();
357 pajs 1.4 systemStats();
358 pajs 1.6 processStats();
359 pajs 1.1 exit(0);
360     }