Hack 93. Recover Lost Partitions
If you can't mount any of the partitions on a hard drive, you may simply need to recreate the partition table. Here's a handy utility for identifying possible partition entries. Seeing messages like "/dev/FOO: device not found" is never a good thing. However, this message can be caused by a number of different problems. There isn't much you can do about a complete hardware failure, but if you're "lucky" your disk's partition table may just have been damaged and your data may just be temporarily inaccessible.
Unless you have a photographic memory, your disk contains only a single partition, or you were sufficiently disciplined to keep a listing of its partition table, trying to guess the sizes and locations of all of the partitions on an ailing disk is almost impossible without some help. Thankfully, Michail Brzitwa has written a program that can provide exactly the help you need. His gpart (guess partitions) program scans a specified disk drive and identifies entries that look like partition signatures. By default, gpart displays only a listing of entries that appear to be partitions, but it can also automatically create a new partition table for you by writing these entries to your disk. That's a scary thing to do, but it beats the alternative of losing all your existing data.
The gpart program works by reading the entire disk and comparing sector sequences against a set of filesystem identification modules. By default, gpart includes filesystem identification modules that can recognize the following types of partitions: beos (BeOS), bsddl (FreeBSD/NetBSD/386BSD), ext2 and ext3 (standard Linux filesystems), fat (MS-DOS FAT12/16/32), hpfs (remember OS/2?), hmlvm (Linux LVM physical volumes), lswap (Linux swap), minix (Minix OS), ntfs (Microsoft Windows NT/2000/XP/etc.), qnx4 (QNX Version 4.x), rfs (ReiserFS Versions 3.5.11 and greater), s86dl (Sun Solaris), and xfs (XFS journaling filesystem). You can write additional partition identification modules for use by gpart (JFS fans, take note!), but that's outside the scope of this hack. For more information about expanding gpart, see its home page at http://www.stud.uni-hannover.de/user/76201/gpart and the README file that is part of the gpart archive. 10.6.1. Looking for PartitionsAs an example of gpart's partition scanning capabilities, let's first look at the listing of an existing disk's partition table as produced by the fdisk program. (BTW, if you're questioning the sanity of the partition layout, this is a scratch disk that I use for testing purposes, not a day-to-day disk.) Here's fdisk's view: # fdisk -l /dev/hdb Disk /dev/hdb: 60.0 GB, 60022480896 bytes 255 heads, 63 sectors/track, 7297 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/hdb1 1 25 200781 83 Linux /dev/hdb2 26 57 257040 82 Linux swap / Solaris /dev/hdb3 58 3157 24900750 83 Linux /dev/hdb4 3158 7297 33254550 5 Extended /dev/hdb5 3158 3337 1445818+ 83 Linux /dev/hdb6 3338 3697 2891668+ 83 Linux /dev/hdb7 3698 4057 2891668+ 83 Linux /dev/hdb8 4058 4417 2891668+ 83 Linux /dev/hdb9 4418 4777 2891668+ 83 Linux /dev/hdb10 4778 5137 2891668+ 83 Linux /dev/hdb11 5138 5497 2891668+ 83 Linux /dev/hdb12 5498 5857 2891668+ 83 Linux /dev/hdb13 5858 6217 2891668+ 83 Linux /dev/hdb14 6218 6577 2891668+ 83 Linux /dev/hdb15 6578 6937 2891668+ 83 Linux /dev/hdb16 6938 7297 2891668+ 83 Linux Let's compare this with gpart's view of the partitions that live on the same disk: # gpart /dev/hdb Begin scan… Possible partition(Linux ext2), size(196mb), offset(0mb) Possible partition(Linux swap), size(251mb), offset(196mb) Possible partition(Linux ext2), size(24317mb), offset(447mb) Possible partition(Linux ext2), size(1411mb), offset(24764mb) Possible partition(Linux ext2), size(2823mb), offset(26176mb) Possible partition(Linux ext2), size(2823mb), offset(29000mb) Possible partition(Linux ext2), size(2823mb), offset(31824mb) Possible partition(Linux ext2), size(2823mb), offset(34648mb) Possible partition(Linux ext2), size(2823mb), offset(37471mb) Possible partition(Linux ext2), size(2823mb), offset(40295mb) Possible partition(Linux ext2), size(2823mb), offset(43119mb) Possible partition(Linux ext2), size(2823mb), offset(45943mb) Possible partition(Linux ext2), size(2823mb), offset(48767mb) Possible partition(Linux ext2), size(2823mb), offset(51591mb) Possible partition(Linux ext2), size(2823mb), offset(54415mb) End scan. Checking partitions… * Warning: more than 4 primary partitions: 15. Partition(Linux ext2 filesystem): primary Partition(Linux swap or Solaris/x86): primary Partition(Linux ext2 filesystem): primary Partition(Linux ext2 filesystem): primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Partition(Linux ext2 filesystem): invalid primary Ok. Guessed primary partition table: Primary partition(1) type: 131(0x83)(Linux ext2 filesystem) size: 196mb #s(401562) s(63-401624) chs: (0/1/1)-(398/6/63)d (0/1/1)-(398/6/63)r Primary partition(2) type: 130(0x82)(Linux swap or Solaris/x86) size: 251mb #s(514080) s(401625-915704) chs: (398/7/1)-(908/6/63)d (398/7/1)-(908/6/63)r Primary partition(3) type: 131(0x83)(Linux ext2 filesystem) size: 24317mb #s(49801496) s(915705-50717200) chs: (908/7/1)-(1023/15/63)d (908/7/1)-(50314/10/59)r Primary partition(4) type: 131(0x83)(Linux ext2 filesystem) size: 1411mb #s(2891632) s(50717268-53608899) chs: (1023/15/63)-(1023/15/63)d (50314/12/1)-(53183/6/58)r Doing the math can be a bit tedious, but calculating the partition size and offsets shows that they are actually the same. gpart found all of the partitions, including all of the logical partitions inside the disk's extended partition, which can be tricky. If you don't want to do the math yourself, gpart provides a special -c option for comparing its idea of a disk's partition table against the partitions that are listed in an existing partition table. Using gpart with the -c option returns 0 if the two are identical or the number of differences if the two differ. 10.6.2. Writing the Partition TableUsing fdisk to recreate a partition table can be a pain, especially if you have multiple partitions of different sizes. As mentioned previously, gpart provides an option that automatically writes a new partition table to the scanned disk. To do this, you need to specify the disk to scan and the disk to write to on the command line, as in the following example: # gpart -W /dev/ FOO /dev/ FOO If you're paranoid (and you should be, even though your disk is already hosed), you can back up the existing MBR before writing it by adding the -b option to your command line and specifying the name of the file to which you want to back up the existing MBR, as in the following example: # gpart -b FILENAME -W /dev/ FOO /dev/ FOO As mentioned at the beginning of this hack, a disk failure may simply be the result of a bad block that happens to coincide with your disk's primary partition table. If this happens to you and you don't have a backup of the partition table, gpart does an excellent job of guessing and rewriting your disk's primary partition table. If the disk can't be mounted because it is severely corrupted or otherwise damaged, see "Recover Data from Crashed Disks" [Hack #94] and "Piece Together Data from the lost+found" [Hack #96] for some suggestions regarding more complex and desperate data recovery hacks. 10.6.3. See Also
|