Solution 1:

This is messy, but doable.

I presume here that / is on /dev/sda3 and that /boot is on /dev/sda1.

  1. Shrink the filesystem on the old server to its minimum possible size.

    oldserver # resize2fs -M /dev/sda3
    
  2. Partition the new server's disk with an identically sized /boot, swapspace, and new / partition (and anything else you need).

    newserver # parted /dev/sda
    
  3. Copy the / and /boot filesystems.

    oldserver # dd if=/dev/sda1 | ssh root@newserver "dd of=/dev/sda1"
    oldserver # dd if=/dev/sda3 | ssh root@newserver "dd of=/dev/sda3"
    

    Because the partition on the new server will be slightly smaller than the one on the old server, you'll receive a spurious No space left on device message at the end of this. However, since you shrank the filesystem at step 1, this doesn't matter.

  4. Resize the filesystem on the new server to the size of the partition.

    newserver # resize2fs /dev/sda3
    
  5. Install GRUB on the new disk.

    newserver # mount /dev/sda3 /mnt
    newserver # mount /dev/sda1 /mnt/boot
    newserver # mount -o bind /dev /mnt/dev
    newserver # mount -o proc proc /mnt/proc
    newserver # chroot /mnt /bin/bash
    
    newserver(chroot) # grub-install /dev/sda
    newserver(chroot) # exit
    
  6. Finish the rest of your fixups (IP address, etc.).

You can probably find a way to avoid copying the partition's free space, but it'll probably take you longer to research than to just copy it all...

Solution 2:

I'd mkfs fresh filesystems on the new server, then rsync them from the old server. That is restartable, consistent, and each file is easily individually verifiable. Where you're discarding unused sections of the filesystem (not a forensic copy), I don't see any reason to not use this method. You would have to re-run GRUB, but that shouldn't be a challenge.

Explaining a raw copy that is file-system aware would take me a while, so unless you comment as to why my rsync solution doesn't work I'll spare myself the typing.

Solution 3:

If you REALLY want to transfer data at a block device level, I can think of one pretty useful trick I was using to migrate servers with minium downtime involved.

The thing is, you can create a degraded mirror on source server with your data partition being the only active half of the mirror, then export destination partition from second server via AOE (I suppose both your servers are in the same broadcast domain). At source server you then connect network block device to your degraded mirror so it would start rebuild. Wait until rebuild is complete, stop your mirror, remove AOE exported device and you're OK.

A bit more details follow (I'll try to keep it brief).

Components:

  • mdadm with its build mode (ad-hoc mirror without metadata);
  • vblade for exporting block device as AOE network device;
  • aoe-tools for importing AOE network block device.

You have to create partition table on your destination server, then shrink source partition so it would fit destination. You can easily install GRUB to your new MBR; syncing just partitions over newly created partition table is a bit less error-prone.

On the receiving side you have to export your partition with vblade tool, on source server you can see exported devices after installing aoe-tools (run aoe-discover then look at /dev/ether/ for devices).

Then you should build raid1 device on source server with your source drive:

mdadm --build /dev/md0 -n2 -l1 --force /dev/sda

After this you can examine newly built mirror:

mdadm --detail /dev/md0
cat /proc/mdstat

At this point you can safely attach exported destination partition to this mirror:

mdadm /dev/md0 --add /dev/ether/eX.Y

Then just watch over synchronization progress:

watch -n5 cat /proc/mdstat

After sync is done, just stop the mirror: mdadm --stop /dev/md0 on source server, terminate vblade process on destination server, install GRUB on second server, change your IP addresses, etc.

Actually, with this trick it is possible to move server between boxes almost live, with downtime just to reboot synced boxes.


For performance reasons, I also suggest you increase your link's MTU (or set up a separate VLAN with jumbo frames enabled, if possible).

Note, you also can use something like nbd-server/nbd-client (or even iSCSI, if you want it rough) as an alternative to AOE, but AOE (vblade + aoe-tools) have a very simple interface and a great performance (no TCP/IP overhead),