飞牛 fnOS 更新后怎么清理系统盘

太阳作者太阳
原创内容采用 CC-4.0 协议发布,转载请注明出处
fnOSLinux磁盘空间内核

这台飞牛 NAS 的根分区只有约 16 GiB。第一次检查时只剩 1.4 GiB,/usr 就占了约 8.9 GiB。顺着目录往下查,发现系统留了五代内核,其中有些版本的驱动在两个目录各存了一份。相比之下,删几份日志腾出来的空间很快又会用掉。

后续再查,同一台机器剩三代内核。通过 APT 卸载最旧的一代,再把残留驱动移到数据卷,系统盘从 4.4 GiB 可用增到 5.1 GiB。更新到 fnOS 1.2.1010 并重启后,可用空间约 5.5 GiB。下面的命令按实测时的排查顺序排列,内核包名和容量以自己机器的输出为准。

更新后先跑一次只读检查

SSH 登录后整段粘贴。需要比较更新前后的变化时,在更新前也跑一次,保留两份输出。这段命令只读取版本、挂载和文件占用。

sudo sh <<'EOF'
printf '\n系统版本和运行内核\n'
cat /usr/trim/etc/version
uname -r

printf '\n系统盘容量、inode 和目录对应的挂载\n'
df -hT /
df -i /
for path in / /boot /boot/efi /vol1 /vol2; do
  [ -d "$path" ] || continue
  printf '%s ' "$path"
  findmnt -n -o TARGET,SOURCE,FSTYPE -T "$path"
done

printf '\n根分区一级目录\n'
du -xhd1 / | sort -hr

printf '\n系统、应用、缓存和用户目录\n'
for path in /usr /var /home /boot /usr/local/apps \
  /usr/local/apps/@appcenter /usr/local/apps/@appdata \
  /var/cache/updatemgr /var/lib/updatemgr /var/cache/apt \
  /var/lib/apt /var/tmp /tmp; do
  [ -d "$path" ] || continue
  du -xhd1 "$path"
done | sort -hr | uniq | head -50

printf '\n启动镜像和各版本内核目录\n'
ls -lh /boot/vmlinuz-* /boot/initrd.img-*
du -xhd1 /usr/lib/modules /usr/lib/modules_trim /usr/trim/modules /usr/src |
  sort -hr
EOF

先看 df 里的 /,再找 du 里占用最大的子目录。多出一代内核就先核对包和启动项。大头落在更新器或应用目录时,再展开该目录,确认是安装包、程序、日志还是数据库。例如 sudo du -xah /var/cache/updatemgr | sort -hr | head -25 会把更新缓存里最大的文件和子目录排在前面。输出里的父目录已经包含其子目录,占用量不要重复相加。

先确认根分区和数据卷

cat /usr/trim/etc/version
uname -r
df -hT / /boot/efi /vol1 /vol2
df -i /
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINTS
findmnt -T /
docker info --format '{{.DockerRootDir}}'

实测 / 在 /dev/sda2,是 ext4。/boot 与 / 共用这个分区,/boot/efi 单独挂载。/vol1 也在同一块物理盘上,通过另一分区上的 RAID 和 LVM 提供约 40 GiB。Docker 数据目录是 /vol1/docker,因此清 Docker 镜像或构建缓存只会释放 /vol1。这台机器的根分区 inode 使用率在 12%–15% 左右,优先查字节占用即可。

从一级目录找到大头

登录后用 sudo du,否则应用数据、更新缓存和部分日志可能只显示目录本身的 4 KiB。先扫 /,再单独展开 /usr、/var、/home 和 /boot。

du -x(--one-file-system)只在扫描起点所在的文件系统内递归。以 / 为起点时,这台机器扫描的是 /dev/sda2。/vol1 和 /vol2 都挂载了独立的文件系统,所以 du 不会进入这两个目录统计卷里的文件。/vol1 虽然和根分区在同一块物理盘上,也一样会被跳过。

/boot 是 /dev/sda2 上的普通目录,因此内核镜像和 initramfs 都计入系统盘。它下面的 /boot/efi 单独挂载在 EFI 分区上,从 / 扫描时会跳过其中的文件。如果显式运行 du -xhd1 /vol1,扫描起点就换成了 /vol1,这时统计的是这个数据卷自己的占用。

