home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 August / PCWorld_1999-08_cd.bin / doc / HOWTO / mini / Ext2fs-Undeletion < prev    next >
Text File  |  1999-05-23  |  44KB  |  1,189 lines

  1.   Linux Ext2fs Undeletion mini-HOWTO
  2.   Aaron Crane, aaronc@pobox.com
  3.   v1.3, 2 February 1999
  4.  
  5.   Picture this.  You've spent the last three days with no sleep, no
  6.   food, not even a shower.  Your hacking compulsion has at last paid
  7.   off: you've finished that program that will bring you world-wide fame
  8.   and recognition.  All that you still need to do is tar it up and put
  9.   it on Metalab.  Oh, and delete all those Emacs backup files.  So you
  10.   say rm * ~.  And too late, you notice the extra space in that command.
  11.   You've just deleted your magnum opus!  But help is at hand.  This doc¡
  12.   ument presents a discussion of how to retrieve deleted files from a
  13.   Second Extended File System.  Just maybe, you'll be able to release
  14.   that program after all...
  15.   ______________________________________________________________________
  16.  
  17.   Table of Contents
  18.  
  19.  
  20.   1. Introduction
  21.  
  22.      1.1 Revision history
  23.         1.1.1 Changes in version 1.1
  24.         1.1.2 Changes in version 1.2
  25.         1.1.3 Changes in version 1.3
  26.      1.2 Canonical locations of this document
  27.  
  28.   2. How not to delete files
  29.  
  30.   3. What recovery rate can I expect?
  31.  
  32.   4. So, how do I undelete a file?
  33.  
  34.   5. Unmounting the file system
  35.  
  36.   6. Preparing to change inodes directly
  37.  
  38.   7. Preparing to write data elsewhere
  39.  
  40.   8. Finding the deleted inodes
  41.  
  42.   9. Obtaining the details of the inodes
  43.  
  44.   10. Recovering data blocks
  45.  
  46.      10.1 Short files
  47.      10.2 Longer files
  48.  
  49.   11. Modifying inodes directly
  50.  
  51.   12. Will this get easier in future?
  52.  
  53.   13. Are there any tools to automate this process?
  54.  
  55.   14. Colophon
  56.  
  57.   15. Credits and Bibliography
  58.  
  59.   16. Legalities
  60.  
  61.  
  62.  
  63.   ______________________________________________________________________
  64.  
  65.  
  66.  
  67.   1.  Introduction
  68.  
  69.   This mini-Howto attempts to provide hints on how to retrieve deleted
  70.   files from an ext2 file system.  It also contains a limited amount of
  71.   discussion of how to avoid deleting files in the first place.
  72.  
  73.   I intend it to be useful certainly for people who have just had, shall
  74.   we say, a little accident with rm; however, I also hope that people
  75.   read it anyway.  You never know: one day, some of the information in
  76.   here could save your bacon.
  77.  
  78.   The text assumes a little background knowledge about UNIX file systems
  79.   in general; however, I hope that it will be accessible to most Linux
  80.   users.  If you are an outright beginner, I'm afraid that undeleting
  81.   files under Linux does require a certain amount of technical knowledge
  82.   and persistence, at least for the time being.
  83.  
  84.   You will be unable to recover deleted files from an ext2 file system
  85.   without at least read access to the raw device on which the file was
  86.   stored.  In general, this means that you must be root, but some
  87.   distributions (such as Debian GNU/Linux) provide a disk group whose
  88.   members have access to such devices.  You also need debugfs from the
  89.   e2fsprogs package.  This should have been installed by your
  90.   distribution.
  91.  
  92.   Why have I written this?  It stems largely from my own experiences
  93.   with a particularly foolish and disastrous rm -r command as root.  I
  94.   deleted about 97 JPEG files which I needed and could almost certainly
  95.   not recover from other sources.  Using some helpful tips (see section
  96.   ``Credits and Bibliography'') and a great deal of persistence, I
  97.   recovered 91 files undamaged.  I managed to retrieve at least parts of
  98.   five of the rest (enough to see what the picture was in each case).
  99.   Only one was undisplayable, and even for this one, I am fairly sure
  100.   that no more than 1024 bytes were lost (though unfortunately from the
  101.   beginning of the file; given that I know nothing about the JFIF file
  102.   format I had done as much as I could).
  103.  
  104.   I shall discuss further below what sort of recovery rate you can
  105.   expect for deleted files.
  106.  
  107.  
  108.   1.1.  Revision history
  109.  
  110.   The various publicly-released revisions of this document (and their
  111.   publication dates) are as follows:
  112.  
  113.  
  114.   ╖  v1.0 on 18 January 1997
  115.  
  116.   ╖  v1.1 on 23 July 1997 (see section ``Changes in version 1.1'')
  117.  
  118.   ╖  v1.2 on 4 August 1997 (see section ``Changes in version 1.2'')
  119.  
  120.   ╖  v1.3 on 2 February 1999 (see section ``Changes in version 1.3'')
  121.  
  122.  
  123.   1.1.1.  Changes in version 1.1
  124.  
  125.   What changes have been made in this version?  First of all, the thinko
  126.   in the example of file recovery has been fixed.  Thankyou to all those
  127.   who wrote to point out my mistaek; I hope I've learned to be more
  128.   careful when making up program interaction.
  129.  
  130.   Secondly, the discussion of UNIX file system layout has been rewritten
  131.   to be, I hope, more understandable.  I wasn't entirely happy with it
  132.   in the first place, and some people's comments indicated that it
  133.   wasn't clear.
  134.  
  135.   Thirdly, the vast uuencoded gzipped tarball of fsgrab in the middle of
  136.   the file has been removed.  The program is now available on my website
  137.   <http://pobox.com/~aaronc/tech/fsgrab-1.2.tar.gz> and on Metalab
  138.   <http://metalab.unc.edu/pub/Linux/utils/file/> (and mirrors).
  139.  
  140.   Fourthly, the document has been translated into the Linux
  141.   Documentation Project SGML Tools content markup language.  This markup
  142.   language can be easily converted to any of a number of other markup
  143.   languages (including HTML and LaTeX) for convenient display and
  144.   printing.  One benefit of this is that beautiful typography in paper
  145.   editions is a much more achievable goal; another is that the document
  146.   has cross-references and hyperlinks when viewed on the Web.
  147.  
  148.  
  149.   1.1.2.  Changes in version 1.2
  150.  
  151.   This revision is very much an incremental change.  It's here mainly to
  152.   include changes suggested by readers, one of which is particularly
  153.   important.
  154.  
  155.   The first change was suggested by Egil Kvaleberg egil@kvaleberg.no,
  156.   who pointed out the dump command in debugfs.  Thanks again, Egil.
  157.  
  158.   The second change is to mention the use of chattr for avoiding
  159.   deleting important files.  Thanks to Herman Suijs H.P.M.Suijs@kub.nl
  160.   for mentioning this one.
  161.  
  162.   The abstract has been revised.  URLs have been added for organisations
  163.   and software.  Various other minor changes have been made (including
  164.   fixing typos and so on).
  165.  
  166.  
  167.   1.1.3.  Changes in version 1.3
  168.  
  169.   Though it is the first release in 17 months, there is very little that
  170.   is new here.  This release merely fixes a few minor errors (typos,
  171.   dangling URLs, that sort of thing -- especially the non-link to the
  172.   Open Group), and updates a few parts of the text that have become
  173.   hopelessly out-of-date, such as the material on kernel versions and on
  174.   lde.  Oh, and I've changed `Sunsite' to `Metalab' throughout.
  175.  
  176.   This release is anticipated to be the last one before release 2.0,
  177.   which will hopefully be a full Howto.  I have been working on some
  178.   substantial changes which will justify an increment of the major
  179.   version number.
  180.  
  181.  
  182.   1.2.  Canonical locations of this document
  183.  
  184.   The latest public release of this document should always be available
  185.   in on the Linux Documentation Project site
  186.   <http://metalab.unc.edu/LDP/> (and mirrors).
  187.  
  188.   The latest release is also kept on my website
  189.   <http://pobox.com/~aaronc/> in several formats:
  190.  
  191.  
  192.   ╖  SGML source <http://pobox.com/~aaronc/tech/e2-undel/howto.sgml>.
  193.      This is the source as I have written it, using the SGML Tools
  194.      package.
  195.  
  196.   ╖  HTML <http://pobox.com/~aaronc/tech/e2-undel/html/>.  This is HTML,
  197.      automatically generated from the SGML source.
  198.  
  199.   ╖  Plain text <http://pobox.com/~aaronc/tech/e2-undel/howto.txt>.
  200.      This is plain text, which is also automatically generated from the
  201.      SGML source.
  202.  
  203.  
  204.  
  205.   2.  How not to delete files
  206.  
  207.   It is vital to remember that Linux is unlike MS-DOS when it comes to
  208.   undeletion.  For MS-DOS (and its bastard progeny Windows 95), it is
  209.   generally fairly straightforward to undelete a file - the `operating
  210.   system' (I use the term loosely) even comes with a utility which
  211.   automates much of the process.  For Linux, this is not the case.
  212.  
  213.   So.  Rule number one (the prime directive, if you will) is:
  214.  
  215.  
  216.        KEEP BACKUPS
  217.  
  218.  
  219.   no matter what.  Think of all your data.  Perhaps, like me, you keep
  220.   several years' of accumulated email, contacts, programs, papers on
  221.   your computer.  Think of how your life would be turned upside down if
  222.   you had a catastrophic disk failure, or if -- heaven forbid! -- a
  223.   malicious cracker wiped your disks.  This is not unlikely; I have
  224.   corresponded with a number of people in just such a situation.  I
  225.   exhort all right-thinking Linux users to go out and buy a useful
  226.   backup device, work out a decent backup schedule, and to stick to it.
  227.   Myself, I use a spare hard disk on a second machine, and periodically
  228.   mirror my home directory onto it over the ethernet.  For more
  229.   information on planning a backup schedule, read Frisch (1995) (see
  230.   section ``Bibliography and Credits'').
  231.  
  232.   In the absence of backups, what then?  (Or even in the presence of
  233.   backups: belt and braces is no bad policy where important data is
  234.   concerned.)
  235.  
  236.   Try to set the permissions for important files to 440 (or less):
  237.   denying yourself write access to them means that rm requires an
  238.   explicit confirmation before deleting.  (I find, however, that if I'm
  239.   recursively deleting a directory with rm -r, I'll interrupt the
  240.   program on the first or second confirmation request and reissue the
  241.   command as rm -rf.)
  242.  
  243.   A good trick for selected files is to create a hard link to them in a
  244.   hidden directory.  I heard a story once about a sysadmin who
  245.   repeatedly deleted /etc/passwd by accident (thereby half-destroying
  246.   the system).  One of the fixes for this was to do something like the
  247.   following (as root):
  248.  
  249.  
  250.  
  251.        # mkdir /.backup
  252.        # ln /etc/passwd /.backup
  253.  
  254.  
  255.  
  256.  
  257.   It requires quite some effort to delete the file contents completely:
  258.   if you say
  259.  
  260.  
  261.  
  262.        # rm /etc/passwd
  263.  
  264.  
  265.   then
  266.  
  267.  
  268.  
  269.        # ln /.backup/passwd /etc
  270.  
  271.  
  272.  
  273.  
  274.   will retrieve it.  Of course, this does not help in the event that you
  275.   overwrite the file, so keep backups anyway.
  276.  
  277.   On an ext2 file system, it is possible to use ext2 attributes to
  278.   protect things.  These attributes are manipulated with the chattr
  279.   command.  There is an `append-only' attribute: a file with this
  280.   attribute may be appended to, but may not be deleted, and the existing
  281.   contents of the file may not be overwritten.  If a directory has this
  282.   attribute, any files or directories within it may be modified as
  283.   normal, but no files may be deleted.  The `append-only' attribute is
  284.   set with
  285.  
  286.  
  287.  
  288.        $ chattr +a FILE...
  289.  
  290.  
  291.  
  292.  
  293.   There is also an `immutable' attribute, which can only be set or
  294.   cleared by root.  A file or directory with this attribute may not be
  295.   modified, deleted, renamed, or (hard) linked.  It may be set as
  296.   follows:
  297.  
  298.  
  299.  
  300.        # chattr +i FILE...
  301.  
  302.  
  303.  
  304.  
  305.   The ext2fs also provides the `undeletable' attribute (+u in chattr).
  306.   The intention is that if a file with that attribute is deleted,
  307.   instead of actually being reused, it is merely moved to a `safe
  308.   location' for deletion at a later date.  Unfortunately this feature
  309.   has not yet been implemented in mainstream kernels; and though in the
  310.   past there has been some interest in implementing it, it is not (to my
  311.   knowledge) available for any current kernels.
  312.  
  313.   Some people advocate making rm a shell alias or function for rm -i
  314.   (which asks for confirmation on every file you delete).  Indeed, the
  315.   Red Hat distribution <http://www.redhat.com/> does this by default for
  316.   all users, including root.  Personally, I cannot stand software which
  317.   won't run unattended, so I don't do that.  There is also the problem
  318.   that sooner or later, you'll be running in single-user mode, or using
  319.   a different shell, or even a different machine, where your rm function
  320.   doesn't exist.  If you expect to be asked for confirmation, it is easy
  321.   to forget where you are and to specify too many files for deletion.
  322.   Likewise, the various scripts and programs that replace rm are, IMHO,
  323.   very dangerous.
  324.  
  325.   A slightly better solution is to start using a package which handles
  326.   `recyclable' deletion by providing a command not named rm.  For
  327.   details on these, see Peek, et al (1993) (see section ``Bibliography
  328.   and Credits'').  These however still suffer from the problem that they
  329.   tend to encourage the user to have a nonchalant attitude to deletion,
  330.   rather than the cautious approach that is often required on Unix
  331.   systems.
  332.  
  333.  
  334.  
  335.   3.  What recovery rate can I expect?
  336.  
  337.   That depends.  Among the problems with recovering files on a high-
  338.   quality, multi-tasking, multi-user operating system like Linux is that
  339.   you never know when someone wants to write to the disk.  So when the
  340.   operating system is told to delete a file, it assumes that the blocks
  341.   used by that file are fair game when it wants to allocate space for a
  342.   new file.  (This is a specific example of a general principle for
  343.   Unix-like systems: the kernel and the associated tools assume that the
  344.   users aren't idiots.)  In general, the more usage your machine gets,
  345.   the less likely you are to be able to recover files successfully.
  346.  
  347.   Also, disk fragmentation can affect the ease of recovering files.  If
  348.   the partition containing the deleted files is very fragmented, you are
  349.   unlikely to be able to read a whole file.
  350.  
  351.   If your machine, like mine, is effectively a single-user workstation,
  352.   and you weren't doing anything disk-intensive at the fatal moment of
  353.   deleting those files, I would expect a recovery rate in the same ball-
  354.   park as detailed above.  I retrieved nearly 94% of the files (and
  355.   these were binary files, please note) undamaged.  If you get 80% or
  356.   better, you can feel pretty pleased with yourself, I should think.
  357.  
  358.  
  359.  
  360.   4.  So, how do I undelete a file?
  361.  
  362.   The procedure principally involves finding the data on the raw
  363.   partition device and making it visible again to the operating system.
  364.   There are basically two ways of doing this: one is to modify the
  365.   existing file system such that the deleted inodes have their `deleted'
  366.   flag removed, and hope that the data just magically falls back into
  367.   place.  The other method, which is safer but slower, is to work out
  368.   where the data lies in the partition and write it out into a new file
  369.   on another file system.
  370.  
  371.   There are some steps you need to take before beginning to attempt your
  372.   data recovery; see sections ``Unmounting the file system'',
  373.   ``Preparing to change inodes directly'' and ``Preparing to write data
  374.   elsewhere'' for details.  To find out how to actually retrieve your
  375.   files, see sections ``Finding the deleted inodes'', ``Obtaining the
  376.   details of the inodes'', ``Recovering data blocks'' and ``Modifying
  377.   inodes directly''.
  378.  
  379.  
  380.  
  381.   5.  Unmounting the file system
  382.  
  383.   Regardless of which method you choose, the first step is to unmount
  384.   the file system containing the deleted files.  I strongly discourage
  385.   any urges you may have to mess around on a mounted file system.  This
  386.   step should be performed as soon as possible after you realise that
  387.   the files have been deleted; the sooner you can unmount, the smaller
  388.   the chance that your data will be overwritten.
  389.  
  390.   The simplest method is as follows: assuming the deleted files were in
  391.   the /usr file system, say:
  392.  
  393.  
  394.  
  395.        # umount /usr
  396.  
  397.   You may, however, want to keep some things in /usr available.  So
  398.   remount it read-only:
  399.  
  400.  
  401.  
  402.        # mount -o ro,remount /usr
  403.  
  404.  
  405.  
  406.  
  407.   If the deleted files were on the root partition, you'll need to add a
  408.   -n option to prevent mount from trying to write to /etc/mtab:
  409.  
  410.  
  411.  
  412.        # mount -n -o ro,remount /
  413.  
  414.  
  415.  
  416.  
  417.   Regardless of all this, it is possible that there will be another
  418.   process using that file system (which will cause the unmount to fail
  419.   with an error such as `Resource busy').  There is a program which will
  420.   send a signal to any process using a given file or mount point: fuser.
  421.   Try this for the /usr partition:
  422.  
  423.  
  424.  
  425.        # fuser -v -m /usr
  426.  
  427.  
  428.  
  429.  
  430.   This lists the processes involved.  Assuming none of them are vital,
  431.   you can say
  432.  
  433.  
  434.  
  435.        # fuser -k -v -m /usr
  436.  
  437.  
  438.  
  439.  
  440.   to send each process a SIGKILL (which is guaranteed to kill it), or
  441.   for example,
  442.  
  443.  
  444.  
  445.        # fuser -k -TERM -v -m /usr
  446.  
  447.  
  448.  
  449.  
  450.   to give each one a SIGTERM (which will normally make the process exit
  451.   cleanly).
  452.  
  453.  
  454.  
  455.   6.  Preparing to change inodes directly
  456.  
  457.   My advice?  Don't do it this way.  I really don't think it's wise to
  458.   play with a file system at a low enough level for this to work.  This
  459.   method also has problems in that you can only reliably recover the
  460.   first 12 blocks of each file.  So if you have any long files to
  461.   recover, you'll normally have to use the other method anyway.
  462.   (Although see section ``Will this get easier in future?'' for
  463.   additional information.)
  464.  
  465.   If you feel you must do it this way, my advice is to copy the raw
  466.   partition data to an image on a different partition, and then mount
  467.   this using loopback:
  468.  
  469.  
  470.  
  471.        # cp /dev/hda5 /root/working
  472.        # mount -t ext2 -o loop /root/working /mnt
  473.  
  474.  
  475.  
  476.  
  477.   (Note that obsolete versions of mount may have problems with this.  If
  478.   your mount doesn't work, I strongly suggest you get the latest
  479.   version, or at least version 2.7, as some very old versions have
  480.   severe security bugs.)
  481.  
  482.   Using loopback means that if and when you completely destroy the file
  483.   system, all you have to do is copy the raw partition back and start
  484.   over.
  485.  
  486.  
  487.  
  488.   7.  Preparing to write data elsewhere
  489.  
  490.   If you chose to go this route, you need to make sure you have a rescue
  491.   partition somewhere -- a place to write out new copies of the files
  492.   you recover.  Hopefully, your system has several partitions on it:
  493.   perhaps a root, a /usr, and a /home.  With all these to choose from,
  494.   you should have no problem: just create a new directory on one of
  495.   these.
  496.  
  497.   If you have only a root partition, and store everything on that,
  498.   things are slightly more awkward.  Perhaps you have an MS-DOS or
  499.   Windows partition you could use?  Or you have the ramdisk driver in
  500.   your kernel, maybe as a module?  To use the ramdisk (assuming a kernel
  501.   more recent than 1.3.48), say the following:
  502.  
  503.  
  504.  
  505.        # dd if=/dev/zero of=/dev/ram0 bs=1k count=2048
  506.        # mke2fs -v -m 0 /dev/ram0 2048
  507.        # mount -t ext2 /dev/ram0 /mnt
  508.  
  509.  
  510.  
  511.  
  512.   This creates a 2MB ramdisk volume, and mounts it on /mnt.
  513.  
  514.   A short word of warning: if you use kerneld (or its replacement kmod
  515.   in 2.2.x and later 2.1.x kernels) to automatically load and unload
  516.   kernel modules, then don't unmount the ramdisk until you've copied any
  517.   files from it onto non-volatile storage.  Once you unmount it, kerneld
  518.   assumes it can unload the module (after the usual waiting period), and
  519.   once this happens, the memory gets re-used by other parts of the
  520.   kernel, losing all the painstaking hours you just spent recovering
  521.   your data.
  522.  
  523.   If you have a Zip, Jaz, or LS-120 drive, or something similar, it
  524.   would probably be a good choice for a rescue partition location.
  525.   Otherwise, you'll just have to stick with floppies.
  526.  
  527.   The other thing you're likely to need is a program which can read the
  528.   necessary data from the middle of the partition device.  At a pinch,
  529.   dd will do the job, but to read from, say, 600 MB into an 800 MB
  530.   partition, dd insists on reading but ignoring the first 600 MB.  This
  531.   takes a not inconsiderable amount of time, even on fast disks.  My way
  532.   round this was to write a program which will seek to the middle of the
  533.   partition.  It's called fsgrab; you can find the source package on my
  534.   website <http://pobox.com/~aaronc/tech/fsgrab-1.2.tar.gz> or on
  535.   Metalab <http://metalab.unc.edu/pub/Linux/utils/file/> (and mirrors).
  536.   If you want to use this method, the rest of this mini-Howto assumes
  537.   that you have fsgrab.
  538.  
  539.   If none of the files you are trying to recover were more than 12
  540.   blocks long (where a block is usually one kilobyte), then you won't
  541.   need fsgrab.
  542.  
  543.   If you need to use fsgrab but don't want to download and build it, it
  544.   is fairly straightforward to translate an fsgrab command-line to one
  545.   for dd.  If we have
  546.  
  547.  
  548.        fsgrab -c count -s skip device
  549.  
  550.  
  551.   then the corresponding (but typically much slower) dd command is
  552.  
  553.  
  554.        dd bs=1k if=device count=count skip=skip
  555.  
  556.  
  557.   I must warn you that, although fsgrab functioned perfectly for me, I
  558.   can take no responsibility for how it performs.  It was really a very
  559.   quick and dirty kludge just to get things to work.  For more details
  560.   on the lack of warranty, see the `No Warranty' section in the COPYING
  561.   file included with it (the GNU General Public Licence).
  562.  
  563.  
  564.  
  565.   8.  Finding the deleted inodes
  566.  
  567.   The next step is to ask the file system which inodes have recently
  568.   been freed.  This is a task you can accomplish with debugfs.  Start
  569.   debugfs with the name of the device on which the file system is
  570.   stored:
  571.  
  572.  
  573.  
  574.        # debugfs /dev/hda5
  575.  
  576.  
  577.  
  578.  
  579.   If you want to modify the inodes directly, add a -w option to enable
  580.   writing to the file system:
  581.  
  582.  
  583.  
  584.        # debugfs -w /dev/hda5
  585.  
  586.  
  587.  
  588.  
  589.   The debugfs command to find the deleted inodes is lsdel.  So, type the
  590.   command at the prompt:
  591.  
  592.  
  593.  
  594.  
  595.   debugfs:  lsdel
  596.  
  597.  
  598.  
  599.  
  600.   After much wailing and grinding of disk mechanisms, a long list is
  601.   piped into your favourite pager (the value of $PAGER).  Now you'll
  602.   want to save a copy of this somewhere else.  If you have less, you can
  603.   type -o followed by the name of an output file.  Otherwise, you'll
  604.   have to arrange to send the output elsewhere.  Try this:
  605.  
  606.  
  607.  
  608.        debugfs:  quit
  609.        # echo lsdel | debugfs /dev/hda5 > lsdel.out
  610.  
  611.  
  612.  
  613.  
  614.   Now, based only on the deletion time, the size, the type, and the
  615.   numerical permissions and owner, you must work out which of these
  616.   deleted inodes are the ones you want.  With luck, you'll be able to
  617.   spot them because they're the big bunch you deleted about five minutes
  618.   ago.  Otherwise, trawl through that list carefully.
  619.  
  620.   I suggest that if possible, you print out the list of the inodes you
  621.   want to recover.  It will make life a lot easier.
  622.  
  623.  
  624.  
  625.   9.  Obtaining the details of the inodes
  626.  
  627.   debugfs has a stat command which prints details about an inode.  Issue
  628.   the command for each inode in your recovery list.  For example, if
  629.   you're interested in inode number 148003, try this:
  630.  
  631.  
  632.  
  633.        debugfs:  stat <148003>
  634.        Inode: 148003   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
  635.        User:   503   Group:   100   Size: 6065
  636.        File ACL: 0    Directory ACL: 0
  637.        Links: 0   Blockcount: 12
  638.        Fragment:  Address: 0    Number: 0    Size: 0
  639.        ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
  640.        atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
  641.        mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
  642.        dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
  643.        BLOCKS:
  644.        594810 594811 594814 594815 594816 594817
  645.        TOTAL: 6
  646.  
  647.  
  648.  
  649.  
  650.   If you have a lot of files to recover, you'll want to automate this.
  651.   Assuming that your lsdel list of inodes to recover in is in lsdel.out,
  652.   try this:
  653.  
  654.  
  655.  
  656.        # cut -c1-6 lsdel.out | grep "[0-9]" | tr -d " " > inodes
  657.  
  658.  
  659.  
  660.  
  661.   This new file inodes contains just the numbers of the inodes to
  662.   recover, one per line.  We save it because it will very likely come in
  663.   handy later on.  Then you just say:
  664.  
  665.  
  666.  
  667.        # sed 's/^.*$/stat <\0>/' inodes | debugfs /dev/hda5 > stats
  668.  
  669.  
  670.  
  671.  
  672.   and stats contains the output of all the stat commands.
  673.  
  674.  
  675.  
  676.   10.  Recovering data blocks
  677.  
  678.   This part is either very easy or distinctly less so, depending on
  679.   whether the file you are trying to recover is more than 12 blocks
  680.   long.
  681.  
  682.  
  683.   10.1.  Short files
  684.  
  685.   If the file was no more than 12 blocks long, then the block numbers of
  686.   all its data are stored in the inode: you can read them directly out
  687.   of the stat output for the inode.  Moreover, debugfs has a command
  688.   which performs this task automatically.  To take the example we had
  689.   before, repeated here:
  690.  
  691.  
  692.  
  693.        debugfs:  stat <148003>
  694.        Inode: 148003   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
  695.        User:   503   Group:   100   Size: 6065
  696.        File ACL: 0    Directory ACL: 0
  697.        Links: 0   Blockcount: 12
  698.        Fragment:  Address: 0    Number: 0    Size: 0
  699.        ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
  700.        atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
  701.        mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
  702.        dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
  703.        BLOCKS:
  704.        594810 594811 594814 594815 594816 594817
  705.        TOTAL: 6
  706.  
  707.  
  708.  
  709.  
  710.   This file has six blocks.  Since this is less than the limit of 12, we
  711.   get debugfs to write the file into a new location, such as
  712.   /mnt/recovered.000:
  713.  
  714.  
  715.  
  716.        debugfs:  dump <148003> /mnt/recovered.000
  717.  
  718.  
  719.  
  720.  
  721.   Of course, this can also be done with fsgrab; I'll present it here as
  722.   an example of using it:
  723.  
  724.  
  725.  
  726.  
  727.   # fsgrab -c 2 -s 594810 /dev/hda5 > /mnt/recovered.000
  728.   # fsgrab -c 4 -s 594814 /dev/hda5 >> /mnt/recovered.000
  729.  
  730.  
  731.  
  732.  
  733.   With either debugfs or fsgrab, there will be some garbage at the end
  734.   of /mnt/recovered.000, but that's fairly unimportant.  If you want to
  735.   get rid of it, the simplest method is to take the Size field from the
  736.   inode, and plug it into the bs option in a dd command line:
  737.  
  738.  
  739.  
  740.        # dd count=1 if=/mnt/recovered.000 of=/mnt/resized.000 bs=6065
  741.  
  742.  
  743.  
  744.  
  745.   Of course, it is possible that one or more of the blocks that made up
  746.   your file has been overwritten.  If so, then you're out of luck: that
  747.   block is gone forever.  (But just imagine if you'd unmounted sooner!)
  748.  
  749.  
  750.   10.2.  Longer files
  751.  
  752.   The problems appear when the file has more than 12 data blocks.  It
  753.   pays here to know a little of how UNIX file systems are structured.
  754.   The file's data is stored in units called `blocks'.  These blocks may
  755.   be numbered sequentially.  A file also has an `inode', which is the
  756.   place where information such as owner, permissions, and type are kept.
  757.   Like blocks, inodes are numbered sequentially, although they have a
  758.   different sequence.  A directory entry consists of the name of the
  759.   file and an inode number.
  760.  
  761.   But with this state of affairs, it is still impossible for the kernel
  762.   to find the data corresponding to a directory entry.  So the inode
  763.   also stores the location of the file's data blocks, as follows:
  764.  
  765.  
  766.   ╖  The block numbers of the first 12 data blocks are stored directly
  767.      in the inode; these are sometimes referred to as the direct blocks.
  768.  
  769.   ╖  The inode contains the block number of an indirect block.  An
  770.      indirect block contains the block numbers of 256 additional data
  771.      blocks.
  772.  
  773.   ╖  The inode contains the block number of a doubly indirect block.  A
  774.      doubly indirect block contains the block numbers of 256 additional
  775.      indirect blocks.
  776.  
  777.   ╖  The inode contains the block number of a triply indirect block.  A
  778.      triply indirect block contains the block numbers of 256 additional
  779.      doubly indirect blocks.
  780.  
  781.   Read that again: I know it's complex, but it's also important.
  782.  
  783.   Now, the kernel implementation for all versions up to and including
  784.   2.0.36 unfortunately zeroes all indirect blocks (and doubly indirect
  785.   blocks, and so on) when deleting a file.  So if your file was longer
  786.   than 12 blocks, you have no guarantee of being able to find even the
  787.   numbers of all the blocks you need, let alone their contents.
  788.  
  789.   The only method I have been able to find thus far is to assume that
  790.   the file was not fragmented: if it was, then you're in trouble.
  791.   Assuming that the file was not fragmented, there are several layouts
  792.   of data blocks, according to how many data blocks the file used:
  793.      0 to 12
  794.         The block numbers are stored in the inode, as described above.
  795.  
  796.  
  797.      13 to 268
  798.         After the direct blocks, count one for the indirect block, and
  799.         then there are 256 data blocks.
  800.  
  801.  
  802.      269 to 65804
  803.         As before, there are 12 direct blocks, a (useless) indirect
  804.         block, and 256 blocks.  These are followed by one (useless)
  805.         doubly indirect block, and 256 repetitions of one (useless)
  806.         indirect block and 256 data blocks.
  807.  
  808.  
  809.      65805 or more
  810.         The layout of the first 65804 blocks is as above.  Then follow
  811.         one (useless) triply indirect block and 256 repetitions of a
  812.         `doubly indirect sequence'.  Each doubly indirect sequence
  813.         consists of a (useless) doubly indirect block, followed by 256
  814.         repetitions of one (useless) indirect block and 256 data blocks.
  815.  
  816.   Of course, even if these assumed data block numbers are correct, there
  817.   is no guarantee that the data in them is intact.  In addition, the
  818.   longer the file was, the less chance there is that it was written to
  819.   the file system without appreciable fragmentation (except in special
  820.   circumstances).
  821.  
  822.   You should note that I assume throughout that your blocksize is 1024
  823.   bytes, as this is the standard value.  If your blocks are bigger, some
  824.   of the numbers above will change.  Specifically: since each block
  825.   number is 4 bytes long, blocksize/4 is the number of block numbers
  826.   that can be stored in each indirect block.  So every time the number
  827.   256 appears in the discussion above, replace it with blocksize/4.  The
  828.   `number of blocks required' boundaries will also have to be changed.
  829.  
  830.   Let's look at an example of recovering a longer file.
  831.  
  832.  
  833.  
  834.        debugfs:  stat <1387>
  835.        Inode: 148004   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
  836.        User:   503   Group:   100   Size: 1851347
  837.        File ACL: 0    Directory ACL: 0
  838.        Links: 0   Blockcount: 3616
  839.        Fragment:  Address: 0    Number: 0    Size: 0
  840.        ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
  841.        atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
  842.        mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
  843.        dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
  844.        BLOCKS:
  845.        8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8583
  846.        TOTAL: 14
  847.  
  848.  
  849.  
  850.  
  851.   There seems to be a reasonable chance that this file is not
  852.   fragmented: certainly, the first 12 blocks listed in the inode (which
  853.   are all data blocks) are contiguous.  So, we can start by retrieving
  854.   those blocks:
  855.  
  856.  
  857.  
  858.  
  859.   # fsgrab -c 12 -s 8314 /dev/hda5 > /mnt/recovered.001
  860.  
  861.  
  862.  
  863.  
  864.   Now, the next block listed in the inode, 8326, is an indirect block,
  865.   which we can ignore.  But we trust that it will be followed by 256
  866.   data blocks (numbers 8327 through 8582).
  867.  
  868.  
  869.  
  870.        # fsgrab -c 256 -s 8327 /dev/hda5 >> /mnt/recovered.001
  871.  
  872.  
  873.  
  874.  
  875.   The final block listed in the inode is 8583.  Note that we're still
  876.   looking good in terms of the file being contiguous: the last data
  877.   block we wrote out was number 8582, which is 8327 + 255.  This block
  878.   8583 is a doubly indirect block, which we can ignore.  It is followed
  879.   by up to 256 repetitions of an indirect block (which is ignored)
  880.   followed by 256 data blocks.  So doing the arithmetic quickly, we
  881.   issue the following commands.  Notice that we skip the doubly indirect
  882.   block 8583, and the indirect block 8584 immediately (we hope)
  883.   following it, and start at block 8585 for data.
  884.  
  885.  
  886.  
  887.        # fsgrab -c 256 -s 8585 /dev/hda5 >> /mnt/recovered.001
  888.        # fsgrab -c 256 -s 8842 /dev/hda5 >> /mnt/recovered.001
  889.        # fsgrab -c 256 -s 9099 /dev/hda5 >> /mnt/recovered.001
  890.        # fsgrab -c 256 -s 9356 /dev/hda5 >> /mnt/recovered.001
  891.        # fsgrab -c 256 -s 9613 /dev/hda5 >> /mnt/recovered.001
  892.        # fsgrab -c 256 -s 9870 /dev/hda5 >> /mnt/recovered.001
  893.  
  894.  
  895.  
  896.  
  897.   Adding up, we see that so far we've written 12 + (7 * 256) blocks,
  898.   which is 1804.  The `stat' results for the inode gave us a
  899.   `blockcount' of 3616; unfortunately these blocks are 512 bytes long
  900.   (as a hangover from UNIX), so we really want 3616/2 = 1808 blocks of
  901.   1024 bytes.  That means we need only four more blocks.  The last data
  902.   block written was number 10125.  As we've been doing so far, we skip
  903.   an indirect block (number 10126); we can then write those last four
  904.   blocks.
  905.  
  906.  
  907.  
  908.        # fsgrab -c 4 -s 10127 /dev/hda5 >> /mnt/recovered.001
  909.  
  910.  
  911.  
  912.  
  913.   Now, with some luck the entire file has been recovered successfully.
  914.  
  915.  
  916.  
  917.   11.  Modifying inodes directly
  918.  
  919.   This method is, on the surface, much easier.  However, as mentioned
  920.   above, it cannot yet cope with files longer than 12 blocks.
  921.  
  922.   For each inode you want to recover, you must set the usage count to
  923.   one, and set the deletion time to zero.  This is done with the mi
  924.   (modify inode) command in debugfs.  Some sample output, modifying
  925.   inode 148003 from above:
  926.  
  927.  
  928.  
  929.        debugfs:  mi <148003>
  930.                                  Mode    [0100644]
  931.                               User ID    [503]
  932.                              Group ID    [100]
  933.                                  Size    [6065]
  934.                         Creation time    [833201524]
  935.                     Modification time    [832708049]
  936.                           Access time    [826012887]
  937.                         Deletion time    [833201524] 0
  938.                            Link count    [0] 1
  939.                           Block count    [12]
  940.                            File flags    [0x0]
  941.                             Reserved1    [0]
  942.                              File acl    [0]
  943.                         Directory acl    [0]
  944.                      Fragment address    [0]
  945.                       Fragment number    [0]
  946.                         Fragment size    [0]
  947.                       Direct Block #0    [594810]
  948.                       Direct Block #1    [594811]
  949.                       Direct Block #2    [594814]
  950.                       Direct Block #3    [594815]
  951.                       Direct Block #4    [594816]
  952.                       Direct Block #5    [594817]
  953.                       Direct Block #6    [0]
  954.                       Direct Block #7    [0]
  955.                       Direct Block #8    [0]
  956.                       Direct Block #9    [0]
  957.                      Direct Block #10    [0]
  958.                      Direct Block #11    [0]
  959.                        Indirect Block    [0]
  960.                 Double Indirect Block    [0]
  961.                 Triple Indirect Block    [0]
  962.  
  963.  
  964.  
  965.  
  966.   That is, I set the deletion time to 0 and the link count to 1 and just
  967.   pressed return for each of the other fields.  Granted, this is a
  968.   little unwieldy if you have a lot of files to recover, but I think you
  969.   can cope.  If you'd wanted chrome, you'd have used a graphical
  970.   `operating system' with a pretty `Recycle Bin'.
  971.  
  972.   By the way: the mi output refers to a `Creation time' field in the
  973.   inode.  This is a lie!  (Or misleading, anyway.)  The fact of the
  974.   matter is that you cannot tell on a UNIX file system when a file was
  975.   created.  The st_ctime member of a struct stat refers to the `inode
  976.   change time', that is, the last time when any inode details were
  977.   changed.  Here endeth today's lesson.
  978.  
  979.   Note that more recent versions of debugfs than the one I'm using
  980.   probably do not include some of the fields in the listing above
  981.   (specifically, Reserved1 and (some of?) the fragment fields).
  982.  
  983.   Once you've modified the inodes, you can quit debugfs and say:
  984.  
  985.  
  986.  
  987.        # e2fsck -f /dev/hda5
  988.  
  989.  
  990.  
  991.   The idea is that each of the deleted files has been literally
  992.   undeleted, but none of them appear in any directory entries.  The
  993.   e2fsck program can detect this, and will add a directory entry for
  994.   each file in the /lost+found directory of the file system.  (So if the
  995.   partition is normally mounted on /usr, the files will now appear in
  996.   /usr/lost+found when you next mount it.)  All that still remains to be
  997.   done is to work out the name of each file from its contents, and
  998.   return it to its correct place in the file system tree.
  999.  
  1000.   When you run e2fsck, you will get some informative output, and some
  1001.   questions about what damage to repair.  Answer `yes' to everything
  1002.   that refers to `summary information' or to the inodes you've changed.
  1003.   Anything else I leave up to you, although it's usually a good idea to
  1004.   say `yes' to all the questions.  When e2fsck finishes, you can remount
  1005.   the file system.
  1006.  
  1007.   Actually, there's an alternative to having e2fsck leave the files in
  1008.   /lost+found: you can use debugfs to create a link in the file system
  1009.   to the inode.  Use the link command in debugfs after you've modified
  1010.   the inode:
  1011.  
  1012.  
  1013.  
  1014.        debugfs:  link <148003> foo.txt
  1015.  
  1016.  
  1017.  
  1018.  
  1019.   This creates a file called foo.txt in what debugfs thinks is the
  1020.   current directory; foo.txt will be your file.  You'll still need to
  1021.   run e2fsck to fix the summary information and block counts and so on.
  1022.  
  1023.  
  1024.  
  1025.   12.  Will this get easier in future?
  1026.  
  1027.   Yes.  In fact, I believe it already has.  Although as of this writing,
  1028.   current stable kernels (in the 2.0.x series) zero indirect blocks,
  1029.   this does not apply to development kernels in the 2.1.x series, nor to
  1030.   the stable 2.2.x series.  As I write this on 2 February 1999, kernel
  1031.   2.2.1 was released a few days ago; Linux vendors are likely to start
  1032.   producing distributions containing and supporting 2.2.x kernels a
  1033.   month or two from now.
  1034.  
  1035.   Once the indirect-zeroing limitation has been overcome in the
  1036.   production kernels, a lot of my objections to the technique of
  1037.   modifying inodes by hand will disappear.  At the same time, it will
  1038.   also become possible to use the dump command in debugfs on long files,
  1039.   and to conveniently use other undeletion tools.
  1040.  
  1041.  
  1042.  
  1043.   13.  Are there any tools to automate this process?
  1044.  
  1045.   As it happens, there are.  Unfortunately, I believe that they
  1046.   currently suffer from the same problem as the manual inode
  1047.   modification technique: indirect blocks are unrecoverable.  However,
  1048.   given the likelihood that this will shortly no longer be a problem,
  1049.   it's well worth looking these programs out now.
  1050.  
  1051.   I have written a tool called e2recover, which is essentially a Perl
  1052.   wrapper around fsgrab.  It makes a reasonable amount of effort to deal
  1053.   with zeroed indirect blocks, and seems to work fairly well as long as
  1054.   there was no fragmentation.  It also correctly sets the permissions
  1055.   (and when possible the ownership) of recovered files, and even makes
  1056.   sure that recovered files have the correct length.
  1057.   I originally wrote e2recover for the forthcoming major update to this
  1058.   Howto; unfortunately this means that much of the useful documentation
  1059.   for e2recover is scheduled for inclusion in that update.  Be that as
  1060.   it may, it should be useful now; it can be downloaded from my web site
  1061.   <http://pobox.com/~aaronc/tech/e2-undel/>, and soon from Metalab.
  1062.  
  1063.   Scott D. Heavner is the author of lde, the Linux Disk Editor.  It can
  1064.   be used as both a binary disk editor, and as an equivalent to debugfs
  1065.   for ext2 and minix file systems, and even for xia file systems (though
  1066.   xia support is no longer available in 2.1.x and 2.2.x kernels).  It
  1067.   has some features for assisting undeletion, both by walking the block
  1068.   list for a file, and by grepping through disk contents.  It also has
  1069.   some fairly useful documentation on basic file system concepts, as
  1070.   well as a document on how to use it for undeletion.  Version 2.4 of
  1071.   lde is available on Metalab
  1072.   <http://metalab.unc.edu/pub/Linux/system/filesystems/lde-2.4.tar.gz>
  1073.   and mirrors, or on the author's web site
  1074.   <http://www.geocities.com/CapeCanaveral/Lab/7731/lde.html>.
  1075.  
  1076.   Another possibility is offered by the GNU Midnight Commander, mc.
  1077.   This is a full-screen file management tool, based AFAIK on a certain
  1078.   MS-DOS program commonly known as `NC'.  mc supports the mouse on the
  1079.   Linux console and in an xterm, and provides virtual file systems which
  1080.   allow tricks like cd-ing to a tarfile.  Among its virtual file systems
  1081.   is one for ext2 undeletion.  It all sounds very handy, although I must
  1082.   admit I don't use the program myself -- I prefer good old-fashioned
  1083.   shell commands.
  1084.  
  1085.   To use the undeletion feature, you have to configure the program with
  1086.   the --with-ext2undel option; you'll also need the development
  1087.   libraries and include files that come with the e2fsprogs package.  The
  1088.   version provided in Debian GNU/Linux <http://www.debian.org/> is built
  1089.   in this way; the same may apply to packages for other Linux
  1090.   distributions.  Once the program is built, you can tell it to cd
  1091.   undel:/dev/hda5, and get a `directory listing' of deleted files.  Like
  1092.   many current undeletion tools, it handles zeroed indirect blocks
  1093.   poorly -- it typically just recovers the first 12k of long files.
  1094.  
  1095.   The current version may be downloaded from the Midnight Commander ftp
  1096.   site <ftp://ftp.nuclecu.unam.mx/Midnight/devel/>.
  1097.  
  1098.  
  1099.  
  1100.   14.  Colophon
  1101.  
  1102.   I intend to produce regular updates to this document as long as I have
  1103.   both enough time to do it, and something interesting to say.  This
  1104.   means that I am eager to hear comments from readers.  Could my writing
  1105.   be clearer?  Can you think of something that would make matters
  1106.   easier?  Is there some new tool that does it all automatically?
  1107.   Whatever.  If you have something to say about this document or about
  1108.   the fsgrab or e2recover tools, drop me a line on aaronc@pobox.com.
  1109.  
  1110.  
  1111.  
  1112.   15.  Credits and Bibliography
  1113.  
  1114.  
  1115.        `If I have seen farther than others, it is because I was
  1116.        standing on the shoulders of giants.' (Isaac Newton)
  1117.  
  1118.  
  1119.   This mini-Howto was originally derived from a posting in the
  1120.   comp.os.linux.misc newsgroup by Robin Glover swrglovr@met.rdg.ac.uk.
  1121.   I would like to thank Robin for graciously allowing me to rework his
  1122.   ideas into this mini-Howto.
  1123.   I would also like to take this opportunity to thank once again all the
  1124.   people who've written to me about the Howto.  Receiving grateful
  1125.   comments makes the effort worth while.
  1126.  
  1127.   Some bibliographic references:
  1128.  
  1129.  
  1130.   ╖  Frisch, ╞leen (1995), Essential System Administration, second
  1131.      edition, O'Reilly and Associates, Inc., ISBN: 1-56592-127-5.
  1132.  
  1133.   ╖  Garfinkel, Simson, Daniel Weise and Steven Strassmann (1994), The
  1134.      Unix-Haters Handbook, IDG Books, ISBN: 1-56884-203-1.  Much of this
  1135.      book is merely the adolescent whinings of people who think that
  1136.      their operating system was so much better than Unix, and much of
  1137.      the rest simply doesn't apply if you have a well-written user-space
  1138.      such as GNU.  But there is some wheat among the chaff; for example,
  1139.      the discussion of how easy it is to delete files under Unix is well
  1140.      worth reading.
  1141.  
  1142.   ╖  Glover, Robin (31 Jan 1996), HOW-TO : undelete linux files
  1143.      (ext2fs/debugfs), comp.os.linux.misc Usenet posting.
  1144.  
  1145.   ╖  Peek, Jerry, Tim O'Reilly, Mike Loukides et al (1993), UNIX Power
  1146.      Tools, O'Reilly and Associates, Inc./Random House, Inc., ISBN:
  1147.      0-679-79073-X.  Second edition, 1998.
  1148.  
  1149.  
  1150.  
  1151.   16.  Legalities
  1152.  
  1153.   All trademarks are the property of their respective owners.
  1154.   Specifically:
  1155.  
  1156.  
  1157.   ╖  MS-DOS and Windows are trademarks of Microsoft
  1158.      <http://www.microsoft.com/>.
  1159.  
  1160.   ╖  UNIX is a trademark of the Open Group <http://www.opengroup.org/>.
  1161.  
  1162.   ╖  Linux is a trademark of Linus Torvalds in the USA and some other
  1163.      countries.
  1164.  
  1165.   This document is Copyright ⌐ 1997, 1999 Aaron Crane aaronc@pobox.com.
  1166.   It may be freely redistributed in its entirety, including the whole of
  1167.   this copyright notice, but may not be changed without permission from
  1168.   either the author or the Linux Documentation Project HOWTO
  1169.   Coordinator.  Dispensation is granted for copying small verbatim
  1170.   portions for the purposes of reviews or for quoting; in these
  1171.   circumstances, sections may be reproduced in the presence of an
  1172.   appropriate citation but without this copyright notice.
  1173.  
  1174.   The author requests but does not require that parties intending to
  1175.   sell copies of this document, whether on computer-readable or human-
  1176.   readable media, inform either him or the Linux HOWTO Coordinator of
  1177.   their intentions.
  1178.  
  1179.   The Linux HOWTO Coordinator is currently Tim Bynum linux-
  1180.   howto@metalab.unc.edu.
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.