home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / rpc3.9 / part09 / rstat_proc.c next >
Encoding:
C/C++ Source or Header  |  1988-02-27  |  8.6 KB  |  354 lines

  1. /* @(#)rstat_proc.c    1.2 87/11/24 3.9 RPCSRC */
  2. #ifndef lint
  3. static  char sccsid[] = "@(#)rpc.rstatd.c 1.1 86/09/25 Copyr 1984 Sun Micro";
  4. #endif
  5.  
  6. /*
  7.  * Copyright (c) 1984 by Sun Microsystems, Inc.
  8.  */
  9.  
  10. /*
  11.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  12.  * unrestricted use provided that this legend is included on all tape
  13.  * media and as a part of the software program in whole or part.  Users
  14.  * may copy or modify Sun RPC without charge, but are not authorized
  15.  * to license or distribute it to anyone else except as part of a product or
  16.  * program developed by the user.
  17.  *
  18.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  19.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  20.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  21.  *
  22.  * Sun RPC is provided with no support and without any obligation on the
  23.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  24.  * modification or enhancement.
  25.  *
  26.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  27.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  28.  * OR ANY PART THEREOF.
  29.  *
  30.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  31.  * or profits or other special, indirect and consequential damages, even if
  32.  * Sun has been advised of the possibility of such damages.
  33.  *
  34.  * Sun Microsystems, Inc.
  35.  * 2550 Garcia Avenue
  36.  * Mountain View, California  94043
  37.  */
  38.  
  39. /*
  40.  * rstat service:  built with rstat.x and derived from rpc.rstatd.c
  41.  */
  42.  
  43. #include <signal.h>
  44. #include <stdio.h>
  45. #include <rpc/rpc.h>
  46. #include <sys/socket.h>
  47. #include <nlist.h>
  48. #include <sys/dk.h>
  49. #include <sys/errno.h>
  50. #include <sys/vmmeter.h>
  51. #include <net/if.h>
  52. #include <sys/time.h>
  53. #include "rstat.h"
  54.  
  55. struct nlist nl[] = {
  56. #define    X_CPTIME    0
  57.     { "_cp_time" },
  58. #define    X_SUM        1
  59.     { "_sum" },
  60. #define    X_IFNET        2
  61.     { "_ifnet" },
  62. #define    X_DKXFER    3
  63.     { "_dk_xfer" },
  64. #define    X_BOOTTIME    4
  65.     { "_boottime" },
  66. #define    X_AVENRUN    5
  67.     { "_avenrun" },
  68. #define X_HZ        6
  69.     { "_hz" },
  70.     "",
  71. };
  72. int kmem;
  73. int firstifnet, numintfs;    /* chain of ethernet interfaces */
  74. int stats_service();
  75.  
  76. /*
  77.  *  Define EXIT_WHEN_IDLE if you are able to have this program invoked
  78.  *  automatically on demand (as from inetd).  When defined, the service
  79.  *  will terminated after being idle for 20 seconds.
  80.  */
  81. int sincelastreq = 0;        /* number of alarms since last request */
  82. #ifdef EXIT_WHEN_IDLE
  83. #define CLOSEDOWN 20        /* how long to wait before exiting */
  84. #endif /* def EXIT_WHEN_IDLE */
  85.  
  86. union {
  87.     struct stats s1;
  88.     struct statsswtch s2;
  89.     struct statstime s3;
  90. } stats_all;
  91.  
  92. int updatestat();
  93. static stat_is_init = 0;
  94. extern int errno;
  95.  
  96. #ifndef FSCALE
  97. #define FSCALE (1 << 8)
  98. #endif
  99.  
  100. stat_init()
  101. {
  102.     stat_is_init = 1;
  103.     setup();
  104.     updatestat();
  105.     alarm(1);
  106.     signal(SIGALRM, updatestat);
  107.     sleep(1);               /* allow for one wake-up */
  108. }
  109.  
  110. statstime *
  111. rstatproc_stats_3()
  112. {
  113.     if (! stat_is_init)
  114.         stat_init();
  115.     sincelastreq = 0;
  116.     return(&stats_all.s3);
  117. }
  118.  
  119. statsswtch *
  120. rstatproc_stats_2()
  121. {
  122.     if (! stat_is_init)
  123.         stat_init();
  124.     sincelastreq = 0;
  125.     return(&stats_all.s2);
  126. }
  127.  
  128. stats *
  129. rstatproc_stats_1()
  130. {
  131.     if (! stat_is_init)
  132.         stat_init();
  133.     sincelastreq = 0;
  134.     return(&stats_all.s1);
  135. }
  136.  
  137. u_int *
  138. rstatproc_havedisk_3()
  139. {
  140.     static u_int have;
  141.  
  142.     if (! stat_is_init)
  143.         stat_init();
  144.     sincelastreq = 0;
  145.     have = havedisk();
  146.     return(&have);
  147. }
  148.  
  149. u_int *
  150. rstatproc_havedisk_2()
  151. {
  152.     return(rstatproc_havedisk_3());
  153. }
  154.  
  155. u_int *
  156. rstatproc_havedisk_1()
  157. {
  158.     return(rstatproc_havedisk_3());
  159. }
  160.  
  161. updatestat()
  162. {
  163.     int off, i, hz;
  164.     struct vmmeter sum;
  165.     struct ifnet ifnet;
  166.     double avrun[3];
  167.     struct timeval tm, btm;
  168.  
  169. #ifdef DEBUG
  170.     fprintf(stderr, "entering updatestat\n");
  171. #endif
  172. #ifdef EXIT_WHEN_IDLE
  173.     if (sincelastreq >= CLOSEDOWN) {
  174. #ifdef DEBUG
  175.     fprintf(stderr, "about to closedown\n");
  176. #endif
  177.         exit(0);
  178.     }
  179.     sincelastreq++;
  180. #endif /* def EXIT_WHEN_IDLE */
  181.     if (lseek(kmem, (long)nl[X_HZ].n_value, 0) == -1) {
  182.         fprintf(stderr, "rstat: can't seek in kmem\n");
  183.         exit(1);
  184.     }
  185.     if (read(kmem, (char *)&hz, sizeof hz) != sizeof hz) {
  186.         fprintf(stderr, "rstat: can't read hz from kmem\n");
  187.         exit(1);
  188.     }
  189.     if (lseek(kmem, (long)nl[X_CPTIME].n_value, 0) == -1) {
  190.         fprintf(stderr, "rstat: can't seek in kmem\n");
  191.         exit(1);
  192.     }
  193.      if (read(kmem, (char *)stats_all.s1.cp_time, sizeof (stats_all.s1.cp_time))
  194.         != sizeof (stats_all.s1.cp_time)) {
  195.         fprintf(stderr, "rstat: can't read cp_time from kmem\n");
  196.         exit(1);
  197.     }
  198.     if (lseek(kmem, (long)nl[X_AVENRUN].n_value, 0) ==-1) {
  199.         fprintf(stderr, "rstat: can't seek in kmem\n");
  200.         exit(1);
  201.     }
  202. #ifdef vax
  203.      if (read(kmem, (char *)avrun, sizeof (avrun)) != sizeof (avrun)) {
  204.         fprintf(stderr, "rstat: can't read avenrun from kmem\n");
  205.         exit(1);
  206.     }
  207.     stats_all.s2.avenrun[0] = avrun[0] * FSCALE;
  208.     stats_all.s2.avenrun[1] = avrun[1] * FSCALE;
  209.     stats_all.s2.avenrun[2] = avrun[2] * FSCALE;
  210. #endif
  211.     if (lseek(kmem, (long)nl[X_BOOTTIME].n_value, 0) == -1) {
  212.         fprintf(stderr, "rstat: can't seek in kmem\n");
  213.         exit(1);
  214.     }
  215.      if (read(kmem, (char *)&btm, sizeof (stats_all.s2.boottime))
  216.         != sizeof (stats_all.s2.boottime)) {
  217.         fprintf(stderr, "rstat: can't read boottime from kmem\n");
  218.         exit(1);
  219.     }
  220.     stats_all.s2.boottime.tv_sec = btm.tv_sec;
  221.     stats_all.s2.boottime.tv_usec = btm.tv_usec;
  222.  
  223.  
  224. #ifdef DEBUG
  225.     fprintf(stderr, "%d %d %d %d\n", stats_all.s1.cp_time[0],
  226.         stats_all.s1.cp_time[1], stats_all.s1.cp_time[2], stats_all.s1.cp_time[3]);
  227. #endif
  228.  
  229.     if (lseek(kmem, (long)nl[X_SUM].n_value, 0) ==-1) {
  230.         fprintf(stderr, "rstat: can't seek in kmem\n");
  231.         exit(1);
  232.     }
  233.      if (read(kmem, (char *)&sum, sizeof sum) != sizeof sum) {
  234.         fprintf(stderr, "rstat: can't read sum from kmem\n");
  235.         exit(1);
  236.     }
  237.     stats_all.s1.v_pgpgin = sum.v_pgpgin;
  238.     stats_all.s1.v_pgpgout = sum.v_pgpgout;
  239.     stats_all.s1.v_pswpin = sum.v_pswpin;
  240.     stats_all.s1.v_pswpout = sum.v_pswpout;
  241.     stats_all.s1.v_intr = sum.v_intr;
  242.     gettimeofday(&tm, (struct timezone *) 0);
  243.     stats_all.s1.v_intr -= hz*(tm.tv_sec - btm.tv_sec) +
  244.         hz*(tm.tv_usec - btm.tv_usec)/1000000;
  245.     stats_all.s2.v_swtch = sum.v_swtch;
  246.  
  247.     if (lseek(kmem, (long)nl[X_DKXFER].n_value, 0) == -1) {
  248.         fprintf(stderr, "rstat: can't seek in kmem\n");
  249.         exit(1);
  250.     }
  251.      if (read(kmem, (char *)stats_all.s1.dk_xfer, sizeof (stats_all.s1.dk_xfer))
  252.         != sizeof (stats_all.s1.dk_xfer)) {
  253.         fprintf(stderr, "rstat: can't read dk_xfer from kmem\n");
  254.         exit(1);
  255.     }
  256.  
  257.     stats_all.s1.if_ipackets = 0;
  258.     stats_all.s1.if_opackets = 0;
  259.     stats_all.s1.if_ierrors = 0;
  260.     stats_all.s1.if_oerrors = 0;
  261.     stats_all.s1.if_collisions = 0;
  262.     for (off = firstifnet, i = 0; off && i < numintfs; i++) {
  263.         if (lseek(kmem, (long)off, 0) == -1) {
  264.             fprintf(stderr, "rstat: can't seek in kmem\n");
  265.             exit(1);
  266.         }
  267.         if (read(kmem, (char *)&ifnet, sizeof ifnet) != sizeof ifnet) {
  268.             fprintf(stderr, "rstat: can't read ifnet from kmem\n");
  269.             exit(1);
  270.         }
  271.         stats_all.s1.if_ipackets += ifnet.if_ipackets;
  272.         stats_all.s1.if_opackets += ifnet.if_opackets;
  273.         stats_all.s1.if_ierrors += ifnet.if_ierrors;
  274.         stats_all.s1.if_oerrors += ifnet.if_oerrors;
  275.         stats_all.s1.if_collisions += ifnet.if_collisions;
  276.         off = (int) ifnet.if_next;
  277.     }
  278.     gettimeofday((struct timeval *)&stats_all.s3.curtime,
  279.         (struct timezone *) 0);
  280.     alarm(1);
  281. }
  282.  
  283. static 
  284. setup()
  285. {
  286.     struct ifnet ifnet;
  287.     int off;
  288.  
  289.     nlist("/vmunix", nl);
  290.     if (nl[0].n_value == 0) {
  291.         fprintf(stderr, "rstat: Variables missing from namelist\n");
  292.         exit (1);
  293.     }
  294.     if ((kmem = open("/dev/kmem", 0)) < 0) {
  295.         fprintf(stderr, "rstat: can't open kmem\n");
  296.         exit(1);
  297.     }
  298.  
  299.     off = nl[X_IFNET].n_value;
  300.     if (lseek(kmem, (long)off, 0) == -1) {
  301.         fprintf(stderr, "rstat: can't seek in kmem\n");
  302.         exit(1);
  303.     }
  304.     if (read(kmem, (char *)&firstifnet, sizeof(int)) != sizeof (int)) {
  305.         fprintf(stderr, "rstat: can't read firstifnet from kmem\n");
  306.         exit(1);
  307.     }
  308.     numintfs = 0;
  309.     for (off = firstifnet; off;) {
  310.         if (lseek(kmem, (long)off, 0) == -1) {
  311.             fprintf(stderr, "rstat: can't seek in kmem\n");
  312.             exit(1);
  313.         }
  314.         if (read(kmem, (char *)&ifnet, sizeof ifnet) != sizeof ifnet) {
  315.             fprintf(stderr, "rstat: can't read ifnet from kmem\n");
  316.             exit(1);
  317.         }
  318.         numintfs++;
  319.         off = (int) ifnet.if_next;
  320.     }
  321. }
  322.  
  323. /*
  324.  * returns true if have a disk
  325.  */
  326. static
  327. havedisk()
  328. {
  329.     int i, cnt;
  330.     long  xfer[DK_NDRIVE];
  331.  
  332.     nlist("/vmunix", nl);
  333.     if (nl[X_DKXFER].n_value == 0) {
  334.         fprintf(stderr, "rstat: Variables missing from namelist\n");
  335.         exit (1);
  336.     }
  337.     if ((kmem = open("/dev/kmem", 0)) < 0) {
  338.         fprintf(stderr, "rstat: can't open kmem\n");
  339.         exit(1);
  340.     }
  341.     if (lseek(kmem, (long)nl[X_DKXFER].n_value, 0) == -1) {
  342.         fprintf(stderr, "rstat: can't seek in kmem\n");
  343.         exit(1);
  344.     }
  345.     if (read(kmem, (char *)xfer, sizeof xfer)!= sizeof xfer) {
  346.         fprintf(stderr, "rstat: can't read kmem\n");
  347.         exit(1);
  348.     }
  349.     cnt = 0;
  350.     for (i=0; i < DK_NDRIVE; i++)
  351.         cnt += xfer[i];
  352.     return (cnt != 0);
  353. }
  354.