Recreating a broken disklabel in FreeBSD:

I accidentally ruined the disklabel on one of my Laptop disks.

I figured it should be possible to find the necessary information by searching the start of each filesystem.

I created a small c program (statically compiled and stripped only 45k) to do this.

The program can be found here. I was able to fit it on a FreeBSD 'fixit' floppy by removing the MAKEDEV script. (Don't forget to create any necessary devices first.)

To create this floppy, first obtain fixit.flp from your FreeBSD cdrom in the floppys/ subdirectory (or from ftp.freebsd.org).

then dd it to a disk: 'dd bs=18k if=fixit.flp of=/dev/fd0'.
then mount the disk: 'mount /dev/fd0a /mnt'
create any devices you need: 'cd /mnt/dev; sh MAKEDEV ad0s1f' (for example)
remove the MAKEDEV script: 'rm /mnt/dev/MAKEDEV'
copy the compiled program to your Disk: 'cp ~/disklabel/dlfind /mnt/bin/'
unmount the disk: 'cd /;umount /mnt'

Now boot your broken Machine with the install CD (or the install-boot floppys), and enter the fixit menu. Select the fixit floppy (don't forget to insert the fixit disk). You can now run the dlfind program, accepting the device name as argument.
dlfind /dev/ad0s2

It outputs something like this:


0 102400 /
364544 102400 /var
466944 2097152 /usr
2564096 41943040 /home
44507136 11190156 /store

This means: / starts at 0 and has a length of 102400, /var starts at 364544 (the gap here is most probably your swap partition) and has a length of 102400 ...

This can now be entered in disklabel. Call it as 'disklabel -e da0s2'

And you see something like this:


[Unimportant stuff on the top]

1 partition:
#        size   offset    fstype   [fsize bsize bps/cpg]
  c: 55697292        0    unused        0     0         # (Cyl.    0 - 3466*)

This number here is the size of your disk. Now add the partitions the program found. They get the letters 'a','e','f','g','h' sequentially. 'a' is usually only used for '/' and can be skipped

#        size   offset    fstype   [fsize bsize bps/cpg]
  a:   102400        0    4.2BSD     1024  8192    16   
  c: 55697292        0    unused        0     0         # (Cyl.    0 - 3466*)
  e:   102400   364544    4.2BSD     1024  8192    16   
  f:  2097152   466944    4.2BSD     1024  8192    16  
  g: 41943040  2564096    4.2BSD     1024  8192    16 
  h: 11190156 44507136    4.2BSD     1024  8192    16 

Watch out: The program prints a wrong length for the last partition. Make sure that 'size'+'offset' of the last one equals exactly the size of 'c'.

If you had swap on your disk, you can calculate that, as it is the gap between 'a' and 'e'. In this case:


#        size   offset    fstype   [fsize bsize bps/cpg]
  a:   102400        0    4.2BSD     1024  8192    16   
  b:   262144   102400      swap                        
  c: 55697292        0    unused        0     0         # (Cyl.    0 - 3466*)
  e:   102400   364544    4.2BSD     1024  8192    16   
  f:  2097152   466944    4.2BSD     1024  8192    16  
  g: 41943040  2564096    4.2BSD     1024  8192    16 
  h: 11190156 44507136    4.2BSD     1024  8192    16 

Now quit disklabel to write that info.

Test your disklabel by manually "fsck -p"'ing every partition. If it doesn't complain, chances are that your disklabel is fine now.

Good Luck,
   Sec

If you have problems, don't hesitate to mail me.

Changes to this document: