Q:

Best way to duplicate Linux server

My company has an old CentOS 5 system that we need to duplicate for testing. I'm running dd on 2 of the partitions which are small and saving them to /home, but the /home partition can't save to itself or another partition as there isn't enough room.
/home is only about 7% full so copying all of its files to a tarball should be easy enough, but I'm wondering if there's a better way to do this.
I can't bring the machine offline and I can't hook up a USB drive externally and copy to files that way so I have to either use SCP, dd or tar most likely.
Any suggestions? Here's a quick breakdown of df -h
Filesystem  Size   Used  Left usage% Mount point
/dev/sda2    97G   17G   75G  19%     /
/dev/sda1    99M   15M   80M  16%     /boot
tmpfs       2.0G     0  2.0G   0%     /dev/shm
/dev/sda3   352G   22G  312G   7%     /home

A:

There are definitely "better" ways to do this, but how you go about doing this comes down to what resources you have available. I'll list a few different ways and you can decide which works best for you.
To begin, copying data in /home to a tarball is pointless. You can't save it locally, which means that to do this, it will require a remote server that you can send the data to. Preferably, a server on the same network as this computer that is accessible via SSH. Frankly, making tarballs of the other partitions and putting them in /home is a waste of time.
If you're looking to duplicate this server, what I would do is use dd to make an image of /dev/sda and send the data over SSH to another server. The two best ways of doing this are to either image another hard drive at the same time or save the image as a file.
dd if=/dev/sda bs=4096 conv=notrunc,noerror,sync | ssh user@machine "dd of=/dev/sdX"
This will clone the entire drive, including MBR (and therefore bootloader), all partitions, UUIDs, and data, sending it over SSH to another machine and imaging a drive of your choosing. The options I suggested do the following:

notrunc or 'do not truncate' maintains data integrity by instructing
dd not to truncate any data.
noerror instructs dd to continue operation, ignoring all read errors.
Default behavior for dd is to halt at any error.
sync writes zeroes for read errors, so data offsets stay in sync.
bs=4096 sets the block size to 4k, an optimal size for hard disk
read/write efficiency and therefore, cloning speed.

For this to work, the user you use log in with SSH as needs to either be root, or part of the disk group. /dev/sdaX should be mode 660, giving group read/write access. The default group owner should be disk.
Alternatively, you can create an image that you can use to write directly to the disk.
dd if=/dev/sda bs=4096 conv=notrunc,noerror,sync | ssh user@machine "dd of=/path/to/wherever/server.img"
To write the image to a hard drive from the computer it is saved on, you can use the following command.
dd if=/path/to/server.img bs=4096 conv=notrunc,noerror,sync of=/dev/sdX
Lastly, if space is a concern, you can gzip the image before sending it over SSH.
dd if=/dev/hda conv=sync,noerror bs=4096 | gzip -c | ssh user@machine "of=/path/to/wherever/server.img.gz"
and writing it by
gunzip -c /path/to/server.img.gz | dd of=/dev/sdX
Lastly, if you want to pull individual files from the image without writing it to another drive, you can mount it. However, this won't work if it's compressed.
You'll have to fdisk -lu /path/to/server.img to get the offset of the individual partitions. Once you do that, you need the starting sector of the partition you want to mount. For the sake of argument, let us say that the partition we want to access starts on sector 122441728.
$ fdisk -lu server.img

Disk server.img: 320.1 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders, total 625142448 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x86308630

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *          63   114441469    57220703+  83  Linux
/dev/sda2       114442240   122441727     3999744   82  Linux swap / Solaris
/dev/sda3       122441728   625141759   251350016   83  Linux

You would then use mount -o ro,loop,offset=$((122441728 * 512)) server.img /mnt to mount the third partition to /mnt.
Sources:

https://wiki.archlinux.org/index.php/Disk_Cloning#Create_disk_image
http://madduck.net/blog/2006.10.20:loop-mounting-partitions-from-a-disk-image/

