事情经过
突然有一天发现路由器(R8000,openWRT19.07.3)samba服务挂了,无法连接,在startup中重启后无效,system log中显示:
daemon.info procd: Instance samba::instance1 s in a crash loop 7 crashes, 0 seconds since last crash
然后登录ssh,想查看命令启动会有什么报错。结果,刚登录就发现有一个异常提示:
Your JFFS2-partition seems full and overlayfs is mounted read-only.
Please try to remove files from /overlay/upper/… and reboot!
赶紧查看了以下各分区的磁盘使用情况:
root@OpenWrt:~# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 3.0M 3.0M 0 100% /rom
tmpfs 124.1M 564.0K 123.6M 0% /tmp
/dev/ubi0_1 21.4M 21.3M 0 100% /overlay
overlayfs:/overlay 21.4M 21.3M 0 100% /
tmpfs 512.0K 0 512.0K 0% /dev
/dev/sda1 917.3G 868.5G 2.2G 100% /mnt/sda1
/dev/sda2 916.3G 818.5G 51.2G 94% /mnt/sda2
/dev/sdb1 1.8T 1.6T 96.6G 94% /mnt/sdb1
/dev/sdc1 10.8G 828.5M 9.4G 8% /mnt/sde1
/dev/sdc2 447.5G 372.7G 52.1G 88% /mnt/sde2
很显然,overlay已经爆满了。问题是我最近没有安装插件啊,也没有更新插件啊,怎么会让overlay爆满呢。需要仔细查看以下overlay内的文件大小:
root@OpenWrt:~# du -h /overlay/upper/
700.0K /overlay/upper/etc/ssl/certs
0 /overlay/upper/etc/ssl/private
700.0K /overlay/upper/etc/ssl
16.0K /overlay/upper/etc/ddns
4.0K /overlay/upper/etc/opkg/keys
12.0K /overlay/upper/etc/opkg
0 /overlay/upper/etc/rc.d
56.0K /overlay/upper/etc/init.d
8.0K /overlay/upper/etc/dropbear
8.0K /overlay/upper/etc/hotplug.d/block
4.0K /overlay/upper/etc/hotplug.d/iface
12.0K /overlay/upper/etc/hotplug.d
12.0K /overlay/upper/etc/adblock
0 /overlay/upper/etc/modules-boot.d
352.0K /overlay/upper/etc/samba
44.0K /overlay/upper/etc/modules.d
4.0K /overlay/upper/etc/sysctl.d
0 /overlay/upper/etc/uci-defaults
4.0K /overlay/upper/etc/crontabs
84.0K /overlay/upper/etc/config
20.0K /overlay/upper/etc/vsftpd
1.5M /overlay/upper/etc
8.0K /overlay/upper/lib/upgrade/keep.d
8.0K /overlay/upper/lib/upgrade
1.3M /overlay/upper/lib/modules/4.14.180
1.3M /overlay/upper/lib/modules
1.4M /overlay/upper/lib
0 /overlay/upper/log
0 /overlay/upper/mnt/sdf
0 /overlay/upper/mnt/sda1
0 /overlay/upper/mnt/sda2
0 /overlay/upper/mnt/sdb1
0 /overlay/upper/mnt/sde1/transmission/done
0 /overlay/upper/mnt/sde1/transmission/.config/torrents
736.0K /overlay/upper/mnt/sde1/transmission/.config/resume
0 /overlay/upper/mnt/sde1/transmission/.config/blocklists
744.0K /overlay/upper/mnt/sde1/transmission/.config
744.0K /overlay/upper/mnt/sde1/transmission
56.9M /overlay/upper/mnt/sde1
0 /overlay/upper/mnt/sde2
0 /overlay/upper/mnt/sdf2
56.9M /overlay/upper/mnt
8.5M /overlay/upper/usr/bin
12.0K /overlay/upper/usr/lib/lua/luci/cbi
12.0K /overlay/upper/usr/lib/lua/luci/i18n
152.0K /overlay/upper/usr/lib/lua/luci/view/cbi
40.0K /overlay/upper/usr/lib/lua/luci/view/ddns
8.0K /overlay/upper/usr/lib/lua/luci/view/kcptun
8.0K /overlay/upper/usr/lib/lua/luci/view/shadowsocks
4.0K /overlay/upper/usr/lib/lua/luci/view/admin_status/index
4.0K /overlay/upper/usr/lib/lua/luci/view/admin_status
212.0K /overlay/upper/usr/lib/lua/luci/view
40.0K /overlay/upper/usr/lib/lua/luci/controller
84.0K /overlay/upper/usr/lib/lua/luci/model/cbi/ddns
这里有个异常出现了,/overlay/upper/mnt/sde1居然占用空间56.9M。问题是sde1是我通过USB挂载的的硬盘,外部硬盘不同于只读的SquashFS系统分区,不应该占用overlay的空间啊。再看看/overlay/upper/mnt/sde1里面具体是什么在占用空间:
root@OpenWrt:~# ls -lh /overlay/upper/mnt/sde1/
-rw------- 1 root root 20.6M May 8 20:54 system.log
-rw------- 1 root root 35.5M May 7 11:33 system.log.old
drwxr-xr-x 4 root root 288 Jun 26 2020 transmission
删除system.log.old文件,再清空system.log文件,终于恢复正常了。
root@OpenWrt:~# rm /overlay/upper/mnt/sde1/system.log.old
root@OpenWrt:~# >/overlay/upper/mnt/sde1/system.log
root@OpenWrt:~# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 3.0M 3.0M 0 100% /rom
tmpfs 124.1M 712.0K 123.4M 1% /tmp
/dev/ubi0_1 21.4M 13.7M 6.6M 67% /overlay
overlayfs:/overlay 21.4M 13.7M 6.6M 67% /
tmpfs 512.0K 0 512.0K 0% /dev
/dev/sda1 917.3G 868.5G 2.2G 100% /mnt/sda1
/dev/sda2 916.3G 818.5G 51.2G 94% /mnt/sda2
/dev/sdb1 1.8T 1.6T 96.6G 94% /mnt/sdb1
/dev/sdc1 10.8G 828.6M 9.4G 8% /mnt/sde1
/dev/sdc2 447.5G 372.7G 52.1G 88% /mnt/sde2
原因分析:
1)openWRT为了保证系统可以快速重置,同时还保持系统的体积小的特点,采用的文件系统是SquashFS与JFFS2文件系统的集成形成的overlayfs机制形成重叠。squashfs是一种只读的压缩文件系统,压缩率和gzip差不多。jffs2是一种日志类型的文件系统,专为NorFlash设计。squashfs作为lower在底层,只读不可写入;jffs2作为upper在上层,可以读写。
比如要修改系统分区里的 /etc/config/aa.conf,只需要在JFFS2分区里新建文件夹/overlay /etc/config/,再写入修改后的 /overlay/etc/config/aa.conf,这样就修改了系统文件。如果选择重置路由器,只需要把overlay里面所有的文件都删除掉就好了。这样,不管怎么折腾,路由器系统都不会出大问题,只需要长按重置按钮就可以删除ovelay里的所有数据。
2)可是,当路由器上USB挂载的硬盘由于某种原因断开了之后,因为未能正常的unmount,导致系统认为/mnt/sde1还在。在系统继续往/mnt/sde1写入system.log的时候,发现不可写入,便作为只读空间,数据就写入到overlay中去了。后来虽然USB挂载恢复了,但是由于/overlay/mnt/sde1/system.log依旧存在,便叠加覆盖了/mnt/sde1/system.log里面的数据。