sudo du -xhd1 / | sort -hr
sudo du -xhd1 /usr /var /home /boot | sort -hr | head -45
sudo du -xah /usr /var /home /boot | sort -hr | head -50

如果 df 的已用空间明显大于 du,先对比 root 权限下的字节统计,再看有没有文件删了但进程还开着。lsof 中同一个文件可能因多个文件描述符重复出现,按 DEVICE 和 NODE 去重,再确认设备对应根分区。

df -B1 /
sudo du -sxB1 /
sudo lsof -nP +L1

11 月清理后的 root 扫描结果如下。普通账号少扫到约 699 MiB,补用 root 后,du 和 df 在 -h 的显示精度下基本一致。lsof 查到的已删除文件去重后只有约 1.2 MiB,无需为这点空间重启服务。

9.7G  /
8.3G  /usr
877M  /var
207M  /boot
131M  /home
 92K  /root

检查旧内核、头文件和驱动副本

旧内核会分散在 /boot、/usr/src 和三个模块目录里。即使 /boot 已经没有某个版本的镜像,模块和头文件也可能还在。/lib/modules 与 /usr/lib/modules 在这台机器上指向同一位置,统计一次即可。

uname -r
ls -lh /boot/vmlinuz-* /boot/initrd.img-*
ls -l /vmlinuz /initrd.img /vmlinuz.old /initrd.img.old
sudo du -xhd1 /usr/lib/modules /usr/lib/modules_trim /usr/trim/modules /usr/src |
  sort -hr
dpkg -l 'linux-image*' 'linux-headers*' 'linux-modules-trim*'
apt-mark showhold
apt-cache depends linux-image-amd64 linux-headers-amd64

8 月初查时,/boot 约 573 MiB,/usr/lib/modules 约 1.3 GiB,/usr/lib/modules_trim 和 /usr/trim/modules 各约 724 MiB,/usr/src 还有约 347 MiB。11 月单独统计最旧的 c1107,启动文件、头文件和三处模块合计约 677 MiB。两个飞牛模块目录里的 nvidia.ko 大小相同,stat 显示 inode 不同,磁盘上确实各占一份。

用 APT 模拟卸载,再确认实际移除列表

下面是 11 月实测用的版本组合。机器已经从 c1186 启动,c1126 的镜像和 initramfs 都在,留作回退。目标是 c1107,模拟结果只移除它的镜像、头文件和飞牛模块包。dpkg -l 中的 hi 表示软件包已安装并处于 hold 状态。本机用交互式 purge 确认后就能卸载旧包。模拟及 hold 相关选项见 Debian Bookworm 的 apt-get 手册。

current=6.18.18.c1186-trim
fallback=6.18.18.c1126-trim
old=6.18.18.c1107-trim

test "$(uname -r)" = "$current" &&
  test -s "/boot/vmlinuz-$current" &&
  test -s "/boot/initrd.img-$current" &&
  test -s "/boot/vmlinuz-$fallback" &&
  test -s "/boot/initrd.img-$fallback" &&
  sudo apt-get -s purge "linux-image-$old" "linux-headers-$old" "linux-modules-trim-$old"

只有模拟和实际提示均只涉及目标版本时才继续。若列表出现运行中的内核、回退内核、linux-image-amd64 或飞牛核心包,退出并重新核对依赖。这里保留 APT 的交互确认。

test "$(uname -r)" = "$current" &&
  sudo apt-get purge "linux-image-$old" "linux-headers-$old" "linux-modules-trim-$old"

本机卸载时自动删除了 c1107 的 initramfs,并重新生成 GRUB 配置,输出只找到 c1186 和 c1126。包卸载提示非空目录时,继续量一下里面还有多少,再查包归属。飞牛这里的 /var/lib/dpkg/info 只有 root 可读,普通用户执行 dpkg-query -S 报权限错误时,需要用 sudo 重查。

