utility to help map block # to pathname

Stu Heiss stu at jpusa1.UUCP
Tue Nov 7 22:33:48 AEST 1989


Here's a utility to help discover what file was affected when
you have a hard disk error.  Assuming you know the block number
where the error occured, this utility will examine a filesystem
and map inodes to data block numbers printing lines in the form of:

inum: blocknum blocknum blocknum...

For example, let's suppose block 12345 is bad as indicated by a
kernal error message and the filesystem is /usr.  You would do
the following:

	# mapino /dev/usr | grep 12345

and note the inode.  Then:

	# ncheck -i inum /dev/usr

to get the pathname.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	mapino.c
# This archive created: Tue Nov  7 05:03:44 1989
# By:	stu (JPUSA - Chicago, IL)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'mapino.c'" '(3296 characters)'
if test -f 'mapino.c'
then
	echo shar: "will not over-write existing file 'mapino.c'"
else
sed 's/^X//' << \SHAR_EOFmapino.c > 'mapino.c'
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/param.h>
X#include <sys/filsys.h>
X#include <sys/ino.h>
X
Xint fd;
Xint retcode=0;
Xstruct filsys sb;
Xino_t maxino;
Xdaddr_t loblk, hiblk;
Xstruct dinode *dinodes;
Xextern char *calloc();
X
X#define DBLKSIZ 1024
X#define nel(x) (sizeof(x)/sizeof(x[0]))
X#define iblk x._iblk
X#define buff x._buff
Xunion x {
X	char _buff[DBLKSIZ];
X	daddr_t _iblk[DBLKSIZ/sizeof(daddr_t)];
X};
X
X#define MININO 2
X#define E_INO 2
X#define E_BLK 4
X
X#define dptr(ino) (&dinodes[(ino)-1])
X
Xgoodino(ino)
Xino_t ino;
X{
X	if (ino >= MININO && ino < maxino) return 1;
X	fprintf(stderr,"impossible ino %d\n",ino);
X	retcode |= E_INO;
X	return 0;
X}
X
Xgoodblk(blk)
Xdaddr_t blk;
X{
X	if (blk >= loblk && blk < hiblk) return 1;
X	fprintf(stderr,"impossible block %ld\n",blk);
X	retcode |= E_BLK;
X	return 0;
X}
X
Xtind(l)
Xdaddr_t l;
X{
X	int i;
X	union x x;
X	d_seek((off_t)l);
X	if (read(fd,buff,sizeof(buff)) == -1) {
X		fprintf(stderr,"triple indirect blk=%ld ",l);
X		perror("read");
X		exit(1);
X	}
X	for (i = 0; i < nel(iblk); ++i) {
X		if (iblk[i] == 0)
X			break;
X		if (goodblk(iblk[i]))
X			dind(iblk[i]);
X	}
X}
X
Xdind(l)
Xdaddr_t l;
X{
X	int i;
X	union x x;
X	d_seek((off_t)l);
X	if (read(fd,buff,sizeof(buff)) == -1) {
X		fprintf(stderr,"double indirect blk=%ld ",l);
X		perror("read");
X		exit(1);
X	}
X	for (i = 0; i < nel(iblk); ++i) {
X		if (iblk[i] == 0)
X			break;
X		if (goodblk(iblk[i]))
X			sind(iblk[i]);
X	}
X}
X
Xsind(l)
Xdaddr_t l;
X{
X	int i;
X	union x x;
X	d_seek((off_t)l);
X	if (read(fd,buff,sizeof(buff)) == -1) {
X		fprintf(stderr,"single indirect blk=%ld ",l);
X		perror("read");
X		exit(1);
X	}
X	for (i = 0; i < nel(iblk); ++i) {
X		if (iblk[i] == 0)
X			break;
X		if (goodblk(iblk[i]))
Xprintf(" %ld",iblk[i]);
X	}
X}
X
Xdoblkno(ino)
Xino_t ino;
X{
X	struct dinode *d;
X	daddr_t blk[13];
X
X	if (goodino((ino_t)ino)) {
X		d = dptr(ino);
X		l3tol(blk, d->di_addr, 13);
X		doinode((ino_t)ino,blk);
X	}
X}
X
Xdoinode(ino,blk)
Xino_t ino;
Xdaddr_t *blk;
X{
X	int i;
X	struct dinode *d = dptr(ino);
Xprintf("ino=%d:",ino);
X		for (i = 0; i < 13; ++i) {
X			if (blk[i] == 0)
X				break;
X			if (i < 10) {
Xif (goodblk(blk[i])) printf(" %ld",blk[i]);
X			} else if (i == 10) {
X				if (goodblk(blk[i]))
X					sind(blk[i]);
X			} else if (i == 11) {
X				if (goodblk(blk[i]))
X					dind(blk[i]);
X			} else if (i == 12) {
X				if (goodblk(blk[i]))
X					tind(blk[i]);
X			}
X		}
Xprintf("\n");
X}
X
Xopenspecial(s)
Xchar *s;
X{
X	if ((fd = open(s,0)) == -1) {
X		fprintf(stderr,"dev=%s ",s);
X		perror("open");
X		exit(1);
X	}
X	d_seek((off_t)1);
X	if (read(fd,&sb,sizeof(sb)) == -1) {
X		perror("read superblock");
X		exit(1);
X	}
X	maxino = (sb.s_isize -2)*(DBLKSIZ/sizeof(struct dinode));
X	loblk = sb.s_isize;
X	hiblk = sb.s_fsize;
X	if ((dinodes = (struct dinode *)calloc(maxino,sizeof(struct dinode))) == 0) {
X		perror("calloc");
X		exit(1);
X	}
X	d_seek((off_t)2);
X	if (read(fd,dinodes,maxino * sizeof(struct dinode)) == -1) {
X		perror("read inode table");
X		exit(1);
X	}
X}
X
Xd_seek(n)
Xoff_t n;
X{
X	lseek(fd,(off_t)(n * DBLKSIZ),0);
X}
X
Xmain(ac,av)
Xint ac;
Xchar **av;
X{
X	char *special;
X	ino_t ino;
X	if (ac < 2) {
X		fprintf(stderr,"usage: %s special [ino...]\n",av[0]);
X		exit(1);
X	}
X	special = *++av;
X	--ac;
X	openspecial(special);
X	if (ac == 1)
X		for (ino = MININO; ino < maxino; ++ino)
X			doblkno((ino_t)ino);
X	else
X		while (ac-- > 1)
X			doblkno((ino_t)atoi(*++av));
X	exit(retcode);
X}
SHAR_EOFmapino.c
if test 54120 -ne "`sum < 'mapino.c' | sed 's/ .*//'`"
then
	echo shar: "possible error transmitting 'mapino.c'" '(sum should have been 54120)'
	echo shar: "trying 'sum -r'"
	if test 04082 -ne "`sum -r < 'mapino.c' | sed 's/ .*//'`"
	then
		echo shar: "probable error transmitting 'mapino.c'" '(sum should have been 04082)'
	echo shar: "trying 'wc -c'"
		if test 3296 -ne "`wc -c < 'mapino.c'`"
		then
			echo shar: "error transmitting 'mapino.c'" '(should have been 3296 characters)'
		else
			echo shar: "wc was ok"
		fi
	fi
fi
chmod 644 'mapino.c'
fi
exit 0
#	End of shell archive
-- 
Stu Heiss - gargoyle.uchicago.edu!jpusa1.uucp!stu, stu at jpusa1.chi.il.us



More information about the Alt.sources mailing list