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.8
Committed: Fri Apr 5 12:02:09 2002 UTC (22 years, 6 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.7: +12 -9 lines
Log Message:
Fixed CPU stats to be a tad more accurate (and erm, not negative, not that anyone notice that :D)

File Contents

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