sudo du -sh "/usr/lib/modules/$old" "/usr/lib/modules_trim/$old" "/usr/trim/modules/$old"
sudo dpkg-query -S "/lib/modules/$old/*" "/usr/lib/modules/$old/*" \
  "/usr/lib/modules_trim/$old/*" "/usr/trim/modules/$old/*"
findmnt -rn -o TARGET,SOURCE | grep -F -- "$old"
sudo grep -E '^[[:space:]]*(linux|initrd)[[:space:]]' /boot/grub/grub.cfg
ls -l /vmlinuz /initrd.img /vmlinuz.old /initrd.img.old
df -h /

这次 /usr/lib/modules/6.18.18.c1107-trim 已经消失,/usr/lib/modules_trim/6.18.18.c1107-trim 只剩 8 KiB 的悬空链接。真正占空间的是 /usr/trim/modules/6.18.18.c1107-trim,还剩约 182 MiB。确认对应内核已卸载、没有单独挂载,并检查现有启动项和模块引用后,把这份副本移到 /vol1 留作备份。下面用的是本机路径,操作前应确认目标目录尚不存在。

mountpoint -q /vol1 &&
  sudo mkdir -p /vol1/fnos-kernel-backup &&
  sudo mv -nT -- /usr/trim/modules/6.18.18.c1107-trim \
    /vol1/fnos-kernel-backup/6.18.18.c1107-trim &&
  sudo du -sh /vol1/fnos-kernel-backup/6.18.18.c1107-trim &&
  df -h /

另一台飞牛机器曾在卸载内核后留下 385 MiB 的常规模块和 185 MiB 的飞牛驱动,还留下了四条指向已移除版本的启动链接。确认残留无包归属后才清目录,并把当前启动链接指向实际存在的镜像和 initramfs,再运行 sudo update-grub 核对生成的启动项。当时可用空间从 5.1 GiB 增至 6.5 GiB,记录只验证到 GRUB 配置,尚未重启。遇到这种情况,先查 ls -l 和 GRUB 输出,再按本机内核版本修正失效链接。

查更新缓存、临时目录和用户目录

sudo du -xhd3 /var/cache/updatemgr /var/lib/updatemgr | sort -hr | head -25
sudo du -xhd2 /var/cache/apt /var/lib/apt /var/tmp /tmp | sort -hr | head -35
sudo du -xhd2 /home /root | sort -hr | head -30
sudo find /var/cache/updatemgr /var/lib/updatemgr /var/tmp /tmp -xdev \
  -type f -size +30M -printf '%TY-%Tm-%Td %p\n'
swapon --show
  • 更新器目录。 /var/cache/updatemgr 和 /var/lib/updatemgr 都是 root 专用目录。1.2.1010 更新后的普通 SSH 账号无法读取里面的内容,实测记录没有确认是否还留有安装包。若 root 扫描发现大文件,先查更新时间和更新任务状态,避免清掉仍在使用的补丁或状态文件。
  • APT 缓存。 /var/cache/apt/archives 放下载的包,/var/lib/apt/lists 放软件源索引。这台机器的 apt-get -s clean 还列出了 pkgcache.bin 和 srcpkgcache.bin。11 月首次清理时下载包和二进制缓存共约 85 MiB,卸载内核后缓存文件又生成了约 83 MiB。约 175 MiB 的软件源索引仍在,可以留着供后续安装查询。apt-get -s autoremove 另列出约 112 MiB 的依赖,主要是 LLVM 和图形相关库,本次没有卸载。
  • 临时文件。 8 月曾在 /var/tmp 找到一个长期遗留的 mkinitramfs_* 目录,约 162 MiB,后续复查时已消失。遇到同类目录,先看日期并确认系统更新、内核安装和 initramfs 生成均已结束。11 月更新后 /var/tmp 只有 28 KiB,/tmp 的占用当时不到 10 MiB。
  • 远程开发工具。 8 月的 ~/.vscode-server 曾占约 724 MiB,后续复查时已不存在。11 月更新后又有约 68 MiB,其中一个旧版 CLI 文件占 34 MiB,另一个版本当时有进程在运行。用 du -ah ~/.vscode-server | sort -hr | head -20 找出具体版本,关闭对应远程会话后再处理旧版。Bun 和 GitKraken CLI 当时分别占约 76 MiB、46 MiB,属于已安装的工具。
  • Swap。 8 月曾有约 2 GiB 的磁盘 swap 文件和 zram。是否保留磁盘 swap 取决于内存和系统配置,这次没有为腾空间改动 swap。

