mknod 不能创建空洞文件,它仅用于创建设备节点或FIFO管道;空洞文件需用 truncate(推荐)或 fallocate(注意非空洞)生成,且必须是普通文件类型(S_IFREG)。

mknod 不能用来创建空洞文件(file hole)。
这是个常见误解。需要明确区分两个完全不同的概念:
-
mknod:用于创建设备节点(如/dev/sda,/dev/ttyS0)或FIFO 命名管道(p类型)。它不操作普通文件内容,也不改变文件大小或布局。 -
空洞文件(sparse file):是普通文件的一种特殊形态——逻辑大小很大,但实际只占用部分磁盘块(中间有“洞”),由
lseek()+write()或ftruncate()等系统调用触发,与设备节点无关。
所以,想模拟磁盘空间耗尽的测试场景(比如压测日志服务、备份工具对稀疏文件的处理),你应该用以下真正有效且标准的方法:
✅ 正确创建空洞文件的两种主流方式
-
用
truncate(最简单安全)
直接将文件逻辑大小设为 10GB,但不写入任何数据,不占磁盘空间:truncate -s 10G ./holefile
查看效果:
ls -lh ./holefile # 显示 10G(逻辑大小) du -h ./holefile # 显示 0B 或几字节(实际磁盘占用)
用
fallocate(快速预分配,非空洞,但常被误用作“占空间”)
注意:fallocate -l 10G file是真实分配磁盘块(除非文件系统支持--keep-size或FALLOC_FL_PUNCH_HOLE),它生成的是满填充文件,不是空洞文件。仅在需“假装有空间但实际不写零”时用;若目标是零磁盘开销+大逻辑尺寸,请坚持用truncate。
❌ 为什么 mknod 不行?
-
mknod filename p→ 创建命名管道(FIFO),不是普通文件,不能ls -l查大小,也不能du统计,更无法用于存储测试。 -
mknod filename c 1 3→ 创建字符设备(如/dev/null的接口),它根本不在你的工作目录里“占空间”,而是内核驱动入口。 - 所有
mknod创建的都是特殊文件类型(S_IFCHR / S_IFBLK / S_IFIFO),stat显示device字段而非size字段;而空洞文件必须是普通文件(S_IFREG),且st_size>st_blocks * 512。
? 验证是否真有“洞”
# 创建后检查 truncate -s 2G ./test_hole # 跳过前 1GB,写 4 字节到末尾 dd if=/dev/zero of=./test_hole bs=1 count=4 seek=$((2*1024*1024*1024-4)) 2>/dev/null # 查看:逻辑大小仍是 2G,但磁盘块极少 ls -lsh ./test_hole # 第一列是实际占用(KB),第二列是逻辑大小
提示:
ls -lsh中第一个数字是磁盘实际占用(KB),第二个是st_size(字节),差值越大,洞越多。
不复杂但容易忽略。


















