Aug 19 2013

继续折腾内核 3.2.50

Category: 技术ssmax @ 21:11:14

今天继续折腾内核了,升级到 3.2.50

查了一下资料 , ubuntu 12.04 和 debian 7 都是使用3.2版本的内核了。

找了debian的kernel deb包,在pool的linux下面,解压获得debian最新的config文件,基本该有的都有了,比ubuntu的靠谱一点,编译了以后资源占用不高。

这个版本应该可以稳定了。不错不错。

CONFIG_DEBUG_INFO 记得设置为n,要不编译出来的文件那就一个大啊,所有模块都支持gdb,大10倍。。。


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。。。


Aug 15 2013

centos 5.x 升级内核到 3.0 以上

Category: 技术ssmax @ 15:17:32

公司的机器终于有申请到ssd硬盘了,昨天插上去服务器,但是发现centos 5.x 虽然可以支持ext4,但是ext4的模块不支持TRIM(discard)功能,用hdpram虽然可以手动TRIM,但不是太保险,查了一下资料,内核太老了,5.x一直是2.6.18.x的内核,centos 6 就可以完美支持TRIM了,但是centos 5.x 不能直接在线升级到 6 ,必须重装系统,不想弄到系统重装这么大件事。

故继续翻资料,发现TRIM支持比较好要到3.0的内核了,好,试试编译内核吧,很久没有玩过了。

1、首先到 https://www.kernel.org/ 找合适的内核,longterm 版本的内核有 2.6.32 (centos 6 就是这个),2.6.34,3.0.90 等等,一不做二不休,直接搞到3.0以上吧,下载内核,解压

2、准备必要的编译工具:

> yum install gcc ncurses ncurses-devel 

2、进入解压目录,要配置内核了,我选择用原来centos 5 的一些内核参数

> cp /boot/config-2.6.18-348.12.1.el5 ./.config
> make oldconfig
> 全部回车,选择默认,或者按照你们自己的需要选择

3、config完毕后,需要手动改写几个参数,vim .config
CONFIG_SAMPLES=n

这个参数可以避免编译阶段 samples/hidraw/hid-example.c编译失败,samples里面有引用当前环境的一些headers

CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y

这两个参数让内核使用旧版的sysfs,由于centos的确太tmd老了,如果不选择这个选项,文件系统等等无法直接装载

4、修改好.config 文件之后,就要编译了

> make 
#等好多分钟
> make modules_install
# 安装 /lib/modules 目录
> make install
# 安装 vmlinux 到 /boot
> 修改 /boot/grub/menu.lst 使default选择新内核启动

完成了之后就reboot吧。。

5、reboot之后,看看各个服务的启动情况,本来很happy,但是突然看到 udev的一个超时报错

udevd-event: wait_for_sysfs waitnig for xxxxxxx ioerr_cnt failed

这个是怎么回事呢。。。
继续翻资料,发现还是udev太老的问题,新版本已经不需要这些事件了。修改udev配置文件
/etc/udev/rules.d/05-udev-early.rules

#ACTION=="add", SUBSYSTEM=="scsi", WAIT_FOR_SYSFS="ioerr_cnt"
# 注释掉上面这行,加上下面这行
ACTION=="add", SUBSYSTEM=="scsi", KERNEL=="[0-9]*:[0-9]*", WAIT_FOR_SYSFS="ioerr_cnt"

重启,错误消失,但是不知道对scsi硬盘控制器会有什么不良影响,以上流程在vmware(scsi控制器),dell 2950 上面的centos 5.9最新版本试验通过。。。
安装的是3.0.90版本,安装完了以后再去查,发现已经更新到3.0.91 了,太tmd勤快了。

最后一点,记得在yum.conf里面去掉kernel*的检查,要不啥时候update一下就不知不觉升级了2.6.18的内核。。。
exclude=kernel*

各位折腾正式服务器环境之前敬请测试。