$OpenBSD: patch-wmmon_wmmon_c,v 1.5 2006/09/23 15:49:36 ckuethe Exp $ --- wmmon/wmmon.c.orig Tue May 19 15:13:16 1998 +++ wmmon/wmmon.c Sat Sep 23 09:43:02 2006 @@ -28,6 +28,10 @@ Changes: ---- + 28/09/2000 (Vladimir Popov, pva48@mail.ru) + * Ported to OpenBSD + Based on FreeBSD port by Stephen Kiernan, + OpenBSD top and vmstat 18/05/1998 (Antoine Nulle, warp@xs4all.nl) * MEM/SWAP/UPTIME only updated when visible * Using global file descriptors to reduce file @@ -72,10 +76,20 @@ #include #include +#include +#include + #include #include #include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -100,11 +114,11 @@ /* Global Variables */ /********************/ -char *ProgName; int stat_current = 0; /* now global */ -FILE *fp_meminfo; -FILE *fp_stat; -FILE *fp_loadavg; +int ndrives; +int pagesize; +int pageshift; +char errbuf[_POSIX2_LINE_MAX]; /* functions */ void usage(void); @@ -114,17 +128,15 @@ void DrawStats_io(int *, int, int, int, void wmmon_routine(int, char **); -void main(int argc, char *argv[]) { +/* OpenBSD specific functions */ +#define pagetok(size) ((size) << pageshift) +int swapmode(long *, long *); +int main(int argc, char *argv[]) +{ int i; - /* Parse Command Line */ - - ProgName = argv[0]; - if (strlen(ProgName) >= 5) - ProgName += (strlen(ProgName) - 5); - for (i=1; i 1) { + pageshift++; + pagesize >>= 1; + } - if (fp) { - fscanf(fp, "%ld", &online_time); - ref_time = time(0); - fclose(fp); + /* we only need the amount of log(2)1024 for our conversion */ + pageshift -= 10; + + mib[0] = CTL_HW; + mib[1] = HW_DISKCOUNT; + size = sizeof(ndrives); + if (sysctl(mib, 2, &ndrives, &size, NULL, 0) < 0 ) { + warn("could not read hw.diskcount"); + ndrives = 0; } for (i=0; iname, &k, &istat, &idle); + /* mostly stolen from src/usr.bin/top/machine.c */ + size = sizeof(cp_time); + if (sysctl(cp_time_mib, 2, &cp_time, &size, NULL, 0) < 0) + warn("sysctl kern.cp_time failed"); + size = sizeof(sysload); + if (sysctl(sysload_mib, 2, &sysload, &size, NULL, 0) < 0) + warn("sysctl failed"); + infoload = ((double) sysload.ldavg[0]) / sysload.fscale; + + for (i = 0, istat = 0; i < CPUSTATES; i++) + if (i != CP_IDLE) istat += cp_time[i]; + idle = cp_time[CP_IDLE]; + st->rt_idle = idle - st->idlelast; st->idlelast = idle; st->rt_stat = istat - st->statlast; st->statlast = istat; - st->his[54] += k; + st->his[54] += (long)(100 * infoload); st->hisaddcnt += 1; } void update_stat_io(stat_dev *st) { - long j, k, istat, idle; - static long maxdiskio = 0; + struct diskstats *q; + static int io_mib[] = {CTL_HW, HW_DISKSTATS}; + int mib[] = {CTL_HW, HW_DISKCOUNT}; + static long maxdiskxfers = 0; + long xfers, rwstat; + size_t size; + int i; - get_statistics(st->name, &k, &istat, &idle); + size = sizeof(ndrives); + if (sysctl(mib, 2, &ndrives, &size, NULL, 0) < 0 ) { + warn("could not read hw.diskcount"); + return; + } - st->rt_idle = idle - st->idlelast; - st->idlelast = idle; - - st->rt_stat = istat - st->statlast; - st->statlast = istat; - - j = st->rt_stat; - if (maxdiskio < j) { - maxdiskio = j; + size = ndrives * sizeof(struct diskstats); + q = malloc(size); + if (q == NULL) + err(1, NULL); + if (sysctl(io_mib, 2, q, &size, NULL, 0) < 0) { + warn("could not read hw.diskstats"); + bzero(q, ndrives * sizeof(struct diskstats)); } - st->rt_idle = maxdiskio - j; - st->his[54] += st->rt_stat; - st->hisaddcnt += 1; -} - -void update_stat_mem(stat_dev *st, stat_dev *st2) { - - char temp[128]; - unsigned long free, shared, buffers, cached; - - freopen("/proc/meminfo", "r", fp_meminfo); - while (fgets(temp, 128, fp_meminfo)) { - if (strstr(temp, "Mem:")) { - sscanf(temp, "Mem: %ld %ld %ld %ld %ld %ld", - &st->rt_idle, &st->rt_stat, - &free, &shared, &buffers, &cached); - st->rt_idle >>= 10; - st->rt_stat -= buffers+cached; - st->rt_stat >>= 10; -// break; - } - if (strstr(temp, "Swap:")) { - sscanf(temp, "Swap: %ld %ld", &st2->rt_idle, &st2->rt_stat); - st2->rt_idle >>= 10; - st2->rt_stat >>= 10; - break; - } + for (i = 0; i < ndrives; i++) { + rwstat += q[i].ds_rbytes + q[i].ds_wbytes; + xfers += q[i].ds_rxfer + q[i].ds_wxfer; } -} + free(q); + + if (st->statlast == 0) + st->statlast = xfers; + if (xfers < st->statlast) + xfers = st->statlast; + st->rt_stat = xfers - st->statlast; + st->statlast = xfers; -void update_stat_swp(stat_dev *st) { + if (maxdiskxfers < st->rt_stat) + maxdiskxfers = st->rt_stat; - char temp[128]; + st->rt_idle = maxdiskxfers - st->rt_stat; + st->idlelast = 0; - fseek(fp_meminfo, 0, SEEK_SET); - while (fgets(temp, 128, fp_meminfo)) { - if (strstr(temp, "Swap:")) { - sscanf(temp, "Swap: %ld %ld", &st->rt_idle, &st->rt_stat); - st->rt_idle >>= 10; - st->rt_stat >>= 10; - break; - } - } - + st->his[54] += rwstat; + st->hisaddcnt += 1; } -/*******************************************************************************\ -|* get_statistics *| -\*******************************************************************************/ +void update_stat_mem(stat_dev *st, stat_dev *st2) { -void get_statistics(char *devname, long *is, long *ds, long *idle) { + struct vmtotal total; + size_t size = sizeof(total); + static int mib[] = { CTL_VM, VM_METER }; - int i; - char temp[128]; - char *p; - char *tokens = " \t\n"; - float f; - long maxdiskio=0; + /* get total -- systemwide main memory usage structure */ + if ( sysctl(mib, 2, &total, &size, NULL, 0) < 0 ) + bzero(&total, sizeof(total)); - *is = 0; - *ds = 0; - *idle = 0; + /* FIXME: is it right to count memory like this */ + st->rt_idle = pagetok(total.t_rm + total.t_free); + st->rt_stat = pagetok(total.t_rm); - if (!strncmp(devname, "cpu", 3)) { - fseek(fp_stat, 0, SEEK_SET); - while (fgets(temp, 128, fp_stat)) { - if (strstr(temp, "cpu")) { - p = strtok(temp, tokens); - /* 1..3, 4 == idle, we don't want idle! */ - for (i=0; i<3; i++) { - p = strtok(NULL, tokens); - *ds += atol(p); - } - p = strtok(NULL, tokens); - *idle = atol(p); - } - } - fp_loadavg = freopen("/proc/loadavg", "r", fp_loadavg); - fscanf(fp_loadavg, "%f", &f); - *is = (long) (100 * f); + if ( !swapmode(&st2->rt_stat, &st2->rt_idle) ) { + st2->rt_idle = 0; + st2->rt_stat = 0; } - - if (!strncmp(devname, "i/o", 3)) { - - fseek(fp_stat, 0, SEEK_SET); - while (fgets(temp, 128, fp_stat)) { - if (strstr(temp, "disk_rio") || strstr(temp, "disk_wio")) { - p = strtok(temp, tokens); - /* 1..4 */ - for (i=0; i<4; i++) { - p = strtok(NULL, tokens); - *ds += atol(p); - } - } - } - if (*ds > maxdiskio) maxdiskio = *ds; - } } -/*******************************************************************************\ -|* checksysdevs *| -\*******************************************************************************/ +/***************************************************************************\ +|* checksysdevs *| +\***************************************************************************/ int checksysdevs(void) { - strcpy(stat_device[0].name, "cpu0"); - strcpy(stat_device[1].name, "i/o"); - strcpy(stat_device[2].name, "sys"); + strncpy(stat_device[0].name, "cpu0", 5); + strncpy(stat_device[1].name, "i/o", 5); + strncpy(stat_device[2].name, "sys", 5); return 3; } @@ -733,7 +729,35 @@ void usage(void) { void printversion(void) { - if (!strcmp(ProgName, "wmmon")) { - fprintf(stderr, "%s\n", WMMON_VERSION); - } + fprintf(stderr, "%s\n", WMMON_VERSION); +} + +int swapmode(long *used, long *total) { + int nswap, rnswap, i; + struct swapent *swdev; + + nswap = swapctl(SWAP_NSWAP, 0, 0); + if (nswap == 0) + return 0; + + swdev = malloc(nswap * sizeof(*swdev)); + if(swdev == NULL) + return 0; + + rnswap = swapctl(SWAP_STATS, swdev, nswap); + if(rnswap == -1) + return 0; + + /* if rnswap != nswap, then what? */ + + /* Total things up */ + *total = *used = 0; + for (i = 0; i < nswap; i++) + if (swdev[i].se_flags & SWF_ENABLE) { + *used += (swdev[i].se_inuse / (1024/DEV_BSIZE)); + *total += (swdev[i].se_nblks / (1024/DEV_BSIZE)); + } + + free (swdev); + return 1; }