Newsgroups: fj.net.programming,fj.unix,fj.lang.c
Path: galaxy.trc.rwcp.or.jp!coconuts.jaist!wnoc-tyo-news!aist-nara!ie.u-ryukyu.ac.jp!yas
From: yas@ocean.ie.u-ryukyu.ac.jp (Yasushi Shinjo)
Subject: Re: rstat()
In-Reply-To: yoshie@kki.esi.yamanashi.ac.jp's message of Thu, 22 Dec 1994 06:03:07 GMT
Message-ID: <YAS.94Dec29125638@top.ie.u-ryukyu.ac.jp>
Followup-To: fj.net.programming
Lines: 419
Sender: news@spn.ie.u-ryukyu.ac.jp (News System Admin)
Organization: Dept. of Elect. & Info. Eng., Univ. of the Ryukyus, Okinawa,
	Japan
References: <1994Dec22.060307.29248@kki.esi.yamanashi.ac.jp>
Date: Thu, 29 Dec 1994 03:56:38 GMT
Xref: galaxy.trc.rwcp.or.jp fj.net.programming:18 fj.unix:2105 fj.lang.c:1773
X-originally-archived-at: http://galaxy.rwcp.or.jp/text/cgi-bin/newsarticle2?ng=fj.unix&nb=2105&hd=a
X-reformat-date: Mon, 18 Oct 2004 15:18:22 +0900
X-reformat-comment: Tabs were expanded into 4 column tabstops by the Galaxy's archiver. See http://katsu.watanabe.name/ancientfj/galaxy-format.html for more info.

$B?7>k!w>pJs!%N05eBg3X$G$9!#$3$s$K$A$O!#(B

$B#C8@8l$NOC$H$$$&$h$j!"(BRPC $B$d(B UNIX $B$NOC$H$$$&$3$H$G!"(B
fj.net.programming, fj.unix $B$K?6$j$^$9!#(BFollowup-To:
fj.net.programming $B$G$9!#(B

