[comp.unix.questions] Can you recover deleted files in Unix ?!?

kellow@ndcheg.cheg.nd.edu (John Kellow) (08/21/89)

I need some help.  Maybe this questions has been covered but I can't
remember seeing anything about it before.  Is there any way to recover
deleted files in System V.2 Unix?  I typed rm * when I thought I was
in the /tmp directory but guess where I was - that's right, my home
directory.  Unfortunately there were some important changes that
haven't been backed up.  I was the only person using the computer at
the time, and I immediately unmounted the file system.  My manual
entry for rm says something to the the effect that if a directory
entry was the last link count for a file then the file is destroyed -
does this mean data and everything?  Please tell me it isn't so.  I'll
be eagerly awaiting any replies.

John Kellow
kellow@ndcheg.cheg.nd.edu

wendt@segovia.CS.ColoState.Edu (alan l wendt) (08/22/89)

One thing to try is to run the "strings" command on the unmounted disk,
and pipe the result to a file on another disk, which you then edit to
extract the info that you need.

Usually you won't be able to run vi on the resulting file, because it
will be too big.  If that happens, you can use strings piped into
combinations of head and tail to extract 10K-line pieces.

Alan W.

kellow@ndcheg.cheg.nd.edu (John Kellow) (08/22/89)

kellow@ndcheg.cheg.nd.edu (John Kellow) writes:


>I need some help.  Maybe this questions has been covered but I can't
>remember seeing anything about it before.  Is there any way to recover
>deleted files in System V.2 Unix?  I typed rm * when I thought I was
>in the /tmp directory but guess where I was - that's right, my home
>directory.  Unfortunately there were some important changes that
>haven't been backed up.  I was the only person using the computer at
>the time, and I immediately unmounted the file system.  My manual
>entry for rm says something to the the effect that if a directory
>entry was the last link count for a file then the file is destroyed -
>does this mean data and everything?  Please tell me it isn't so.  I'll
>be eagerly awaiting any replies.

