Updating Hyper-V drivers after a kernel upgrade on CentOS

Dec 26 2009

A few days ago I was updating a CentOS machine that happens to be running on Microsoft's Hyper-V platform. Everything went very smooth. So I tried to reboot the machine, because I wanted to make sure that everything worked fine after a reboot.

The reboot

Apparently the kernel was updated too and the system did not boot with the new kernel. Since I have no access to the Hyper V environment itself, I needed to call my hosting provider (I only have shell access to the server). The restarted the machine and chose to boot the old kernel (which still worked). This was only a temporary solution because after a reboot the machine would still try to boot the new kernel.

Linux Integration Components

After some investigation I found out that I needed to install the Linux Integration Components for Hyper-V in the new kernel. It turns out that these integration components must be installed for each kernel that you want to boot into. There is one problem however, the integration components will only be installed in the currently running kernel by default. Since I have no access to the Hyper V environment and the machine has no ethernet connection without the components, I needed to find another way to install the components into the new kernel. I called my hosting provider again and they wanted to help me, but they would charge me around € 90,- for this (simple) task. I decided to find another solution myself.

Installing the Linux Integration Components into a non-running kernel

There are a few good tutorials for installing the Linux Integration Components in the currently running kernel, but I couldn't find proper documentation. It turns out that the scripts (and makefiles) that install the components make intensive use of the "uname -r" command to find out for which kernel the integration components should be installed. This means taht by default it's not possible to install the components into another kernel. I found the following solution:

  • Create a checkpoint for your Hyper-V machine (if you can), so that you can always restore the machine to the current state in case something goes wrong.
  • Find the kernel that you want to boot in by listing the installed kernels.
    rpm -q kernel
  • In my case I got the following output:
    In my case the running kernel was "2.6.18-128.7.1.el5" and I wanted to boot into the newest kernel "2.6.18-164.9.1.el5".
  • Backup your linux integration components setup directory:
    cp -R Linux_IC_V2 Linux_IC_V2-backup
    And change directory to the Linux integration components setup directory (in my case the components are installed in /root/Linux_IC_V2):
    cd Linux_IC_V2
  • The setup script assumes that you've already booted the new kernel when you are installing the new drivers. I think that it would be a lot easier if the kernel version could be passed as an argument to the script. But this is not the case so we need to adjust some files in the setup directory, you can find out which files need to be changed by using grep:
    grep -iR "uname -r" *
    In my case the following files where found:
  • Now we need to edit all those files (you can use your favorite editor) and make sure that we replace "uname -r" with the new kernel version. So in my case I replaced
    shell uname -r
    shell echo "2.6.18-164.9.1.el5"
    in the Makefiles. And in the perl scripts you can replace
    `uname -r`
  • Now it is time to install the integration components in the kernel:
    ./setup.pl drivers
  • If the previous step was successful, we can check /boot/grub/menu.lst to make sure that we are booting the new kernel on reboot.
  • We should now be able to boot into the new kernel!

I hope this post was useful for you, because I have spent quite some hours tackling this specific problem. I have learned a lot about the Hyper-V platform in those hours though...