Blob


1 #include <u.h>
2 #include <kvm.h>
3 #include <nlist.h>
4 #include <sys/types.h>
5 #include <sys/param.h>
6 #include <sys/socket.h>
7 #include <sys/sysctl.h>
8 #include <sys/time.h>
9 #include <sys/dkstat.h>
10 #include <net/if.h>
11 #include <machine/apmvar.h>
12 #include <sys/ioctl.h>
13 #include <uvm/uvm_param.h>
14 #include <uvm/uvm_extern.h>
15 #include <limits.h>
16 #include <libc.h>
17 #include <bio.h>
18 #include "dat.h"
20 void xapm(int);
21 void xloadavg(int);
22 void xcpu(int);
23 void xswap(int);
24 void xsysctl(int);
25 void xnet(int);
26 void xkvm(int);
28 void (*statfn[])(int) =
29 {
30 xkvm,
31 xapm,
32 xloadavg,
33 xcpu,
34 xsysctl,
35 xnet,
36 0
37 };
39 static kvm_t *kvm;
41 static struct nlist nl[] = {
42 { "_ifnet" },
43 { "_cp_time" },
44 { "" }
45 };
47 void
48 xloadavg(int first)
49 {
50 double l[3];
52 if(first)
53 return;
55 if(getloadavg(l, 3) < 0)
56 return;
57 Bprint(&bout, "load =%d 1000\n", (int)(l[0]*1000.0));
58 }
60 void
61 xapm(int first)
62 {
63 static int fd;
64 struct apm_power_info ai;
66 if(first){
67 fd = open("/dev/apm", OREAD);
68 return;
69 }
71 if(ioctl(fd, APM_IOC_GETPOWER, &ai) < 0)
72 return;
74 if(ai.battery_life <= 100)
75 Bprint(&bout, "battery =%d 100\n", ai.battery_life);
76 }
79 void
80 kvminit(void)
81 {
82 char buf[_POSIX2_LINE_MAX];
84 if(kvm)
85 return;
86 kvm = kvm_openfiles(nil, nil, nil, O_RDONLY, buf);
87 if(kvm == nil) {
88 fprint(2, "kvm open error\n%s", buf);
89 return;
90 }
91 if(kvm_nlist(kvm, nl) < 0 || nl[0].n_type == 0){
92 kvm = nil;
93 return;
94 }
95 }
97 void
98 xkvm(int first)
99 {
100 if(first)
101 kvminit();
104 int
105 kread(ulong addr, char *buf, int size)
107 if(kvm_read(kvm, addr, buf, size) != size){
108 memset(buf, 0, size);
109 return -1;
111 return size;
114 void
115 xnet(int first)
117 ulong out, in, outb, inb, err;
118 static ulong ifnetaddr;
119 ulong addr;
120 struct ifnet ifnet;
121 struct ifnet_head ifnethead;
122 char name[16];
124 if(first)
125 return;
127 if(ifnetaddr == 0){
128 ifnetaddr = nl[0].n_value;
129 if(ifnetaddr == 0)
130 return;
133 if(kread(ifnetaddr, (char*)&ifnethead, sizeof ifnethead) < 0)
134 return;
136 out = in = outb = inb = err = 0;
137 addr = (ulong)TAILQ_FIRST(&ifnethead);
138 while(addr){
139 if(kread(addr, (char*)&ifnet, sizeof ifnet) < 0
140 || kread((ulong)ifnet.if_xname, name, 16) < 0)
141 return;
142 name[15] = 0;
143 addr = (ulong)TAILQ_NEXT(&ifnet, if_list);
144 out += ifnet.if_opackets;
145 in += ifnet.if_ipackets;
146 outb += ifnet.if_obytes;
147 inb += ifnet.if_ibytes;
148 err += ifnet.if_oerrors+ifnet.if_ierrors;
150 Bprint(&bout, "etherin %lud 1000\n", in);
151 Bprint(&bout, "etherout %lud 1000\n", out);
152 Bprint(&bout, "etherinb %lud 1000000\n", inb);
153 Bprint(&bout, "etheroutb %lud 1000000\n", outb);
154 Bprint(&bout, "ethererr %lud 1000\n", err);
155 Bprint(&bout, "ether %lud 1000\n", in+out);
156 Bprint(&bout, "etherb %lud 1000000\n", inb+outb);
159 void
160 xcpu(int first)
162 static int stathz;
163 ulong x[20];
164 struct clockinfo *ci;
165 int mib[2];
166 size_t l;
168 if(first){
169 mib[0] = CTL_KERN;
170 mib[1] = KERN_CLOCKRATE;
171 l = sizeof(x);
172 sysctl(mib, 2, (char *)&x, &l, nil, 0);
173 x[l] = 0;
174 if (l < sizeof(ci))
175 stathz = 128;
176 else{
177 ci = (struct clockinfo*)x;
178 stathz = ci->stathz;
180 return;
183 mib[0] = CTL_KERN;
184 mib[1] = KERN_CPTIME;
185 l = sizeof(x);
186 sysctl(mib, 2, (char *)&x, &l, nil, 0);
187 if (l < 5*sizeof(ulong))
188 return;
189 x[l] = 0;
191 Bprint(&bout, "user %lud %d\n", x[CP_USER]+x[CP_NICE], stathz);
192 Bprint(&bout, "sys %lud %d\n", x[CP_SYS], stathz);
193 Bprint(&bout, "cpu %lud %d\n", x[CP_USER]+x[CP_NICE]+x[CP_SYS], stathz);
194 Bprint(&bout, "idle %lud %d\n", x[CP_IDLE], stathz);
197 void
198 xsysctl(int first)
200 struct uvmexp vm;
201 static int pgsize;
202 int mib[2];
203 size_t l;
205 l = sizeof(vm);
206 mib[0] = CTL_VM;
207 mib[1] = VM_UVMEXP;
208 sysctl(mib, 2, &vm, &l, nil, 0);
209 if (l < sizeof(vm))
210 return;
212 if (first)
213 pgsize = vm.pagesize;
215 Bprint(&bout, "mem =%lud %lud\n", vm.active*pgsize, vm.npages*pgsize);
216 Bprint(&bout, "context %lud 1000\n", vm.swtch);
217 Bprint(&bout, "syscall %lud 1000\n", vm.syscalls);
218 Bprint(&bout, "intr %lud 1000\n", vm.intrs+vm.traps);
219 Bprint(&bout, "fault %lud 1000\n", vm.faults);
221 Bprint(&bout, "fork %ud 1000\n", vm.forks);
222 Bprint(&bout, "swap =%lud %lud\n", vm.swpginuse*pgsize, vm.swpages*pgsize);