home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / perfmon < prev    next >
Encoding:
Text File  |  1992-05-08  |  17.8 KB  |  646 lines

  1. Newsgroups: comp.sources.unix
  2. From: lm@Sunburn.Stanford.EDU (Larry McVoy)
  3. Subject: v26i020: perfmon - line- and screen-oriented interface to rstatd(8)
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: lm@Sunburn.Stanford.EDU (Larry McVoy)
  8. Posting-Number: Volume 26, Issue 20
  9. Archive-Name: perfmon
  10.  
  11. These work on Sun's or anything else running rstatd(8).  You may need to
  12. enable rstatd in /etc/inetd.conf (Sun ships it turned on, though).  Bug
  13. fixes to me, I'll repost.  Thanks.
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of shell archive."
  22. # Contents:  Makefile barmon.8 barmon.c hoststat.8 hoststat.c
  23. # Wrapped by lm@Sunburn.Stanford.EDU on Sat Jan 18 14:23:36 1992
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'Makefile'\"
  27. else
  28. echo shar: Extracting \"'Makefile'\" \(414 characters\)
  29. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  30. X# @(#)Makefile    1.1 1/18/92
  31. X
  32. XALL = hoststat barmon
  33. XMAN = hoststat.8 barmon.8
  34. XCFLAGS = -O4
  35. X
  36. Xall: $(ALL)
  37. X
  38. Xbarmon: barmon.c
  39. X    $(CC) $(CFLAGS) barmon.c -o barmon -lcurses -ltermlib -lrpcsvc
  40. X
  41. Xhoststat: hoststat.c
  42. X    $(CC) $(CFLAGS) hoststat.c -o hoststat -lrpcsvc
  43. X
  44. Xinstall: $(ALL) $(MAN)
  45. X    mv $(ALL) /usr/etc
  46. X    mv $(MAN) /usr/man/man8
  47. X
  48. Xclean:
  49. X    /bin/rm -f *.o a.out core 
  50. X    sccs clean
  51. X
  52. Xclobber:
  53. X    @make clean
  54. X    /bin/rm -f $(ALL)
  55. END_OF_FILE
  56. if test 414 -ne `wc -c <'Makefile'`; then
  57.     echo shar: \"'Makefile'\" unpacked with wrong size!
  58. fi
  59. # end of 'Makefile'
  60. fi
  61. if test -f 'barmon.8' -a "${1}" != "-c" ; then 
  62.   echo shar: Will not clobber existing file \"'barmon.8'\"
  63. else
  64. echo shar: Extracting \"'barmon.8'\" \(3188 characters\)
  65. sed "s/^X//" >'barmon.8' <<'END_OF_FILE'
  66. X.\" @(#)barmon.8    1.1 1/18/92 14:04:30 (c) 1992 Larry McVoy
  67. X.TH BARMON 8 "November 1991"
  68. X.SH NAME
  69. Xbarmon \- display performance bar graphs for several hosts
  70. X.SH SYNOPSIS
  71. X.B barmon
  72. X.I "host1 host2 ..."
  73. X[
  74. X.I interval
  75. X]
  76. X.SH DESCRIPTION
  77. X.B barmon
  78. Xuses the
  79. X.BR rstatd (8)
  80. Xto gather system statistics from the specified hosts and then displays
  81. Xthat information interactively on a tty using curses(3).
  82. XThe display is a series of bar graphs divided by host
  83. Xon the Y axis and activity type on the X axis.
  84. XIt is typically used to watch a number of processors running distributed
  85. Xapplications.  Other uses include monitoring a network of machines for
  86. Xoverloading, balance, etc.
  87. X.LP
  88. XUpon start up,
  89. X.B barmon
  90. Xwill be a little sluggish because it is pinging all the hosts for
  91. Xstatistics.  After the information is retrieved, the screen is cleared
  92. Xand a graph like so will be shown (this graph shows one machine paging,
  93. Xall others are idle):
  94. X.sp 2
  95. X.nf
  96. X          [% USER CPU][% SYS CPU ][Pkts   100][Disk    40][Page    60]
  97. Xsbox0     [          ][          ][          ][          ][          ]
  98. Xsbox1     [UUU       ][          ][          ][DDDDDDDDDD][PPPPPPPPPP]
  99. Xsbox4     [          ][          ][          ][          ][          ]
  100. X.fi
  101. X.sp 2
  102. XThe graph is updated every
  103. X.I interval
  104. Xseconds (default: 5 seconds).
  105. X.LP
  106. XAll of the fields of
  107. X.B barmon
  108. Xare averaged over 
  109. X.IR interval .
  110. XThe fields are:
  111. X.TP 12
  112. X.B "% USER CPU"
  113. XPercentage of time spent on user CPU in the last interval.
  114. X.TP
  115. X.B "% SYS CPU"
  116. XPercentage of time spent on system (kernel) CPU in the last interval.
  117. X.TP
  118. X.B "PKTS"
  119. XNumber of network packets (both input and output) seen in the
  120. Xlast interval.
  121. X.TP
  122. X.B "DISK"
  123. XNumber of disk operations (both input and output) seen in the
  124. Xlast interval.
  125. X.TP
  126. X.B "PAGE"
  127. XNumber of paging operations (both input and output) seen in the
  128. Xlast interval.
  129. X.LP
  130. X.ne 6
  131. XThe fields with numbers in the title are auto scaled each interval.
  132. XIf a field is marked 200, that means a full bar indicates 200 events,
  133. Xa half bar indicates 100, and so on.  All the fields are auto scaled
  134. Xacross all the hosts, so if the standard deviation is high, you start
  135. Xlosing information.
  136. X.SH BUGS
  137. XThe rstat()ing hosts effect the timing enough that sometimes the numbers 
  138. Xcome out wrong.  They are usually too large.  I tried to address this 
  139. Xsomewhat by fudging the numbers down and by using interval timers
  140. Xinstead of sleep(3).  Don't use short intervals.
  141. X.LP
  142. XSilently ignores unreachable hosts.  However, a dead host tends to slow
  143. Xdown startup quite a bit.
  144. X.LP
  145. XA host that crashes causes the program to exit.
  146. X.LP
  147. XRstatd(8) does not dig out all the info I'd like.  It would be cool if we
  148. Xcould implement vmstat(8) and xperfmon(8) with rstatd(8).
  149. X.LP
  150. XBarmon(8) does not display all the information it could.  The I/O operations
  151. Xcould be displayed as "IIIOOOO" to indicate "in" or "out" direction since
  152. Xrstat(8) does tell you this information.
  153. X.LP
  154. X(I'd refer you to rstat(3) to figure out the fields but that seems to be
  155. Xundocumented.  Sigh.  I figured it out by looking at the rstat.h include
  156. Xfile.)
  157. X.LP
  158. XRstatd(8) seems to be a Sun only thing - lobby BSD to include it.
  159. X.SH AUTHOR
  160. XLarry McVoy, Stanford University, lm@sunburn.stanford.edu
  161. END_OF_FILE
  162. if test 3188 -ne `wc -c <'barmon.8'`; then
  163.     echo shar: \"'barmon.8'\" unpacked with wrong size!
  164. fi
  165. # end of 'barmon.8'
  166. fi
  167. if test -f 'barmon.c' -a "${1}" != "-c" ; then 
  168.   echo shar: Will not clobber existing file \"'barmon.c'\"
  169. else
  170. echo shar: Extracting \"'barmon.c'\" \(5630 characters\)
  171. sed "s/^X//" >'barmon.c' <<'END_OF_FILE'
  172. Xstatic char *what = "@(#)barmon.c    1.7 1/18/92 (c) 1991 Larry McVoy";
  173. X#include <stdio.h>
  174. X#include <curses.h>
  175. X#include <sys/dk.h>
  176. X#include <time.h>
  177. X#include <signal.h>
  178. X#include <sys/time.h>
  179. X#include <ctype.h>
  180. X#include <rpcsvc/rstat.h>
  181. X
  182. X#define    LABEL        10
  183. X/*
  184. X * XXX - this should be an array of structs.
  185. X */
  186. X#define    USRLABEL    "[% USER CPU]"
  187. X#define    USRWID        11
  188. X#define    USRLEFT        LABEL
  189. X#define    USRRIGHT    (USRLEFT+USRWID)
  190. X#define    SYSLABEL    "[% SYS CPU ]" 
  191. X#define    SYSWID        11
  192. X#define    SYSLEFT        (USRRIGHT+1)
  193. X#define    SYSRIGHT    (SYSLEFT+SYSWID)
  194. X#define    PKTFMT        "[PKTS %5d]"
  195. X#define    PKTWID        11
  196. X#define    PKTLEFT        (SYSRIGHT+1)
  197. X#define    PKTRIGHT    (PKTLEFT+PKTWID)
  198. X#define    PKTADJUST    100
  199. X#define    DISKFMT        "[DISK %5d]"
  200. X#define    DISKWID        11
  201. X#define    DISKLEFT    (PKTRIGHT+1)
  202. X#define    DISKRIGHT    (DISKLEFT+DISKWID)
  203. X#define    DISKADJUST    10
  204. X#define    PAGEFMT        "[PAGE %5d]"
  205. X#define    PAGEWID        11
  206. X#define    PAGELEFT    (DISKRIGHT+1)
  207. X#define    PAGERIGHT    (PAGELEFT+PAGEWID)
  208. X#define    PAGEADJUST    10
  209. X#define    SLPDEFAULT    5
  210. X#define    sane(x)        ((x) > 100000 ? (-1) : (x))
  211. X#define    scale(x)    sane(secs == 1 ? (x) : (x) / secs)
  212. X#define    sleep(x)    usleep(1000000 * (x))
  213. X
  214. Xchar    **hosts;
  215. Xstruct    statstime *orig, *new;
  216. Xstruct    mystat {
  217. X    int    usr;
  218. X    int    sys;
  219. X    int    pkt;
  220. X    int    page;
  221. X    int    disk;
  222. X}    *save;
  223. Xint    secs;
  224. Xint    n;
  225. Xint    pagemax = 10, pktmax = 100, diskmax = 20;
  226. Xint    newpagemax = 10, newpktmax = 100, newdiskmax = 20;
  227. Xcatch() {}
  228. X
  229. Xmain(ac, av)
  230. X    char    **av;
  231. X{
  232. X    int    i;
  233. X    char    *calloc();
  234. X    struct    itimerval it;
  235. X    time_t    clock;
  236. X
  237. X    if (isdigit(av[ac - 1][0])) {
  238. X        secs =  atoi(av[ac - 1]);
  239. X        ac--;
  240. X    } else {
  241. X        secs = SLPDEFAULT;
  242. X    }
  243. X    hosts = (char**)calloc(ac, sizeof(char *));
  244. X    orig = (struct statstime*)calloc(ac, sizeof(struct statstime));
  245. X    new = (struct statstime*)calloc(ac, sizeof(struct statstime));
  246. X    save = (struct mystat*)calloc(ac, sizeof(struct mystat));
  247. X
  248. X    /*
  249. X     * Go through it once to fire up all the rstatd's.
  250. X     */
  251. X    for (i = 1; i < ac; ++i) {
  252. X        if (rstat(av[i], &orig[i - 1]) == 0) {
  253. X            hosts[n++] = av[i];
  254. X        } else {
  255. X            perror(av[i]);
  256. X            exit(1);
  257. X        }
  258. X    }
  259. X
  260. X    /*
  261. X     * Initialize
  262. X     * XXX - cath sigint and restore modes?
  263. X     */
  264. X    initscr();
  265. X    clear();
  266. X    mvaddstr(0, USRLEFT, USRLABEL);
  267. X    mvaddstr(0, SYSLEFT, SYSLABEL);
  268. X    mvprintw(0, PKTLEFT, PKTFMT, pktmax);
  269. X    mvprintw(0, DISKLEFT, DISKFMT, diskmax);
  270. X    mvprintw(0, PAGELEFT, PAGEFMT, pagemax);
  271. X    for(i = 1; i < ac; ++i) {
  272. X        if (strlen(av[i]) >= LABEL)
  273. X            av[i][LABEL] = 0;    /* XXX off by 1? */
  274. X        mvaddstr(i, 0, av[i]);
  275. X        mvaddch(i, USRLEFT, '[');
  276. X        mvaddch(i, USRRIGHT, ']');
  277. X        mvaddch(i, SYSLEFT, '[');
  278. X        mvaddch(i, SYSRIGHT, ']');
  279. X        mvaddch(i, PKTLEFT, '[');
  280. X        mvaddch(i, PKTRIGHT, ']');
  281. X        mvaddch(i, DISKLEFT, '[');
  282. X        mvaddch(i, DISKRIGHT, ']');
  283. X        mvaddch(i, PAGELEFT, '[');
  284. X        mvaddch(i, PAGERIGHT, ']');
  285. X    }
  286. X
  287. X    /*
  288. X     * Set up an interval timer - this should help get rid of delays.
  289. X     */
  290. X    it.it_interval.tv_sec = secs;
  291. X    it.it_interval.tv_usec = secs;
  292. X    it.it_value.tv_sec = secs;
  293. X    it.it_value.tv_usec = secs;
  294. X    signal(SIGALRM, catch);
  295. X    setitimer(ITIMER_REAL, &it, 0);
  296. X    sigblock(sigmask(SIGALRM));
  297. X
  298. X    /*
  299. X     * Do it again now that it is fast.
  300. X     */
  301. X    for (i = 0; i < ac - 1; ++i) {
  302. X        rstat(hosts[i], &orig[i]);
  303. X    }
  304. X    while (1) {
  305. X        /*
  306. X         * We need the signal handling because of the fact that the
  307. X         * rstat could be infinitely long.
  308. X         * XXX - need corbin's async rpc's.
  309. X         */
  310. X        sigpause(0);
  311. X        newpktmax = newdiskmax = newpagemax = 0;
  312. X        for (i = 0; i < ac - 1; ++i) {
  313. X            getstats(i);
  314. X        }
  315. X#define    adjustmax(n, o, a)    if (n > o) { \
  316. X                    o = ((n + a - 1) / a) * a; \
  317. X                } else if (n < o / 2) { \
  318. X                    o /= 2; \
  319. X                    o = ((o + a - 1) / a) * a; \
  320. X                }
  321. X        adjustmax(newdiskmax, diskmax, DISKADJUST);
  322. X        adjustmax(newpktmax, pktmax, PKTADJUST);
  323. X        adjustmax(newpagemax, pagemax, PAGEADJUST);
  324. X        mvprintw(0, PKTLEFT, PKTFMT, pktmax);
  325. X        mvprintw(0, DISKLEFT, DISKFMT, diskmax);
  326. X        mvprintw(0, PAGELEFT, PAGEFMT, pagemax);
  327. X        for (i = 0; i < ac - 1; ++i) {
  328. X            display(i);
  329. X        }
  330. X        time(&clock);
  331. X        mvprintw(23, 0, "%.24s", ctime(&clock));
  332. X        refresh();
  333. X    }
  334. X}
  335. X
  336. X/*
  337. X * Get the statistics and rescale
  338. X */
  339. Xgetstats(i)
  340. X{
  341. X    int    y, u, s, d, pkt, pg, pos;
  342. X
  343. X    if (rstat(hosts[i], &new[i]) != 0) {
  344. X        perror(hosts[i]);
  345. X        exit(1);
  346. X    }
  347. X    u = scale(new[i].cp_time[0] - orig[i].cp_time[0]);
  348. X    s = scale(new[i].cp_time[2] - orig[i].cp_time[2]);
  349. X    pkt = scale(new[i].if_ipackets - orig[i].if_ipackets) +
  350. X        scale(new[i].if_opackets - orig[i].if_opackets);
  351. X    d = scale(new[i].dk_xfer[0] - orig[i].dk_xfer[0]) +
  352. X        scale(new[i].dk_xfer[1] - orig[i].dk_xfer[1]) +
  353. X        scale(new[i].dk_xfer[2] - orig[i].dk_xfer[2]) +
  354. X        scale(new[i].dk_xfer[3] - orig[i].dk_xfer[3]);
  355. X    pg = scale(new[i].v_pgpgin - orig[i].v_pgpgin) +
  356. X        scale(new[i].v_pgpgout - orig[i].v_pgpgout);
  357. X    while (u + s > 100)    /* timing errors */
  358. X        u--, s--;
  359. X
  360. X#define    adjust(x, w, m)    if (x > m) x = m; \
  361. X            x = (x + ((m/(w-1) / 2))) * (w - 1) / m;
  362. X    adjust(u, USRWID, 100);
  363. X    adjust(s, SYSWID, 100);
  364. X    if (newpktmax < pkt)
  365. X        newpktmax = pkt;
  366. X    adjust(pkt, PKTWID, pktmax);
  367. X    if (newdiskmax < d)
  368. X        newdiskmax = d;
  369. X    adjust(d, DISKWID, diskmax);
  370. X    if (newpagemax < pg)
  371. X        newpagemax = pg;
  372. X    adjust(pg, PAGEWID, pagemax);
  373. X    save[i].usr = u;
  374. X    save[i].sys = s;
  375. X    save[i].pkt = pkt;
  376. X    save[i].disk = d;
  377. X    save[i].page = pg;
  378. X    orig[i] = new[i];
  379. X}
  380. X
  381. Xdisplay(i)
  382. X{
  383. X    int    y, pos;
  384. X
  385. X    y = i + 1;
  386. X    for (pos = USRLEFT + 1; pos < USRRIGHT; ++pos)
  387. X        mvaddch(y, pos, save[i].usr-- > 0 ? 'U' : ' ');
  388. X    for (pos = SYSLEFT + 1; pos < SYSRIGHT; ++pos)
  389. X        mvaddch(y, pos, save[i].sys-- > 0 ? 'S' : ' ');
  390. X    for (pos = PKTLEFT + 1; pos < PKTRIGHT; ++pos)
  391. X        mvaddch(y, pos, save[i].pkt-- > 0 ? 'N' : ' ');
  392. X    for (pos = DISKLEFT + 1; pos < DISKRIGHT; ++pos)
  393. X        mvaddch(y, pos, save[i].disk-- > 0 ? 'D' : ' ');
  394. X    for (pos = PAGELEFT + 1; pos < PAGERIGHT; ++pos)
  395. X        mvaddch(y, pos, save[i].page-- > 0 ? 'P' : ' ');
  396. X}
  397. END_OF_FILE
  398. if test 5630 -ne `wc -c <'barmon.c'`; then
  399.     echo shar: \"'barmon.c'\" unpacked with wrong size!
  400. fi
  401. # end of 'barmon.c'
  402. fi
  403. if test -f 'hoststat.8' -a "${1}" != "-c" ; then 
  404.   echo shar: Will not clobber existing file \"'hoststat.8'\"
  405. else
  406. echo shar: Extracting \"'hoststat.8'\" \(3156 characters\)
  407. sed "s/^X//" >'hoststat.8' <<'END_OF_FILE'
  408. X.\" @(#)hoststat.8    1.1 1/18/92 14:13:44 (c) 1991 Larry McVoy
  409. X.TH HOSTSTAT 8 "November 1991"
  410. X.SH NAME
  411. Xhoststat \- report performance statistics for several hosts
  412. X.SH SYNOPSIS
  413. X.B hoststat
  414. X.I "host1 host2 ..."
  415. X[
  416. X.I interval
  417. X]
  418. X.SH DESCRIPTION
  419. X.B hoststat
  420. Xuses the
  421. X.BR rstatd (8)
  422. Xto gather system statistics from the specified hosts.
  423. XIt is typically used to watch a number of processors running distributed
  424. Xapplications.  Other uses include monitoring a network of machines for
  425. Xoverloading, balance, etc.
  426. X.LP
  427. XUpon start up,
  428. X.B hoststat
  429. Xdisplays a one-line summary of the activity on each system over the last 
  430. Xsecond.
  431. XThis information is repeated every 
  432. X.I interval
  433. Xseconds (default: 5 seconds).
  434. X.LP
  435. XFor example, the following command displays a summary of what the
  436. Xsystem is doing every five seconds.
  437. X.LP
  438. X.RS
  439. X.nf
  440. X.ft B
  441. Xexample% hoststat sunbox0 sunbox1 sunbox2 sunbox3
  442. X.if t .sp .5v
  443. X   host load ipkt opkt err d0 d1 d2 d3 ipg opg intr    cs usr sys idl
  444. Xsunbox0  1.4  717  768   2 40 88  0  0  59  13 2643  3730  34 154  16
  445. Xsunbox1  0.4   72   73   0  0  0  0  0   6   0  216   144  67  38   0
  446. Xsunbox2  0.4    5    5   0  0  0  0  0   2   0   34    31  99   2   0
  447. Xsunbox3  0.6    0    1   0  0  0  0  0   0   0   14    19  87  14   0
  448. X   host load ipkt opkt err d0 d1 d2 d3 ipg opg intr    cs usr sys idl
  449. Xsunbox0  0.5  453  514   2  9 14  0  0  23  18 1500  2220  13  87   1
  450. Xsunbox1  0.1   54   46   0  0  0  0  0   3   0  141   100  78  22   0
  451. Xsunbox2  0.1   35   32   0  0  0  0  0   1   0   96    77  84  16   0
  452. Xsunbox3  0.1    0    0   0  0  0  0  0   0   0    1    15  90  10   0
  453. X.if t .sp .5v
  454. X^C
  455. Xexample%
  456. X.fi
  457. X.ft R
  458. X.RE
  459. X.LP
  460. XAll of the fields of
  461. X.B hoststat 
  462. Xare averaged over the 
  463. X.I interval
  464. Xspecified.
  465. XThe fields are:
  466. X.TP 8
  467. X.B load
  468. XThe 1 minute load average.
  469. X.TP 8
  470. X.B ipkt
  471. XThe number of input packets (summation of all network interfaces).
  472. X.TP 8
  473. X.B opkt
  474. XThe number of output packets (as above).
  475. X.TP 8
  476. X.B err
  477. XThe number of packets considered errors, both output and collusion errors
  478. X(as above).
  479. X.TP 8
  480. X.B d0
  481. XDisk activity on the ``first'' disk.  The names are useless but you can usually
  482. Xfigure out which is which.
  483. X.TP 8
  484. X.B d1
  485. XDisk activity on the ``second'' disk.
  486. X.TP 8
  487. X.B d2
  488. XDisk activity on the ``third'' disk.
  489. X.TP 8
  490. X.B d3
  491. XDisk activity on the ``fourth'' disk.
  492. X.TP 8
  493. X.B ipg
  494. XPages faulted in.
  495. X.TP 8
  496. X.B opg
  497. XPages paged out (by pageout daemon or freebehind of sequential I/O).
  498. X.TP 8
  499. X.B intr
  500. XDevice interrupts.
  501. X.TP 8
  502. X.B cs
  503. XContext switches.
  504. X.TP 8
  505. X.B usr
  506. XPercentage of CPU time spent executing user applications.
  507. X.TP 8
  508. X.B sys
  509. XPercentage of CPU time spent in the kernel.
  510. X.TP 8
  511. X.B idl
  512. XPercentage of CPU time spent idle.
  513. X.SH BUGS
  514. XThe rstat()ing hosts effect the timing enough that sometimes the numbers 
  515. Xcome out wrong.  They are usually too large.  Use larger intervals if you
  516. Xstart getting bogus numbers.
  517. X.LP
  518. XSilently ignores unreachable hosts.  Crashing hosts crashes the program.
  519. X.LP
  520. XRstatd(8) doesn't dig out all the info I'd like.  It would be cool if we
  521. Xcould implement vmstat(8) and xperfmon(8) with rstatd(8).
  522. X.LP
  523. X(I'd refer you to rstat(3) to figure out the fields but that seems to be
  524. Xundocumented.  Sigh.)
  525. X.SH AUTHOR
  526. XLarry McVoy, Stanford University
  527. END_OF_FILE
  528. if test 3156 -ne `wc -c <'hoststat.8'`; then
  529.     echo shar: \"'hoststat.8'\" unpacked with wrong size!
  530. fi
  531. # end of 'hoststat.8'
  532. fi
  533. if test -f 'hoststat.c' -a "${1}" != "-c" ; then 
  534.   echo shar: Will not clobber existing file \"'hoststat.c'\"
  535. else
  536. echo shar: Extracting \"'hoststat.c'\" \(2386 characters\)
  537. sed "s/^X//" >'hoststat.c' <<'END_OF_FILE'
  538. X#include <rpcsvc/rstat.h>
  539. X#include <sys/dk.h>
  540. X#include <ctype.h>
  541. X#include <stdio.h>
  542. X
  543. X#define    SLPDEFAULT    10
  544. X#define    sane(x)        ((x) > 100000 ? (-1) : (x))
  545. X#define    scale(x)    sane(secs == 1 ? (x) : (x) / secs)
  546. X#define    sleep(x)    usleep(1000000 * (x))
  547. X
  548. Xchar    **hosts;
  549. Xstruct    statstime *orig;
  550. Xint    secs;
  551. Xint    n;
  552. X
  553. Xmain(ac, av)
  554. X    char    **av;
  555. X{
  556. X    int    i;
  557. X    char    *calloc();
  558. X
  559. X    for (i = 1; i < ac && !isdigit(av[i][0]); i++)
  560. X        ;
  561. X    hosts = (char**)calloc(i, sizeof(char *));
  562. X    orig = (struct statstime*)calloc(i, sizeof(struct statstime));
  563. X
  564. X    /*
  565. X     * Go through it once to fire up all the rstatd's.
  566. X     */
  567. X    for (i = 1; i < ac; ++i) {
  568. X        fprintf(stderr, "%s ", av[i]);
  569. X        if (rstat(av[i], &orig[i - 1]) == 0) {
  570. X            hosts[n++] = av[i];
  571. X        }
  572. X    }
  573. X    fprintf(stderr, "\n");
  574. X    for (i = 1; i < ac; ++i) {
  575. X        if (!hosts[i])
  576. X            continue;
  577. X        rstat(av[i], &orig[i - 1]);
  578. X    }
  579. X    /*
  580. X     * Initialize
  581. X     */
  582. X    sleep(secs = 1);
  583. X    for (i = 0; i < ac - 1; ++i) {
  584. X        if (!hosts[i])
  585. X            continue;
  586. X        dohost(i);
  587. X    }
  588. X    secs = isdigit(av[ac - 1][0]) ? atoi(av[ac -1]) : SLPDEFAULT;
  589. X    while (1) {
  590. X        sleep(secs);
  591. X        for (i = 0; i < ac - 1; ++i) {
  592. X            if (!hosts[i])
  593. X                continue;
  594. X            dohost(i);
  595. X        }
  596. X    }
  597. X}
  598. X
  599. Xdohost(i)
  600. X{
  601. X    struct    statstime st;
  602. X    static    count;
  603. X    
  604. X    if (count++ % n == 0) {
  605. X        printf("%8.8s %4s %4s %4s %3s %3s %3s %3s %3s ",
  606. X            "host", "load", "ipkt", "opkt", "err",
  607. X            "d0", "d1", "d2", "d3");
  608. X        printf("%3s %3s %4s %5s ",
  609. X            "ipg", "opg", "intr", "cs");
  610. X        printf("%3s %3s %3s\n", "usr", "sys", "idl");
  611. X    }
  612. X    if (rstat(hosts[i], &st) != 0) {
  613. X        perror(hosts[i]);
  614. X        exit(1);
  615. X    }
  616. X    printf("%8.8s %4.1f %4d %4d %3d %3d %3d %3d %3d %3d %3d %4d %5d ",
  617. X        hosts[i], 
  618. X        scale(st.avenrun[0] / 256.),
  619. X        scale(st.if_ipackets - orig[i].if_ipackets),
  620. X        scale(st.if_opackets - orig[i].if_opackets),
  621. X        scale((st.if_collisions + st.if_oerrors) - 
  622. X          (orig[i].if_collisions + orig[i].if_oerrors)),
  623. X        scale(st.dk_xfer[0] - orig[i].dk_xfer[0]),
  624. X        scale(st.dk_xfer[1] - orig[i].dk_xfer[1]),
  625. X        scale(st.dk_xfer[2] - orig[i].dk_xfer[2]),
  626. X        scale(st.dk_xfer[3] - orig[i].dk_xfer[3]),
  627. X        scale(st.v_pgpgin - orig[i].v_pgpgin),
  628. X        scale(st.v_pgpgout - orig[i].v_pgpgout),
  629. X        scale(st.v_intr - orig[i].v_intr),
  630. X        scale(st.v_swtch - orig[i].v_swtch),
  631. X        0);
  632. X    printf("%3d %3d %3d\n",
  633. X        scale(st.cp_time[0] - orig[i].cp_time[0]),
  634. X        scale(st.cp_time[2] - orig[i].cp_time[2]),
  635. X        scale(st.cp_time[3] - orig[i].cp_time[3]));
  636. X    orig[i] = st;
  637. X}
  638. END_OF_FILE
  639. if test 2386 -ne `wc -c <'hoststat.c'`; then
  640.     echo shar: \"'hoststat.c'\" unpacked with wrong size!
  641. fi
  642. # end of 'hoststat.c'
  643. fi
  644. echo shar: End of shell archive.
  645. exit 0
  646.