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

290 lines
6.5 KiB
C

#ident "$Header: /proj/irix6.5.7m/isms/irix/cmd/icrash/RCS/stream.c,v 1.1 1999/05/25 19:21:38 tjm Exp $"
#include <stdio.h>
#define _KERNEL
#include <sys/types.h>
#include <sys/uio.h>
#undef _KERNEL
#include <sys/vnode.h>
#include <klib/klib.h>
#include "icrash.h"
/* Global variables
*/
stream_rec_t strmtab[1024];
int strmtab_valid = 0;
int strcnt = 0;
/*
* clean_strmtab()
*/
void
clean_strmtab()
{
int i;
file_rec_t *file, *nextfile;
if (ACTIVE && strmtab_valid) {
for (i = 0; i < 1024; i++) {
file = strmtab[i].file;
while (file) {
nextfile = file->next;
kl_free_block((k_ptr_t)file);
file = nextfile;
}
}
bzero(strmtab, sizeof(strmtab));
strmtab_valid = 0;
strcnt = 0;
}
}
/*
* streamcmp() -- Stream comparison function for qsort().
*/
int
streamcmp(stream_rec_t *s1, stream_rec_t *s2)
{
if ((unsigned)s1->str < (unsigned)s2->str) {
return(-1);
}
else if ((unsigned)s1->str > (unsigned)s2->str) {
return(1);
}
else {
return(0);
}
}
/*
* find_stream_rec()
*/
stream_rec_t *
find_stream_rec(kaddr_t stream)
{
int i;
if (DEBUG(DC_FUNCTRACE, 3)) {
fprintf(KL_ERRORFP, "find_stream_rec: stream=0x%llx\n", stream);
}
if (!strmtab_valid) {
if (build_stream_tab()) {
if (DEBUG(DC_STREAM, 1)) {
/* XXX - Error messager ?!?
*/
}
return(0);
}
}
for (i = 0; i < strcnt; i++) {
if (strmtab[i].str == stream) {
return(&strmtab[i]);
}
}
return((stream_rec_t *)NULL);
}
/*
* build_stream_tab()
*/
int
build_stream_tab()
{
int i = 0, j, k, gap, first_time = 1;
stream_rec_t *srec;
file_rec_t *frec;
kaddr_t file, stream, vnode, snode;
k_ptr_t strp, qp, kfp, vp, sp;
if (ACTIVE || !strmtab_valid) {
#ifdef NOTYET
strcnt = 0;
/* Allocate some buffer space.
*/
strp = kl_alloc_block(STDATA_SIZE, K_TEMP);
qp = kl_alloc_block(QUEUE_SIZE, K_TEMP);
kfp = kl_alloc_block(VFILE_SIZE, K_TEMP);
vp = kl_alloc_block(VNODE_SIZE, K_TEMP);
sp = kl_alloc_block(LSNODE_SIZE, K_TEMP);
/* Get the first file pointer in open file chain. Then walk the list
* of open files looking for streams. Capture all stream pointers in
* stream table -- then sort it and remove duplicates. Next locate
* all files that point to each stream (along with vnode, snode and
* commonvp. On an active system, this has to be done each time through.
* When analyzing vmcore dumps, it only has to be done once.
*/
file = K_ACTIVEFILES;
while (file) {
if (!get_vfile(file, kfp, 0)) {
if (DEBUG(DC_STREAM, 1)) {
fprintf(KL_ERRORFP, "list_streams: file=0x%llx\n", file);
}
file = kl_kaddr(kfp, "vfile", "vf_next");
continue;
}
if (KL_INT(kfp, "vfile", "vf_count")) {
if (!get_vnode(kl_kaddr(kfp, "vfile", "vf_vnode"), vp, 0)) {
if (DEBUG(DC_STREAM, 1)) {
fprintf(KL_ERRORFP,
"vnode virtual address (0x%llx) out of range!\n",
kl_kaddr(kfp, "vfile", "vf_vnode"));
}
file = kl_kaddr(kfp, "vfile", "vf_next");
continue;
}
if ((KL_UINT(vp, "vnode", "v_type") == VCHR) &&
kl_kaddr(vp, "vnode", "v_stream")) {
if (!get_snode(kl_kaddr(vp, "vnode", "v_data"), sp, 0)) {
if (DEBUG(DC_STREAM, 1)) {
fprintf(KL_ERRORFP,
"snode virtual address (0x%llx) out of range!\n",
kl_kaddr(vp, "vnode", "v_data"));
}
file = kl_kaddr(kfp, "vfile", "vf_next");
continue;
}
strmtab[i].str = kl_kaddr(vp, "vnode", "v_stream");
strcnt++, i++;
}
}
file = kl_kaddr(kfp, "vfile", "vf_next");
}
/* sort the stream pointers
*/
qsort((char*)&strmtab[0], strcnt, sizeof(stream_rec_t), streamcmp);
/* remove duplicates
*/
i = 0;
j = 1;
while (i < strcnt - 1) {
while (strmtab[i].str == strmtab[j].str) {
if (j == strcnt - 1) {
strcnt = i + 1;
goto rmvdups_done;
}
j++;
}
i++;
gap = j - i;
if (gap) {
for (k = i; k < strcnt - gap; k++) {
strmtab[k] = strmtab[k + gap];
}
strcnt -= gap;
}
j = i + 1;
}
strmtab_valid = 1;
rmvdups_done:
/* Now go back through the list of open files and capture
* information on each file pointing to each stream.
*/
file = K_ACTIVEFILES;
while (file) {
if (!get_vfile(file, kfp, 0)) {
if (DEBUG(DC_STREAM, 1)) {
fprintf(KL_ERRORFP, "list_streams: file=0x%llx\n", file);
}
file = kl_kaddr(kfp, "vfile", "vf_next");
continue;
}
if (KL_INT(kfp, "vfile", "vf_count")) {
vnode = kl_kaddr(kfp, "vfile", "vf_vnode");
if (!get_vnode(vnode, vp, 0)) {
if (DEBUG(DC_STREAM, 1)) {
fprintf(KL_ERRORFP, "vnode virtual address (0x%llx) "
"out of range!\n", vnode);
}
file = kl_kaddr(kfp, "vfile", "vf_next");
continue;
}
if ((KL_UINT(vp, "vnode", "v_type") == VCHR) &&
(stream = kl_kaddr(vp, "vnode", "v_stream"))) {
snode = kl_kaddr(vp, "vnode", "v_data");
if (!get_snode(snode, sp, 0)) {
if (DEBUG(DC_STREAM, 1)) {
fprintf(KL_ERRORFP, "snode virtual address "
"(0x%llx) out of range!\n", snode);
}
file = kl_kaddr(kfp, "vfile", "vf_next");
continue;
}
/* Locate the stream_rec in the strmtab[]
*/
if (!(srec = find_stream_rec(stream))) {
if (DEBUG(DC_STREAM, 1)) {
fprintf(KL_ERRORFP, "Virtual address (0x%llx) "
"not found in stream table!\n", stream);
}
kl_free_block(strp);
kl_free_block(qp);
kl_free_block(qp);
kl_free_block(kfp);
kl_free_block(vp);
kl_free_block(sp);
return(1);
}
/* Allocate a file_rec for this file and link it into the
* stream_rec.
*/
if (!(frec = srec->file)) {
if (ACTIVE) {
srec->file =
kl_alloc_block(sizeof(file_rec_t), K_TEMP);
}
else {
srec->file =
kl_alloc_block(sizeof(file_rec_t), B_PERM);
}
frec = srec->file;
}
else {
while(1) {
if (frec->next) {
frec = frec->next;
continue;
}
break;
}
if (ACTIVE) {
frec->next =
kl_alloc_block(sizeof(file_rec_t), K_TEMP);
}
else {
frec->next =
kl_alloc_block(sizeof(file_rec_t), B_PERM);
}
frec = frec->next;
}
frec->fp = file;
frec->vp = vnode;
frec->sp = snode;
frec->cvp = kl_kaddr(sp, "snode", "s_commonvp");
}
}
file = kl_kaddr(kfp, "vfile", "f_next");
}
kl_free_block(strp);
kl_free_block(qp);
kl_free_block(kfp);
kl_free_block(vp);
kl_free_block(sp);
#else
return(1);
#endif /* NOTYET */
}
strmtab_valid = 2;
return(0);
}