V10/cmd/showq.c

Compare this file to the similar file:
Show the results in this format:


#include <nlist.h>
#include <sys/param.h>
#include <ctype.h>
#include <sys/stream.h>
#include <sys/inode.h>
#include <sys/conf.h>
#include <sys/dkp.h>
#include <sys/dz.h>

struct nlist nl[] ={
#define	QNL	0
	{"_queue"},
#define	BLNL	1
	{"_cblock"},
#define	STNL	2
	{"_streams"},
#define	QFNL	3
	{"_qfreelist"},
#define DKPNL	4
	{ "_dkpstream" },
#define	NBLOCK	5
	{ "_blkcnt"},
#define	NQUEUE	6
	{ "_queuecnt"},
#define	NSTREAM	7
	{ "_streamcnt"},
#define	DZNL	8
	{"_dzinfo"},
#define CDKPNL	9
	{ "_cdkpstream" },
#define	BLKALL	10
	{ "_blkall" },
#define	BLKMAX	11
	{ "_blkmax" },
#define	BLKFREE	12
	{ "_blkfree" },
#define	STWNL	13
	{ "_stwdata" },
#define	BLKOWN	14
	{ "_blkowner" },
#define	STRDATA	15
	{ "_strdata" },
#define	STREAMSTART	16
	{ "_bufldstream" },
	{ "_rdkstream" },
	{ "_connstream" },
	{ "_connginfo" },
	{ "_kcinfo" },
	{ "_rcureinfo" },
	{ "_qesinfo" },
	{ "_dhvinfo" },
	{ "_dkinfo" },
	{ "_dkpstream" },
	{ "_cdkpstream" },
	{ "_dzinfo" },
	{ "_kbinfo" },
	{ "_kdiinfo" },
	{ "_msgstream" },
	{ "_rmsgstream" },
	{ "_mginfo" },
	{ "_ilsinfo" },
	{ "_nttystream" },
	{ "_spinfo" },
	{ "_ttystream" },
	{ "_xpstream" },
	{ "_ipdinfo" },
	{ "_ipstream" },
	{ "_tcpdinfo" },
	{ "_tcpstream" },
	{ "_udpdinfo" },
	{ "_udpstream" },
	{ "_nilinfo" },
	{ "_cnstream" },
	{ "" },
};

struct	infoinfo {
	char	*name;
	struct	streamtab inf;
} inf[50];

struct	qinit **qall;
char	*ball;
char	*strall;
char	*core = "/dev/mem";
char	*sys  = "/unix";
int	mem;
int	blkcnt;
int	queuecnt;
int	streamcnt;
short	blkall[6];
short	blkmax[6];
short	blkfree[6];

#define	DK_OPEN	01
#define	DK_LCLOSE	02
#define	DK_RCLOSE	04
#define	DK_XCHARMODE	010
#define	DK_RCHARMODE	0200
#define	DK_OPENING	020

#define	getme(s, kind, off, type)  _get(kind, off, sizeof(type), &s)

struct flags {
	int	flag;
	char	*name;
};

struct flags stflags[] = {
	IOCWAIT,	"IOC",
	RSLEEP,		"RSLEEP",
	WSLEEP,		"WSLEEP",
	HUNGUP,		"HUNGUP",
	RSEL,		"RSEL",
	WSEL,		"WSEL",
	EXCL,		"EXCL",
	STWOPEN,	"WOPEN",
	0
};

struct flags qflags[] = {
	QUSE,		"use",
	QREADR,		"read",
	QNOENB,		"noenb",
	QENAB,		"enab",
	QWANTR,		"wantr",
	QWANTW,		"wantw",
	QFULL,		"full",
	QDELIM,		"delim",
	QBIGB,		"bigb",
	0
};

struct	flags dkpflags[] = {
	DK_OPEN,	"open",
	DK_LCLOSE,	"lclose",
	DK_RCLOSE,	"rclose",
	DK_XCHARMODE,	"xcharmode",
	DK_RCHARMODE,	"rcharmode",
	DK_OPENING,	"opening",
	0
};

#define	DZEXIST	01
#define	DZISOPEN 02
#define	DZWOPEN	04
#define	DZTIME	010
#define	DZCARR	020
#define	DZSTOP	040
#define	DZHUPCL	0100

