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 (23 years, 8 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

# Content
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 #include <sys/utsname.h>
9 #include <sys/types.h>
10 #include <utmp.h>
11 #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 #include <time.h>
18 #include <sys/time.h>
19
20 uid_t uid;
21 uid_t euid;
22 gid_t gid;
23 gid_t egid;
24
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 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 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 }
111
112 void systemStats(){
113
114 long cp_time[CPUSTATES];
115 long total, user, idle, kernel, nice;
116 long totalmem, freemem, swaptotal, swapused;
117 float stat;
118
119 static char *uptimename = "kern.boottime";
120 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 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
145 printf("packet.os.uptime %ld\n",(current-(uptime.tv_sec)));
146
147
148 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
175 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
180 total=user+nice+kernel+idle;
181 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
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
204 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 /* Lose our setgid'ness */
244
245 if ((setegid(gid)) != 0){
246 errf("Failed to release permissions, refusing to keep setgid. (%m)");
247 die();
248 }
249
250
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 }
267
268 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 int main(){
318 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 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
334 diskStats();
335 osStats();
336 loadStats();
337 userStats();
338 systemStats();
339 processStats();
340 exit(0);
341 }