now using kstat for Solaris, which works on Solaris 2.x as well as 8.

This commit is contained in:
lindes 2001-08-24 21:00:01 +00:00
parent 59d20accb3
commit 9ef120571b
2 changed files with 60 additions and 29 deletions

4
README
View File

@ -65,9 +65,7 @@ ttyload has been shown to run on systems running, at least:
- IRIX 6.5 (and possibly other versions?)
- FreeBSD (some version or other, I'm not familiar with their
numbering system... 4.4, I think.)
- Solaris 8 (I haven't tested this recently, as I don't have
access to a Solaris 8 machine, but I saw it work in the past,
and I'm told it still does)
- Solaris 2.x and later (at least 2.6 and 8)
Feel free, if you like, to submit patches to add more platforms
(or other versions of existing platforms), and please let me

View File

@ -2,40 +2,73 @@
#include <stdio.h> /* for perror */
#include <stdlib.h> /* for exit() */
#include <unistd.h> /* for sleep() */
#include <sys/loadavg.h> /* for getloadavg() */
#include <kstat.h> /* for the various kstat stuff */
void getload(load_list *loadavgs)
{
double theload[3];
int ret;
static kstat_ctl_t *kc; /* kstat control */
static kstat_t *ksrec; /* the kstat record */
kstat_named_t *info; /* our pointer to the info */
if((ret = getloadavg(theload, 3)) < 0)
if(!kc) /* initialize, first time only */
{
perror("getloadavg() failed");
if(!(kc = kstat_open()))
{
perror("kstat_open failed");
exit(1);
}
/* find the record where the load averages are stored
* (It seems like it's safe to only do this once) */
if(!(ksrec = kstat_lookup(kc, "unix", 0, "system_misc")))
{
perror("ksatat_lookup failed");
exit(1);
}
}
/* read in the latest data into the buffer space that ksrec
* keeps for us. */
if(kstat_read(kc, ksrec, NULL) == -1)
{
perror("kstat_read failed");
exit(1);
}
/* so the caller _can_ (maybe not _will_) know how we did */
loadavgs->numloads = ret;
loadavgs->one_minute = theload[0] * 1024;
loadavgs->five_minute = theload[1] * 1024;
loadavgs->fifteen_minute = theload[2] * 1024;
switch(ret)
/* need a pointer with a type we can dig into: */
for(info = (kstat_named_t*)ksrec->ks_data, loadavgs->numloads = 0;
(char*)info < ((char*)ksrec->ks_data + ksrec->ks_data_size); info++)
{
case 2:
fprintf(stderr, "15 minute Load average is unreliable.\n");
sleep(5);
break;
case 1:
fprintf(stderr, "5 and 15 minute load averages are unreliable.\n");
sleep(5);
break;
case 0:
fprintf(stderr, "Sorry, couldn't get any load "
"averages. This is, therefore, pointless.\n");
exit(1);
/* DEBUG: printf("info->name = %s\n", info->name); */
/* in theory, the loop will take us through all three of
* these, in order... I depend on that being true: */
if(strcmp(info->name, "avenrun_1min") == 0)
{
/* Note: Sun stores this data as the float value *
* 256; we use 1024 as the multiplier, so multiply
* by 4 to make up the difference: */
loadavgs->one_minute = info->value.ul * 4;
loadavgs->numloads++;
}
else if(strcmp(info->name, "avenrun_5min") == 0)
{
loadavgs->five_minute = info->value.ul * 4;
loadavgs->numloads++;
}
else if(strcmp(info->name, "avenrun_15min") == 0)
{
loadavgs->fifteen_minute = info->value.ul * 4;
loadavgs->numloads++;
}
}
/* hopefully, this never happens: */
if(loadavgs->numloads != 3)
{
fprintf(stderr, "Woah, kstat walking didn't get us the "
"number of load average data points we were expecting; "
"got %d instead of 3.\n", loadavgs->numloads);
exit(1);
}
}