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

# User Rev Content
1 tdb 1.9 /*
2     * i-scream central monitoring system
3 tdb 1.10 * http://www.i-scream.org.uk
4 tdb 1.9 * 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 pajs 1.1 #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 pajs 1.2 #include <sys/utsname.h>
29     #include <sys/types.h>
30     #include <utmp.h>
31 pajs 1.4 #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 pajs 1.7 #include <time.h>
38     #include <sys/time.h>
39 pajs 1.4
40     uid_t uid;
41     uid_t euid;
42     gid_t gid;
43     gid_t egid;
44 pajs 1.1
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 pajs 1.2 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 pajs 1.3 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 pajs 1.4 }
131    
132     void systemStats(){
133    
134     long cp_time[CPUSTATES];
135     long total, user, idle, kernel, nice;
136     long totalmem, freemem, swaptotal, swapused;
137 pajs 1.8 float stat;
138 pajs 1.4
139 pajs 1.7 static char *uptimename = "kern.boottime";
140 pajs 1.4 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 pajs 1.7 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 pajs 1.4
165 pajs 1.7 printf("packet.os.uptime %ld\n",(current-(uptime.tv_sec)));
166    
167    
168 pajs 1.4 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 pajs 1.3
195 pajs 1.8 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 pajs 1.4
200     total=user+nice+kernel+idle;
201 pajs 1.8 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 pajs 1.4
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 pajs 1.3
224 pajs 1.4 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 pajs 1.8 /* Lose our setgid'ness */
264 pajs 1.5
265     if ((setegid(gid)) != 0){
266     errf("Failed to release permissions, refusing to keep setgid. (%m)");
267     die();
268     }
269    
270 pajs 1.4
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 pajs 1.3 }
287    
288 pajs 1.6 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 pajs 1.1 int main(){
338 pajs 1.4 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 pajs 1.5 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 pajs 1.4
354 pajs 1.1 diskStats();
355 pajs 1.2 osStats();
356     loadStats();
357 pajs 1.3 userStats();
358 pajs 1.4 systemStats();
359 pajs 1.6 processStats();
360 pajs 1.1 exit(0);
361     }