plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }