Saturday, August 18, 2007

HP Netraid and Modern Linux Kernels


They just don't play well together.

I recently acquired an aging HP Netserver (for free!) and wanted to load up a LAMP server on it for testing. It seemed like a very straightforward proposition until I attempted to put it into practice. Not one modern distribution would would detect the RAID controller. Redhat 7.3 on some old disks would, however, and this gave me a bit of hope. The problem with using such an old version was that it wouldn't support some of the more modern packages I needed. PHP5, for example. I would need to upgrade somehow. This I did, going through the upgrade path all the way to RH9. Going any further, however, was nearly impossible due to some odd restructuring that had occurred at RedHat sometime after this version. Besides, what I really wanted was some flavor of debian, with it's delicious apt-get.

Researching a bit, it turns out that the 2.6 and above kernel has lost the ability to detect these hardware RAID adapters for some reason (the PCI ID's are missing from the newer drivers for HP Netraid 1M and Netraid 2M, even though the legacy driver itself is otherwise the same). There is, luckily, a useable patch to the 2.6 and above kernel that takes care of this problem by adding the two ID's to the source code of the megaraid files (megaraid.h and megaraid.c must both be patched or it won't work). The 2.6+ kernel patch, by Kevin Carson, can be found here.

This is the essence of it, in case the old archive disappears:

+++ kernel-source-2.6.11.works/drivers/scsi/megaraid.h 2005-07-05 10:05:44.000000000 -0700 @@ -84,6 +84,10 @@ #define LSI_SUBSYS_VID 0x1000 #define INTEL_SUBSYS_VID 0x8086 +/* Sub-System Device IDs */ +#define HP_NETRAID1M_SUBSYS_DID 0x60E7 +#define HP_NETRAID2M_SUBSYS_DID 0x60E8 + #define HBA_SIGNATURE 0x3344 #define HBA_SIGNATURE_471 0xCCCC #define HBA_SIGNATURE_64BIT 0x029 --- kernel-source-2.6.11/drivers/scsi/megaraid.c 2005-06-16 08:06:21.000000000 -0700 +++ kernel-source-2.6.11.works/drivers/scsi/megaraid.c 2005-07-05 10:06:39.000000000 -0700 @@ -5037,6 +5037,10 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, + HP_SUBSYS_VID, HP_NETRAID1M_SUBSYS_DID, 0, 0, 0}, + {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, + HP_SUBSYS_VID, HP_NETRAID2M_SUBSYS_DID, 0, 0, 0}, {0,} }; MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);

I find it rather odd that the fix, distributed two years ago, still hasn't made it into the official source. It's not as if it were some huge change and would add support to these servers, which are rather old but still quite useful. For anyone not familiar with the patch format displayed above, the lines preceded by a plus(+) are the additions to the existing code which is shown around the new lines for reference. The @@ -84,6 +84,10 @@ line tells you around which line numbers the changes will be made. In this case, we're looking at line 84 of the header (.h) file. The changes are made directly to the files of the kernel source before compiling. (I've been so spoiled with automated patches and such that I actually had to look this up.)

I cobbled together this procedure from four different places:

http://www.falkotimme.com/howtos/debian_kernel2.6_compile/

http://www.suseblog.com/?p=156

http://www.edseek.com/archives/2004/03/22/creating-an-initrd-image-on-debian-gnulinux/

http://www.linuxquestions.org/questions/showthread.php?t=335214

While it may be better to compile the source on another machine and create an install disk, this just seems easier and doesn't require compiling an entire distro from scratch.

 

1) Download Sarge 3.1 (it's out there, though you might have to hunt) minimal install, change sources.list, run apt-get update then dist-upgrade. This didn't upgrade my kernel, but changed everything else to etch. This can break things, but should be just good enough for the next step.

2) Get some needed utilities and the source:

apt-get install kernel-package ncurses-dev fakeroot wget bzip2

cd /usr/src

wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz2

3) Unpack the sources:

tar xjf linux-2.6.18.tar.bz2

cd linux-2.6.18

4) Edit both megaraid.c and .h with patch code. The only things you'll be adding are:

#define HP_NETRAID1M_SUBSYS_DID 0x60E7

#define HP_NETRAID2M_SUBSYS_DID 0x60E8

In megaraid.h. and:

{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,

HP_SUBSYS_VID, HP_NETRAID1M_SUBSYS_DID, 0, 0, 0},

{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,

HP_SUBSYS_VID, HP_NETRAID2M_SUBSYS_DID, 0, 0, 0}, {0,}

In megaraid.c

5) Make sure you're in the /usr/src/linux-2.6.18 directory and type:

make menuconfig

This will bring up a nice menu driven way to configure your new kernel's options.  There are a few hundred esoteric options in here. I suggest checking them carefully because some things aren't included by default that I consider a necessity. IPTables and Netfilter, for example.

In the SCSI drivers section: select *only* the legacy driver remember to compile it with the driver as a <m>odule, this is very important. I also selected RAID transport class and a few dozen other things in the kernel cinfiguration that seemed interesting or useful. This may or may not be a good idea, see your favorite linux expert for details.

Once this is done, save and exit. Then type the following:

make-kpkg clean
fakeroot make-kpkg --revision=myKernel.1.0 kernel_image

6) After a few dozen hours install your shiny new kernel:

dpkg -i kernel-image-2.6.8.1_myKernel.1.0_i386.deb

7) Do not reboot. Well, you can if you really want to but the new kernel won't work just yet, so you'll need to boot into the previous version to finish up.

8) Now edit the intramfs file in /etc/intramfs-tools/modules (memory fails me here, but that's about where it should be) and add 'megaraid' on a line by itself. If it doesn't exist you'll need to apt-get intramfs or whatever the heck the package is called.

9) Type: update-intramfs -c -k 2.6.18 (or your kernel version)at the command prompt

10) edit the grub menu.lst in /boot/grub and add:

initrd        /boot/initrd.img-2.6.20





To the boot image of your new kernel. The old kernel's boot parameters should guide you if you're not sure where to put this.






That should do it, if it doesn't work for you, see my disclaimer. One good thing about GRUB is that it keeps my old (2.4) kernel handy in case I screw up and need to do this over again. I can now use more up to date packages on my old Netserver. Unfortunately, this has to be done every time I upgrade the kernel from now on.






3 Comments:

gache56 said...

I just want to thank you. You should modify steps 8 and 10.
Step 8 : the file to edit is "modules" in /etc/initramfs-tools. The name of the package is "initramfs-tools".

Step 10 :
initrd /boot/initrd.img-2.6.18

Tour tutorial works very well for me.Bye.

Ironlizard said...

Thank you! Glad it helped.

mrlag said...

There is a debian bug for this here :

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=317258

You can found there a patch.

It works for me ( I've installed a sarge with netcd, then net upgrade to etch, then patch the last etch kernel ).

Here are my commands to build the kernel in a proper way :

apt-get source linux-image-2.6.18-6-686

apt-get install build-essential fakeroot dpkg-dev
apt-get build-dep linux-image-2.6.18-6-686

dpkg-source -x linux-2.6_2.6.18.dfsg.1-18etch1.dsc

cd linux-2.6-2.6.18.dfsg.1/

patch the files

update linux-2.6-2.6.18.dfsg.1/debian/arch/i386/defines to remove unused flavors

dpkg-buildpackage -rfakeroot -uc -b