struct flags dzflags[] = {
	DZEXIST,	"exists",
	DZISOPEN,	"open",
	DZWOPEN,	"wopen",
	DZTIME,		"time",
	DZCARR,		"carrier",
	DZSTOP,		"stop",
	DZHUPCL,	"hupcl",
	0
};

int	vflag;
int	sflag;
int	mflag;
char	*infstr();

main(argc, argv)
char **argv;
{
	struct queue q;
	struct block b;
	struct stdata s;
	int i;
	int nq = 0;

	for (;;argc--, argv++) {
		if (argc>1 && strcmp(argv[1], "-v")==0) {
			vflag++;
			continue;
		}
		if (argc>1 && strcmp(argv[1], "-m")==0) {
			mflag++;
			continue;
		}
		if (argc>1 && strcmp(argv[1], "-V")==0) {
			vflag = 2;
			continue;
		}
		if (argc>1 && strcmp(argv[1], "-s")==0) {
			sflag++;
			continue;
		}
		break;
	}
	if (argc>1)
		sys = argv[1];
	if (argc>2)
		core = argv[2];
	nlist(sys, nl);
	mem = open(core, 0);
	if (mem<0) {
		printf("can't open %s\n", core);
		exit(1);
	}
	getme(queuecnt, NQUEUE, 0, int);
	getme(streamcnt, NSTREAM, 0, int);
	getme(blkcnt, NBLOCK, 0, int);
	getme(blkmax[0], BLKMAX, 0, blkmax);
	getme(blkall[0], BLKALL, 0, blkall);
	getme(blkfree[0], BLKFREE, 0, blkfree);
	printf("blocks max: (%d,%d,%d,%d,%d,%d)\n",
		blkmax[0], blkmax[1], blkmax[2], blkmax[3], blkmax[4], blkmax[5]);
	printf("blocks cur: (%d,%d,%d,%d,%d,%d)\n",
		blkall[0], blkall[1], blkall[2], blkall[3], blkall[4], blkall[5]);
	printf("blocks free: (%d,%d,%d,%d,%d,%d)\n",
		blkfree[0], blkfree[1], blkfree[2], blkfree[3], blkfree[4], blkfree[5]);
	initinfo();
	ball = (char *)malloc(blkcnt*sizeof(char));
	strall = (char *)malloc(streamcnt*sizeof(char));
	qall = (struct qinit **)malloc(queuecnt*sizeof(struct queue *));
	for (i=0; i<blkcnt; i++)
		ball[i] = 0;
	for (i=0; i<streamcnt; i++)
		strall[i] = 0;
	for (i=0; i<queuecnt; i++) {
		getme(q, QNL, i, struct queue);
		if (q.flag==0)
			qall[i] = 0;
		else {
			qall[i] = q.qinfo;
			nq++;
		}
	}
	for (i=0; i<streamcnt; i++)
		pstream(i);
	for (i=0; i<queuecnt; i++) {
		if (qall[i])
			printf("Loose queue %d, info #%x\n", i, qall[i]);
	}
	printf("%d queues in use\n", nq);
	bfreecount();
	nq = 0;
	for (i=0; i<blkcnt; i++)
		if (ball[i]==0) {
			struct block b;
			long owner;

			if (mflag) {
				getme(b, BLNL, i, struct block);
#if BLKOWNER
				getme(owner, BLKOWN, i, long);
				printf("   owner=##%x\n", owner);
#endif
				pblock(&b);
			}
			nq++;
		}
	if (!sflag)
		printf("%d blocks missing\n", nq);
	nq = 0;
	for (i=0; i<blkcnt; i++) {
		if (ball[i])
			continue;
		if (nq >= 5 && vflag < 2)
			continue;
		printf("#%x\n", (struct block *)nl[BLNL].n_value+i);
		nq++;
	}
	exit(0);
}

