From f0f4401f0cfc654646bdf21849627ebcbd5d82b5 Mon Sep 17 00:00:00 2001 From: rsc Date: Fri, 23 Apr 2004 05:12:11 +0000 Subject: [PATCH] stats helper --- src/cmd/auxstats/Darwin.c | 250 +++++++++++++++++++++++++++++++++++ src/cmd/auxstats/FreeBSD.c | 262 +++++++++++++++++++++++++++++++++++++ src/cmd/auxstats/Linux.c | 177 +++++++++++++++++++++++++ src/cmd/auxstats/NetBSD.c | 10 ++ src/cmd/auxstats/OpenBSD.c | 10 ++ src/cmd/auxstats/SunOS.c | 10 ++ src/cmd/auxstats/core | Bin 0 -> 258048 bytes src/cmd/auxstats/dat.h | 9 ++ src/cmd/auxstats/main.c | 123 +++++++++++++++++ src/cmd/auxstats/mkfile | 15 +++ 10 files changed, 866 insertions(+) create mode 100644 src/cmd/auxstats/Darwin.c create mode 100644 src/cmd/auxstats/FreeBSD.c create mode 100644 src/cmd/auxstats/Linux.c create mode 100644 src/cmd/auxstats/NetBSD.c create mode 100644 src/cmd/auxstats/OpenBSD.c create mode 100644 src/cmd/auxstats/SunOS.c create mode 100644 src/cmd/auxstats/core create mode 100644 src/cmd/auxstats/dat.h create mode 100644 src/cmd/auxstats/main.c create mode 100644 src/cmd/auxstats/mkfile diff --git a/src/cmd/auxstats/Darwin.c b/src/cmd/auxstats/Darwin.c new file mode 100644 index 00000000..da6c2a22 --- /dev/null +++ b/src/cmd/auxstats/Darwin.c @@ -0,0 +1,250 @@ +/* + * No idea whether this will work. It does compile. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dat.h" + +void xloadavg(int); +void xcpu(int); +void xswap(int); +void xsysctl(int); +void xnet(int); +void xkvm(int); + +void (*statfn[])(int) = +{ + xkvm, + xloadavg, + xswap, + xcpu, + xsysctl, + xnet, + 0 +}; + +static kvm_t *kvm; + +static struct nlist nl[] = { + { "_ifnet" }, + { "_cp_time" }, + { "" }, +}; + +void +kvminit(void) +{ + char buf[_POSIX2_LINE_MAX]; + + if(kvm) + return; + kvm = kvm_openfiles(nil, nil, nil, OREAD, buf); + if(kvm == nil) + return; + if(kvm_nlist(kvm, nl) < 0 || nl[0].n_type == 0){ + kvm = nil; + return; + } +} + +void +xkvm(int first) +{ + if(first) + kvminit(); +} + +int +kread(ulong addr, char *buf, int size) +{ + if(kvm_read(kvm, addr, buf, size) != size){ + memset(buf, 0, size); + return -1; + } + return size; +} + +void +xnet(int first) +{ + ulong out, in, outb, inb, err; + static ulong ifnetaddr; + ulong addr; + struct ifnet ifnet; + struct ifnethead ifnethead; + char name[16]; + + if(first) + return; + + if(ifnetaddr == 0){ + ifnetaddr = nl[0].n_value; + if(ifnetaddr == 0) + return; + } + + if(kread(ifnetaddr, (char*)&ifnethead, sizeof ifnethead) < 0) + return; + + out = in = outb = inb = err = 0; + addr = (ulong)TAILQ_FIRST(&ifnethead); + while(addr){ + if(kread(addr, (char*)&ifnet, sizeof ifnet) < 0 + || kread((ulong)ifnet.if_name, name, 16) < 0) + return; + name[15] = 0; + addr = (ulong)TAILQ_NEXT(&ifnet, if_link); + out += ifnet.if_opackets; + in += ifnet.if_ipackets; + outb += ifnet.if_obytes; + inb += ifnet.if_ibytes; + err += ifnet.if_oerrors+ifnet.if_ierrors; + } + Bprint(&bout, "etherin %lud\n", in); + Bprint(&bout, "etherout %lud\n", out); + Bprint(&bout, "etherinb %lud\n", inb); + Bprint(&bout, "etheroutb %lud\n", outb); + Bprint(&bout, "ethererr %lud\n", err); + Bprint(&bout, "ether %lud\n", in+out); + Bprint(&bout, "etherb %lud\n", inb+outb); +} + + +int +rsys(char *name, char *buf, int len) +{ + size_t l; + + l = len; + if(sysctlbyname(name, buf, &l, nil, 0) < 0) + return -1; + buf[l] = 0; + return l; +} + +vlong +isys(char *name) +{ + ulong u; + size_t l; + + l = sizeof u; + if(sysctlbyname(name, &u, &l, nil, 0) < 0) + return 0; + return u; +} + +void +xsysctl(int first) +{ + static int pgsize; + vlong t; + + if(first){ + pgsize = isys("vm.stats.vm.v_page_size"); + if(pgsize == 0) + pgsize = 4096; + } + if((t = isys("vm.stats.vm.v_page_count")) != 0) + Bprint(&bout, "mem %lld %lld\n", + isys("vm.stats.vm.v_active_count")*pgsize, + t*pgsize); + Bprint(&bout, "context %lld 1000\n", isys("vm.stats.sys.v_swtch")); + Bprint(&bout, "syscall %lld 1000\n", isys("vm.stats.sys.v_syscall")); + Bprint(&bout, "intr %lld 1000\n", isys("vm.stats.sys.v_intr")+isys("vm.stats.sys.v_trap")); + Bprint(&bout, "fault %lld 1000\n", isys("vm.stats.vm.v_vm_faults")); + Bprint(&bout, "fork %lld 1000\n", isys("vm.stats.vm.v_forks") + +isys("vm.stats.vm.v_rforks") + +isys("vm.stats.vm.v_vforks")); +} + +void +xcpu(int first) +{ +#if 0 + static int stathz; + ulong x[20]; + struct clockinfo *ci; + int n; + + if(first){ + if(rsys("kern.clockrate", (char*)&x, sizeof x) < sizeof ci) + stathz = 128; + else{ + ci = (struct clockinfo*)x; + stathz = ci->stathz; + } + return; + } + + if((n=rsys("kern.cp_time", (char*)x, sizeof x)) < 5*sizeof(ulong)) + return; + + Bprint(&bout, "user %lud %d\n", x[CP_USER]+x[CP_NICE], stathz); + Bprint(&bout, "sys %lud %d\n", x[CP_SYS], stathz); + Bprint(&bout, "cpu %lud %d\n", x[CP_USER]+x[CP_NICE]+x[CP_SYS], stathz); + Bprint(&bout, "idle %lud %d\n", x[CP_IDLE], stathz); +#endif +} + +void +xloadavg(int first) +{ + double l[3]; + + if(first) + return; + + if(getloadavg(l, 3) < 0) + return; + Bprint(&bout, "load %d 1000\n", (int)(l[0]*1000.0)); +} + +void +xswap(int first) +{ +#if 0 + static struct kvm_swap s; + static ulong pgin, pgout; + int i, o; + static int pgsize; + + if(first){ + pgsize = getpagesize(); + if(pgsize == 0) + pgsize = 4096; + return; + } + + if(kvm == nil) + return; + + i = isys("vm.stats.vm.v_swappgsin"); + o = isys("vm.stats.vm.v_swappgsout"); + if(i != pgin || o != pgout){ + pgin = i; + pgout = o; + kvm_getswapinfo(kvm, &s, 1, 0); + } + + + Bprint(&bout, "swap %lld %lld\n", s.ksw_used*(vlong)pgsize, s.ksw_total*(vlong)pgsize); +#endif +} + diff --git a/src/cmd/auxstats/FreeBSD.c b/src/cmd/auxstats/FreeBSD.c new file mode 100644 index 00000000..b0379f88 --- /dev/null +++ b/src/cmd/auxstats/FreeBSD.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dat.h" + +void xapm(int); +void xloadavg(int); +void xcpu(int); +void xswap(int); +void xsysctl(int); +void xnet(int); +void xkvm(int); + +void (*statfn[])(int) = +{ + xkvm, + xapm, + xloadavg, + xswap, + xcpu, + xsysctl, + xnet, + 0 +}; + +static kvm_t *kvm; + +static struct nlist nl[] = { + { "_ifnet" }, + { "_cp_time" }, + { "" }, +}; + +void +kvminit(void) +{ + char buf[_POSIX2_LINE_MAX]; + + if(kvm) + return; + kvm = kvm_openfiles(nil, nil, nil, OREAD, buf); + if(kvm == nil) + return; + if(kvm_nlist(kvm, nl) < 0 || nl[0].n_type == 0){ + kvm = nil; + return; + } +} + +void +xkvm(int first) +{ + if(first) + kvminit(); +} + +int +kread(ulong addr, char *buf, int size) +{ + if(kvm_read(kvm, addr, buf, size) != size){ + memset(buf, 0, size); + return -1; + } + return size; +} + +void +xnet(int first) +{ + ulong out, in, outb, inb, err; + static ulong ifnetaddr; + ulong addr; + struct ifnet ifnet; + struct ifnethead ifnethead; + char name[16]; + int n; + + if(first) + return; + + if(ifnetaddr == 0){ + ifnetaddr = nl[0].n_value; + if(ifnetaddr == 0) + return; + } + + if(kread(ifnetaddr, (char*)&ifnethead, sizeof ifnethead) < 0) + return; + + out = in = outb = inb = err = 0; + addr = (ulong)TAILQ_FIRST(&ifnethead); + while(addr){ + if(kread(addr, (char*)&ifnet, sizeof ifnet) < 0 + || kread((ulong)ifnet.if_name, name, 16) < 0) + return; + name[15] = 0; + addr = (ulong)TAILQ_NEXT(&ifnet, if_link); + out += ifnet.if_opackets; + in += ifnet.if_ipackets; + outb += ifnet.if_obytes; + inb += ifnet.if_ibytes; + err += ifnet.if_oerrors+ifnet.if_ierrors; + } + Bprint(&bout, "etherin %lud 1000\n", in); + Bprint(&bout, "etherout %lud 1000\n", out); + Bprint(&bout, "etherinb %lud 1000000\n", inb); + Bprint(&bout, "etheroutb %lud 1000000\n", outb); + Bprint(&bout, "ethererr %lud 1000\n", err); + Bprint(&bout, "ether %lud 1000\n", in+out); + Bprint(&bout, "etherb %lud 1000000\n", inb+outb); +} + +void +xapm(int first) +{ + static int fd; + struct apm_info ai; + + if(first){ + fd = open("/dev/apm", OREAD); + return; + } + + if(ioctl(fd, APMIO_GETINFO, &ai) < 0) + return; + + if(ai.ai_batt_life <= 100) + Bprint(&bout, "battery =%d 100\n", ai.ai_batt_life); +} + +int +rsys(char *name, char *buf, int len) +{ + size_t l; + + l = len; + if(sysctlbyname(name, buf, &l, nil, 0) < 0) + return -1; + buf[l] = 0; + return l; +} + +vlong +isys(char *name) +{ + ulong u; + size_t l; + + l = sizeof u; + if(sysctlbyname(name, &u, &l, nil, 0) < 0) + return -1; + return u; +} + +void +xsysctl(int first) +{ + static int pgsize; + + if(first){ + pgsize = isys("vm.stats.vm.v_page_size"); + if(pgsize == 0) + pgsize = 4096; + } + + Bprint(&bout, "mem =%lld %lld\n", + isys("vm.stats.vm.v_active_count")*pgsize, + isys("vm.stats.vm.v_page_count")*pgsize); + Bprint(&bout, "context %lld 1000\n", isys("vm.stats.sys.v_swtch")); + Bprint(&bout, "syscall %lld 1000\n", isys("vm.stats.sys.v_syscall")); + Bprint(&bout, "intr %lld 1000\n", isys("vm.stats.sys.v_intr")+isys("vm.stats.sys.v_trap")); + Bprint(&bout, "fault %lld 1000\n", isys("vm.stats.vm.v_vm_faults")); + Bprint(&bout, "fork %lld 1000\n", isys("vm.stats.vm.v_forks") + +isys("vm.stats.vm.v_rforks") + +isys("vm.stats.vm.v_vforks")); +} + +void +xcpu(int first) +{ + static int stathz; + ulong x[20]; + struct clockinfo *ci; + int n; + + if(first){ + if(rsys("kern.clockrate", (char*)&x, sizeof x) < sizeof ci) + stathz = 128; + else{ + ci = (struct clockinfo*)x; + stathz = ci->stathz; + } + return; + } + + if((n=rsys("kern.cp_time", (char*)x, sizeof x)) < 5*sizeof(ulong)) + return; + + Bprint(&bout, "user %lud %d\n", x[CP_USER]+x[CP_NICE], stathz); + Bprint(&bout, "sys %lud %d\n", x[CP_SYS], stathz); + Bprint(&bout, "cpu %lud %d\n", x[CP_USER]+x[CP_NICE]+x[CP_SYS], stathz); + Bprint(&bout, "idle %lud %d\n", x[CP_IDLE], stathz); +} + +void +xloadavg(int first) +{ + double l[3]; + + if(first) + return; + + if(getloadavg(l, 3) < 0) + return; + Bprint(&bout, "load =%d 1000\n", (int)(l[0]*1000.0)); +} + +void +xswap(int first) +{ + static struct kvm_swap s; + static ulong pgin, pgout; + int i, o; + static int pgsize; + + if(first){ + pgsize = getpagesize(); + if(pgsize == 0) + pgsize = 4096; + return; + } + + if(kvm == nil) + return; + + i = isys("vm.stats.vm.v_swappgsin"); + o = isys("vm.stats.vm.v_swappgsout"); + if(i != pgin || o != pgout){ + pgin = i; + pgout = o; + kvm_getswapinfo(kvm, &s, 1, 0); + } + + + Bprint(&bout, "swap =%lld %lld\n", s.ksw_used*(vlong)pgsize, s.ksw_total*(vlong)pgsize); +} + diff --git a/src/cmd/auxstats/Linux.c b/src/cmd/auxstats/Linux.c new file mode 100644 index 00000000..06e9d422 --- /dev/null +++ b/src/cmd/auxstats/Linux.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include "dat.h" + +void xapm(int); +void xloadavg(int); +void xmeminfo(int); +void xnet(int); +void xstat(int); + +void (*statfn[])(int) = +{ + xapm, + xloadavg, + xmeminfo, + xnet, + xstat, + 0 +}; + +void +xapm(int first) +{ + static int fd = -1; + + if(first){ + fd = open("/proc/apm", OREAD); + return; + } + readfile(fd); + tokens(0); + if(ntok >= 7 && atoi(tok[6]) != -1) + Bprint(&bout, "battery =%d 100\n", atoi(tok[6])); +} + +void +xloadavg(int first) +{ + static int fd = -1; + + if(first){ + fd = open("/proc/loadavg", OREAD); + return; + } + + readfile(fd); + tokens(0); + if(ntok >= 1) + Bprint(&bout, "load =%d 1000\n", (int)(atof(tok[0])*1000)); +} + +void +xmeminfo(int first) +{ + int i; + vlong tot, used; + static int fd = -1; + + if(first){ + fd = open("/proc/meminfo", OREAD); + return; + } + + readfile(fd); + for(i=0; i= 5){ + Bprint(&bout, "user %lld 100\n", atoll(tok[1])); + Bprint(&bout, "sys %lld 100\n", atoll(tok[3])); + Bprint(&bout, "cpu %lld 100\n", atoll(tok[1])+atoll(tok[3])); + Bprint(&bout, "idle %lld\n", atoll(tok[4])); + } + /* + if(strcmp(tok[0], "page") == 0 && ntok >= 3){ + Bprint(&bout, "pagein %lld 500\n", atoll(tok[1])); + Bprint(&bout, "pageout %lld 500\n", atoll(tok[2])); + Bprint(&bout, "page %lld 1000\n", atoll(tok[1])+atoll(tok[2])); + } + if(strcmp(tok[0], "swap") == 0 && ntok >= 3){ + Bprint(&bout, "swapin %lld 500\n", atoll(tok[1])); + Bprint(&bout, "swapout %lld 500\n", atoll(tok[2])); + Bprint(&bout, "swap %lld 1000\n", atoll(tok[1])+atoll(tok[2])); + } + */ + if(strcmp(tok[0], "intr") == 0) + Bprint(&bout, "interrupt %lld 1000\n", atoll(tok[1])); + if(strcmp(tok[0], "ctxt") == 0) + Bprint(&bout, "context %lld 1000\n", atoll(tok[1])); + if(strcmp(tok[0], "processes") == 0) + Bprint(&bout, "fork %lld 1000\n", atoll(tok[1])); + } +} + diff --git a/src/cmd/auxstats/NetBSD.c b/src/cmd/auxstats/NetBSD.c new file mode 100644 index 00000000..ec931044 --- /dev/null +++ b/src/cmd/auxstats/NetBSD.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include "dat.h" + +void (*statfn[])(int) = +{ + 0 +}; + diff --git a/src/cmd/auxstats/OpenBSD.c b/src/cmd/auxstats/OpenBSD.c new file mode 100644 index 00000000..ec931044 --- /dev/null +++ b/src/cmd/auxstats/OpenBSD.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include "dat.h" + +void (*statfn[])(int) = +{ + 0 +}; + diff --git a/src/cmd/auxstats/SunOS.c b/src/cmd/auxstats/SunOS.c new file mode 100644 index 00000000..ec931044 --- /dev/null +++ b/src/cmd/auxstats/SunOS.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include "dat.h" + +void (*statfn[])(int) = +{ + 0 +}; + diff --git a/src/cmd/auxstats/core b/src/cmd/auxstats/core new file mode 100644 index 0000000000000000000000000000000000000000..f8fc24176efab053795c2367c8b68d6e9d6298e4 GIT binary patch literal 258048 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 XTsP@Pz>R<#0XG6}1l$Oms1f*ISgJd- literal 0 HcmV?d00001 diff --git a/src/cmd/auxstats/dat.h b/src/cmd/auxstats/dat.h new file mode 100644 index 00000000..17e5c615 --- /dev/null +++ b/src/cmd/auxstats/dat.h @@ -0,0 +1,9 @@ +extern Biobuf bout; +extern void (*statfn[])(int); +extern char buf[]; +extern char *line[]; +extern char *tok[]; +extern int nline, ntok; + +void readfile(int); +void tokens(int); diff --git a/src/cmd/auxstats/main.c b/src/cmd/auxstats/main.c new file mode 100644 index 00000000..a3624824 --- /dev/null +++ b/src/cmd/auxstats/main.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include "dat.h" + +Biobuf bout; + +void +usage(void) +{ + fprint(2, "usage: auxstats [system [executable]]\n"); + exits("usage"); +} + +int pid; + +void +notifyf(void *v, char *msg) +{ + USED(v); + + if(strcmp(msg, "child") == 0) + noted(NCONT); + postnote(PNPROC, pid, msg); + exits(nil); +} + +void +main(int argc, char **argv) +{ + char *sys, *exe; + int i; + Waitmsg *w; + + ARGBEGIN{ + default: + usage(); + }ARGEND + + notify(notifyf); + + sys = nil; + exe = nil; + if(argc > 0) + sys = argv[0]; + if(argc > 1) + exe = argv[1]; + if(argc > 2) + usage(); + + if(sys){ + if(exe == nil) + exe = "auxstats"; + for(;;){ + switch(pid = fork()){ + case -1: + sysfatal("fork: %r"); + case 0: + rfork(RFNOTEG); + execlp("ssh", "ssh", "-C", sys, exe, nil); + _exit(12); + default: + if((w = wait()) == nil) + sysfatal("wait: %r"); + if(w->pid != pid) + sysfatal("wait got wrong pid"); + if(atoi(w->msg) == 12) + sysfatal("exec ssh failed"); + free(w); + fprint(2, "stats: %s hung up; sleeping 60\n", sys); + sleep(60*1000); + fprint(2, "stats: redialing %s\n", sys); + break; + } + } + } + + for(i=0; statfn[i]; i++) + statfn[i](1); + + Binit(&bout, 1, OWRITE); + for(;;){ + Bflush(&bout); + sleep(900); + for(i=0; statfn[i]; i++) + statfn[i](0); + } +} + +char buf[16384]; +char *line[100]; +char *tok[100]; +int nline, ntok; + +void +readfile(int fd) +{ + int n; + + if(fd == -1){ + nline = 0; + return; + } + + seek(fd, 0, 0); + n = read(fd, buf, sizeof buf-1); + if(n < 0) + n = 0; + buf[n] = 0; + + nline = getfields(buf, line, nelem(line), 0, "\n"); +} + +void +tokens(int i) +{ + if(i >= nline){ + ntok = 0; + return; + } + ntok = tokenize(line[i], tok, nelem(tok)); +} + diff --git a/src/cmd/auxstats/mkfile b/src/cmd/auxstats/mkfile new file mode 100644 index 00000000..5652c60c --- /dev/null +++ b/src/cmd/auxstats/mkfile @@ -0,0 +1,15 @@ +<$PLAN9/src/mkhdr + +TARG=auxstats + +OFILES=\ + $SYSNAME.$O\ + main.$O\ + +HFILES=\ + dat.h\ + +SHORTLIB=bio 9 + +<$PLAN9/src/mkone +