Re: OFF TOPIC: But please help :-(

From: Alexander van Koppen (alexk@odie.et.fnt.hvu.nl)
Date: 06/13/96


Hi !

> Hiya all you question answering types-

> This is a fairly standard installation of 1.2 with no history of problems 
> at all. I am not too concerned with the installation of the OS but I 
> really need to get a few files off of my user's home directory. This is a 
> stand-alone system and I am the only user. I will probably jsut end up 
> formating the drive and installing 2.0 anyway, but I absolutely have to 
> get the files off of the directory before I do that. Here are the errors 
> that I get:
> 
> hda: read_intr: status=0X59 { DriveReady SeekComplete DataRequest Error }

Don't know exactly what this is, doesn't look good though....

> hda: read_intr: error 0X01 { AddrMark Not Found }, LBA sect=1876496, 
>  sector=360464

Mmh, this would mean that your HD has a format error, you'll probably
have to low-level format it, either to recover the error, or add the
sector to the bad-sector list... 

> end_request: I/O error, dev 0302, sector 360464
> Kernel panic: EXT2-fs panic (device 3/2): ext2_read_inode: unable to read 
>  i_node block-inode=45263, block=180232

Uhoh... 
 
> [Then the system just sits. It isn't crashed, but it just sits]

Indeed, the kernel *is* happily running, it is the filesystem that crashed...
(which might have happened because the disk was full,
but that's another story...)

> This looks to me like a partition failure. Is there ANY WAY to mount the 
> home directory just long enough to get some files before I format the 
> drive? Any help at all is REALLY REALLY appreciated, as many months of 
> work is at stake here.

Well, as far as I see it, the data-recovery will not be really simple (alas).

First, try to make a backup from the hard-disk, this is tougher
than it sounds, and might involve writing a little program which
tries to read each sector of the harddisk in turn, and writes them to
another hard-disk... (preferably using low-level routines...)
(I put some pascal routines for reading harddisk sectors below)

If this cannot be done, be extremely cautious about any steps you take
with the following programs.

Then you should try to boot with the boot/root disk, and run
fsck (the file-system diagnostics/repair tool) on your hard-disk.
(type "fsck -rV -t ext2 /dev/<your hd-device here>", this will
run fsck in interactive mode). It should be quite straightforward.

If fsck is unable to fix your disk (it might be able to fix the disk
using some older information, which might result in the loss of some 
(recent) files), then you could either try to repair the file-system
manually, or try to work a way around the file-system's problem (both 
*real* tricky, requires a good understanding of the structures/values
used by the file-system. Luckily, the file-system's c-files are
included with the Linux kernel sources), or you could try to piece
the data together by looking through each sector, and piecing them
together in the right order (which would require a program to read
each sector from the HD; doing this should be fairly easy, as Ext-2
tries to make all files continuous, so if you find the first sector,
the others should follow (in the right order) after it.

I don't know if there are any (good) disk-repair programs for Linux
out there, but taking a look around might make things a lot easier..

Furthermore, piecing the hard-disk together is a lot of work (I know,
it took me a week to piece together 20% of code I lost when I tested
my own formatting routine, and accidentally wiped dir and fat entries
on my source disk (which was a DD)), so it might be better just to 
forget about the whole stuff, and write it again (which isn't as
tough as doing it the first time, as you already did it once, and a
lot of the solutions are now known...)

Well, I hope this is of any help, and hope that you'll get the code
back together...

See ya,
  Alex.

P.S.: Here the code, it's for DOS, the important bit is in readsector:

program readpartitiontable;

uses dos, crt;

type    partition = record
	  active,
	  ostype,
	  s_track,
	  s_head,
	  s_sector,
	  e_track,
	  e_head,
	  e_sector      : Integer;
	  s_block,
	  blocks        : LongInt;
	end;

const   disk_reset      = 0;    { dl = drive (bij alle operaties)}
	disk_status     = 1;
	disk_read       = 2;   { dh:kop, ch:cl llllllll:hhssssss, al:aant. }
	disk_write      = 3;   { es:bx:addr. l/h=low/high trackno, s=sect. }
	disk_verwrite   = 4;
	disk_format     = 5;    { see bios-docs }

var     r       : registers;
	p       : partition;
	v1, v2, v3, v4, fats,
	dr, pa  : integer;
	s       : array[0..511] of byte;

procedure readsector(drive, track, head, sector : integer; adr : pointer);
var     l, t, s : integer;
	r       : registers;
begin
  t := (track and $00ff);
  s := ((sector and $3f) or ((track and $0300) shr 2));
  r.ah := 2;
  r.dl := $80 + drive;
  r.dh := head;
  r.ch := t;
  r.cl := s;
  r.al := 1;
  r.es := seg(adr^);
  r.bx := ofs(adr^);
  intr($13, r);
end;

procedure getpartition(drive, number: integer; var p: partition);
var     sector  : array[0..511] of byte;
	s, t, h, o      : integer;
	v1, v2, v3, v4  : longint;
begin
  r.ah := 2;
  r.dx := drive + 128;
  r.cx := 1;
  r.al := 1;
  r.es := seg(sector[0]);
  r.bx := ofs(sector[0]);
  intr($13, r);
  if (r.flags and 1) = 1 then
  begin
      p.active := 0;
      p.ostype := 0;
      p.s_track := 0;
      p.s_head := 0;
      p.s_sector := 0;
      p.e_track := 0;
      p.e_head := 0;
      p.e_sector := 0;
      p.s_block := 0;
      p.blocks := 0;
  end
  else
  begin
    o := $1ae + $10 * number;
    p.active := sector[o];
    p.ostype := sector[o + 4];
    h := sector[o + 1];
    s := sector[o + 2];
    t := sector[o + 3];
    t := t + ((s and $c0) shl 2);
    s := s and $3f;
    p.s_track := t;
    p.s_head := h;
    p.s_sector := s;
    h := sector[o + 5];
    s := sector[o + 6];
    t := sector[o + 7];
    t := t + ((s and $c0) shl 2);
    s := s and $3f;
    p.e_track := t;
    p.e_head := h;
    p.e_sector := s;
    v1 := sector[o+11];
    v2 := sector[o+10];
    v3 := sector[o+ 9];
    v4 := sector[o+ 8];
    p.s_block := (v1 shl 24) + (v2 shl 16) + (v3 shl 8) + v4;
    v1 := sector[o+15];
    v2 := sector[o+14];
    v3 := sector[o+13];
    v4 := sector[o+12];
    p.blocks := (v1 shl 24) + (v2 shl 16) + (v3 shl 8) + v4;
  end;
end;

procedure showdrive(drive : integer);
var     l       : integer;
	p       : partition;
begin
  writeln('--- Drive ', drive:1,' Partitions -------------------------------------------');
  for l := 1 to 4 do
  begin
    getpartition(drive, l, p);
    if p.active = $80 then
      write('A ')
    else
      write('  ');
    write(l:1,': ', p.ostype:3);
    write(' C',p.s_track:4,' H',p.s_head:2,' S',p.s_sector:2);
    write(' C',p.e_track:4,' H',p.e_head:2,' S',p.e_sector:2);
    writeln(' F', p.s_block:7, ' L', p.blocks:7);
  end;
end;

function isdrive(drive : integer) : integer;
var     r       : registers;
begin
  r.ah := 21;
  r.dl := $80 + drive;
  intr($13, r);
  isdrive := ord((r.flags and 1) = 0) * r.ah;
end;

begin
  clrscr;
  if isdrive(0) = 3 then
    showdrive(0);
  if isdrive(1) = 3 then
    showdrive(1);
  writeln;
  writeln('-- View Bootblock --');
  repeat
    write('Enter Drive Number:');
    readln(dr);
  until isdrive(dr) = 3;
  repeat
    write('Enter Partition Number:');
    readln(pa);
    getpartition(dr, pa, p);
  until (p.ostype = 6) or (p.ostype = 4);
  readsector(dr, p.s_track, p.s_head, p.s_sector, @s[0]);
  writeln;
  writeln('--- Bootblock Drive ', dr:1, ' Partition ', pa:1, ' -------------------------------------------');
  v1 := s[12];
  v2 := s[11];
  writeln('    bytes per sector:', ((v1 shl 8) + v2):6);
  writeln(' sectors per cluster:', s[13]:6);
  v1 := s[15];
  v2 := s[14];
  writeln('    reserved sectors:', ((v1 shl 8) + v2):6);
  writeln('      number of FATs:', s[16]:6);
  v1 := s[18];
  v2 := s[17];
  writeln('   directory entries:', ((v1 shl 8) + v2):6);
  v1 := s[20];
  v2 := s[19];
  writeln('   number of sectors:', ((v1 shl 8) + v2):6);
  writeln('    media describtor:', s[21]:6);
  v1 := s[23];
  v2 := s[22];
  writeln('     sectors per FAT:', ((v1 shl 8) + v2):6);
  v1 := s[25];
  v2 := s[24];
  writeln('   sectors per track:', ((v1 shl 8) + v2):6);
  v1 := s[27];
  v2 := s[26];
  writeln('     number of heads:', ((v1 shl 8) + v2):6);
  v1 := s[29];
  v2 := s[28];
  writeln('      hidden sectors:', ((v1 shl 8) + v2):6);
  readln;
end.
 



This archive was generated by hypermail 2b30 : 12/18/00 PST