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