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.4
Committed: Thu Mar 28 17:42:05 2002 UTC (23 years, 8 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.3: +148 -0 lines
Log Message:
Now gets CPU stats, mem and swap stats. The problem with swap stats is that it needs to be
either suid root, or setgid kmem. I've assumed the latter since thats safer, and so it needs to be
setgid kmem to work now. The program however runs as a mortal except at the very moment it needs the
permissions where it gets them, and then releases them one system call later.

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
18 uid_t uid;
19 uid_t euid;
20 gid_t gid;
21 gid_t egid;
22
23 void die(){
24 exit(1);
25 }
26
27 void diskStats(){
28 struct statfs *mp;
29 int nummnt;
30 int counter=0;
31 char *mntpnt;
32 char *devicename;
33
34 nummnt=getmntinfo(&mp , MNT_LOCAL);
35 if (nummnt<=0){
36 errf("Failed to get disk stats (%m)");
37 die();
38 }
39
40 mntpnt=malloc(MNAMELEN);
41 devicename=malloc(MNAMELEN);
42
43 for(;counter<nummnt;counter++){
44 strncpy(mntpnt, mp->f_mntonname ,MNAMELEN);
45 strncpy(devicename, mp->f_mntfromname ,MNAMELEN);
46 printf("packet.disk.p%d.attributes.mount %s\n", counter, mntpnt);
47 printf("packet.disk.p%d.attributes.name %s\n", counter, devicename);
48 printf("packet.disk.p%d.attributes.kbytes %lu\n",counter, ((mp->f_bsize/1024) * mp->f_blocks));
49 printf("packet.disk.p%d.attributes.used %lu\n",counter, (((mp->f_bsize/1024) * mp->f_blocks) -((mp->f_bsize/1024) * mp->f_bfree)));
50 printf("packet.disk.p%d.attributes.avail %lu\n",counter, (mp->f_bsize/1024) * mp->f_bavail);
51 printf("packet.disk.p%d.attributes.totalinodes %lu\n", counter, mp->f_files);
52 printf("packet.disk.p%d.attributes.freeinodes %lu\n",counter, mp->f_ffree);
53
54 mp++;
55 }
56
57
58 }
59
60 void osStats(){
61 struct utsname os;
62
63 if((uname(&os)) != 0){
64 errf("Failed to get os stats (%m)");
65 die();
66 }
67
68 printf("packet.os.name %s\n", os.sysname);
69 printf("packet.os.release %s\n" , os.release);
70 printf("packet.os.version %s\n", os.version);
71 printf("packet.os.sysname %s\n" , os.nodename);
72 printf("packet.os.platform %s\n", os.machine);
73
74 }
75 void loadStats(){
76 double loadav[3];
77
78 if((getloadavg(loadav,3)) == -1){
79 errf("Failed to get load averages (%m)");
80 die();
81 }
82
83 printf("packet.load.load1 %.2f\n",loadav[0]);
84 printf("packet.load.load5 %.2f\n",loadav[1]);
85 printf("packet.load.load15 %.2f\n",loadav[2]);
86 }
87
88 void userStats(){
89 struct utmp users;
90 FILE *f;
91 int numusers=0;
92
93 if ((f=fopen(_PATH_UTMP, "r")) == NULL){
94 errf("Failed to get user stats(%m)");
95 die();
96 }
97
98 printf("packet.users.list");
99
100 while((fread(&users, sizeof(users),1,f)) != 0){
101 if (users.ut_name[0] == '\0') continue;
102 printf(" %s",users.ut_name);
103 numusers++;
104 }
105
106 printf("\npacket.users.count %d\n",numusers);
107
108 }
109
110 void systemStats(){
111
112 long cp_time[CPUSTATES];
113 long total, user, idle, kernel, nice;
114 long totalmem, freemem, swaptotal, swapused;
115
116 static char *cpname = "kern.cp_time";
117 static char *tmemname = "hw.physmem";
118 static char *fmemname = "vm.stats.vm.v_free_count";
119 int pagesize=-1;
120 size_t size;
121
122 kvm_t *kvmd = NULL;
123 struct kvm_swap swapinfo;
124 char errbuf[_POSIX2_LINE_MAX];
125
126 if (sysctlbyname(cpname, NULL, &size, NULL, NULL) < 0){
127 errf("sysctlbyname (%m)");
128 die();
129 }
130
131 if (size != sizeof cp_time){
132 errf("bailing out, trying to write into something to small");
133 die();
134 }
135
136 if (sysctlbyname(cpname, &cp_time, &size, NULL, NULL) < 0){
137 errf("Failed to get cpu stats (%m)");
138 die();
139 }
140
141 user=cp_time[CP_USER];
142 nice=cp_time[CP_NICE];
143 kernel=cp_time[CP_SYS];
144 idle=cp_time[CP_IDLE];
145
146 sleep(1);
147
148 if (sysctlbyname(cpname, &cp_time, &size, NULL, NULL) < 0){
149 errf("Failed to get cpu stats (%m)");
150 die();
151 }
152
153 user-=cp_time[CP_USER];
154 nice-=cp_time[CP_NICE];
155 kernel-=cp_time[CP_SYS];
156 idle-=cp_time[CP_IDLE];
157
158 total=user+nice+kernel+idle;
159
160 printf("packet.cpu.user %ld\n",((user+nice)*100)/total);
161 printf("packet.cpu.kernel %ld\n",(kernel*100)/total);
162 printf("packet.cpu.idle %ld\n",(idle*100)/total);
163
164 /* Cos i-scream's expects this to be sent :/ */
165 printf("packet.cpu.iowait 0\n");
166 printf("packet.cpu.swap 0\n");
167
168 /* MEMORY STATS */
169 pagesize=getpagesize();
170 if (pagesize==-1){
171 errf("Failed to get pagesize (%m)");
172 die();
173 }
174
175 if (sysctlbyname(tmemname, NULL, &size, NULL, NULL) < 0){
176 errf("sysctlbyname (%m)");
177 die();
178 }
179
180 if (sysctlbyname(tmemname, &totalmem, &size, NULL, NULL) < 0){
181 errf("Failed to get memory stats (%m)");
182 die();
183 }
184
185 if (sysctlbyname(fmemname, NULL, &size, NULL, NULL) < 0){
186 errf("sysctlbyname (%m)");
187 die();
188 }
189
190 if (sysctlbyname(fmemname, &freemem, &size, NULL, NULL) < 0){
191 errf("Failed to get memory stats (%m)");
192 die();
193 }
194
195 totalmem/=(1024*1024);
196 freemem=(freemem*pagesize)/(1024*1024);
197
198 printf("packet.memory.total %ld\n", totalmem);
199 printf("packet.memory.free %ld\n", freemem);
200 printf("packet.memory.used %ld\n", (totalmem-freemem));
201
202 /* Swap stats */
203
204 /* Get sufficent privilages to do this */
205 if (gid!=egid){
206 /* Means we are setgid something, hopefully kmem :) */
207 if ((setegid(egid)) != 0){
208 errf("Failed to gain sufficent privilages (%m)");
209 die();
210 }
211 }
212
213 kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
214 if (kvmd == NULL){
215 errf("Failed to open kvm info to get swap stats (%m)");
216 die();
217 }
218
219 /* Lose are setgid'ness */
220 setegid(gid);
221
222 /* ok, just for proof of concept atm, ideally this will need to handle more
223 than one swap device */
224
225 if ((kvm_getswapinfo(kvmd, &swapinfo, 1,0)) == -1){
226 errf("Failed to get swap info (%m)");
227 die();
228 }
229
230 swaptotal=((((long)swapinfo.ksw_total)*pagesize)/1024)/1024;
231 swapused=((((long)swapinfo.ksw_used)*pagesize)/1024)/1024;
232
233 printf("packet.swap.total %ld\n" , swaptotal);
234 printf("packet.swap.used %ld\n", swapused);
235 printf("packet.swap.free %lu\n", (swaptotal-swapused));
236
237 }
238
239 int main(){
240 uid=getuid();
241 euid=geteuid();
242 gid=getgid();
243 egid=getegid();
244
245 /* We dont want to run with more permissions than we need, until we need em */
246 seteuid(uid);
247 setegid(gid);
248
249 diskStats();
250 osStats();
251 loadStats();
252 userStats();
253 systemStats();
254 exit(0);
255 }