ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

modprobe ipmi_si报错No such device?一文读懂IPMI驱动加载失败排查全流程

modprobe ipmi_si报错No such device?一文读懂IPMI驱动加载失败排查全流程 在服务器上执行modprobe ipmi_si大多数时候你期望的是顺利加载然后出现/dev/ipmi0之后可以放心地用ipmitool去查电源、温度、风扇但现实往往是刚敲完回车就弹出一句modprobe: ERROR: could not insert ipmi_si: No such device。这个报错我前前后后踩过不少次排查路径从 BIOS 设置一路查到内核参数最后才发现问题可能出在一个很不起眼的地方。这篇就把我对modprobe ipmi_si报错问题的理解、排查思路和实操过程完整写出来适合所有要给物理服务器做带外管理配置的运维和测试人员参考。1. 先搞清楚ipmi_si到底是干什么的1.1 IPMI与BMC服务器里“带外管家”IPMIIntelligent Platform Management Interface是服务器行业最常见的带外管理协议它独立于操作系统运行靠的是主板上那颗单独的 BMCBaseboard Management Controller芯片。只要有 BMC 存在哪怕系统挂了、断电了只要还有待机电源你依然能通过专用网口或者共享网口远程开机、看硬件信息、刷 BIOS、看串口控制台。在 Linux 系统里要使用 IPMI 能力内核需要一组驱动模块其中ipmi_si是绕不开的核心模块之一。这里的si是 System Interface 的缩写负责跟 BMC 的实际硬件通道打交道比如通过 KCS、BT、SMIC 这些系统接口发送和接收 IPMI 消息。简单理解ipmi_msghandler是消息调度中心ipmi_si是打通硬件通路的那根管子ipmi_devintf则是给用户态程序提供/dev/ipmi0的入口。modprobe ipmi_si之所以会报错本质上就是这根管子没插进去可能原因是硬件根本没有、通道类型对不上、资源被占用或者固件层面没有把接口暴露给内核。搞清楚这一步很多问题就好定位了。1.2 ipmi_si模块在整个驱动链中的位置驱动链的顺序一般是ipmi_msghandler优先然后才是ipmi_si最后加载ipmi_devintf或对应的字符设备接口模块。如果顺序不对或者依赖模块没先加载modprobe ipmi_si也会识别不到对应的消息处理层从而报错。不过实际测试下来最常见的报错不是依赖问题而是ipmi_si在初始化时去探测系统接口结果一个都没找到。它会去 ACPI 表里找 SPMI 表IPMI 相关的 ACPI 数据、去常规 I/O 端口比如 0xCA2/0xCA3找 KCS 接口、去 PCI 配置空间里找 IPMI 控制器如果这些地方都没有可用的接口就直接放弃初始化向控制台输出一行Unable to find any System Interface(s)之类的日志。所以你要把modprobe ipmi_si报错看作是一个结果而不是原因驱动加载失败背后一定有一个具体的探测环节失败了。理解了这一点就不会只是盲目地反复重试了。2. 报错之前的现场还原2.1 那些年我见过的几种报错长什么样不同内核版本、不同硬件平台modprobe ipmi_si的失败表现不完全一样。我整理了一下实际工作里遇到过的形式方便大家对号入座。第一种是最典型的modprobe: ERROR: could not insert ipmi_si: No such device对应dmesg里通常能看到ipmi_si: Unable to find any System Interface(s)第二种是模块能加载但/dev/ipmi0不出现lsmod | grep ipmi里能看到ipmi_si可用ipmitool mc info却报连接失败。这种情况不是加载报错而是接口通道没有真正通本质上是同一个问题域。第三种是出现资源冲突类的报错比如ipmi_si: Unable to set up I/O space ipmi_si: The system interface is not set up, aborting或者是ipmi_si: Could not find any KCS interfaces这些都是ipmi_si在尝试访问硬件资源时遇到了障碍。看到这些日志第一反应就应该是不是驱动自身有问题而是它要找的东西不在预期的位置或者被占用了。2.2 为什么modprobe能找到模块却插不进去驱动模块文件在文件系统里是真实存在的modprobe在执行时第一步会去/lib/modules/$(uname -r)下找到对应的.ko.xz文件解析模块依赖然后调用init_module系统调用把模块插入内核。文件能找到只是说明内核模块仓库里确实有这个驱动不代表硬件层面就绪。ipmi_si是一个典型的平台设备驱动它注册了探测函数驱动加载时会去扫描平台设备、ACPI 设备、PCI 设备试图找到属于自己的那个设备节点。找不到节点时驱动初始化函数会返回一个负数返回值比如-ENODEV内核把这个结果翻译成用户态的错误就是No such device。所以这个报错有一层很直观的含义模块本身没问题但内核认为当前这台机器上没有对应的设备或者设备无法被识别。这跟modprobe无关跟硬件和固件有关。2.3 硬件探测失败最常见的三个原因第一个原因是 BIOS 里把 IPMI 功能关掉了。很多主板默认是开启 BMC 的但也有部分型号、部分固件版本默认关闭尤其是一些准系统、白牌服务器或者桌面级主板。你连 BMC 都没开启内核自然探测不到任何系统接口。第二个原因是接口类型不匹配。ipmi_si只负责 KCS、BT、SMIC 这三种传统系统接口但部分平台走的是 SMBus 接口这种场景需要加载的是ipmi_ssif模块而不是ipmi_si。加载错了模块一样报找不到设备。第三个原因是 ACPI 表里的信息不完整或者被屏蔽。ipmi_si在初始化时很依赖 ACPI 提供的 IPMI 设备信息如果固件里 SPMI 表缺失、损坏或者 BIOS 设置里把 IPMI 的 ACPI 接口隐藏了驱动就无法完成资源映射最终只能放弃。这三个原因优先级很高排查时应该先从硬件和固件入手而不是一上来就折腾内核配置。3. 一步一步把它救活完整排障流程3.1 先确认硬件层DMICode与BIOS排查ipmi_si报错我建议第一步不是在内核层面折腾而是先确认这台机器到底有没有 BMC以及 BMC 是否被固件暴露出来。最简单的确认方式是使用dmidecode查看 IPMI 设备信息。DMI 类型 38 就是 IPMI 设备信息记录它包含了接口类型、基地址、中断号等关键数据dmidecode -t 38正常有 IPMI 设备的机器输出大致如下Handle 0x0037, DMI type 38, 18 bytes IPMI Device Information Interface Type: KCS (Keyboard Control Style) Base Address: 0x0000000000000CA2 (I/O) Register Spacing: 32-bit boundaries Interrupt Polarity: Active High Interrupt Trigger Mode: Level Interrupt Number: 5如果这条命令返回No SMBIOS nor DMI entry point found说明要么 dmidecode 工具没装好要么这台机器根本没有标准 SMBIOS 信息。如果是完整服务器但这里查不到 IPMI 设备很大概率是 BIOS 里被关掉了。接着要进 BIOS 确认。不同品牌服务器的菜单路径不同但关键词一般都有IPMI、BMC、Server Management或Advanced IPMI Configuration。把状态设置成 Enabled保存重启后再执行modprobe ipmi_si。我遇到过一个很典型的场景一台品牌塔式服务器拿来做测试拿到手进系统后加载 ipmi 模块失败折腾了半天最后发现 BIOS 里 IPMI 功能处于 Disabled 状态打开后一次就过了。所以这个步骤不要跳。3.2 dmesg里找线索硬件确认没问题后再回过头看内核日志。加载失败后立刻看dmesg用 grep 过滤出跟 IPMI 相关的行dmesg | grep -i -E ipmi|BMC|SPMI常见的关键日志有ipmi_si: Trying ACPI-specified kcs interface at 0xca2 ipmi_si: Could not set up I/O space ipmi_si: Unable to find any System Interface(s)如果看到Trying ACPI-specified kcs interface说明 ACPI 已经把信息给了驱动但后续访问 I/O 端口时失败了这时候问题可能出在端口被占用或者寄存器间距配置不对。如果直接看到Unable to find any System Interface(s)说明 ACPI、PCI、默认端口这些探测路径全都没有命中这时候要多花点时间确认平台本身支持的是不是 SI 接口。还有一个操作很有用就是看驱动把系统接口枚举到了哪里。加载模块后查看ls -l /sys/module/ipmi_si/parameters/内核模块参数会以文件形式暴露在 sysfs 下比如ports、type、trydefaults等可以通过这些参数文件确认当前驱动使用的探测配置。3.3 手动指定参数强制加载如果 ACPI 信息不可靠或者驱动默认探测路径没覆盖到实际硬件可以手动指定接口类型和端口地址强制ipmi_si去加载。这不属于歪门邪道在兼容性不佳的板子上很常见。首先卸载掉已加载的模块按依赖顺序从后往前卸载modprobe -r ipmi_devintf modprobe -r ipmi_si modprobe -r ipmi_msghandler然后手动加载消息处理层和 SI 层指定接口类型和端口地址。以 KCS 接口、端口 0xCA2 为例modprobe ipmi_msghandler modprobe ipmi_si typekcs ports0xCA2 modprobe ipmi_devintf如果 ACPI 给出的信息本身有误还可以在模块参数里关掉默认探测只使用你手动指定的端口modprobe ipmi_si typekcs ports0xCA2 trydefaults0加载成功后用下面几个命令验证ls /dev/ipmi* ipmitool mc infoipmitool mc info能输出 BMC 固件版本、设备 ID 等信息说明驱动到 BMC 的整条链路已经通了。有些板卡可能使用内存映射地址而不是 I/O 端口这时候要改用addrs参数同时可能需要配合regspacing、regsize这些参数。具体地址从哪里来dmidecode -t 38里Base Address就是重要参考。比如显示0x0000000000000CA2 (I/O)这就是 I/O 映射的 KCS 基地址。如果是内存映射形式会类似0xFEDC0000那就要用addrs0xFEDC0000。3.4 配置开机自启模块手动加载成功之后还要考虑系统重启后能不能自动加载。如果服务器每次重启后都要手动执行一遍那显然不可接受尤其是远程维护场景。配置开机自动加载推荐使用modules-load.d和modprobe.d两个目录配合。首先创建模块加载列表把三个模块按依赖顺序写进去cat /etc/modules-load.d/ipmi.conf EOF ipmi_msghandler ipmi_si ipmi_devintf EOF然后创建模块参数配置文件把刚才手动验证成功的参数固化下来。比如cat /etc/modprobe.d/ipmi_si.conf EOF options ipmi_si typekcs ports0xCA2 trydefaults0 EOF写完后可以手动触发一次模块加载服务验证配置是否正确systemctl restart systemd-modules-load.service接着确认加载状态lsmod | grep ipmi ls -l /dev/ipmi*我把这个方案用在过一台加载总是失败的机器上只要参数写对重启后驱动能自动起来/dev/ipmi0也稳定出现。这一步的关键是参数一定要跟硬件实际匹配不能随便抄网上配置。4. 特殊场景与深坑4.1 虚拟机里加载IPMI模块有一种场景会让很多人白费力气在虚拟机里执行modprobe ipmi_si。虚拟机一般不会向客户机暴露真实的 BMC 硬件设备除非你专门做了 PCI 透传或者使用了特殊的虚拟化管理接口否则ipmi_si报No such device是很正常的。如果你只是想在内核层面让模块加载通过另一个思路是加载虚拟化平台提供的 IPMI 设备模块比如 QEMU/KVM 环境下偶尔会用到ipmi_si配合模拟设备但前提是虚拟化层启用了相关模拟。绝大多数云主机、虚拟机环境下ipmitool走进的是宿主机的带外管理而不是客户机的/dev/ipmi0这一点要区分开。所以遇到modprobe ipmi_si报错先问一句这台机器是物理机吗如果是虚拟机那大概率不用继续深挖。4.2 刷固件后模块突然失灵还有一种让人措手不及的情况原来能正常使用ipmitool的服务器刷完 BMC 固件或者 BIOS 之后重启modprobe ipmi_si开始报错了。这种问题通常不是新固件把 IPMI 功能砍掉了而是固件升级后 ACPI 表里的接口描述发生了变化比如接口类型从 KCS 变成了 BT或者 I/O 资源从一个端口换到了另一个端口。内核里缓存模块参数如果还写着旧值或者 ACPI 信息跟默认探测路径不一致就会出现驱动找不到接口的情况。处理办法很直接先看dmidecode -t 38现在给出的接口类型和基地址是什么再对比驱动实际探测的结果然后手动指定新的参数去加载。大多数情况下按新固件给的信息配置一遍就恢复了。像这种升级固件后出现的回归问题我一般会习惯性地把升级前后的dmidecode -t 38输出留存一份遇到问题时对比着看排查速度会快很多。4.3 ipmi_devintf / ipmitool联动问题ipmi_si加载成功不代表ipmitool就一定能用中间还有/dev/ipmi0设备节点和用户态权限的问题。常见的情况是ipmi_si加载了但ipmi_devintf没加载于是/dev/ipmi0不存在ipmitool mc info也会报错。验证时可以把三个模块都加载完再跑命令modprobe ipmi_msghandler modprobe ipmi_si modprobe ipmi_devintf ls -l /dev/ipmi*如果/dev/ipmi0存在但非 root 用户执行ipmitool权限不够那就是设备节点访问权限的问题可以临时用 root 验证或者通过 udev 规则给指定用户授权。这种联动问题不算ipmi_si报错但在实操中经常被混在一起看待。4.4 带外网口 down 却有 IPMI 管理需求还有一种非典型场景服务器本身有 BMC 和专用管理口但是ipmi_si加载失败。排查到最后发现网卡和设备都正常只是 BMC 的固件因为异常状态进入了某种保护模式导致系统接口长时间无响应驱动探测超时后放弃了。这种故障用命令几乎无法在线恢复让我处理只能做一次 BMC 的重置一般通过前面板的维护按钮按住若干秒实现或者断开电源三五分钟再重新上电。很多 IPMI 系统接口的诡异问题最后都靠“断电重启 BMC”解决这个手段在正规排障流程里也占一席之地。5. 快速定位对照表与老运维经验5.1 常见报错速查表下面这张表是我根据多次排障经验整理出来的里面包含现象、直接原因和优先处理思路可以作为现场快速定位的参考。现象/日志可能原因优先处理思路modprobe: ERROR: could not insert ipmi_si: No such device硬件/固件未暴露接口或接口类型不匹配查dmidecode -t 38进 BIOS 确认 IPMI 开启日志出现Unable to find any System Interface(s)ACPI/PCI/默认端口探测全部未命中确认是否虚拟机查 ACPI SPMI 表手动指定端口日志出现Could not set up I/O spaceI/O 端口资源冲突或地址错误用lspci -v、/proc/ioports检查端口占用lsmod有ipmi_si但无/dev/ipmi0ipmi_devintf未加载或设备节点未创建加载ipmi_devintf重建设备节点ipmitool mc info连接失败用户态工具与驱动版本不兼容或 BMC 无响应检查 BMC 状态必要时重置 BMC模块在虚拟机上加载失败虚拟机未模拟 IPMI 设备不处理改用宿主机 IPMI 或虚拟化透传5.2 几条写在文档外的经验第一不要一上来就modprobe反复重试先把dmesg当时打印的日志留住。很多内核驱动只会在第一次初始化时打印完整信息你反复卸载加载日志反而被冲掉或者让你错过关键行。正确顺序是失败后立刻执行dmesg | tail -n 50把现场留下来。第二要养成看内核配置的习惯。有些精简内核或定制内核把CONFIG_IPMI_SI编成了模块但实际没启用或者把依赖模块CONFIG_IPMI_HANDLER去掉了这时候再折腾硬件参数也没用。判断方法很简单grep -E CONFIG_IPMI /boot/config-$(uname -r) 2/dev/null || zgrep -E CONFIG_IPMI /proc/config.gz如果看到CONFIG_IPMI_SIm之类的结果说明内核本身支持问题还在硬件或参数上。第三遇到ipmi_si加载失败但手头只有一台机器的情况可以先用ipmitool带-I open参数试试看是不是/dev/ipmi0的问题。如果 open 方式不通再用内核参数强制指定端口基本上能区分是用户态问题还是内核驱动问题。第四也是最容易被忽略的一点不要把服务器管理网口和业务网口搞混。有时候你以为带外管理不通是ipmi_si的问题其实 BMC 的独立网口压根没接网线或者网口被配置成了共享模式但交换机没放行。先确认管理入口是通的再判断系统内驱动问题能省很多时间。我个人的习惯是拿到一台新服务器第一件事就是先跑一遍dmidecode -t 38并截图归档同时把 BIOS 里的 IPMI/BMC 选项状态记录下来。这样等到以后模块加载报错手里已经有基线数据对照一下就能知道是硬件配置变了还是内核升级导致的问题。IPMI 这类带外管理功能平时不起眼但真到了系统宕机需要远程救场的时候它甚至比 SSH 还重要所以趁着平时把驱动和配置调通绝对是一笔划算的维护投入。
返回列表