“No space left on device”不等于磁盘块满——可能因inode耗尽、已删除但进程占用的文件未释放,或/boot等小分区被内核镜像撑爆;须依次执行df -h、df -i、lsof +L1定位真因。

Linux 内核编译完成后报 “No space left on device”,表面是磁盘满,但实际原因可能不止一种。关键要区分:是真实磁盘块(block)耗尽?还是inode 耗尽?抑或已删除但进程仍占用的大文件未释放空间?这三类问题现象一致,排查路径却完全不同。
先确认到底是哪类“满”
别急着删文件,第一步必须精准定位问题类型:
- 运行 df -h 查看各挂载点的 Use% —— 如果根分区(/)或 /lib/modules、/boot 所在分区接近或达到 100%,说明磁盘块可能真满了;
- 紧接着运行 df -i,重点看同一挂载点的 IUse% —— 若该值为 100%,哪怕
df -h显示还有 30% 空间,也无法创建新文件(比如mkdir、install或模块加载失败),这就是 inode 耗尽; - 特别注意:/boot 分区通常很小(200–500MB),内核编译后执行
make install会拷贝新内核镜像(vmlinuz)、initramfs 和 System.map 到此,极易撑爆;/lib/modules 下也会写入对应版本的模块目录,同样占空间。
检查编译产物和残留临时文件
内核编译过程会在多个位置留下大量中间文件,尤其容易被忽略:
-
源码目录本身:编译时生成的
vmlinux、System.map、整个arch/x86/boot/目录、以及所有.o、.ko、.mod.c等中间目标文件,都在源码树里,总大小常达数 GB; -
临时构建目录(O=):如果用了
make O=/path/to/build,则完整构建产物都在该路径下,需手动清理; -
/tmp 和 $TMPDIR:部分配置或脚本会把临时文件写到此处,编译完未自动清理;可用
du -sh /tmp/* 2>/dev/null | sort -hr | head -5快速筛查; -
旧内核残留:
make install不会自动删除旧内核,/boot下堆积多个vmlinuz-5.x、initrd.img-5.x文件很常见。
查已被删除但仍被占用的空间(典型陷阱)
内核编译过程中若被中断、或后台有日志服务(如 rsyslog、journald)正在写入编译日志,而你又用 rm -f 清过日志,就极易触发“文件已删但句柄未关”问题——df 显示满,du 却统计不出大文件。
- 运行 lsof +L1 2>/dev/null 或 lsof | grep deleted,查看是否有大尺寸的
(deleted)条目; - 重点关注
journalctl、rsyslogd、make进程是否持有已删日志或临时文件; - 确认后,可对对应 PID 发送
SIGHUP(如kill -HUP 1234)尝试重载日志,或直接重启服务(systemctl restart rsyslog)释放空间。
针对性清理与预防
确认问题后,按需操作,避免误删:
-
清理内核编译产物:进入源码目录,执行
make clean(清除 obj 文件)或更彻底的make mrproper(清空全部构建痕迹,包括 .config); -
精简 /boot:列出旧内核
ls -lt /boot/vmlinuz*,保留当前运行版(uname -r)和上一稳定版,其余用dpkg --purge linux-image-X.X(Debian/Ubuntu)或dnf remove kernel-X.X(RHEL/Fedora)安全卸载; -
清空 journal 日志:
journalctl --disk-usage查用量,再用journalctl --vacuum-size=500M限制最大体积; -
长期建议:给
/boot单独挂载大些的分区;编译前设置export TMPDIR=/home/tmp(指向空间充裕位置);启用logrotate管理构建日志。


















