home *** CD-ROM | disk | FTP | other *** search
- static char *what = "@(#)barmon.c 1.7 1/18/92 (c) 1991 Larry McVoy";
- #include <stdio.h>
- #include <curses.h>
- #include <sys/dk.h>
- #include <time.h>
- #include <signal.h>
- #include <sys/time.h>
- #include <ctype.h>
- #include <rpcsvc/rstat.h>
-
- #define LABEL 10
- /*
- * XXX - this should be an array of structs.
- */
- #define USRLABEL "[% USER CPU]"
- #define USRWID 11
- #define USRLEFT LABEL
- #define USRRIGHT (USRLEFT+USRWID)
- #define SYSLABEL "[% SYS CPU ]"
- #define SYSWID 11
- #define SYSLEFT (USRRIGHT+1)
- #define SYSRIGHT (SYSLEFT+SYSWID)
- #define PKTFMT "[PKTS %5d]"
- #define PKTWID 11
- #define PKTLEFT (SYSRIGHT+1)
- #define PKTRIGHT (PKTLEFT+PKTWID)
- #define PKTADJUST 100
- #define DISKFMT "[DISK %5d]"
- #define DISKWID 11
- #define DISKLEFT (PKTRIGHT+1)
- #define DISKRIGHT (DISKLEFT+DISKWID)
- #define DISKADJUST 10
- #define PAGEFMT "[PAGE %5d]"
- #define PAGEWID 11
- #define PAGELEFT (DISKRIGHT+1)
- #define PAGERIGHT (PAGELEFT+PAGEWID)
- #define PAGEADJUST 10
- #define SLPDEFAULT 5
- #define sane(x) ((x) > 100000 ? (-1) : (x))
- #define scale(x) sane(secs == 1 ? (x) : (x) / secs)
- #define sleep(x) usleep(1000000 * (x))
-
- char **hosts;
- struct statstime *orig, *new;
- struct mystat {
- int usr;
- int sys;
- int pkt;
- int page;
- int disk;
- } *save;
- int secs;
- int n;
- int pagemax = 10, pktmax = 100, diskmax = 20;
- int newpagemax = 10, newpktmax = 100, newdiskmax = 20;
- catch() {}
-
- main(ac, av)
- char **av;
- {
- int i;
- char *calloc();
- struct itimerval it;
- time_t clock;
-
- if (isdigit(av[ac - 1][0])) {
- secs = atoi(av[ac - 1]);
- ac--;
- } else {
- secs = SLPDEFAULT;
- }
- hosts = (char**)calloc(ac, sizeof(char *));
- orig = (struct statstime*)calloc(ac, sizeof(struct statstime));
- new = (struct statstime*)calloc(ac, sizeof(struct statstime));
- save = (struct mystat*)calloc(ac, sizeof(struct mystat));
-
- /*
- * Go through it once to fire up all the rstatd's.
- */
- for (i = 1; i < ac; ++i) {
- if (rstat(av[i], &orig[i - 1]) == 0) {
- hosts[n++] = av[i];
- } else {
- perror(av[i]);
- exit(1);
- }
- }
-
- /*
- * Initialize
- * XXX - cath sigint and restore modes?
- */
- initscr();
- clear();
- mvaddstr(0, USRLEFT, USRLABEL);
- mvaddstr(0, SYSLEFT, SYSLABEL);
- mvprintw(0, PKTLEFT, PKTFMT, pktmax);
- mvprintw(0, DISKLEFT, DISKFMT, diskmax);
- mvprintw(0, PAGELEFT, PAGEFMT, pagemax);
- for(i = 1; i < ac; ++i) {
- if (strlen(av[i]) >= LABEL)
- av[i][LABEL] = 0; /* XXX off by 1? */
- mvaddstr(i, 0, av[i]);
- mvaddch(i, USRLEFT, '[');
- mvaddch(i, USRRIGHT, ']');
- mvaddch(i, SYSLEFT, '[');
- mvaddch(i, SYSRIGHT, ']');
- mvaddch(i, PKTLEFT, '[');
- mvaddch(i, PKTRIGHT, ']');
- mvaddch(i, DISKLEFT, '[');
- mvaddch(i, DISKRIGHT, ']');
- mvaddch(i, PAGELEFT, '[');
- mvaddch(i, PAGERIGHT, ']');
- }
-
- /*
- * Set up an interval timer - this should help get rid of delays.
- */
- it.it_interval.tv_sec = secs;
- it.it_interval.tv_usec = secs;
- it.it_value.tv_sec = secs;
- it.it_value.tv_usec = secs;
- signal(SIGALRM, catch);
- setitimer(ITIMER_REAL, &it, 0);
- sigblock(sigmask(SIGALRM));
-
- /*
- * Do it again now that it is fast.
- */
- for (i = 0; i < ac - 1; ++i) {
- rstat(hosts[i], &orig[i]);
- }
- while (1) {
- /*
- * We need the signal handling because of the fact that the
- * rstat could be infinitely long.
- * XXX - need corbin's async rpc's.
- */
- sigpause(0);
- newpktmax = newdiskmax = newpagemax = 0;
- for (i = 0; i < ac - 1; ++i) {
- getstats(i);
- }
- #define adjustmax(n, o, a) if (n > o) { \
- o = ((n + a - 1) / a) * a; \
- } else if (n < o / 2) { \
- o /= 2; \
- o = ((o + a - 1) / a) * a; \
- }
- adjustmax(newdiskmax, diskmax, DISKADJUST);
- adjustmax(newpktmax, pktmax, PKTADJUST);
- adjustmax(newpagemax, pagemax, PAGEADJUST);
- mvprintw(0, PKTLEFT, PKTFMT, pktmax);
- mvprintw(0, DISKLEFT, DISKFMT, diskmax);
- mvprintw(0, PAGELEFT, PAGEFMT, pagemax);
- for (i = 0; i < ac - 1; ++i) {
- display(i);
- }
- time(&clock);
- mvprintw(23, 0, "%.24s", ctime(&clock));
- refresh();
- }
- }
-
- /*
- * Get the statistics and rescale
- */
- getstats(i)
- {
- int y, u, s, d, pkt, pg, pos;
-
- if (rstat(hosts[i], &new[i]) != 0) {
- perror(hosts[i]);
- exit(1);
- }
- u = scale(new[i].cp_time[0] - orig[i].cp_time[0]);
- s = scale(new[i].cp_time[2] - orig[i].cp_time[2]);
- pkt = scale(new[i].if_ipackets - orig[i].if_ipackets) +
- scale(new[i].if_opackets - orig[i].if_opackets);
- d = scale(new[i].dk_xfer[0] - orig[i].dk_xfer[0]) +
- scale(new[i].dk_xfer[1] - orig[i].dk_xfer[1]) +
- scale(new[i].dk_xfer[2] - orig[i].dk_xfer[2]) +
- scale(new[i].dk_xfer[3] - orig[i].dk_xfer[3]);
- pg = scale(new[i].v_pgpgin - orig[i].v_pgpgin) +
- scale(new[i].v_pgpgout - orig[i].v_pgpgout);
- while (u + s > 100) /* timing errors */
- u--, s--;
-
- #define adjust(x, w, m) if (x > m) x = m; \
- x = (x + ((m/(w-1) / 2))) * (w - 1) / m;
- adjust(u, USRWID, 100);
- adjust(s, SYSWID, 100);
- if (newpktmax < pkt)
- newpktmax = pkt;
- adjust(pkt, PKTWID, pktmax);
- if (newdiskmax < d)
- newdiskmax = d;
- adjust(d, DISKWID, diskmax);
- if (newpagemax < pg)
- newpagemax = pg;
- adjust(pg, PAGEWID, pagemax);
- save[i].usr = u;
- save[i].sys = s;
- save[i].pkt = pkt;
- save[i].disk = d;
- save[i].page = pg;
- orig[i] = new[i];
- }
-
- display(i)
- {
- int y, pos;
-
- y = i + 1;
- for (pos = USRLEFT + 1; pos < USRRIGHT; ++pos)
- mvaddch(y, pos, save[i].usr-- > 0 ? 'U' : ' ');
- for (pos = SYSLEFT + 1; pos < SYSRIGHT; ++pos)
- mvaddch(y, pos, save[i].sys-- > 0 ? 'S' : ' ');
- for (pos = PKTLEFT + 1; pos < PKTRIGHT; ++pos)
- mvaddch(y, pos, save[i].pkt-- > 0 ? 'N' : ' ');
- for (pos = DISKLEFT + 1; pos < DISKRIGHT; ++pos)
- mvaddch(y, pos, save[i].disk-- > 0 ? 'D' : ' ');
- for (pos = PAGELEFT + 1; pos < PAGERIGHT; ++pos)
- mvaddch(y, pos, save[i].page-- > 0 ? 'P' : ' ');
- }
-