henesyinit from lsubb0c8bdb6 years agoHistory
720 lines · 13.1 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <thread.h>#include <ctype.h>#include <auth.h>#include <fcall.h>#include <omero.h>#include <error.h>#include <b.h> typedef struct Plot	Plot;typedef struct Machine	Machine; enum {	Mbattery,	Mcontext,	Mether,	Methererr,	Metherin,	Metherout,	Mfault,	Midle,	Minintr,	Mintr,	Mload,	Mmem,	Mswap,	Msyscall,	Mtlbmiss,	Mtlbpurge,	Msignal,	Mend,}; enum{	/* /dev/swap */	Mem		= 0,	Maxmem,	Swap,	Maxswap,	/* /dev/sysstats */	Procno	= 0,	Context,	Interrupt,	Syscall,	Fault,	TLBfault,	TLBpurge,	Load,	Idle,	InIntr,	/* /net/ether0/stats */	In		= 0,	Link,	Out,	Err0, 	MAXNUM	= 10,	Dot		= 2,	/* height of dot */}; struct Plot{	int		*data;	int		ndata;	char		*label;	int		overflow;	void		(*newvalue)(Machine*, ulong*, ulong*, int);	Panel*		graph;};  struct Machine{	char		*name;	int		remote;	int		statsfd;	int		swapfd;	int		etherfd;	int		ifstatsfd;	int		batteryfd;	int		bitsybatfd;	int		disable; 	ulong		devswap[4];	ulong		devsysstat[10];	ulong		prevsysstat[10];	int		nproc;	ulong		netetherstats[8];	ulong		prevetherstats[8];	ulong		batterystats[2];	ulong		netetherifstats[2]; 	char		buf[1024];	char		*bufp;	char		*ebufp;}; char	*mname[Mend+1] = {	"battery",	"context",	"ether",	"ethererr",	"etherin",	"etherout",	"fault",	"idle",	"inintr",	"intr",	"load",	"mem",	"swap",	"syscall",	"tlbmiss",	"tlbpurge",	"802.11b",	nil,}; int	present[Mend];Plot	*plot[20];int	nplot;int	sleeptime;char*	machine;Panel*	grow;Machine	*m;int vsize = 40;int hsize = 100;  voidmemval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->devswap[Mem];	*vmax = m->devswap[Maxmem];} voidswapval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->devswap[Swap];	*vmax = m->devswap[Maxswap];} voidcontextval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Context]-m->prevsysstat[Context];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;} voidintrval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Interrupt]-m->prevsysstat[Interrupt];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;} voidsyscallval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Syscall]-m->prevsysstat[Syscall];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;} voidfaultval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Fault]-m->prevsysstat[Fault];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;} voidtlbmissval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[TLBfault]-m->prevsysstat[TLBfault];	*vmax = (sleeptime/1000)*10*m->nproc;	if(init)		*vmax = (sleeptime/1000)*10;} voidtlbpurgeval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[TLBpurge]-m->prevsysstat[TLBpurge];	*vmax = (sleeptime/1000)*10*m->nproc;	if(init)		*vmax = (sleeptime/1000)*10;} voidloadval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Load];	*vmax = 1000*m->nproc;	if(init)		*vmax = 1000;} voididleval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->devsysstat[Idle]/m->nproc;	*vmax = 100;} voidinintrval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->devsysstat[InIntr]/m->nproc;	*vmax = 100;} voidetherval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->netetherstats[In]-m->prevetherstats[In] + m->netetherstats[Out]-m->prevetherstats[Out];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;} voidetherinval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->netetherstats[In]-m->prevetherstats[In];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;} voidetheroutval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->netetherstats[Out]-m->prevetherstats[Out];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;} voidethererrval(Machine *m, ulong *v, ulong *vmax, int init){	int i; 	*v = 0;	for(i=Err0; i<nelem(m->netetherstats); i++)		*v += m->netetherstats[i];	*vmax = (sleeptime/1000)*10*m->nproc;	if(init)		*vmax = (sleeptime/1000)*10;} voidbatteryval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->batterystats[0];	if(m->bitsybatfd >= 0)		*vmax = 184;		// at least on my bitsy...	else		*vmax = 100;} voidsignalval(Machine *m, ulong *v, ulong *vmax, int){	ulong l; 	*vmax = sleeptime;	l = m->netetherifstats[0];	/*	 * Range is seen to be from about -45 (strong) to -95 (weak); rescale	 */	if(l == 0){	/* probably not present */		*v = 0;		return;	}	*v = 20*(l+95);} void	(*newvaluefn[Mend])(Machine*, ulong*, ulong*, int init) = {	batteryval,	contextval,	etherval,	ethererrval,	etherinval,	etheroutval,	faultval,	idleval,	inintrval,	intrval,	loadval,	memval,	swapval,	syscallval,	tlbmissval,	tlbpurgeval,	signalval,}; intneedswap(void){	return present[Mmem] | present[Mswap];}  intneedstat(void){	return  present[Mcontext]  | present[Mfault] | present[Mintr] | present[Mload] | present[Midle] |		present[Minintr] | present[Msyscall] | present[Mtlbmiss] | present[Mtlbpurge];}  intneedether(void){	return  present[Mether] | present[Metherin] | present[Metherout] | present[Methererr];} intneedbattery(void){	return  present[Mbattery];} intneedsignal(void){	return  present[Msignal];} int connectexportfs(char *addr){	char buf[ERRMAX], dir[256], *na;	int fd, n;	char *tree;	AuthInfo *ai; 	tree = "/";	na = netmkaddr(addr, 0, "exportfs");	if((fd = dial(na, 0, dir, 0)) < 0)		return -1; 	ai = auth_proxy(fd, nil, "proto=p9any role=client");	if(ai == nil)		return -1; 	n = write(fd, tree, strlen(tree));	if(n < 0){		close(fd);		return -1;	} 	strcpy(buf, "can't read tree");	n = read(fd, buf, sizeof buf - 1);	if(n!=2 || buf[0]!='O' || buf[1]!='K'){		buf[sizeof buf - 1] = '\0';		werrstr("bad remote tree: %s\n", buf);		close(fd);		return -1;	} 	return fd;} intloadbuf(Machine *m, int *fd){	int n;  	if(*fd < 0)		return 0;	seek(*fd, 0, 0);	n = read(*fd, m->buf, sizeof m->buf);	if(n <= 0){		close(*fd);		*fd = -1;		return 0;	}	m->bufp = m->buf;	m->ebufp = m->buf+n;	return 1;} intreadnums(Machine* m, int n, ulong *a, int spanlines){	int i;	char *p, *ep; 	if(spanlines)		ep = m->ebufp;	else		for(ep=m->bufp; ep<m->ebufp; ep++)			if(*ep == '\n')				break;	p = m->bufp;	for(i=0; i<n && p<ep; i++){		while(p<ep && !isdigit(*p) && *p!='-')			p++;		if(p == ep)			break;		a[i] = strtoul(p, &p, 10);	}	if(ep < m->ebufp)		ep++;	m->bufp = ep;	return i == n;} intinitmach(char *name){	int n, fd;	ulong a[MAXNUM];	char *p, mpt[256], buf[256]; 	p = strchr(name, '!');	if(p)		p++;	else		p = name;	m->name = estrdup(p);	m->remote = (strcmp(p, sysname()) != 0);	if(m->remote == 0)		strcpy(mpt, "");	else{		snprint(mpt, sizeof mpt, "/n/%s", p);		fd = connectexportfs(name);		if(fd < 0){			fprint(2, "can't connect to %s: %r\n", name);			return 0;		}		/* BUG? need to use amount() now? */		if(mount(fd, -1, mpt, MREPL, "") < 0)			return 0;	} 	seprint(buf, buf+sizeof(buf), "%s/dev/swap", mpt);	m->swapfd = open(buf, OREAD);	if(loadbuf(m, &m->swapfd) && readnums(m, nelem(m->devswap), a, 0))		memmove(m->devswap, a, sizeof m->devswap);	else		m->devswap[Maxmem] = m->devswap[Maxswap] = 100; 	snprint(buf, sizeof buf, "%s/dev/sysstat", mpt);	m->statsfd = open(buf, OREAD);	if(loadbuf(m, &m->statsfd)){		for(n=0; readnums(m, nelem(m->devsysstat), a, 0); n++)			;		m->nproc = n;	}else		m->nproc = 1; 	snprint(buf, sizeof buf, "%s/net/ether0/stats", mpt);	m->etherfd = open(buf, OREAD);	if(loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1))		memmove(m->netetherstats, a, sizeof m->netetherstats); 	snprint(buf, sizeof buf, "%s/net/ether0/ifstats", mpt);	m->ifstatsfd = open(buf, OREAD);	if(loadbuf(m, &m->ifstatsfd)){		/* need to check that this is a wavelan interface */		if(strncmp(m->buf, "Signal: ", 8) == 0 && readnums(m, nelem(m->netetherifstats), a, 1))			memmove(m->netetherifstats, a, sizeof m->netetherifstats);	} 	snprint(buf, sizeof buf, "%s/mnt/apm/battery", mpt);	m->batteryfd = open(buf, OREAD);	m->bitsybatfd = -1;	if(m->batteryfd >= 0){		if(loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0))			memmove(m->batterystats, a, sizeof(m->batterystats));	}else{		snprint(buf, sizeof buf, "%s/dev/battery", mpt);		m->bitsybatfd = open(buf, OREAD);		if(loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0))			memmove(m->batterystats, a, sizeof(m->batterystats));	}	return 1;} voidreadmach(void){	int n, i;	ulong a[8];

Lines 1–500 of 720.