Hyper-V Integration Components in x86_64 CentOS and RHEL

Update 13th July 2008: New version of this HOWTO is available with information on Linux Integration Components RC2.

This page tells you how to install the Windows Server 2008 virtualization Hyper-V Linux Integration Components in CentOS and RHEL (RedHat Enterprise Linux) 5. I did it all in x86_64 (or x64) as it is much more interesting and useful.

Installing the ICs in CentOS 5.1 or RHEL 5.1 is rather harder than in SuSE 10.

You need to copy the code off the CDROM ISO image, so let’s start by doing that:
mkdir -p /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
mkdir /opt/linux_ic
( cd /mnt/cdrom && tar cf - . ) | ( cd /opt/linux_ic && tar xvBpf - )
umount /mnt/cdrom

Next, get the kernel source for the exact version of kernel and kernel-headers you are using. “rpm -qa | grep kernel” will tell you what kernel-headers you have. Remember that a “yum update” may change the kernel version.

Once you have the the kernel version, go and find the kernel source SRPM. You can get this from
http://mirrors.centos.org/centos/5/updates/SRPMS/ or http://mirrors.centos.org/centos/5/os/SRPMS/.

Install the SRPM which will get you the full kernel source in /usr/src/redhat/SOURCES (along with all RedHat’s patches) and the spec file in /usr/src/redhat/SPECS. You need to edit the spec file, so make a backup copy of it first. Find the “buildid” definition line, uncomment it, remove the extra space after % and change it to something like
%define buildid .JKF1
The tools supplied with RHEL5 and CentOS 5 are not good enough to build the kernel-headers, due to a lack of support for “unifdef” in GNU make. So find the line that sets “with_headers” and change it to
%define with_headers 0

Just before the “%build” line, you need to add the patch for the Hypervisor code. 2 of the parts of the Microsoft-supplied patch do not apply successfully, due to differences in the source code where it doesn’t match what Microsoft think it is. So do a “rpmbuild -bp kernel-2.6.spec” to build a patched source tree in /usr/src/redhat/BUILD. Then cd into it and try to apply the patch in /opt/linux_ic/patch/. You will find 2 bits of it don’t apply correctly. Look at the .rej file for each failed patch and apply the changes by hand. Copy the 2 manually patched source files to somewhere convenient like /root. Before the “%build” line, add a chunk of shell script that does something like this: (I am assuming here that you know what you’re doing Happy
cd /usr/src/redhat/BUILD/kernel-2.6.18
( patch -p0 < /opt/linux_ic/patch/x2c-x64-sles.patch ; /bin/true )
cp -f /root/head64-xen.c linux-2.6.18.x86_64/arch/x86_64/kernel/
cp -f /root/pgalloc.h linux-2.6.18.x86_64/include/asm-x86_64/mach-xen/asm/

You can now build the RPM, which will construct several kernels, including the xen one which is what you need. So
cd /usr/src/redhat/SPECS
rpmbuild -ba kernel-2.6.spec
Be warned, this will take *hours* on a on a virtual machine.

Now install the xen version of the new kernel:
cd /usr/src/redhat/RPMS/x86_64
rpm -ivh --force kernel-xen-2*.JKF2*rpm

Build the x2v version of the kernel
cd /opt/linux_ic
perl setup.pl x2v /boot/grub/grub.conf

Now you need to fix up the /boot/grub/grub.conf file. For the section that includes the x2v-64 stuff, remove the “/boot” leading path, as all paths must be given relative to /boot. You *do* need the leading “/” though. The final section you get should look like this:
title CentOS (2.6.18-53.1.4.el5.JKF2xen)
root (hd0,0)
kernel /x2v-64.gz
module /vmlinuz-2.6.18-53.1.4.el5.JKF2xen ro root=/dev/VolGroup00/LogVol00 rhgb quiet
module /initrd-2.6.18-53.1.4.el5.JKF2xen.img
I strongly advise you comment out the “hiddenmenu” setting, and set the default to this kernel (they are numbered from 0=start of file).

Now reboot, and it should boot your newly built kernel with the X2V shims in place.

Next step is to build the drivers. There is one problem that needs fixing first, the “build” link in the /lib/modules/ directory will be broken. To fix this, make it point into the kernel source that you have been building from, with something like this:
cd /lib/modules/`uname -r`
ln -nsf /usr/src/rdhat/BUILD/kernel-2.6.18/linux-2.6.18.x86_64 build
Now build the drivers:
cd /opt/linux_ic
perl setup.pl drivers

You should now have the drivers running, and should have just seen the output of the “modprobe vmbus” command. And you should find that “ifconfig” outputs a new network device “seth0”. When you reboot, the vmbus module willl automatically be started. Unfortunately, it loads too late in time for it to be used for the seth0 network interface to be the sole external network interface, nor in time for the SCSI device to mount filesystems stored on virtual SCSI disks. Moving the init.d script to S04vmbus doesn’t help, as kudzu does not see the device and so removes it from the /etc/sysconfig/network-scripts directory.
UPDATE -- appears to work okay as a network interface, like on SuSE 10.
If you try to attach the network interface automatically at boot time, you will need to do this after the machine has booted:
service network start
service sshd restart
along with any other network-connected daemons you have started, such as MailScanner or sendmail.

You now have the same ICs running in CentOS 5.1 or RHEL 5 as Microsoft intended to run in SuSE 10.