18 October 2010

Disk Cloning in FreeBSD

Disk Cloning in FreeBSD:

A few assumptions:
        master disk:  da0

                \--> disk already configured and in use
        alternate:    da1
                \--> disk not configured and will become a clone of master
        configured slice:  s1
                \--> slices 2, 3, and 4 remain unconfigured
        configured partitions:  a, b, d, e
                \--> a=/, b=swap, d=/usr, e=/var  (c reserved for whole slice)
        your path:    PATH=/bin:/usr/bin:/sbin
                \--> your path must contain at least the above
        disk geometry:
                \--> the disk geometry of both devices should be the same or
                     you should be aware of the potential issues otherwise
                     (the following assumes identical)
        shell prompt: host [0]
                \--> this is simply the shell prompt used in the examples
                     that follow

1) use fdisk to determine the current slice configuration of the master
   disk and configure the alternate  (note, this is performed interactive
   wherein fdisk will interrogate you for an appropriate response)

        host [0] fdisk /dev/da0
        ******* Working on device /dev/da0 *******
        parameters extracted from in-core disklabel are:
        cylinders=2213 heads=255 sectors/track=63 (16065 blks/cyl)

        Figures below won't work with BIOS for partitions not in cyl 1
        parameters to be used for BIOS calculations are:
        cylinders=2213 heads=255 sectors/track=63 (16065 blks/cyl)

        Media sector size is 512
        Warning: BIOS sector numbering starts with sector 1
        Information from DOS bootblock is:
        The data for partition 1 is:
        sysid 165 (0xa5),(FreeBSD/NetBSD/386BSD)
            start 63, size 35551782 (17359 Meg), flag 80 (active)
                beg: cyl 0/ head 1/ sector 1;
                end: cyl 1023/ head 254/ sector 63

  To set the slice information of the alternate disk, one must execute
  fdisk against it:

        host [0] fdisk -iv /dev/da1

  For the most part, the information provided by the BIOS should be fine.
  When the above command is run, the following output is displayed,
  prompting for input.  Unless you are familiar with disk geometry, etc,
  you should answer "no" or "n" to the initial prompt.  The second prompt
  requires a "y" or "yes" answer.  (Of note, the number of cynlinders,
  heads, and sectors should be of equal or greater value to the master
  disk.)

        ******* Working on device /dev/da1 *******
        parameters extracted from in-core disklabel are:
        cylinders=2234 heads=255 sectors/track=63 (16065 blks/cyl)

        Figures below won't work with BIOS for partitions not in cyl 1
        parameters to be used for BIOS calculations are:
        cylinders=2234 heads=255 sectors/track=63 (16065 blks/cyl)

        Do you want to change our idea of what BIOS thinks ? [n] n
        Media sector size is 512
        Warning: BIOS sector numbering starts with sector 1
        Information from DOS bootblock is:
        The data for partition 1 is:
        sysid 165 (0xa5),(FreeBSD/NetBSD/386BSD)
            start 63, size 35551782 (17359 Meg), flag 80 (active)
                beg: cyl 0/ head 1/ sector 1;
                end: cyl 161/ head 254/ sector 63

  The section that follows governs how each of the 4 potential slices
  may be carved up.  To this extent, certain bits of information will be
  required from the slice output of da0.  This includes the following,
  as it will be needed by the fdisk input prompts:

        sysid:  165             (used to label the slice, FreeBSD uses 165)
        start:  63              (start sector address)
        size:   35551782        (slice size in sectors)
        beg:
          cyl:    0             (starting cylinder)
          head:   1             (starting head)
          sector: 1             (starting sector)
        end:
          cyl:    1023          (ending cylinder)
          head:   254           (ending head)
          sector: 63            (ending sector)

  Proceeding through fdisk's interactive mode, the following prompts
  are encountered with their respective responses:

        Explicityly specify beg/end address ? [n] y
        Are we happy with this entry? [n] y
        Do you want to change it? [n] n
        Do you want to change the active partition? [n] y
        Supply a decimal value for "active partition" [1] 1
        Are you happy with this choice [n] y
        Should we write new partition table? [n] y

  Unfortunately, while fdisk does have the availability to read a
  configuration file for a lot of the above information, the configuration
  directives leave a little to be desired.  For further information
  regarding fdisk, please see the man page, fdisk (8).