pstream(i)
{
	struct stdata s;
	struct queue rq, wq;
	struct inode ino;
	struct queue *rqp, *wqp;
	struct stdata *sp;
	static struct streamtab dkpinfo, dzinfo, cdkpinfo;
	static int stread = 0;
	int d;
	int forward = 1;

	if (strall[i])
		return;
	strall[i]++;
	sp = (struct stdata *)getme(s, STNL, i, struct stdata);
	if (s.wrq==NULL)
		return;
	if (!sflag)
		printf("\nstream %d: ", i);
	getme(ino, s.inode, 0, struct inode);
	d = ino.i_un.i_rdev;
	if (!sflag) {
		printf("dev %d,%d  ", major(d), minor(d));
		printf("ino %d  ", ino.i_number);
		printf("count %d ", s.count);
		flags(stflags, s.flag);
		if (vflag)
			printf(" pgrp %d", s.pgrp);
		printf("\n");
	}
	wqp = (struct queue *)getme(wq, s.wrq, 0, struct queue);
	rqp = (struct queue *)getme(rq, RD(s.wrq), 0, struct queue);
	if ((struct stdata *)rq.ptr != sp)
		printf("rq ptr? = #%x\n", rq.ptr);
	if (stread == 0) {
		getme(dkpinfo, DKPNL, 0, struct streamtab);
		getme(cdkpinfo, CDKPNL, 0, struct streamtab);
		getme(dzinfo, DZNL, 0, struct streamtab);
		stread++;
	}
	for (;;) {
		d = rqp - (struct queue *)nl[QNL].n_value;
		if (d<0 || d>=queuecnt)
			printf("?");
		else
			qall[d] = 0;
		d = wqp - (struct queue *)nl[QNL].n_value;
		if (d<0 || d>=queuecnt)
			printf("?");
		else
			qall[d] = 0;
		if (!sflag) {
			printf("   RQ #%x: ", rqp);
			printf("%s; ", infstr(rq.qinfo));
			flags(qflags, rq.flag);
			printf(". ptr #%x", rq.ptr);
			printf("\n");
			pblocks(&rq);
			printf("   WQ #%x:   ", wqp);
			flags(qflags, wq.flag);
			printf(". ptr #%x", wq.ptr);
			printf("\n");
			pblocks(&wq);
			if ((long)wq.qinfo == nl[STWNL].n_value)
				strfacts(&wq);
			if (wq.qinfo == dkpinfo.wrinit || wq.qinfo == cdkpinfo.wrinit)
				dkpline(&wq);
			if (wq.qinfo == dzinfo.wrinit)
				dzfacts(&wq);
		}
		if (forward) {
			if (wq.next == NULL)
				break;
			wqp = (struct queue *)
			     getme(wq, wq.next, 0, struct queue);
			if (wq.flag&QREADR) {
				printf("   <>\n");
				forward = 0;
				rqp = wqp;
				rq = wq;
				wqp = (struct queue *)
				     getme(wq, WR(rqp), 0, struct queue);
			} else
				rqp = (struct queue *)
				     getme(rq, RD(wqp), 0, struct queue);
		} else {
			if (rq.next == NULL)
				break;
			rqp = (struct queue *)
			     getme(rq, rq.next, 0, struct queue);
			if ((rq.flag&QREADR) == 0) {
				printf("   <>\n");
				forward = 1;
				wqp = rqp;
				wq = rq;
				rqp = (struct queue *)
				     getme(rq, RD(wqp), 0, struct queue);
			} else
				wqp = (struct queue *)
				     getme(wq, WR(rqp), 0, struct queue);
		}
	}
}

strfacts(q)
register struct queue *q;
{
	register int i;
	struct stdata s;
	dev_t d;
	struct inode ino;

	i = (struct stdata *)q->ptr - (struct stdata *)nl[STNL].n_value;
	if (i < 0 || i > streamcnt)
		return;
	if (strall[i])
		return;
	strall[i]++;
	getme(s, STNL, i, struct stdata);
	if (s.wrq==NULL)
		return;
	if (!sflag)
		printf("stream %d: ", i);
	getme(ino, s.inode, 0, struct inode);
	d = ino.i_un.i_rdev;
	if (!sflag) {
		printf("dev %d,%d  ", major(d), minor(d));
		printf("ino %d  ", ino.i_number);
		printf("count %d ", s.count);
		flags(stflags, s.flag);
		if (vflag)
			printf(" pgrp %d", s.pgrp);
		printf("\n");
	}
}

