Aug 17 2013

继续折腾内核 centos 5.9 to 3.0.91 kernel

Category: 技术ssmax @ 13:28:53

前两天升级内核到3.0.90,用的是centos 5.9的 oldconfig,但是由于2.6.18的config文件实在是太老了,用它来做oldconfig,发现很多新内核的特性没有编译进来,最简单的哦iptalbes NAT模块都没有。。。

所以这几天都在折腾内核,折腾了几次之后,决定用centos 6.4的config文件做基础,来进行oldconfig,6.4的config文件从对应的rpm里面提取,编译的过程中遇到不少坑,现记录如下:

1、坑一
新config的scsi_mod会默认编译进内核,而不是作为模块存在了

CONFIG_SCSI_MOD=y
CONFIG_SCSI=y

但是CONFIG_BLK_DEV_SD依旧是m,那样导致scsi_mod编译到内核了,而sa_mod 依然在外面,最后mkinitrd的时候,由于scsi_mod 没有了,所以sa_mod 也不会带到initrd引导里面,导致我在vmware测试的时候老是说找不到盘。。。

调试了非常久的时间,中间还学会了一招,在内核启动崩溃的时候,虚拟机有个很方便的设置,配置一个串行接口,输出到文件,然后
kernel后面加参数 console=ttyS0 就会输出到这个文件,调试内核就方便很多。

所以,编译的时候记得要不就把三个都编译进内核,要不三个都m,要不就自己解压initrd把module加上去。

CONFIG_SCSI_MOD=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y

#当然不要忘记这两个
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y

2、坑二
hwclock在新内核里面无法使用,这个问题是由于新内核已经使用了新的RTC设计

CONFIG_RTC_CLASS=y

当这个参数存在的时候,无法再使用CONFIG_RTC这个参数来支持旧的RTC设置,这两个模块是互斥的,但是在说明文档里面没有详细说明
CONFIG_RTC_CLASS 会生成一个 /dev/rtc0 的设备,大小类分别是 254 0 , 而不是原来的10 135,这个大小类的char设备在CONFIG_RTC_CLASS配置里面不再存在了。

但是mkinitrd命令生成initrd的时候,还是会在init脚本里面加上一句

mknod /dev/rtc c 10 135

所以如果你要想hwclock可用,要不就升级hwclock版本,新版本支持读取rtc0设备
要不就解压initrd,自己修改init脚本,如下操作:

mkdir /root/init
cd /root/init
zcat /boot/initrd-3.0.91.img | cpio -di

#编辑init文件,找到rtc,改为
mknod /dev/rtc c 254 0

#保存退出,当然现在可以在启动时加上你自己喜欢的模块,或者去掉你不想要的模块了
#这里也要检查下和旧版本的区别,以防启动不了

find . | cpio -c -o | gzip -9 -c > /boot/initrd-3.0.91.img 

这样重新引导之后,就可以直接使用hwclock来同步系统和主板的时间了

3、坑三
网卡顺序在不同内核里面,会由于MSI的读取和udev的版本而呈现不同的顺序,我在服务器上面启动内核的时候,eth0和eth1的模块都是bnx2
在旧的内核里面mac0对应eth0, mac1对应eth1,但是在新版本的读取里面,就反过来了,mac1对应eth0, mac0对应eth1
导致原来的配置文件出问题了,网卡没有启动。。。
在网上查了很久,总结了好几个解决办法
第一个,启动加参数pci=nomsi,没有测试过,但是觉得既然系统引入了这个功能,总有它的用处,所以没改
第二个,改udev规则,在udev启动网卡的时候,设定具体的mac地址,/etc/udev/rules.d/60-net.rules,写死在这里,个人觉得也没有这个必要吧
第三个,自己琢磨出来的,在看udev规则的时候,看到这样一句

cat /etc/udev/rules.d/60-net.rules
ACTION=="add", SUBSYSTEM=="net", IMPORT{program}="/lib/udev/rename_device"
SUBSYSTEM=="net", RUN+="/etc/sysconfig/network-scripts/net.hotplug"

怎么有个rename的程序。。。看样子有戏,查资料
rename_device, which searches the ifcfg-* files for a HWADDR that matches the new device and uses the DEVICE setting from that file to give a name to the new interface.

看到这里,恍然大悟,centos为了这种情况,已经出来应对方案了,只要在
/etc/sysconfig/network-scripts/ifcfg-eth*
网卡的配置文件里面,写好了HWADDR 和DEVICE ,就会自动按照这个参数重命名

如下:

BOOTPROTO=static
ONBOOT=yes
DEVICE=eth0
TYPE=Ethernet
IPADDR=123.123.123.123
NETMASK=255.255.255.0
GATEWAY=123.123.123.1
HWADDR=00:12:34:56:78:23

记得两个网卡都设置下HWADDR,就行了,重启之后,udev启动网卡的时候,就会按照这个配置里面的设置,重命名网卡。

4、不知算不算坑
新内核启动之后,一切正常,但是几个kworker的进程,时不时的占用着一些cpu资源(在vmware里面),我记得以前在kvm和vmware的vps里面安装centos 6,也碰到过类似问题。
这个kworker好像是响应bios事件的,网上说了一堆,但暂时没有发现什么好办法。。。

在服务器上面,就有一个kimpi0的进程,也是类似的占用,该死dell服务器带有ipmi模块,刚好新内核把impi_si 也编译到内核中了。。。
但是我们的ipmi没有使用,所以还是把这个禁用掉吧,由于已经编译到内核,没办法不加载。。
在kernel加上参数:

kernel /vmlinuz-3.0.91 ro root=LABEL=/ ipmi_si.force_kipmid=0

先应付着吧,再观察几天看看,自己编译内核真是一个体力+技术活,没有测试好的config不敢放到服务器上面跑,但是服务器环境毕竟和vmware的不一样,来回折腾啊。
以后有水平了再针对服务器做精简内核吧,现在还是参考别人的成熟经验,适合多数服务器的配置。

希望这次编译的稳定,就可以开启ssd的TRIM了!估计也是这些原因,最后centos还是不支持从5直接升级到6。。。