2) use bsdlabel (or disklabel) to partition the alternate disk

        host [0] bsdlabel -A /dev/da0s1 >> /tmp/label.da1
        host [0] bsdlabel -R /dev/da1s1 /tmp/label.da1
        host [0] rm /tmp/label.da1

3) use bsdlabel to make the first slice of da1 bootable

        host [0] bsdlabel -B /dev/da1s1

4) newfs the slices on the second disk

        host [0] for i in a d e ; do echo "newfs /dev/da1s1${i}" ;
                newfs /dev/da1s1${i} ; done

5) mount the root slice of the alternate disk under /mnt

        host [0] [ ! -d /mnt ] && mkdir /mnt
        host [0] mount /dev/da1s1a /mnt

6) change directory to /mnt and mirror the master disk

        host [0] cd /mnt ; dump 0uf - / | restore rf -
        host [0] rm restoresymtable
        host [0] mount /dev/da1s1d /mnt/usr
        host [0] cd /mnt/usr ; dump 0uf - /usr | restore rf -
        host [0] rm restoresymtable
        host [0] mount /dev/da1s1e /mnt/var
        host [0] cd /mnt/var ; dump 0uf - /var | restore rf -
        host [0] rm restoresymtable
 
7) update the fstab to be appropriate for the cloned (alternate) disk

        host [0] sed < /mnt/etc/fstab -e s/da0s1/da1s1/g > /tmp/fstab.new
        host [0] mv /tmp/fstab.new /mnt/etc/fstab
                # you should probably verify the contents of /tmp/fstab.new
                # before moving it into place

8) unmount all new filesystems and fsck each new FS partition

        host [0] cd / ; umount /mnt/var
        host [0] umount /mnt/usr
        host [0] umount /mnt
        host [0] fsck /dev/da1s1a
        host [0] fsck /dev/da1s1d
        host [0] fsck /dev/da1s1e

9) bring down your box and boot from your alternate disk... enjoy



Some details on the various steps and points of consideration:

        step 1) fdisk is somewhat awkward in its handling, such as it
                does not allow for the output it produces to be directly
                used as input.  For this reason, this step is so lengthy
                to hopefully assist others in its usage.
 
        step 2) bsdlabel is represented in two forms here, the output
                of the master disk's configuration and the setup of
                the alternate's.  The -A option enables the processing
                of the historical parts of the BSD label.  The -R will
                "restore" the label information to the alternate disk
                from the file listed as the last parameter.

        step 3) bsdlabel's -B option installs a new bootstrap to the
                alterate disk's slice 1, obtained from /boot/boot.

        step 4) newfs creates a filesystem on the specified device (ufs by
                default.

        step 5) mounting the alternate disk so that the master disk can be
                mirrored to it

        step 6) dump will dump the contents of the specified device out to
                the file specified prior to the device being dumped (in this
                case, STDIN); the options are specified in BSD styling, not
                requiring a hyphen preceding; option 0 states to dump the
                entire file system, u updates /etc/dumpdates with relevant
                dump information, f states to dump to a specific file which
                is seen above as - (STDIN)

                restore will restore the contents of a filesystem; option
                r performs a recursive restoration of a filesystem relative
                to the current working directory, f specifies the dumpfile
                to restore from though in this case is - (STDIN) from dump

        step 7) the fstab on the new device needs to be updated so that the
                appropriate filesystems are mounted relative to the alternate
                disk (failure to do so will cause the box not to boot if one
                tries to boot from this device); the sed command is simply
                changing any instances of da0s1 (master disk) to da1s1
                (the alternate disk) on the copy of fstab on the new disk

        step 8) fsck is run to make sure the filesystems are
                sane and usable on the alternate disk

        note 1) Should the above procedure be followed on a newly
                installed box, with no application specific configuration
                having been done yet, the alternate disk may be easily
                used for the root disk on another host.  For this to
                occur, one must update a handful of files relative
                to data of the alternate host.  FreeBSD contains host
                specific information within only the following two files:

                        /etc/hosts
                        /etc/rc.conf

                Basically just hostname and IP information need to be
                changed reflective of the alternate host.  This presents a
                creative and relatively static approach to rebuilding a host
                with a standardized "stock" install.

see also:
    Disk Cloning in Solaris
    Disk Cloning in Linux