Well, in answer to my own question - I did recover the important data
that I had deleted.  I guess the answer would be no, you can't
"undelete" files in SYSV.2 Unix but you can recover individual blocks
of data.  It took a few hours of trying to decipher the manuals and
some trial and error but I think I've got it figured out and its not
too complicated (someone correct me if I'm wrong).  The actual blocks
of data are not removed, only the inode entry.  Since the inode entry
contains all of the information as to what blocks belong to what file
and in what order, you can't very well "undelete" the file but the
data might still be there and you can piece it back together by hand.
The names of the deleted files are not removed from the directory but
the inode number is set to zero, so all that gives you is the list of
which files were deleted.  The important information is the free list.
The superblock contains a list of the 50 most recently freed blocks
and the address of the next block in the list.  It seems that the last
block freed will be the first block allocated, so you have to act
fast!  Luckily I synched the disks and umounted the file system as
soon as my mistake occured.  One more problem is that once the 50
entries of free blocks in the superblock are filled, the free list
will be copied into the next block to be freed, so that the free list
space in the superblock can be used again.  In other words, for every
50 blocks of space freed, 1 of those blocks will be used to contain
the next block in the freelist.  That means that there's a very good
chance that some of your data will be lost.  Now the good news,
recovering the data is actually pretty simple (this all has to be done
as the root user):

	-Examine the Superblock of the file system with fsdb
	 typing 512B.p0e will give something like this:

0001000:     248       0   15760      32       0    1066       0    3584
0001020:       0    3583       0    3615       0    3614       0    3613
0001040:       0    3612       0    3611       0    3610       0    3609
0001060:       0    3608       0    3607       0    3606       0    3605
0001100:       0    3604       0    3603       0    3602       0    2496
0001120:       0    3675       0    3684       0    3683       0    3682
...

	-248 is the # of blocks in the inode list,  15760 is the
	 number of blocks in the file system,  32 is the number of
	 entries in the free list and the next 50 numbers are the free
	 blocks (but only the first 32 make up the current list)

	-1066 is the first block in the free list and indicates the
	 next block in the list, so if you want to recover more than
	 the number of blocks in the current list(32) you would look
	 in block 1066 and that would contain another free list with
	 50 free blocks, with the first entry pointing to the next
	 block in the list, etc.

	-from what I understand, block 1066 was one of the blocks
	 freed up but now it contains part of the free list so you
	 can't recover that data

	-write down the numbers of the blocks you want to recover and
	 use bcopy to copy those blocks into files on another file system

	-for example, to recover block 3584 type bcopy and answer the
	 questions:
	 bcopy
	 TO: 3584 (this makes a file called 3584 in the current file system)
	 OFFSET: 0
	 FROM: /dev/fp003 (the name of the partion you're recovering from)
	 OFFSET: 7168 (my version of bcopy goes by 512 byte blocks so
	 I have to multiply 3584 by 2)
	 COUNT: 2 (2 512 byte blocks or 1 1024 byte logical disk block)
	 (it keeps asking FROM: so just press return twice to exit)

	-Thats it, just use emacs or vi to look at the blocks and
	 piece them back together, blocks belonging to the same file
	 should appear consecutively in the free list but you don't
	 know what order they should go in - thats not too difficult
	 to figure out with text files but I guess binary files are
	 another story (luckily I didn't need to recover any of those)
	 
Well, this explanation turned out longer than I thought but maybe it
will help someone else in a similar situation.  I think most of this is
standard System V.2 but some of it may be specific to my system.  I'd
appreciate any comments anyone has.  Maybe there's a better way to do
this or it seems to me that you could write a simple shell script or
program to automate this procedure ( I hope I didn't go to all this
trouble if there's already something that does this!).

John Kellow
kellow@ndcheg.cheg.nd.edu

ric@Apple.COM (Ric Urrutia) (08/22/89)

In article <741@ndcheg.cheg.nd.edu> kellow@ndcheg.cheg.nd.edu (John Kellow) writes:
>kellow@ndcheg.cheg.nd.edu (John Kellow) writes:
>
>Well, in answer to my own question - I did recover the important data
>that I had deleted.  I guess the answer would be no, you can't
>"undelete" files in SYSV.2 Unix but you can recover individual blocks
>of data.  It took a few hours of trying to decipher the manuals and
>some trial and error but I think I've got it figured out and its not
>too complicated (someone correct me if I'm wrong).  The actual blocks
>of data are not removed, only the inode entry.  Since the inode entry
>contains all of the information as to what blocks belong to what file
>and in what order, you can't very well "undelete" the file but the
>data might still be there and you can piece it back together by hand.

I have never understood why the entire inode is zeroed out when a file is 
removed.  I believe that a SVFS inode is "free" if the link count is 0.  If
the removal of a file simply made the di_nlink field 0 and left the rest of
the inode info intact, one would have a better chance of "undeleting" a file.  

Granted that if the file is quite large, certain blocks will be lost as they
are allocated for chaining the free list together.

debra@alice.UUCP (Paul De Bra) (08/23/89)

In article <34209@apple.Apple.COM> ric@Apple.COM (Ric Urrutia) writes:
>In article <741@ndcheg.cheg.nd.edu> kellow@ndcheg.cheg.nd.edu (John Kellow) writes:
>...
>I have never understood why the entire inode is zeroed out when a file is 
>removed.  I believe that a SVFS inode is "free" if the link count is 0.  If
>the removal of a file simply made the di_nlink field 0 and left the rest of
>the inode info intact, one would have a better chance of "undeleting" a file.  

A file with just di_nlink = 0 is not necessarily a deleted file. It is
simply a linkless file, still being accessed by a process. It MUST be
distinguished from deleted files somehow, otherwise the kernel can't know
which files are really deleted.
Furthermore, after a crash fsck can easily detect such linkless files
and reconnect them to lost+found, whereas it would not be able to
distinguish a linkless file from a deleted file if the inodes of deleted
files where not marked in a different way.

Now, one could imagine more friendly ways to distinguish a linkless file
from a deleted file, but at least the distinction is some motivation for
zeroing the inode.

Paul.
-- 
------------------------------------------------------
|debra@research.att.com   | uunet!research!debra     |
------------------------------------------------------