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

# 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    
18     uid_t uid;
19     uid_t euid;
20     gid_t gid;
21     gid_t egid;
22 pajs 1.1
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 pajs 1.2 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 pajs 1.3 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 pajs 1.4 }
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 pajs 1.3
153 pajs 1.4 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 pajs 1.3
180 pajs 1.4 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 pajs 1.3 }
238    
239 pajs 1.1 int main(){
240 pajs 1.4 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 pajs 1.1 diskStats();
250 pajs 1.2 osStats();
251     loadStats();
252 pajs 1.3 userStats();
253 pajs 1.4 systemStats();
254 pajs 1.1 exit(0);
255     }