半日惊魂
Linux 系统 Debug 小记 date: 2005-11-14 15:01:00 +0800 categories: - works tags: - boot - debug - init - works status: publish type: post
published: true
原创文章,转载请保留出处 (bupt.org 或 gnawux.blogchina.com) 和作者 (王旭)
笔记本的 Debian Sid 系统于周末在无网络条件下出现故障,经过半天的排查、分析,
调整若干处,重启十数回,终于定位错误并修正,使系统恢复如初,特此记录
-------------(目录)---------------
1 万恶之源---背景概述
2 危机浮现---案发现场
2.1 现场一: 无线网卡无法启动了
2.2 现场二: CPUFreqd 启动失败
2.3 现场三: 硬件监视传感器失灵、快捷键停转
3 蛛丝马迹---错误排查
3.1 新安装的软家包没有问题
3.2 降级 udev 没有效果
3.3 新内核不是罪魁祸首
3.4 modconf 招来最大嫌疑
3.5 单用户模式找不到问题,濒临放弃
4 拨云见日---定位错误
4.1 udev 仍在风口浪尖
4.2 udev 拒绝认罪
4.3 真相只有一个
5 余音绕梁---疑虑尚存
5.1 为什么会这样
5.2 FHS 之疑
------------------------------------
万恶之源---背景概述
===================
这是一台华硕 M2N 笔记本,Pentium M 处理器,Intel I845GMe 的芯片组/整合显卡,
以及 Intel Pro/Wireless 2100 (ipw2100) 802.11b 无线网卡,典型的迅驰配置,购
买一年以来,它的 40 G 硬盘上只装过一种操作系统---Debian GNU/Linux,而且只安
装过一次,稳定性、性能与功能都很不错,无可非议。
硬盘的分区是很讲究的老鸟的划分方式: /, /usr/, /var/, /home/ 分享硬盘,而恰恰
是这种细致的划分,让系统陷入了危机,如果上天重新给我一次机会,我一定不会分这
么多分区,不过这是后话了。
我的所有硬件,包括快捷按钮、无线网卡、屏幕切换、多媒体控制中心等,全部工作良
好,而根据电池的情况和计算机所执行的人物,我的 Dophin Pentium M CPU 的主频也
可以在 600MHz 到 1500MHz 之间浮动,一年之后的今天,电池也可以使用超过四个小
时,对我来说,这台爱机真是天衣无缝阿。
危机浮现---案发现场
===================
十一月十日,光光节前夜,在 IPW2100 进入官方内核的鼓舞下,我安装了 Debian 打
包的 2.6.14 内核,并且,证实该内核工作良好,系统完全正常,无须安装其他驱动和
补丁,这是我第一次在笔记本上使用这么省事的内核。
第二天 (11.11) 启动,系统仍然正常,无线网卡工作很好,我还用它传送了不少数
据,之后,升级了系统,安装了几个关于蓝牙软件包,准备有机会借个蓝牙适配器来调
教蓝牙玩玩。
晚上,回家之后,系统启动后突然发现出问题了……
现场一: 无线网卡无法启动了
--------------------------
第一个注意到的问题就是无线网卡加载失败了……这是不小的打击,刚才不是还好好的
么? 使用 modconf 加载 ipw2100 模块,仍然不起作用,究竟是怎么回事呢?
系统日志里没有说明这一点,重新启动之后注意到,居然是 firmware 无法加载? 我的
天阿,一年前他们就已经存在了阿? 况且刚刚换内核的时候也没有说过他们有不兼容的
情况阿,重新复制一次文件也毫无反应,究竟是什么原因呢,总不会是硬盘平白无故的
出问题了吧……
现场二: CPUFreqd 启动失败
-------------------------
第二个被注意到的问题是十分容易被发现的 cpufreqd 的问题,它作为处理器频率调整
工具十分重要,而且,它的启动脚本中,十分厚道的用红字显式出来---启动失败。
本来一次失败不容易被注意的,因为与 ipw2100 不同,cpufreqd 在我手动加载相应模
块之后便正常了,只是每次启动都需要手工加载一次,这点十分不正常!于是才引起了
我的极大注意。
现场三: 硬件监视传感器失灵、快捷键停转
--------------------------------------
同时被观察到的还有硬件传感器 lm-sensors 的硬件温度采集失灵和笔记本的快捷键也
都一一停止了工作,这让我觉得十分懊恼,而他们和 cpufreqd 一样,稍后加载模块就
可以工作了,只是每次加载都无法保存,似乎 /etc/modules 根本就没人理。
蛛丝马迹---错误排查
===================
周五 (11.11) 当天晚上比较累了,于是就没有解决,问题一直拖到周日(11.13) 下午
才正式开始解决,这也就是所谓的“惊魂半日”,在劫后余生的今天,我回忆着把主要
的调试过程记录下来,重复一次显然不需要半天,不过当时的复杂考虑、犹豫、斗争等
夹杂着的情况下,用这么长时间还是挺正常的。
新安装的软家包没有问题
----------------------
从出问题的先后顺序看,系统在出问题前后最大的变化莫过于更新了几个软件包、安装
了一些蓝牙相关的软件包,而其中恰好有一个是有关 firmware 的,它们就首当其冲的
成为了我的第一批刀下之鬼。
闲话少说,根据 /var/log/aptitude,直接删掉新安装软件包,使用 purge,让它随风
去,不留一点痕迹 (当是显然是没有现在这么轻松的心情了)。
重启系统……居然不管用! 无奈下只好考虑降级刚刚升级的软件包,可是它们看起来实
在是太无辜了,根本就不关系统和硬件什么事,于是,只好转移目光。
降级 udev 没有效果
------------------
近来硬件相关的系统级软件包当中,udev 无疑是最具偶像气质的一个,因为彻底删除
了 hotplug,其出镜率一直居高不下,bug 多多也是此君最近表现枪眼的原因,自然
的,我对他投上怀疑的目光也是不无道理的。
迄今为止,我对系统调整仍然是软件包级别的,如果我就此深入调查一下的话,可能可
以节省至少两个小时的时间,不过,处理问题总要循序渐进的,以我的水平和对问题的
认识,不可能先验地直接去 Debug。
于是,我抱着侥幸心理,利用 /var/cache/apt/archives 目录下的藏品,把 udev 强
行降级,结果,根据上面的现象其实就已经注定这种尝试是不会有结果的,udev 包其
实根本就没有变动过的。
新内核不是罪魁祸首
------------------
那么……会不会是新内核惹的祸呢? 这是我不愿意做的假设,我对这个官方内核包还是
很有信心的,可是事到如今,我也只好拿起怀疑一切的态度来了。
使用旧内核启动,问题不减当年,更换内核参数,仍然是问题如故……真是有些万念俱
灰的感觉阿,难道让我放弃么?!
modconf 招来最大嫌疑
--------------------
想想这两天还动过些什么--- modconf! 用它加载的模块在后来证明根本无效,包存在
/etc/modules 中的模块从来没有在启动过程中顺利启动的,这个东西已经把很多重复
的内容写到 /etc/modules 里面了,难道是它干的?
几乎一定是它了,去掉老的 /etc/modules,重新手动创建一个,只写我最需要的几个
模块,不再用 modconf 了,而是用 modprobe 一个一个来。
然后用 module-init-tools 的启动搅拌试一次,可以加载这几个模块,好了,重新启
动。
打击再一次降临,上面的修改,架空 modconf 根本没有取得效果,我仍然停留在原地,
甚至可能让情况更糟了。
单用户模式找不到问题,濒临放弃
------------------------------
使用单用户模式进入系统,问题丝毫没有变化,我开始把做过的大多数调整恢复,盼望
着新一次的系统更新可以还给我一个干净的系统。
不过,modules 刚才的问题还困扰着我,我仍然在观察着 /etc/rcS.d/ 的内容,
modules-init-tools 为什么会在那个时候不工作呢? 这个问题我似乎曾经在别的什么
地方遇到过啊……
拨云见日---定位错误
===================
这种时候放弃是一个选择,但我还有方法没有尝试,更多的蛛丝马迹仍然在不断地暴
露出来,我隐隐的感到---udev 还是有问题的。
udev 仍在风口浪尖
-----------------
似乎有某个软件包宣称找不到设备,难道 udev 仍然不正常么? 来到 /dev/ 下面一
ls,吓了我一大跳---这么多文件,难道 udev 没有工作么?
大家知道,根据 hal (硬件抽象层) 提供的规则,udev 会在 /dev/ 下面创建一个
disk/ 目录,可是事实是,现在这个目录并不存在,可以得到结论:udev 根本就没工
作!
那么,启动过程中的 udev 到底发生了什么呢? dmesg 和 syslog 都没有给我答案,
我试试手动启动一下 udev,看看会怎么样。
/etc/init.d/udev start 运行的结果是,该程序已经在运行中了---那它在干什么?!
udev 拒绝认罪
-------------
忽然我在又一次启动中注意到,udev 抱怨说它无法加载 tmpfs,所以无法启动。笑
话! /dev/shm 的 249MB 的 tmpfs 在那里乖乖的,你居然说挂不上! 作为愤青的我当
然不能接受,可是怎么才能知道这是为什么呢?
我把 /etc/udev/udev.conf 里面的日志记录级别从 ``err'' 调整到了 ``info'',
冀望于它能够把更多信息写到 syslog 里面。不过,事实又一次证明了敌人的强大和
我的不成熟,把希望寄托到这里是徒劳的,syslog 里面连挂不上 tmpfs 都没写,那
只在系统启动时 post 出来的信息中存在……
局面似乎僵持在这里了
真相只有一个
------------
不过,我还有杀手锏没有亮出来呢!
我注意到,udev 在 /etc/rcS.d/ 之中的位置是第三个,仅仅在 glibc 和
mountvirtualfs 之后,我们不妨手动启动一次系统,这样,谁犯的错误就是``秃子
头上的虱子''---明摆着的了。
grub 中设定内核参数 init=/bin/sh,这是绕过复杂登录过程的看家本领,如果密码
丢失或是什么其它特殊情况,这个手段是绕过 /sbin/init 的最好手段。不要说密码
了,任何守护进程都没有开过。
这时,系统启动后得到了 root 权限的 shell 提示符,我已经准备好解决问题了,
进入 /etc/rcS.d,一个一个的用 start 参数运行这些脚本,不多,只要三个就可以
发现问题的。
事实是,当运行到第二个的时候,也就是 mountvirtualfs,加载虚拟文件系统时,
问题已经产生,因为缺少 libpcre3.so,无法挂载!!!
这个错误其实刚才我已经注意到了,但它是 Perl 5 兼容政则表达式库,会那么关键
么? 我居然忽略了它! 是事实,正是它的缺席导致了 grep -E 运行出错,既无法挂载
虚拟文件系统,也会让 udev 出错,而它原本是在 /usr/lib/ 之下的,在 /usr/ 挂
载之前是不可能找到的。
解决问题很简单,复制一份到 / 分区里面的 /usr/lib/, 这个目录在 /usr 挂载之后
会被覆盖,但在挂载之前,它独自支撑起了这个系统。
重新起动……振奋人心的一刻终于来到了!问题解决,一切正常了!
余音绕梁---疑虑尚存
===================
为什么会这样
------------
时至今日,我仍然不知道为什么会这样,是脚本的 grep 参数变化了,还是 grep 变
化了,还是 libpcre3 变化了才引发的半日惊魂? 这个问题从何而来的让我百思不得
其解,因为从软件包变化上,这个问题实在难以引人注意。
FHS 之疑
--------
可是根据 Linux 文件系统层次标准 (debian-policy 包中),/usr 不需要在系统启动
中始终存在,甚至应该可以位于 NFS 分区上的,为什么会这样呢? 究竟是哪里的问题
呢。
现在,经历劫后余生,我也希望大家要主义,如果没有特殊情况,/usr 和 / 还是放到
同一个分区之中吧,免生事端。
补充
====
目前(11.14 星期一,问题发生后的第一次更新系统),Debian 已经升级了 grep 软件包,
去掉了对 libpcre 的依赖,从而解决了这一问题。