Cloning or duplicating a running system using dump/restore. Assumptions: The dump command will be issued from a host running in multiple-user-mode. The host is a default configuration. IE: / as â€œaâ€ partition, /var as â€œdâ€ partition, /tmp as â€œeâ€ partition and /usr as â€œfâ€ partition. We will dump from the hard drive where the running system is installed to a second hard drive cabled to the motherboard or an external USB cabled hard drive or a USB memory stick of sufficient size. Whatever the target media is, all the data currently on it will be destroyed by this procedure. Even the MBR (Master Boot Record) will be recreated. For this example /dev/ad0 is the hard drive where the live system is running. The target is an USB flash stick /dev/da0. The following is the sequence of commands used: * Collect live file system sizes and save df -h > liveFSsizes Code: cat liveFSsizes Filesystem Size Used Avail Capacity Mounted on /dev/ad0s1a 496M 169M 287M 37% / devfs 1.0K 1.0K 0B 100% /dev /dev/ad0s1d 1.5G 26M 1.4G 2% /var /dev/ad0s1e 496M 10K 456M 0% /tmp /dev/ad0s1f 15G 410M 13G 3% /usr * Collect live Slice Partition sizes and save Bsdlabel lists the live Slice Partition sizes to a file. This file will be used later to allocate the slice partitions to the target. bsdlabel ad0s1 > liveSPsizes Code: cat liveSPsizes # /dev/ad0s1: 8 partitions: # size offset fstype [fsize bsize bps/cpg] a: 1048576 0 4.2BSD 0 0 0 b: 2291584 1048576 swap c: 39862305 0 unused 0 0 d: 3241984 3340160 4.2BSD 0 0 0 e: 1048576 6582144 4.2BSD 0 0 0 f: 32231585 7630720 4.2BSD 0 0 0 If you want to increase or decrease the partition allocation space sizes edit the liveSPsizes.usb file. I have edited this changing partition sizes so it will fit on a 2GB USB stick. You can see from the df â€“h output that the default sizes sysinstall calculates leaves a lot of free space in the partitions. Code: # /dev/da0s1: 2GB USB flash drive stick 8 partitions: # size offset fstype [fsize bsize bps/cpg] a: 300M * 4.2BSD 0 0 0 b: 200M * swap c: * * unused 0 0 d: 50M * 4.2BSD 0 0 0 e: 100M * 4.2BSD 0 0 0 f: * * 4.2BSD 0 0 0 * Zero out the target MBR destroying all the data on the target. dd if=/dev/zero of=/dev/da0 count=2 * fdisk the target with a new MBR. fdisk -BI /dev/da0 The â€“B means Reinitialize the boot code contained is sector 0 of the disk Default from /boot/mbr The â€˜Iâ€™ means initialize sector 0 slice table for one slice covering the entire disk. You will get 2 messages. Code: Fdisk: invalid fdisk partition table found Fdisk: Class not found Disregard these messages, they are the result of zeroing out the old MBR. * Label the target: bsdlabel -B -w da0s1 The â€“B means bootstrap code will be read from /boot/boot & written to the disk The â€“w means write a standard label * Allocate the partitions * Restore the partition sizes as defined in the file liveSPsizes bsdlabel -R -w da0s1 liveSPsizes * Format all the new empty file system on the target. Code: newfs â€“U /dev/da0s1a # / newfs -U /dev/da0s1d # /var newfs -U /dev/da0s1e # /tmp newfs -U /dev/da0s1f # /usr * Mount target file system â€˜aâ€™ / and clone Code: mount /dev/da0s1a /mnt cd /mnt dump -0Lauf - /dev/ad1s1a | restore -rf - Flags: -0 means do full dump, -L means take snapshot because source is live file system, -a means enforce writing until a end-of media is reached -u means update the /etc/dumpdates file with the results -f - means standard output is where the dumped data is to be written. You can think of 'standard output' as a un-named virtual file or buffer. If there was no pipe | to the restore program the dumped data would roll across the terminal screen. The restore program, on the other side of the | pipe, usually reads from the system's tape drive. But in this case, it reads from standard input as the -f â€“ command line option indicates. It restores the data to where the working directory is currently positioned. In the example the current working directory is /mnt where the target file system. â€˜aâ€™ is mounted The â€“r flag means rebuild the file system. The restored file system will be of the same size as the one dumped including its free space it you did not change the content of the (liveSPsizes) file. In reality what we have with the above dump command is as dump writes a block of data to standard output its immediately handed to restores standard input and written to the target. The above snippet of code would have to be duplicated for each file system you wanted to dump. The following (fbsd2clone) script employs the sample code snippet detailed above. Code: #!/bin/sh # This script will use dump/restore to clone your running # system to another motherboard cabled hard drive or # USB cabled hard drive or USB flash stick. # This is run as root. # # Change these device unit pre-fixs as needed # ad0 is the live file system # da0 is the target echo "Collect live file system sizes and save" df -h > liveFSsizes cat liveFSsizes echo " " echo " " echo "Collect live Slice Partition sizes and save" bsdlabel ad0s1 > liveSPsizes cat liveSPsizes echo " " echo " " cat liveSPsizes.usb # At this point you can edit the liveSPsizes files and # increase or decrease the file system partition sizes # man bsdlabel for details echo " " echo " " echo "Prepare the target" dd if=/dev/zero of=/dev/da0 count=4 fdisk -BI /dev/da0 bsdlabel -B -w da0s1 bsdlabel -R da0s1 liveSPsizes.usb newfs -U /dev/da0s1a newfs -U /dev/da0s1d newfs -U /dev/da0s1e newfs -U /dev/da0s1f echo " " echo " " echo "Mount target file system 'a' / and clone" mount /dev/da0s1a /mnt cd /mnt dump -0Lauf - /dev/ad0s1a | restore -rf - echo " " echo " " echo "Mount target file system 'd' /var and clone" mount /dev/da0s1d /mnt/var cd /mnt/var dump -0Lauf - /dev/ad0s1d | restore -rf - echo " " echo " " echo "Mount target file system 'e' /tmp and clone" mount /dev/da0s1e /mnt/tmp cd /mnt/tmp dump -0Lauf - /dev/ad0s1e | restore -rf - echo " " echo " " echo "Mount target file system 'f'/usr and clone" mount /dev/da0s1f /mnt/usr cd /mnt/usr dump -0Lauf - /dev/ad0s1f | restore -rf - echo " " echo " " echo "Clean up" sync cd /root umount /mnt/usr umount /mnt/tmp umount /mnt/var umount /mnt echo " Script completed"