Copying a FreeBSD install to a smaller disk

Jerry McAllister jerrymc at
Fri Sep 12 16:12:21 UTC 2008

On Thu, Sep 11, 2008 at 05:19:55PM -0700, Chris Weiss wrote:

> How would I go about copying an existing FreeBSD installation to a smaller disk?
> I've got a 3rd FreeBSD install I can boot from and store temporary
> files on, all the disks are in the same hardware, so there's no
> reconfiguration other than the boot device name and interface (IE
> -SATA ad4 will become IDE ad0). The disk is partitioned using the
> "default" sysinstall values and the contents of the larger disk will
> fit on the smaller disk, although I need to increase the size of the /
> and /var slices on the target to hold everything (/usr is fairly
> empty, so it'll easily fit on the smaller disk).
> For now, we'll say ad0 = new smaller disk, ad4 = boot BSD disk, and
> ad6 = the BSD install I want to clone.
> The path I've been going down is to manually partition and slice ad0
> create ad4/mnt/source and ad4/mnt/target and mount /var, /tmp, etc
> from ad0 and ad6 and manually copy the files. But I'm stuck on how to
> handle /, since it'll have dev and proc and such.
> Any thoughts on how to do this, or on a completely different approach?
> I'm not aware of any 3rd party tools that'll deal with shrinking
> FreeBSD partitions.
> Thanks in advance for any help you folks can give!

Seems like you are generally on the right track, though some of your 
mounting seems backwards to me.

First, as you have indicated, manually slice, partition and newfs
the new disk (ad0) to match what you want to have on it.  If you
are making an identical, just smaller, disk to ad4, then do a df 
and see what slices and partitions are being used on ad4.   Probably
it is one slice, divided into several partitions.   

While you are at it, look at each of the filesystem sizes and make 
sure you will have room on the new, smaller disk.   You want at least
the current used size + 10%.   Really you want more to actually

Presuming you want a single bootable slice (ad0s1) which is then 
divided in to partitions for:
 a: /
 b: swap
 d: /tmp
 e: /usr
 f: /var
 g: /home

  fdisk -BI ad0
    Creates a single bootable slice with default MBR (good enough).
  bsdlabel -w -B da0s1
    Writes an initial label and boot block on the slice
  bsdlabel -e da0s1
    Puts you in edit (vi by default) with the current condition of
    the partition label showing.  If it is new, it will only show
    a 'c' partition covering the whole available size of the slice.
  Edit this page by duplicating that 'c' line for each real partition
  you want to have and changing fstype from 'unused' to '4.2BSD' on
  the a, d, e, f, g partitions and 'swap' on the b partition.

In the end you will have something that looks about like:

# /dev/ad0s3:
8 partitions:
#       size   offset   fstype  [fsize bsize bps/cpg]
 a:   524288        0   4.2BSD    2048 16384 32776
 b:  2572288        *     swap
 c: 78316875        0   unused       0     0        # "raw" part, don't edit
 d:  1048576        *   4.2BSD    2048 16384     8
 e:  4194304        *   4.2BSD    2048 16384 28552
 f:  6291456        *   4.2BSD    2048 16384 28552
 g:        *        *   4.2BSD    2048 16384 28552

You need only specify the sizes.  You can put '*' for the offset
and the bsdlabel utility figures it out correctly.
Also, you can put '*' for both size and offset on the last
partition and it will use all the remaining available space.
Don't do anything with the actual 'c' partition.

Remember that sizes here are in 512 Byte blocks/sectors.
The sizes I have here are for a disk I happen to have handy at
the moment to look at.
  a:     256 MB    Mount as;  /
  b:   1,256 MB               swap
  d:     512 MB      "   "    /tmp
  e:   2,048 MB      "   "    /usr
  f:   3,072 MB      "   "    /var
  g:  31,096 MB      "   "    /home

Then do a regular newfs on each real file system a, d, e, f, g
  newfs /dev/ad0s1a
  newfs /dev/ad0s1d
    etc  for e, f, g

Once you have the new disk created, I would do the rest all in
single user mode.

Boot to single useri, then

  fsck -p
  mount -u /
  mount -a
  swapon -a

Create temporary mount points for the new filesystems (ignore /tmp
unless you actually have something there to maintain - unlikely)
  mkdir /newroot
  mkdir /newusr
  mkdir /newvar
  mkdir /newhome

Use dump/restore to copy the file systems

  cd /newroot
  dump -0af - / | restore -rf -
  cd /newusr
  dump -0af - /usr | restore -rf -
  cd /newvar
  dump -0af - /var | restore -rf -
  cd /newhome
  dump -0af - /home | restore -rf -

These can take a while, especially the /home dump/restore if
it is large.  

Once you are finished with this you need to fix up 
the /etc/fstab file on /newroot.
After this, when you reboot, as long as ad0 is in front of ad4 in
the BIOS boot sequence, the system will attempt to boot from ad0.
Since there are more than one bootable disks now on the machine,
it should give you a menu of bootable slices from which you can select.

Have fun,


> -- 
> -Chris
> _______________________________________________
> freebsd-questions at mailing list
> To unsubscribe, send any mail to "freebsd-questions-unsubscribe at"

More information about the freebsd-questions mailing list