dzfacts(q)
register struct queue *q;
{
	struct dz dz;

	getme(dz, q->ptr, 0, struct dz);
	printf("     DZ: ");
	flags(dzflags, dz.state);
	printf("\n");
}

dkpline(q)
register struct queue *q;
{
	struct dkp dkp;
	register i;

	getme(dkp, q->ptr, 0, struct dkp);
	printf("	WS %o WACK %o WNX %o iseq %o; ", dkp.WS, dkp.WACK,
	    dkp.WNX, dkp.iseq);
	printf("window %d x %d; ", dkp.XW, dkp.xsize);
	flags(dkpflags, dkp.state);
	printf("\n	");
	for (i=0; i<8; i++)
		printf(" #%x", dkp.xb[i]);
	printf("\n");
}

pblocks(q)
register struct queue *q;
{
	struct block b, *bp;
	int nb = 0;
	u_char buf[512];
	register i, bno;

	bp = q->first;
	for (i = 0; i < 1000; i++) {
		if (bp==NULL)
			break;
		bno = bp - (struct block *)nl[BLNL].n_value;
		nb++;
		baccount(bno);
		getme(b, bp, 0, struct block);
		if (vflag && (i<10 || vflag>1))
			pblock(&b);
		bp = b.next;
	}
	if (vflag && i>=10)
		printf("(gave up) ");
	if (nb > 0)
		printf("       %d blocks\n", nb);
}

pblock(bp)
register struct block *bp;
{
	register u_char *cp;
	register i = 0;
	u_char buf[4096];

	printf("       %c%.3o:", bp->class&0200?'D':' ', bp->type);
	cp = buf;
	getme(buf[0], bp->base, 0, buf);
	printf("%3d:", bp->wptr-bp->base);
	while (bp->base < bp->wptr) {
		if (i >= 16) {
			printf("\n	        ");
			i = 0;
		}
		if (*cp<040 || *cp>=0177)
			printf(" %.3o", *cp);
		else
			printf("  %c ", *cp);
		cp++;
		bp->base++;
		i++;
	}
	printf("\n");
}

flags(fp, w)
register struct flags *fp;
{
	int any = 0;
	while (fp->name) {
		if (fp->flag&w) {
			if (any)
				printf(", ");
			any++;
			printf("%s", fp->name);
		}
		fp++;
	}
}

_get(addr, off, size, loc)
unsigned long addr;
char *loc;
{

	if (addr < 20)
		addr = nl[addr].n_value;
	addr += off*size;
	lseek(mem, addr&0x7fffffff, 0);
	read(mem, loc, size);
	return(addr);
}

bfreecount()
{
	struct block b;
	struct block *bp;
	register i;

	for (i=0; i<6; i++) {
		getme(bp, QFNL, i, struct block *);
		while (bp) {
			baccount(bp - (struct block *)nl[BLNL].n_value);
			getme(b, bp, 0, struct block);
			bp = b.next;
		}
	}
}

baccount(bno)
{
	if (bno < 0 || bno >= blkcnt)
		printf("funny block %d\n", bno);
	else if (ball[bno])
		printf("dup block %d\n", bno);
	else
		ball[bno]++;
}

initinfo()
{
	register i, j;

	inf[0].name = "head";
	inf[0].inf.rdinit = (struct qinit *)nl[STRDATA].n_value;
	for (j=1, i=STREAMSTART; nl[i].n_name[0]; i++) {
		if (nl[i].n_type!=0) {
			getme(inf[j].inf, nl[i].n_value, 0, struct streamtab);
			inf[j].name = nl[i].n_name;
			if (inf[j].name[0]=='_')
				inf[j].name++;
			j++;
		}
	}
}

char *
infstr(s)
long s;
{
	register i;
	static char buf[64];

	for (i=0; inf[i].name; i++) {
		if (inf[i].inf.rdinit == (struct qinit *)s
		 || inf[i].inf.wrinit == (struct qinit *)s) {
			sprintf(buf, "%s", inf[i].name);
			break;
		}
	}
	if (inf[i].name == NULL)
		sprintf(buf, "qinfo #%x", s);
	return(buf);
}