It turns out that migrating a linux box to a new hardware is not as easy task as it used to be. I’m running a Trixbox system on an old 1 GHz Pentium III machine. The owner of the box got another antique – a Dual 1.4 GHz Pentium III ProLiant DL360 G2 with two SCSI drives. So I was tasked with migrating the trixbox to the new hardware. It took me about 20 hours to get this working, but all the work can be done in 3-4 hours, depending on how much data you have. This guide requires you to have a basic knowledge of the linux architecture and the linux commands, as well as what is in the /dev directory. Due to the fact that trixbox is CentOS-based this guide can easily be applied to migrating a regular CentOS installation .
Let me guide you through the procedure how to migrate all your data and information. Here are the necessary ingredients:
- Two System Rescue CDs (one for each machine) – download is free
- Uplink ethernet cable – or a regular if one of the machines has auto-sensing ethernet NICs
- Keyboard, monitors, etc. for both machines. Using a customized System Rescue CD you can do it all over the network, but I used monitors and keyboards, hence I cannot guide you how to make a customized System Rescue CDs
The following steps should lead to the complete migration of your trixbox system:
- Stop the old trixbox and boot it from the first System Rescue CD
- Boot the new trixbox-to-be with the second System Rescue CD
- Connect both boxes via ethernet cable
- Setup the network
00:00 root@sysresccd /root % net-setup eth0
The following settings are assumed for the first machine. If you change any of the addresses please note to change them in all operations mentioned bellow:
Network type: “Wired”, Manually specify IP address
IP Address: 192.168.1.1
Netmask: 255.255.255.0
Broadcast: 192.168.1.255
Gateway: (leave blank) - Do the same for the new machine, just set the IP address to 192.168.1.2 (again, if you decide to use different IPs change accordingly, bellow)
- Mount the partitions on the old machine: A typical installation will have separate partitions for / (root), and /boot, thus:
00:00 root@sysresccd /root % cd /mnt
00:00 root@sysresccd /mnt % mkdir hda
00:00 root@sysresccd /mnt % mount /dev/hda2 /mnt/hda
00:00 root@sysresccd /mnt % mount /dev/hda1 /mnt/hda/boot
hdaX: change accordingly to your configuration – if you have SCSI drive this will be sda1-8, or if you have a special RAID controller (which was my case) the devices might be in a subdirectory of /dev, e.g.: /dev/cciss/c0d0p2 instead of /dev/hda2.
- If your new machine’s hard drives are not partitioned just yet, type wizard on the command line of the new machine and use GPartED to partition your new hard drive. wizzard will start a graphical interface from where you can start GPartED. I advise you to keep the same partitions as the one you already have on your old machine – first partition is /boot, second partition is /, and third partition is swap. Make sure you set the same labels for each partition as they are on the old trixbox
- Mount the partitions on the new machine:
00:00 root@sysresccd /root % cd /mnt
00:00 root@sysresccd /mnt % mkdir hda
00:00 root@sysresccd /mnt % mount /dev/hda2 /mnt/hda
00:00 root@sysresccd /mnt % mkdir /mnt/hda/boot
00:00 root@sysresccd /mnt % mount /dev/hda1 /mnt/hda/boot
hdaX: change accordingly to your configuration – if you have SCSI drive this will be sda1-8. I strongly advise you to keep the directory of the mount point of the root partition (/mnt/hda) intact as its name is irrelevant to the system and it will be easier to follow this guide.
- View the labels of your partitions on your old machine (you may skip this if you already labeled your new drives when partitioning):
00:00 root@sysresccd /mnt % e2label /dev/hda1
/boot
00:00 root@sysresccd /mnt % e2label /dev/hda2
/ - Set the new labels on your new machine:
00:00 root@sysresccd /mnt % e2label /dev/hda1 /boot
00:00 root@sysresccd /mnt % e2label /dev/hda2 /
If you do not set the labels to be the same on your old machine you’ll end up with an unbootable OS.
- Change the password for root on your new box (type anything you can remember):
00:00 root@sysresccd /mnt % passwd
Password:
- Start pushing the content to your new box. Type on the old box:
00:00 root@sysresccd /mnt % rsync -av /mnt/hda 192.168.1.1:/mnt/hda
- When rsync is done transferring your files unmount all disks on your old system and shut it down:
00:00 root@sysresccd /mnt % umount /mnt/hda/boot
00:00 root@sysresccd /mnt % umount /mnt/hda
00:00 root@sysresccd /mnt % shutdown -h now
- Chroot to the root (/) partition of your new system:
00:00 root@sysresccd /mnt % cd hda
00:00 root@sysresccd /mnt/hda % chroot . bin/bash
- Setup GRUB on your new system:
[00:00 root@new /] # grub
grub> root(hd0,0)
grub> setup(hd0)
hd0,0 should be where your boot partition is located and hd0 should be the hard drive which will holds your MBR. You might have to edit /boot/grub/devices.map so that hd0 points to the device name representing your new hard disk
- Exit the chroot environment:
[00:00 root@new /] # exit
- Reboot the system:
00:00 root@sysresccd /mnt/hda % reboot
- Remove the CD from the tray and let your new machine boot from the hard drive
- That SHOULD be it!
Modify your initrd image to add an additional kernel module
As I said above – that SHOULD be it, but I doubt very much that this will be it. Most probably you will run into a bunch of problems. Before wondering what’s going on make sure your new hardware is supported by Trixbox/CentOS. My new hardware for example was using a HP Smart Array RAID controller. It turned out that this device is supported but the driver was built as a module. Due to this, I was stuck – the kernel needed a driver to access the hard drive, but the driver (kernel module) was located on the hard drive, thus the kernel could not load it.
There are 2 possible solutions to this:
1. Recompile the kernel and compile the required module (and all modules it depends on) statically in the kernel
2. Modify your Initial Ramdisk image (initrd.img) to accommodate all required modules
In order to recompile the kernel, you can folow the CentOS Custom Kernel HOWTO.
If you have never recompiled a kernel, or prefer to go the easy way – choose the second option
The Initial Ramdisk image is an image that holds a mini-filesystem that holds the bare essentials of a root filesystem and it is used, among other things, to store essential kernel modules – for accessing your SCSI RAID hard drives, for example.
Here is a quick tutorial how to add a kernel module, in my case the cciss.ko HP/Compaq Smart Array Controller. I used this tutorial to help me figure out how the initrd image is build. You can also use mkintird to make an image, but I preferred going the manual way.
- Boot again with the System Rescue CD your new system and mount the hard drives (all of them, on their respective mount points)
- Use a search engine to find out the driver that you are missing – I will use cciss.ko as an example
- Mount your hard drive again and change to the directory of the mount point:
00:00 root@sysresccd /root % mkdir /mnt/hda
00:00 root@sysresccd /root % mount /dev/hda1 /mnt/hda/boot && cd /mnt/hda
- Chroot to the hard drive:
00:00 root@sysresccd /mnt/hda % chroot . bin/bash
- Copy your current initrd to /root on the hard disk. The ramdisk is located in /boot and is named initrd-a.b.c-d.e.f.el5.img. a to f in the filename represent numbers. When copying the initrd image rename it simply to initrd.img.gz:
[00:00 root@new /] # cp /boot/initrd-a.b.c-d.e.f.el5.img /root/initrd.img.gz
- Unpack the image:
[00:00 root@new /] # cd /root
[00:00 root@new /root] # gunzip intird.img.gz
[00:00 root@new /root] # mkdir intird
[00:00 root@new /root] # cd initrd && cpio -i –make-directories < ../initrd.img
- Locate the kernel module you need and all the modules it dependents on and copy them into /root/initrd/lib:
[00:00 root@new /root] # cd /lib/modules/a.b.c-d.e.f.el5/
[00:00 root@new /lib/modules/a.b.c-d.e.f.el5/] # find . -iname "*cciss*"
./kernel/drivers/block/cciss.ko
[00:00 root@new /lib/modules/a.b.c-d.e.f.el5/] # cp ./kernel/drivers/block/cciss.ko /root/initd/lib/
* Replace cciss above, with the name of your missing kernel module.
Repeat these steps for every depending module. - Go to /root/initrd
[00:00 root@new /lib/modules/a.b.c-d.e.f.el5/] # cd /root/initrd
- edit the init file and make sure you add an insmod command for every module you need to load, in the appropriate order, e.g.:
insmod /lib/cciss.ko
- create the appropriate device nodes, e.g.:
mkdir /dev/cciss
mknod /dev/cciss/c0d0 b 104 0
mknod /dev/cciss/c0d0p1 b 104 1
mknod /dev/cciss/c0d0p2 b 104 2
See the man page for mknod for more information.
- Pack the initrd image:
[00:00 root@new /root/initrd/] # (find . | cpio –quiet -c -o) > ../initrd.new.img
[00:00 root@new /root/initrd/] # cd ..
[00:00 root@new /root/] # gzip initrd.new.img
- Create a backup copy of your initrd image in case something goes wrong:
[00:00 root@new /root/] # mv /boot/initrd-a.b.c-d.e.f.el5.img /boot/initrd-a.b.c-d.e.f.el5.img.old
- Move the initrd image to /boot
[00:00 root@new /root/] # mv initrd.new.img.gz /boot/initrd-a.b.c-d.e.f.el5.img
- Reinstall grub
[00:00 root@new /root/] # grub
grub> root (hd0,0)
grub> setup (hd0)
grub> quit
- Reboot the system
Wow! Even Windows User can complete this!
I have moved CentOS VM from 4G Virtual HD to 8G Virtual HD.
I had problems with grub. At the end I have used:
grub-install –recheck /dev/sda –root-directory=/mnt/sda
and I have not used chroot at all.
Thanks a lot!