ARTICLE DETAIL

资讯详情

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

Linux内核与模块管理:uname、lsmod、modprobe、sysct

Linux内核与模块管理:uname、lsmod、modprobe、sysct Linux内核与模块管理uname、lsmod、modprobe、sysctl内核是 Linux 的心脏但日常打交道最多的其实是两件事看版本uname、管理模块和参数lsmod、modprobe、sysctl。装网卡驱动、开 IP 转发、调文件句柄上限都落在这几条命令上。这一篇把它们串起来。一、uname看内核与系统信息语法格式uname[选项]常用参数参数说明-a全部信息内核名、主机名、版本、架构-r只看内核版本号-m机器硬件架构x86_64、aarch64-n主机名-v内核编译日期示例与预期输出uname-a预期输出Linux web01 6.8.0-45-generic #45~22.04.1-Ubuntu SMP Wed Sep 4 13:02:00 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux拆一下6.8.0-45-generic主版本 6、次版本 8、修订 0、发行版补丁 45、generic是 Ubuntu 的通用内核变体。这个版本号后面找模块路径时天天用。uname-r预期输出6.8.0-45-generic模块都装在/lib/modules/$(uname -r)/下面。升级内核后旧模块路径还在但不会再被加载uname -r一变整套模块树就换了。二、lsmod看已经加载的模块Linux 内核把驱动做成可插拔模块需要时装进来不需要时卸掉。lsmod列出当前已经在内核里的模块。语法格式lsmod它本质是读/proc/modules没有选项。示例与预期输出lsmod预期输出节选Module Size Used by e1000e 413696 0 ixgbe 307200 0 xt_conntrack 16384 1 nf_conntrack 155648 1 xt_conntrack sd_mod 57344 3 usbcore 311296 4 xhci_hcd,usb_storage三列含义模块名、占用内存大小、被多少其他模块/进程引用。最后一列是引用它的模块。Used by那列不是 0说明还有东西在用这时候想卸载会失败——后面讲modprobe -r时细说。想知道某个驱动对应哪个模块用modinfomodinfo e1000e预期输出节选filename: /lib/modules/6.8.0-45-generic/kernel/drivers/net/ethernet/intel/e1000e/e1000e.ko version: 6.8.0 license: GPL description: Intel(R) PRO/1000 Network Driver author: Intel Corporation alias: pci:v00008086d000015A3sv*sd*bc*sc*i*filename告诉你模块文件在硬盘哪。alias是 PCI 设备 ID 匹配规则内核发现对应硬件时自动按 alias 找到这个模块。三、modprobe加载与卸载模块语法格式modprobe[选项]模块名不带选项就是加载。modprobe比insmod强在自动处理依赖它读/lib/modules/$(uname -r)/modules.dep把这个模块依赖的其他模块一起拉进来。常用参数参数说明无加载模块-r卸载模块同时卸载没人再用的依赖-n干跑不真执行看会发生什么-v显示详细动作示例与预期输出加载一个模块sudomodprobe e1000e没报错就是成了。验证lsmod|grepe1000e预期输出e1000e 413696 0卸载sudomodprobe-re1000e如果这张网卡还在用、有 IP 地址内核会拒绝卸载报Module e1000e is in use。先把网卡 down 掉再卸。对比一下insmod它只往内核塞指定那一个.ko文件不处理依赖。实际工作几乎都用modprobeinsmod留着自己写模块调试时用。开机自动加载模块希望每次开机都加载某模块写进配置echoe1000e|sudotee/etc/modules-load.d/network.conf/etc/modules-load.d/下任意.conf文件里一行一个模块名开机时systemd-modules-load.service会读。Debian 老版本用/etc/modules新发行版统一走modules-load.d。给模块传参数有些模块需要启动参数比如某个声卡要指定缓冲区大小。在/etc/modprobe.d/下写options snd_hda_intel index0文件名随便.conf后缀。modprobe snd_hda_intel时会自动带上index0。四、sysctl运行时改内核参数内核暴露了几千个可调参数绝大多数挂在/proc/sys/下。sysctl是官方接口。语法格式sysctl[选项][参数值]常用参数命令说明sysctl -a列出所有可调参数和当前值sysctl 键名查单个参数sysctl -w 键名值运行时立即改sysctl -p从配置文件重新加载sysctl --system加载所有默认配置目录示例与预期输出查 IP 转发开没开sysctlnet.ipv4.ip_forward预期输出net.ipv4.ip_forward 00是没开。当路由器、跑 Docker、做 k8s 节点都得开成1。临时开重启失效sudosysctl-wnet.ipv4.ip_forward1预期输出net.ipv4.ip_forward 1永久生效写配置。Ubuntu 上建议写到/etc/sysctl.d/99-custom.conf别直接改/etc/sysctl.confnet.ipv4.ip_forward 1 vm.swappiness 10加载sudosysctl-p/etc/sysctl.d/99-custom.confswappiness10的意思是内存还够的时候尽量别用 swap数据库机器常用这个调优。/proc/sys/路径和sysctl键名是一一对应的把点换斜杠、去掉前缀sysctl 键名对应文件net.ipv4.ip_forward/proc/sys/net/ipv4/ip_forwardvm.swappiness/proc/sys/vm/swappinesskernel.hostname/proc/sys/kernel/hostname不想用sysctl直接echo 1 /proc/sys/net/ipv4/ip_forward效果一样重启都失效。几个高频调参项搞网络和数据库的人常打交道键名默认生产常用用途net.ipv4.ip_forward01开启内核转发Docker/路由器必开vm.swappiness6010越小越倾向用物理内存数据库建议调低fs.file-max随内存655350系统级最大文件句柄数net.core.somaxconn409665535TCP 半连接队列上限高并发 web 调大net.ipv4.tcp_tw_reuse01允许 TIME_WAIT 套接字复用短连接多的服务有用注意区分两个句柄限制fs.file-max是全系统上限ulimit -n是单进程上限。调了前者不调后者业务进程照样报too many open files。五、⚠️ 常见错误modprobe: module xxx not found多半是内核版本对不上。装的是另一个内核的头文件/模块包uname -r看当前跑的内核模块得装到那个版本的目录里。卸载模块报in uselsmod最后一列看谁在用把使用者停掉再卸。网卡先ip link set eth0 down存储先卸载文件系统。改 sysctl 重启失效sysctl -w是临时的。永久配置必须写/etc/sysctl.d/*.conf或/etc/sysctl.conf再sysctl -p。升级内核后起不来旧模块第三方编译的内核模块比如某些显卡、虚拟化驱动要针对新内核重新编译dkms包能自动做这件事。改/etc/sysctl.conf不生效某些发行版读/etc/sysctl.d/优先或需要sysctl --system重新加载全部。六、知识扩展modules.dep 与 depmodmodprobe怎么知道一个模块依赖谁答案是/lib/modules/$(uname -r)/modules.dep这个文件。它里面记着每个.ko模块的完整依赖树。手动往/lib/modules/扔了一个新编译的.komodprobe一开始不认识它得跑sudodepmod-adepmod扫描一遍所有.ko重新生成modules.dep。之后modprobe才能找到。系统升级内核、装dkms包时这些步骤都是脚本自动跑的。自己手撸模块的时候忘了depmod -a就会出现文件明明在modprobe 却说找不到的怪事。模块加载失败时dmesg比 modprobe 的报错信息详细得多dmesg|tail-20驱动版本不匹配、符号未找到、设备资源冲突全在内核环形缓冲区里。modprobe 只告诉你失败了dmesg 告诉你为什么。
返回列表