#!/usr/bin/perl -w ########################################################################## # RecoverDiskLabel.pl # # # # Simple Script which will try and recover disk layout information # # in the event of the disk label being lost or accidentally deleted. # # # # This will only work for FreeBSD systems, it assumes that the install # # is in a single slice rather than indivdual slices per mount point. # # and make sure the disk is unmounted while in use (which should already # # be the case if you are needing this script in the first place) # # # # The script will return what it expects the disklabel to look like if # # the orginal system was a standard FreeBSD system disk, otherwise use # # the information as a starting point # # ego@neilstyles.com # ########################################################################## # Disk Device you must use the Raw Device e.g. if the the disk # shows up up in dmesg as ad0, you would add /dev/rad0s1 below $disk = "/dev/rad2s1"; # Lets open the Disk up open DISK,"<$disk" or die "Open!"; $bufsize = 65536; # Keep a 64K rolling window read (DISK, $data, $bufsize) == $bufsize or die "Read!"; $bufptr = 0; $block = 0; $partition = 0; print "# size offset fstype [fsize bsize bps/cpg]\n"; while (1) { if (substr($data,($bufptr+0x215c)%$bufsize, 4) eq "\x54\x19\x01\x00" && substr($data,($bufptr+0x415c)%$bufsize, 4) eq "\x54\x19\x01\x00") { $size = &getint32(substr($data,($bufptr+0x1c24)%$bufsize,4)) * 2; $bsize = &getint32(substr($data,($bufptr+0x1c30)%$bufsize,4)); $fsize = &getint32(substr($data,($bufptr+0x1c34)%$bufsize,4)); $cpg = &getint32(substr($data,($bufptr+0x1cb4)%$bufsize,4)); $offset = $block - 2; if ($partition == 1) { printf " b: %8d %8d swap\n", $offset-$watermark, $watermark; printf " c: %8d %8d unused %8d %5d\n", -1, 0, 0, 0; $partition = 4; } printf " %c: %8d %8d 4.2BSD %8d %5d %5d\n", $partition+ord('a'), $size, $offset, $fsize, $bsize, $cpg; $watermark = $offset+$size; $partition++; } read (DISK, substr($data, $bufptr, 512), 512) == 512 or last; $bufptr = ($bufptr+512) % $bufsize; $block++; } $totsize = $block+($bufsize/512); printf "# Replace -1 with %d in partition c\n", $totsize; if ($totsize & 1) { printf "# Add 1 to size of last partition\n"; } sub getint32() { my $val; $val = ord(substr($_[0],0,1)); $val += ord(substr($_[0],1,1)) << 8; $val += ord(substr($_[0],2,1)) << 16; $val += ord(substr($_[0],3,1)) << 24; return $val; } print "\nCompleted.. Good Luck!\n";