Copying a FreeBSD install to a smaller disk

Giorgos Keramidas keramida at
Fri Sep 12 01:55:49 UTC 2008

On Thu, 11 Sep 2008 17:19:55 -0700, "Chris Weiss" <chris.weiss at> 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.

Hi Chris,

If all you want is to make ad0 bootable, you don't need the *contents*
of the /dev and /proc file systems.  They are dynamically generated by
the kernel when you mount these file systems and access them.

If the used disk space in ad6 (the clone source drive) is less than the
size of the clone target, it should be possible to copy the source files
using any of:

    * tar
    * dump & restore
    * cpio

Some care must be taken to avoid copying special file systems, like /dev
and /proc that you mentioned.  If you use something like a Live CD-ROM
to boot, instead of booting from the 'source' disk, this should be easy,
because the special /dev and /proc file systems will be mounted only for
the *boot* device (the CD-ROM in this case), so the hard disk partitions
will merely include empty directories as `potential mount-points' for
the /dev, /proc and other special places.

FWIW, the steps I followed when I cloned my old laptop installation to a
new hard disk are the ones shown below.  I didn't want to open the
laptop, because that would violate its guarantee terms.  So I kept the
'target' disk as ad0 and used a USB-attached enclosure for 2.5" hard
disks to attach the original 'source' disk (taken out of my old, dead

[1] Boot from CD-ROM using a FreeSBIE installation(*).

    (*) Many thanks to the FreeSBIE folks, for making such an easy to
    use Live CD-ROM.  I have found it very useful far too many times to
    mention all of them in an email post!

[2] Create an /mnt/source and /mnt/target directory.

        # mkdir -p /mnt/source
        # mkdir -p /mnt/target

[3] Mount the source root partition, and then use the existing mount
    points under that source tree to mount the target partitions:

        # mount -o ro /dev/da0s1a /mnt/source
        # mount -o ro /dev/da0s1e /mnt/source/home

    Note that, for extra safety, I mounted the source partitions as
    read-only.  This way I would at least get a warning if I botched the
    copying process, and avoid messing my original 'source' data.

[4] Partition and mount the target disk (the internal ad0 disk of the
    laptop).  This is where booting from a Live CD-ROM helped a lot,
    because I didn't have to do anything special to 'resize' or 'keep'
    parts of the disk unpartitioned.  I could use the *full* disk for
    the new installation.

        # fdisk -BI /dev/ad0
        # bsdlabel -w -B /dev/ad0s1
        # bsdlabel -e /dev/ad0s1

    When I had configured the new ad0s1a and ad0s1e partitions, I saved
    the label and exited bsdlabel's editor.

[5] Format the target partitions:

        # newfs -L MYROOT /dev/ad0s1a
        # newfs -L MYHOME -U /dev/ad0s1e

    The -L labels are entirely optional, and, as you can see, I only
    enabled softupdates on the new /home partition.

[6] Mount the target partitions under `/mnt/target'.  The mounts were
    read-write this time:

        # mount /dev/ad0s1a /mnt/target
        # mkdir /mnt/target/home
        # mount /dev/ad0s1e /mnt/target/home

    Note that the second command is not optional.  The new root file
    system was brand new, so it appears completely empty after being

[7] Copy everything using BSD tar(1):

        # tar -C /mnt/source -cf - . | tar -C /mnt/target xvf -

[8] The final step was to chroot into the new 'target' system, and
    fix-up any special directory permissions, by using the mtree(8)
    specifications from `/etc/mtree'.  This restores any special flags
    like `noschg' or the permissions required for proper daemon
    operation in `/var/run' and so on.

    To avoid side-effects from the runtime environment of the shell I
    was using `outside' of the chroot, I cleared all environment
    variables, and manually set only the bare minimum of stuff I needed
    `inside' the chroot:

        # env -i USER='root' SHELL='/bin/csh' HOME='/root' \
              PATH='/bin:/sbin:/usr/bin:/usr/sbin' \
              chroot /mnt/chroot /bin/csh
        freesbie# set prompt = 'chroot# '

    Then I run the `/etc/mtree/BSD.*.dist' files through mtree inside
    the chroot:

        chroot# cd / ; mtree -deU -f /etc/mtree/BSD.root.dist
        chroot# cd /usr ; mtree -deU -f /etc/mtree/BSD.usr.dist
        chroot# cd /usr/include ; mtree -deU -f /etc/mtree/BSD.include.dist
        chroot# cd /var ; mtree -deU -f /etc/BSD.var.dist

[9] Finally, I checked the new `/etc/fstab' file to make sure it was ok
    (in my case the partitions did not change name or order, so I already
    everything was fine; I was just being careful).

    Then I exited from the chroot, unmounted all partitions, and
    rebooted the laptop.  The internal ad0 disk was a 'copy' of my old
    disk, so I expected it to boot normally into FreeBSD... which, much
    to my amusement (since this was one of the few times I had to move
    _everything_ to a new disk), it promptly did :)

More information about the freebsd-questions mailing list