In article <1994Dec22.060307.29248@kki.esi.yamanashi.ac.jp> 
yoshie@kki.esi.yamanashi.ac.jp (Yoshie Masaki) writes:
> $B$O$8$a$^$7$F!"5H9>!w;3M|Bg$G$9!#(B
> $B:#:n$C$F$$$k%W%m%0%i%`$K$*$$$F!"(BUNIX $B$N%j%b!<%H%+!<%M%k$NE}7W>pJs$rDs(B
> $B6!$9$k(B rstatd $B$H$$$&%G!<%b%s$KLd$$9g$o$;$h$&$H$7$F(B rstat() $B4X?t$r;HMQ(B
> $B$7$h$&$H$7$F$$$k$N$G$9$,!"(Brstat() $B$,M?$($k%j%b!<%H%[%9%H$KBP$9$k>pJs$N(B
> $BCf?H$N>\$7$$$3$H$,J,$+$j$^$;$s!#(B

$B3N$+$K!"%^%K%e%"%k8+$F$b$o$+$j$^$;$s$M!#$7$+$79,$$$J$3$H$K!"(B
rstat() $B$N(B RPC$B$N%5!<%PB&$N%W%m%0%i%`$N%=!<%9!&%3!<%I$,!"(B
SunRPC $B$N0lIt$H$7$F8x3+$5$l$F$$$^$9!#$=$l$+$iN`?d$9$k$3$H$O(B
$B$G$-$^$9!#(B

>   struct statstime {
>   int cp_time[4];
...
>   long avenrun[3];
..
> $B$G!"$3$NCf$G(B cp_time[]$B!"(Bavenrun[] $B$NCM$r;HMQ$7$?$$$N$G$9$,!"G[Ns$N(B1$BHV(B
> $BL\!"(B2$BHVL\!"(B3$BHVL\!"(B4$BHVL\$N3FFbMF$,2?$J$N$+J,$+$j$^$;$s!#(Bcp_time[] $B$,(BCPU
> $B;~4V!"(B 

cp_time[] $B$O!"%+!<%M%kCf$N(B cp_time[] $B$H$$$&G[Ns$r$=$N$^$^FI(B
$B$_=P$7$F$$$k$h$&$G$9!#(BBSD $B$@$H!!(Bkern_clock.c$B!!$NCf$K$"$C$F!"(B
$B%?%$%^3d9~$_$N$J$+$G!"3d9~$_A0$N>uBV$NCf$G$I$l$+$,(B ++ $B$5$l$F(B
$B$$$k$h$&$G$9!#(B0, 1, 2, 3 $B$NE:$(;z$O!"(B<sys/dk.h>$B$KF~$C$F$$$^(B
$B$9!#$3$l$O!"(B<rpcsvc/rstat.h> $B$+$i(B include $B$5$l$F$$$^$9!#(B
------------------------------------------------------------
struct statstime *s ;
printf("cp_time: CP_USER=%d, CP_NICE=%d, CP_SYS=%d, CP_IDLE=%d \n",
        s->cp_time[CP_USER],s->cp_time[CP_NICE],
        s->cp_time[CP_SYS], s->cp_time[CP_IDLE] );
------------------------------------------------------------
$B$*$=$i$/!"(Biostat $B$G(B us ni sy id $B$NI=<($O!"$3$l$+$i7W;;$7$F=P(B
$B$7$F$$$k$N$@$H;W$$$^$9!#(B
$B!J(Bdk.h $B$J$s$+$K(B CP_* $B$,F~$C$F$$$k$N$O!"(BI/O $B$,=E$/$J$k$H(B sy 
$B$,A}$($k$H$$$&$3$H$+$J!#!K(B

> avenrun[] $B$,<B9TBT$A%-%e!<$K$"$kJ?6Q$N%W%m%;%9?t(B $B$rI=$7$F$$$k$h(B
> $B$&$G$9!#(B

$B$O$$!#$3$l$O!"(Buptime (rup) $B$GI=<($5$l$kIi2Y$,8GDj>.?tE@$GF~$C(B
$B$F$$$^$9!#<!$N$h$&$K$9$k$H!"(Brup $B%3%^%s%I$HF1$8$h$&$JI=<($K$J(B
$B$j$^$9!#(B
------------------------------------------------------------
printf("load average: %4.2f, %4.2f, %4.2f\n",
(double)s->avenrun[0]/256.0,
(double)s->avenrun[1]/256.0,
(double)s->avenrun[2]/256.0 );
------------------------------------------------------------
$B$=$l$>$l!"(B1, 5, 15 $BJ,4V$N!"BT$A9TNs$ND9$5$NJ?6Q$G$9!#(B

NetBSD $B$G$O!"(Bevenrun $B$H$$$&JQ?t$,$J$/$J$C$?$s$G$9$M!#(B

$B!@!@!!?7>k!!Lw!!!J$7$s$8$g$&!!$d$9$7!K!!!@!@(B
$B!@!@!!N05eBg3X!!>pJs9)3X!!!!!!!!!!!!!!!!!@!@(B

$BIUO?(B
SunRPC $B$N%=!<%9$N(B rpcsvc/rstat_proc.c $B$h$j(B:
----------------------------------------------------------------------
/* @(#)rstat_proc.c1.2 87/11/24 3.9 RPCSRC */
#ifndef lint
static  char sccsid[] = "@(#)rpc.rstatd.c 1.1 86/09/25 Copyr 1984 Sun Micro";
#endif

/*
 * Copyright (c) 1984 by Sun Microsystems, Inc.
 */

/*
 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
 * unrestricted use provided that this legend is included on all tape
 * media and as a part of the software program in whole or part.  Users
 * may copy or modify Sun RPC without charge, but are not authorized
 * to license or distribute it to anyone else except as part of a product or
 * program developed by the user.
 *
 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
 *
 * Sun RPC is provided with no support and without any obligation on the
 * part of Sun Microsystems, Inc. to assist in its use, correction,
 * modification or enhancement.
 *
 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
 * OR ANY PART THEREOF.
 *
 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
 * or profits or other special, indirect and consequential damages, even if
 * Sun has been advised of the possibility of such damages.
 *
 * Sun Microsystems, Inc.
 * 2550 Garcia Avenue
 * Mountain View, California  94043
 */

/*
 * rstat service:  built with rstat.x and derived from rpc.rstatd.c
 */

#include <signal.h>
#include <stdio.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <nlist.h>
#include <sys/dk.h>
#include <sys/errno.h>
#include <sys/vmmeter.h>
#include <net/if.h>
#include <sys/time.h>
#include "rstat.h"

struct nlist nl[] = {
#defineX_CPTIME0
{ "_cp_time" },
#defineX_SUM1
{ "_sum" },
#defineX_IFNET2
{ "_ifnet" },
#defineX_DKXFER3
{ "_dk_xfer" },
#defineX_BOOTTIME4
{ "_boottime" },
#defineX_AVENRUN5
{ "_avenrun" },
#define X_HZ6
{ "_hz" },
"",
};
int kmem;
int firstifnet, numintfs;/* chain of ethernet interfaces */
int stats_service();

/*
 *  Define EXIT_WHEN_IDLE if you are able to have this program invoked
 *  automatically on demand (as from inetd).  When defined, the service
 *  will terminated after being idle for 20 seconds.
 */
int sincelastreq = 0;/* number of alarms since last request */
#ifdef EXIT_WHEN_IDLE
#define CLOSEDOWN 20/* how long to wait before exiting */
#endif /* def EXIT_WHEN_IDLE */

union {
    struct stats s1;
    struct statsswtch s2;
    struct statstime s3;
} stats_all;

int updatestat();
static stat_is_init = 0;
extern int errno;

#ifndef FSCALE
#define FSCALE (1 << 8)
#endif

stat_init()
{
    stat_is_init = 1;
setup();
updatestat();
alarm(1);
signal(SIGALRM, updatestat);
    sleep(1);               /* allow for one wake-up */
}

statstime *
rstatproc_stats_3()
{
    if (! stat_is_init)
        stat_init();
    sincelastreq = 0;
    return(&stats_all.s3);
}

statsswtch *
rstatproc_stats_2()
{
    if (! stat_is_init)
        stat_init();
    sincelastreq = 0;
    return(&stats_all.s2);
}

stats *
rstatproc_stats_1()
{
    if (! stat_is_init)
        stat_init();
    sincelastreq = 0;
    return(&stats_all.s1);
}

u_int *
rstatproc_havedisk_3()
{
    static u_int have;

    if (! stat_is_init)
        stat_init();
    sincelastreq = 0;
    have = havedisk();
return(&have);
}

u_int *
rstatproc_havedisk_2()
{
    return(rstatproc_havedisk_3());
}

u_int *
rstatproc_havedisk_1()
{
    return(rstatproc_havedisk_3());
}

updatestat()
{
int off, i, hz;
struct vmmeter sum;
struct ifnet ifnet;
double avrun[3];
struct timeval tm, btm;

#ifdef DEBUG
fprintf(stderr, "entering updatestat\n");
#endif
#ifdef EXIT_WHEN_IDLE
if (sincelastreq >= CLOSEDOWN) {
#ifdef DEBUG
fprintf(stderr, "about to closedown\n");
#endif
exit(0);
}
sincelastreq++;
#endif /* def EXIT_WHEN_IDLE */
if (lseek(kmem, (long)nl[X_HZ].n_value, 0) == -1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
if (read(kmem, (char *)&hz, sizeof hz) != sizeof hz) {
fprintf(stderr, "rstat: can't read hz from kmem\n");
exit(1);
}
if (lseek(kmem, (long)nl[X_CPTIME].n_value, 0) == -1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
 if (read(kmem, (char *)stats_all.s1.cp_time, sizeof (stats_all.s1.cp_time))
    != sizeof (stats_all.s1.cp_time)) {
fprintf(stderr, "rstat: can't read cp_time from kmem\n");
exit(1);
}
if (lseek(kmem, (long)nl[X_AVENRUN].n_value, 0) ==-1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
#ifdef vax
 if (read(kmem, (char *)avrun, sizeof (avrun)) != sizeof (avrun)) {
fprintf(stderr, "rstat: can't read avenrun from kmem\n");
exit(1);
}
stats_all.s2.avenrun[0] = avrun[0] * FSCALE;
stats_all.s2.avenrun[1] = avrun[1] * FSCALE;
stats_all.s2.avenrun[2] = avrun[2] * FSCALE;
#endif
if (lseek(kmem, (long)nl[X_BOOTTIME].n_value, 0) == -1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
 if (read(kmem, (char *)&btm, sizeof (stats_all.s2.boottime))
    != sizeof (stats_all.s2.boottime)) {
fprintf(stderr, "rstat: can't read boottime from kmem\n");
exit(1);
}
stats_all.s2.boottime.tv_sec = btm.tv_sec;
stats_all.s2.boottime.tv_usec = btm.tv_usec;


#ifdef DEBUG
fprintf(stderr, "%d %d %d %d\n", stats_all.s1.cp_time[0],
    stats_all.s1.cp_time[1], stats_all.s1.cp_time[2], stats_all.s1.cp_time[3]);
#endif

if (lseek(kmem, (long)nl[X_SUM].n_value, 0) ==-1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
 if (read(kmem, (char *)&sum, sizeof sum) != sizeof sum) {
fprintf(stderr, "rstat: can't read sum from kmem\n");
exit(1);
}
stats_all.s1.v_pgpgin = sum.v_pgpgin;
stats_all.s1.v_pgpgout = sum.v_pgpgout;
stats_all.s1.v_pswpin = sum.v_pswpin;
stats_all.s1.v_pswpout = sum.v_pswpout;
stats_all.s1.v_intr = sum.v_intr;
gettimeofday(&tm, (struct timezone *) 0);
stats_all.s1.v_intr -= hz*(tm.tv_sec - btm.tv_sec) +
    hz*(tm.tv_usec - btm.tv_usec)/1000000;
stats_all.s2.v_swtch = sum.v_swtch;

if (lseek(kmem, (long)nl[X_DKXFER].n_value, 0) == -1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
 if (read(kmem, (char *)stats_all.s1.dk_xfer, sizeof (stats_all.s1.dk_xfer))
    != sizeof (stats_all.s1.dk_xfer)) {
fprintf(stderr, "rstat: can't read dk_xfer from kmem\n");
exit(1);
}

stats_all.s1.if_ipackets = 0;
stats_all.s1.if_opackets = 0;
stats_all.s1.if_ierrors = 0;
stats_all.s1.if_oerrors = 0;
stats_all.s1.if_collisions = 0;
for (off = firstifnet, i = 0; off && i < numintfs; i++) {
if (lseek(kmem, (long)off, 0) == -1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
if (read(kmem, (char *)&ifnet, sizeof ifnet) != sizeof ifnet) {
fprintf(stderr, "rstat: can't read ifnet from kmem\n");
exit(1);
}
stats_all.s1.if_ipackets += ifnet.if_ipackets;
stats_all.s1.if_opackets += ifnet.if_opackets;
stats_all.s1.if_ierrors += ifnet.if_ierrors;
stats_all.s1.if_oerrors += ifnet.if_oerrors;
stats_all.s1.if_collisions += ifnet.if_collisions;
off = (int) ifnet.if_next;
}
gettimeofday((struct timeval *)&stats_all.s3.curtime,
(struct timezone *) 0);
alarm(1);
}

static 
setup()
{
struct ifnet ifnet;
int off;

nlist("/vmunix", nl);
if (nl[0].n_value == 0) {
fprintf(stderr, "rstat: Variables missing from namelist\n");
exit (1);
}
if ((kmem = open("/dev/kmem", 0)) < 0) {
fprintf(stderr, "rstat: can't open kmem\n");
exit(1);
}

off = nl[X_IFNET].n_value;
if (lseek(kmem, (long)off, 0) == -1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
if (read(kmem, (char *)&firstifnet, sizeof(int)) != sizeof (int)) {
fprintf(stderr, "rstat: can't read firstifnet from kmem\n");
exit(1);
}
numintfs = 0;
for (off = firstifnet; off;) {
if (lseek(kmem, (long)off, 0) == -1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
if (read(kmem, (char *)&ifnet, sizeof ifnet) != sizeof ifnet) {
fprintf(stderr, "rstat: can't read ifnet from kmem\n");
exit(1);
}
numintfs++;
off = (int) ifnet.if_next;
}
}

/*
 * returns true if have a disk
 */
static
havedisk()
{
int i, cnt;
long  xfer[DK_NDRIVE];

nlist("/vmunix", nl);
if (nl[X_DKXFER].n_value == 0) {
fprintf(stderr, "rstat: Variables missing from namelist\n");
exit (1);
}
if ((kmem = open("/dev/kmem", 0)) < 0) {
fprintf(stderr, "rstat: can't open kmem\n");
exit(1);
}
if (lseek(kmem, (long)nl[X_DKXFER].n_value, 0) == -1) {
fprintf(stderr, "rstat: can't seek in kmem\n");
exit(1);
}
if (read(kmem, (char *)xfer, sizeof xfer)!= sizeof xfer) {
fprintf(stderr, "rstat: can't read kmem\n");
exit(1);
}
cnt = 0;
for (i=0; i < DK_NDRIVE; i++)
cnt += xfer[i];
return (cnt != 0);
}
