URI:
       tFreeBSD.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tFreeBSD.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 }