查飞牛应用本体、数据和日志

sudo du -xhd2 /usr/local/apps /usr/data | sort -hr | head -40
sudo du -xhd2 /var | sort -hr | head -35
sudo du -xhd2 /usr/local/apps/@appdata | sort -hr | head -35
sudo find /var/log /usr/local/apps/@appdata -xdev -type f -size +5M \
  -printf '%s\t%TY-%Tm-%Td\t%p\n' | sort -nr | numfmt --field=1 --to=iec

11 月更新前,/usr/local/apps/@appcenter 的应用程序占约 647 MiB,@appdata 里的应用数据占约 356 MiB。检查时要同时看这两处。几个较大的实测项如下。

  • 安全防护。 程序约 293 MiB,数据约 168 MiB。数据主要是 ClamAV 的 main.cvd 和 daily.cld,应用在用时要保留病毒库。更新到 1.2.1010 后,原来的 @appcenter/trim.security 和 @appdata/trim.security 已不在原位,系统的 security_service 仍在运行。目录变化和更新前后的 df 差值是两份独立证据,无法据此精确拆分此次更新释放的空间。
  • 相册。 程序约 165 MiB,数据约 93 MiB。数据里 photo.db 和 photo.db-wal 各约 28 MiB,搜索索引约 28 MiB。保留 SQLite 数据库及其 WAL。确实不用相册时,从应用中心卸载,并看界面是否提供删除应用数据的选项。
  • 影视。 程序约 86 MiB,数据约 90 MiB,其中约 83 MiB 是 @appdata/trim.media/logs/trim-media.log。这类应用日志可能放在应用数据下,只扫 /var/log 会漏掉。
  • 系统及应用日志。 /var/log 共约 374 MiB,应用中心目录约 79 MiB,Samba 约 24 MiB,trim-connect 约 22 MiB。最大的两个应用日志是影视的 83 MiB 和应用中心 error.log 的 72 MiB。已经轮转的 syslog.1 和 btmp.1 合计约 91 MiB。旧日志可以按需归档,持续增长的日志应先看轮转配置和报错原因。这次没有为这一两百 MiB 清空活动日志。
  • 数据库。 /var/lib/postgresql 约 127 MiB,属于 PostgreSQL 数据目录。/var/lib/dpkg 约 52 MiB,属于包管理数据库。这两处保留。

清理和更新前后的实测结果

同一台 16 GiB 根分区的机器,两次排查相隔数月,期间还有其他系统变化。下面按每次检查分别记录 df -h / 的读数。

  • 8 月。 最初剩 1.4 GiB(92%)。检查到用户缓存、日志和遗留临时目录清理后剩 2.3 GiB(85%)。确认前三代旧内核卸载后剩 3.9 GiB(75%)。当时计划再删除 c938,原始记录没有确认该操作完成。
  • 11 月清理。 开始时剩 4.4 GiB(71%)。执行 apt-get clean 和 c1107 包卸载后剩 4.9 GiB(67%)。将 182 MiB 的旧驱动副本移到 /vol1 后剩 5.1 GiB(66%)。这轮实际腾出了约 675 MiB,仍保留一代回退内核。
  • 11 月更新到 1.2.1010。 重启后运行的仍是 c1186,/boot 仍只有 c1186 和 c1126 两代。根分区剩约 5.5 GiB,复查时使用率为 63%–64%。已能读取的目录里没有发现值得再清的大块更新残留。更新器的 root 专用目录需要单独用前面的命令核实。

这台机器的系统盘已经全部分区。以后若反复在更新前遇到容量不足,需要腾出数 GiB 时,扩大根分区或换更大的系统盘才有足够余量。由于 /vol1 和 / 在同一物理盘,调整前要先考虑 /vol1 上的数据和 RAID/LVM 布局。