1
0
Files
irix-657m-src/eoe/cmd/gr_osview/getinfo.c
2022-09-29 17:59:04 +03:00

562 lines
12 KiB
C

/**************************************************************************
* *
* Copyright (C) 1989, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
# include "grosview.h"
# include <sys/sysinfo.h>
# include <sys/sysmp.h>
# include <sys/swap.h>
# include <sys/times.h>
# include <sys/ioctl.h>
# include <sys/sbd.h>
# include <sys/buf.h>
# include <sys/var.h>
# include <sys/socket.h>
# include <sys/stat.h>
# include <sys/sysmips.h>
# include <sys/fs/efs_fs.h>
# include <sys/tcpipstats.h>
# include <netinet/in_systm.h>
# include <netinet/in.h>
# include <netinet/ip.h>
# include <netinet/ip_var.h>
# include <netinet/tcp.h>
# include <netinet/tcp_timer.h>
# include <netinet/tcp_var.h>
# include <netinet/udp.h>
# include <netinet/udp_var.h>
# include <net/if.h>
# include <time.h>
# include <string.h>
# include <malloc.h>
# include <fcntl.h>
# include <mntent.h>
# include <unistd.h>
static struct sysinfo *splbuf[MAXCPU];
static struct sysinfo *spnbuf[MAXCPU];
static struct sysinfo *Sinbuf[2];
static int sinfosz;
static struct minfo *mplbuf;
static struct minfo *mpnbuf;
static int minfosz;
static struct kna *knainbuf[2];
static int cpuvalid[MAXCPU];
static int ifsock;
static int rminfosz;
struct sysinfo *lsp[MAXCPU];
struct sysinfo *nsp[MAXCPU];
struct minfo *lmp;
struct minfo *nmp;
struct sysinfo *lSp;
struct sysinfo *nSp;
struct gfxinfo *lGp;
struct gfxinfo *nGp;
struct ipstat *nipstat;
struct ipstat *lipstat;
struct udpstat *ludpstat;
struct udpstat *nudpstat;
struct tcpstat *ntcpstat;
struct tcpstat *ltcpstat;
struct ifreq *nifreq = 0;
struct ifreq *lifreq;
struct rminfo *lrm;
struct rminfo *nrm;
off_t fswap; /* current free swap in blocks */
off_t mswap; /* current max growable swap */
off_t tswap; /* current physical swap */
off_t vswap; /* current virtual swap */
off_t rlswap; /* current reserved logical swap */
off_t llswap; /* last max logical swap */
off_t nlswap; /* new max logical swap */
int nif;
int nifsize;
long lticks;
long nticks;
long ticks;
int ncpu = 1;
int nacpu = 1;
long nscpus = 1;
long nmcpus = 1;
long physmem;
buf_t* bufaddr;
struct var* var;
static void getgfxinfo(void);
void
initinfo(void)
{
register int err = 0;
register ptrdiff_t i;
ncpu = sysmp(MP_NPROCS);
nacpu = sysmp(MP_NAPROCS);
stg_open();
if ((i = sysmp(MP_KERNADDR, MPKA_PHYSMEM)) == -1) {
fprintf(stderr, "can't get address of physmem");
err++;
} else
stg_vread(i, &physmem, sizeof(physmem));
if ((i = sysmp(MP_KERNADDR, MPKA_BUF)) == -1) {
fprintf(stderr, "can't get address of buf[0]");
err++;
}
bufaddr = (buf_t *)i;
if ((i = sysmp(MP_KERNADDR, MPKA_VAR)) == -1) {
fprintf(stderr, "can't get address of struct var ``v''");
err++;
}
var = (struct var *)i;
if (err)
exit(1);
}
void
setinfo(void)
{
register int ssize;
int i;
int j;
if ((sinfosz = ssize = sysmp(MP_SASZ, MPSA_SINFO)) < 0) {
fprintf(stderr, "sysinfo scall interface not supported\n");
exit(1);
}
nscpus = sysmp(MP_NPROCS);
for (i = 0; i < nscpus; i++) {
splbuf[i] = (struct sysinfo *) calloc(1, ssize);
lsp[i] = splbuf[i];
spnbuf[i] = (struct sysinfo *) calloc(1, ssize);
nsp[i] = spnbuf[i];
}
Sinbuf[0] = (struct sysinfo *) calloc(1, ssize);
Sinbuf[1] = (struct sysinfo *) calloc(1, ssize);
lSp = Sinbuf[0];
nSp = Sinbuf[1];
lGp = (struct gfxinfo *)calloc(nacpu, sizeof(struct gfxinfo));
nGp = (struct gfxinfo *)calloc(nacpu, sizeof(struct gfxinfo));
/*
* If we do a per-cpu readout, then we might encounter an
* empty slot for CPUs. Compress this into the given numer.
*/
for (i = 0, j = 0; j < MAXCPU && i < nscpus; j++) {
if (sysmp(MP_SAGET1, MPSA_SINFO, (char *) splbuf[i],
sinfosz, j) == -1)
cpuvalid[j] = 0;
else {
cpuvalid[j] = 1;
i++;
}
}
minfosz = ssize = sysmp(MP_SASZ, MPSA_MINFO);
mplbuf = (struct minfo *) calloc(1, ssize);
lmp = mplbuf;
mpnbuf = (struct minfo *) calloc(1, ssize);
nmp = mpnbuf;
/* init rminfo buffers */
rminfosz = ssize = sysmp(MP_SASZ, MPSA_RMINFO);
lrm = calloc(1, ssize);
nrm = calloc(1, ssize);
knainbuf[0] = (struct kna *) calloc(1, sizeof(struct kna));
knainbuf[1] = (struct kna *) calloc(1, sizeof(struct kna));
lipstat = &(knainbuf[0]->ipstat);
nipstat = &(knainbuf[1]->ipstat);
ludpstat = &(knainbuf[0]->udpstat);
nudpstat = &(knainbuf[1]->udpstat);
ltcpstat = &(knainbuf[0]->tcpstat);
ntcpstat = &(knainbuf[1]->tcpstat);
if (gi_if)
netifinfo((char *) 0);
nticks = 0;
lticks = 0;
getinfo();
}
int
netifinfo(char *s)
{
int i;
struct ifreq *ift;
if (nifreq == 0) {
char ipbuf[MAXIP];
struct ifconf ifc;
struct ifreq *ifr;
struct ifreq *ifr2;
if ((ifsock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr,
"%s: networking not enabled\n",
pname);
return(-1);
}
ifc.ifc_len = sizeof(ipbuf);
ifc.ifc_buf = ipbuf;
if (ioctl(ifsock, SIOCGIFCONF, &ifc) == -1) {
fprintf(stderr,
"%s: unable to monitor network interfaces\n",
pname);
close(ifsock);
return(-1);
}
nifsize = ifc.ifc_len;
nif = nifsize / sizeof(struct ifreq);
if (nif == 0) {
fprintf(stderr,
"%s: no network interfaces present\n",
pname);
close(ifsock);
return(-1);
}
nifreq = (struct ifreq *) calloc(1, nifsize);
ifr = (struct ifreq *)ipbuf;
ifr2 = nifreq;
for (i = 0; i < nif; i++, ifr++) {
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
memcpy(ifr2++, ifr, sizeof(*ifr));
}
nifsize = (char*)ifr2 - (char*)nifreq;
nif = nifsize / sizeof *ifr;
if (nif == 0) {
fprintf(stderr,
"%s: no network interfaces present\n",
pname);
close(ifsock);
free(nifreq);
nifreq = 0;
return(-1);
}
lifreq = (struct ifreq *) calloc(1, nifsize);
}
if (s != 0) {
i = 0;
for (ift = nifreq, i = 0; i < nif; i++, ift++) {
if (eq(ift->ifr_name, s)) {
if (ioctl(ifsock,SIOCGIFSTATS,ift)==-1) {
fprintf(stderr,
"%s: no IP status in this kernel\n",
pname);
return(-1);
}
return(i);
}
}
fprintf(stderr, "%s: no network interface \"%s\" found\n",
pname, s);
return(-1);
}
else {
if (nif > 0) {
ift = nifreq;
for (i = 0; i < nif; i++, ift++)
ioctl(ifsock, SIOCGIFSTATS, ift);
memcpy((char *) lifreq, (char *) nifreq, nifsize);
}
return(0);
}
}
int
diskinfo(char *s)
{
struct stat sbuf;
int rstat;
if (s == 0) {
int i;
for (i = 0; i < ndisknames; i++) {
if (dstat[i].d_sname) free(dstat[i].d_sname);
if (dstat[i].d_name) free(dstat[i].d_name);
}
ndisknames = 0;
return(0);
}
if (debug)
fprintf(stderr, "diskinfo: finding \"%s\"\n", s);
if (ndisknames == MAXDISK) {
fprintf(stderr, "%s: too many disks to monitor\n",
pname);
return(-1);
}
rstat = ndisknames;
dstat[rstat].d_flags = 0;
/*
* Verify that this actually indicates a valid
* filesystem to monitor.
*/
if (stat(s, &sbuf) == -1) {
fprintf(stderr, "%s: unknown filesystem\n", pname);
return(-1);
}
if ((sbuf.st_mode & S_IFMT) == S_IFREG ||
(sbuf.st_mode & S_IFMT) == S_IFDIR) {
FILE *md;
if ((md = setmntent(MNTTAB, "r")) != NULL) {
struct mntent *mp;
char *fsname;
char *fstyp;
int len;
int match;
match = 0;
fsname = 0;
while ((mp = getmntent(md)) != NULL) {
len = strlen(mp->mnt_dir);
if (strncmp(mp->mnt_dir,s,len)==0) {
if (len > match) {
if (fsname != 0) {
free(fsname);
free(fstyp);
}
fsname = strdup(mp->mnt_fsname);
fstyp = strdup(mp->mnt_type);
}
match = len;
}
}
endmntent(md);
if (strcmp(fstyp, FSID_EFS) == 0)
dstat[rstat].d_flags |= DF_EFS;
else if (strcmp(fstyp, FSID_NFS) == 0)
dstat[rstat].d_flags |= DF_NFS;
else if (strcmp(fstyp, FSID_XFS) == 0)
dstat[rstat].d_flags |= DF_XFS;
free(fstyp);
free(fsname);
}
dstat[rstat].d_sname = strdup(s);
/*
* Regular file or directory. Mounted somewhere.
*/
if (statfs(dstat[rstat].d_sname, &dstat[rstat].d_stat,
sizeof(struct statfs), 0) == -1) {
fprintf(stderr, "%s: unknown filesystem \"%s\"\n",
pname, dstat[rstat].d_sname);
return(-1);
}
}
else if ((sbuf.st_mode & S_IFMT) == S_IFBLK) {
int fdes;
int fstyp_efs;
int fstyp_xfs;
/*
* Block special. Has to be an EFS or XFS filesystem.
*/
if ((fdes = open(s, O_RDONLY)) == -1) {
fprintf(stderr, "%s: no permission\n", pname);
return(-1);
}
fstyp_efs = sysfs(GETFSIND, FSID_EFS);
fstyp_xfs = sysfs(GETFSIND, FSID_XFS);
if (fstatfs(fdes, &dstat[rstat].d_stat, sizeof(struct statfs),
fstyp_efs) != -1) {
dstat[rstat].d_flags |= DF_EFS;
dstat[rstat].d_fstyp = fstyp_efs;
}
else if (fstatfs(fdes, &dstat[rstat].d_stat,
sizeof(struct statfs), fstyp_xfs) != -1) {
dstat[rstat].d_flags |= DF_XFS;
dstat[rstat].d_fstyp = fstyp_xfs;
}
else {
fprintf(stderr, "%s: unknown filesystem\n", pname);
return(-1);
}
dstat[rstat].d_flags |= DF_FSSTAT;
dstat[rstat].d_fdes = fdes;
}
else {
fprintf(stderr, "%s: can't find disk \"%s\"\n", pname, s);
return(-1);
}
ndisknames++;
return(rstat);
}
void
getinfo_text_start(void) {} /* begin locked text */
void
getinfo(void)
{
register struct sysinfo *tsp;
register struct gfxinfo *tgp;
register struct minfo *tmp;
register struct rminfo *trm;
register int i;
register int j;
struct tms tbuf;
struct ipstat *tip;
struct udpstat *tudp;
struct tcpstat *ttcp;
lticks = nticks;
nticks = times(&tbuf);
ticks = nticks - lticks;
for (i = 0, j = 0; j < MAXCPU && i < nscpus; j++) {
if (!cpuvalid[j])
continue;
tsp = lsp[i];
lsp[i] = nsp[i];
nsp[i] = tsp;
# ifdef MP_SAGET1
if (nscpus == 1) {
# endif
sysmp(MP_SAGET, MPSA_SINFO, (char *) tsp, sinfosz);
# ifdef FIXGFX
tsp->cpu[CPU_WAIT] -=
(tsp->wait[W_GFXF] + tsp->wait[W_GFXC]);
# endif
}
# ifdef MP_SAGET1
else {
sysmp(MP_SAGET1, MPSA_SINFO, (char *) tsp, sinfosz, j);
# ifdef FIXGFX
tsp->cpu[CPU_WAIT] -=
(tsp->wait[W_GFXF] + tsp->wait[W_GFXC]);
# endif
}
# endif
i++;
}
if (nscpus > 1) {
tsp = lSp;
lSp = nSp;
nSp = tsp;
sysmp(MP_SAGET, MPSA_SINFO, (char *) tsp, sinfosz);
# ifdef FIXGFX
tsp->cpu[CPU_WAIT] -= tsp->wait[W_GFXF] + tsp->wait[W_GFXC];
# endif
}
else {
*lSp = *lsp[0];
*nSp = *nsp[0];
}
/* get minfo stats */
tmp = lmp;
lmp = nmp;
nmp = tmp;
sysmp(MP_SAGET, MPSA_MINFO, (char *) tmp, minfosz);
/* get rminfo stats */
trm = lrm;
lrm = nrm;
nrm = trm;
sysmp(MP_SAGET, MPSA_RMINFO, (char *) trm, rminfosz);
/* get gfxinfo */
tgp = lGp;
lGp = nGp;
nGp = tgp;
getgfxinfo();
if (gi_ip || gi_udp || gi_tcp) {
/*
* Get the tcp/ip statistics for all cpu's in one call
*/
(void) sysmp(MP_SAGET, MPSA_TCPIPSTATS,
(struct kna *)nipstat, sizeof(struct kna));
/*
* We get one set of stats from the kernel for all the
* tcp/ip protocols. We then for all sets swap the two
* pointers to correspond to the latest and oldest values.
*/
tip = lipstat;
lipstat = nipstat;
nipstat = tip;
tudp = ludpstat;
ludpstat = nudpstat;
nudpstat = tudp;
ttcp = ltcpstat;
ltcpstat = ntcpstat;
ntcpstat = ttcp;
}
if (gi_if)
netifinfo((char *) 0);
if (gi_swap) {
llswap = nlswap;
swapctl(SC_GETFREESWAP, &fswap);
swapctl(SC_GETSWAPMAX, &mswap);
swapctl(SC_GETSWAPVIRT, &vswap);
swapctl(SC_GETSWAPTOT, &tswap);
swapctl(SC_GETLSWAPTOT, &nlswap);
swapctl(SC_GETRESVSWAP, &rlswap);
}
/* get disk info */
for (i = 0; i < ndisknames; i++) {
if (dstat[i].d_flags & DF_FSSTAT)
fstatfs(dstat[i].d_fdes, &dstat[i].d_stat,
sizeof(struct statfs),
dstat[i].d_fstyp);
else
statfs(dstat[i].d_sname, &dstat[i].d_stat,
sizeof(struct statfs), 0);
}
}
static void
getgfxinfo(void)
{
extern int isgfx(void);
static off64_t gfxinfo_ptr = 0;
if (isgfx()) {
if (gfxinfo_ptr == 0)
stg_sptr_read("gfxinfo", &gfxinfo_ptr);
stg_vread(gfxinfo_ptr, nGp, sizeof(struct gfxinfo)*nacpu);
}
}
void
getinfo_text_end(void) {} /* end of locked text */