[net.bugs.4bsd] rwho on suns finds zero load average

mark@cbosgd.UUCP (Mark Horton) (06/26/84)

The "ruptime" command, on any network with Sun workstations on it,
either does not show the Suns at all, or shows them with a zero
load average.

The system comes configured not to run rwhod, apparently because it
is a performance pig.  However, on a Sun with 2MB of RAM or more,
it seems not to degrade performance noticeably.  You must uncomment
out a line in /etc/rc to enable rwhod to run.

Once it runs, the load average is always claimed to be zero, even
though uptime shows it correctly.  The problem is that, since not
all Sun systems have floating point hardware, Sun apparently redid
the kernel code that keeps track of the load average to use fixed
point calculations.  The w command was updated to know about this,
but rwhod was not.

The new method has an array of three 4 byte integers, rather than
an array of three 8 byte doubles.  The integers are stored scaled
by 8 bits, that is, the integer value, divided by 256, is the
correct load average.

The following changes to a VAX 4.2BSD rwhod.c work correctly on a Sun
1.1 system and on a 1.0 system.  (For reasons I haven't figured out,
however, the 1.0 system does not see a 4.2BSD VAX on the same net.)

By the way, if there is a preferred way to report Sun bugs and fixes,
I'd be interested to hear about it.

	Mark Horton

*** orwhod.c	Tue Jun 26 13:46:53 1984
--- rwhod.c	Tue Jun 26 13:52:21 1984
***************
*** 226,232
  	struct stat stb;
  	register struct whoent *we = mywd.wd_we, *wlast;
  	int cc;
! 	double avenrun[3];
  	time_t now = time(0);
  	register struct neighbor *np;
  

--- 226,232 -----
  	struct stat stb;
  	register struct whoent *we = mywd.wd_we, *wlast;
  	int cc;
! 	long avenrun[3];
  	time_t now = time(0);
  	register struct neighbor *np;
  
***************
*** 270,276
  	(void) lseek(kmemf, (long)nl[NL_AVENRUN].n_value, L_SET);
  	(void) read(kmemf, (char *)avenrun, sizeof (avenrun));
  	for (i = 0; i < 3; i++)
! 		mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100));
  	cc = (char *)we - (char *)&mywd;
  	mywd.wd_sendtime = htonl(time(0));
  	mywd.wd_vers = WHODVERSION;

--- 270,276 -----
  	(void) lseek(kmemf, (long)nl[NL_AVENRUN].n_value, L_SET);
  	(void) read(kmemf, (char *)avenrun, sizeof (avenrun));
  	for (i = 0; i < 3; i++)
! 		mywd.wd_loadav[i] = htonl((u_long)(avenrun[i]*100+128)/256);
  	cc = (char *)we - (char *)&mywd;
  	mywd.wd_sendtime = htonl(time(0));
  	mywd.wd_vers = WHODVERSION;