FreeBSD.c (4957B)
1 #include <u.h> 2 #include <kvm.h> 3 #include <nlist.h> 4 #include <sys/types.h> 5 #include <sys/protosw.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 <net/if_var.h> 12 #include <net/if_dl.h> 13 #include <net/if_types.h> 14 #if __FreeBSD_version < 600000 15 #include <machine/apm_bios.h> 16 #endif 17 #include <sys/ioctl.h> 18 #include <limits.h> 19 #include <libc.h> 20 #include <bio.h> 21 #include <ifaddrs.h> 22 #include "dat.h" 23 24 void xapm(int); 25 void xloadavg(int); 26 void xcpu(int); 27 void xswap(int); 28 void xsysctl(int); 29 void xnet(int); 30 void xkvm(int); 31 32 void (*statfn[])(int) = 33 { 34 xkvm, 35 xapm, 36 xloadavg, 37 xswap, 38 xcpu, 39 xsysctl, 40 xnet, 41 0 42 }; 43 44 static kvm_t *kvm; 45 46 static struct nlist nl[] = { 47 { "_cp_time" }, 48 { "" } 49 }; 50 51 void 52 kvminit(void) 53 { 54 char buf[_POSIX2_LINE_MAX]; 55 56 if(kvm) 57 return; 58 kvm = kvm_openfiles(nil, nil, nil, OREAD, buf); 59 if(kvm == nil) 60 return; 61 if(kvm_nlist(kvm, nl) < 0 || nl[0].n_type == 0){ 62 kvm = nil; 63 return; 64 } 65 } 66 67 void 68 xkvm(int first) 69 { 70 if(first) 71 kvminit(); 72 } 73 74 int 75 kread(ulong addr, char *buf, int size) 76 { 77 if(kvm_read(kvm, addr, buf, size) != size){ 78 memset(buf, 0, size); 79 return -1; 80 } 81 return size; 82 } 83 84 void 85 xnet(int first) 86 { 87 struct ifaddrs *ifap, *ifa; 88 ulong out, in, outb, inb, err; 89 90 if(first) 91 return; 92 93 if (getifaddrs(&ifap) != 0) 94 return; 95 96 out = in = outb = inb = err = 0; 97 #define IFA_STAT(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s) 98 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 99 if (ifa->ifa_addr->sa_family != AF_LINK) 100 continue; 101 out += IFA_STAT(opackets); 102 in += IFA_STAT(ipackets); 103 outb += IFA_STAT(obytes); 104 inb += IFA_STAT(ibytes); 105 err += IFA_STAT(oerrors) + IFA_STAT(ierrors); 106 } 107 freeifaddrs(ifap); 108 109 Bprint(&bout, "etherin %lud 1000\n", in); 110 Bprint(&bout, "etherout %lud 1000\n", out); 111 Bprint(&bout, "etherinb %lud 1000000\n", inb); 112 Bprint(&bout, "etheroutb %lud 1000000\n", outb); 113 Bprint(&bout, "ethererr %lud 1000\n", err); 114 Bprint(&bout, "ether %lud 1000\n", in+out); 115 Bprint(&bout, "etherb %lud 1000000\n", inb+outb); 116 } 117 118 #if __FreeBSD_version >= 500000 119 int 120 xacpi(int first) 121 { 122 int rv; 123 int val; 124 size_t len; 125 126 len = sizeof(val); 127 rv = sysctlbyname("hw.acpi.battery.life", &val, &len, nil, 0); 128 if(rv != 0) 129 return -1; 130 Bprint(&bout, "battery =%d 100\n", val); 131 return 0; 132 } 133 #else 134 int 135 xacpi(int first) 136 { 137 return -1; 138 } 139 #endif 140 141 #if __FreeBSD_version < 600000 142 void 143 xapm(int first) 144 { 145 static int fd; 146 struct apm_info ai; 147 148 if(first){ 149 xacpi(first); 150 fd = open("/dev/apm", OREAD); 151 return; 152 } 153 154 if(xacpi(0) >= 0) 155 return; 156 157 if(ioctl(fd, APMIO_GETINFO, &ai) < 0) 158 return; 159 160 if(ai.ai_batt_life <= 100) 161 Bprint(&bout, "battery =%d 100\n", ai.ai_batt_life); 162 } 163 #else 164 void 165 xapm(int first) 166 { 167 xacpi(first); 168 } 169 #endif 170 171 int 172 rsys(char *name, char *buf, int len) 173 { 174 size_t l; 175 176 l = len; 177 if(sysctlbyname(name, buf, &l, nil, 0) < 0) 178 return -1; 179 buf[l] = 0; 180 return l; 181 } 182 183 vlong 184 isys(char *name) 185 { 186 ulong u; 187 size_t l; 188 189 l = sizeof u; 190 if(sysctlbyname(name, &u, &l, nil, 0) < 0) 191 return -1; 192 return u; 193 } 194 195 void 196 xsysctl(int first) 197 { 198 static int pgsize; 199 200 if(first){ 201 pgsize = isys("vm.stats.vm.v_page_size"); 202 if(pgsize == 0) 203 pgsize = 4096; 204 } 205 206 Bprint(&bout, "mem =%lld %lld\n", 207 isys("vm.stats.vm.v_active_count")*pgsize, 208 isys("vm.stats.vm.v_page_count")*pgsize); 209 Bprint(&bout, "context %lld 1000\n", isys("vm.stats.sys.v_swtch")); 210 Bprint(&bout, "syscall %lld 1000\n", isys("vm.stats.sys.v_syscall")); 211 Bprint(&bout, "intr %lld 1000\n", isys("vm.stats.sys.v_intr")+isys("vm.stats.sys.v_trap")); 212 Bprint(&bout, "fault %lld 1000\n", isys("vm.stats.vm.v_vm_faults")); 213 Bprint(&bout, "fork %lld 1000\n", isys("vm.stats.vm.v_forks") 214 +isys("vm.stats.vm.v_rforks") 215 +isys("vm.stats.vm.v_vforks")); 216 } 217 218 void 219 xcpu(int first) 220 { 221 static int stathz; 222 union { 223 ulong x[20]; 224 struct clockinfo ci; 225 } u; 226 int n; 227 228 if(first){ 229 if(rsys("kern.clockrate", (char*)u.x, sizeof u.x) < sizeof u.ci) 230 stathz = 128; 231 else 232 stathz = u.ci.stathz; 233 return; 234 } 235 236 if((n=rsys("kern.cp_time", (char*)u.x, sizeof u.x)) < 5*sizeof(ulong)) 237 return; 238 239 Bprint(&bout, "user %lud %d\n", u.x[CP_USER]+u.x[CP_NICE], stathz); 240 Bprint(&bout, "sys %lud %d\n", u.x[CP_SYS], stathz); 241 Bprint(&bout, "cpu %lud %d\n", u.x[CP_USER]+u.x[CP_NICE]+u.x[CP_SYS], stathz); 242 Bprint(&bout, "idle %lud %d\n", u.x[CP_IDLE], stathz); 243 } 244 245 void 246 xloadavg(int first) 247 { 248 double l[3]; 249 250 if(first) 251 return; 252 253 if(getloadavg(l, 3) < 0) 254 return; 255 Bprint(&bout, "load =%d 1000\n", (int)(l[0]*1000.0)); 256 } 257 258 void 259 xswap(int first) 260 { 261 static struct kvm_swap s; 262 static ulong pgin, pgout; 263 int i, o; 264 static int pgsize; 265 266 if(first){ 267 pgsize = getpagesize(); 268 if(pgsize == 0) 269 pgsize = 4096; 270 return; 271 } 272 273 if(kvm == nil) 274 return; 275 276 i = isys("vm.stats.vm.v_swappgsin"); 277 o = isys("vm.stats.vm.v_swappgsout"); 278 if(i != pgin || o != pgout){ 279 pgin = i; 280 pgout = o; 281 kvm_getswapinfo(kvm, &s, 1, 0); 282 } 283 284 285 Bprint(&bout, "swap =%lld %lld\n", s.ksw_used*(vlong)pgsize, s.ksw_total*(vlong)pgsize); 286 }