apt在更新内核的时候不会移除旧版本内核。随着内核的不断更新,新的内核装进来,老的内核不会被删除,于是默认只有不到500MiB的 /boot 慢慢变得不堪重负,塞满了内核和initrd。终于有一天,你在愉快地 apt update && apt full-upgrade 的时候遇到了这样的错误:
1 2 3 4 5 6 7 8 9 10 |
gzip: stdout: No space left on device E: mkinitramfs failure cpio 141 gzip 1 update-initramfs: failed for /boot/initrd.img-4.10.0-37-generic with 1. run-parts: /etc/kernel/postinst.d/initramfs-tools exited with return code 1 dpkg: error processing package linux-image-extra-4.10.0-37-generic (--purge): subprocess installed post-removal script returned error exit status 1 Removing linux-image-extra-4.10.0-40-generic (4.10.0-40.44~16.04.1) ... run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 4.10.0-40-generic /boot/vmlinuz-4.10.0-40-generic run-parts: executing /etc/kernel/postinst.d/initramfs-tools 4.10.0-40-generic /boot/vmlinuz-4.10.0-40-generic update-initramfs: Generating /boot/initrd.img-4.10.0-40-generic |
那么让我们试试修复这台服务器。
注意,因为每台服务器配置不尽相同,以下命令可能造成该服务器无法使用或数据损毁!请在知道你在做什么的前提下操作,事先做好备份工作,并且中途不要重启。作者对造成的任何损失概不负责。
首先我们来试试用正常的办法卸载不需要用到的内核包。
1 2 3 4 5 6 7 8 9 |
# 移除所有 initramfs 以便给接下来的操作留出空间 sudo update-initramfs -d -k all # 删除所有不必要的包 sudo apt-get -f autoremove # 修复安装中断的包 sudo dpkg --configure -a sudo apt-get -f install # 删掉所有仍然存在但是不必要的内核(以及其它包) sudo apt-get autoremove |
一般来说,这样就能解决问题了。但是有些时候由于一些包处于中间状态(half-installed)导致initrd之类的没有办法完全删除,就必须用下面的方法彻底删除掉所有相关文件然后重新安装最新版本内核了。
1 2 3 4 5 6 7 8 9 10 11 |
# 删除所有内核包 dpkg --get-selections | grep -E "linux-image(-extra)?-[0-9]" | cut -f1 | xargs -n1 sudo dpkg --purge --force-all # 删除所有残留的内核相关文件 sudo update-initramfs -d -k all dpkg -S /boot/initrd.img* /boot/vmlinuz* /boot/System.map* /boot/retpoline* 2>&1 >/dev/null | grep "no path" | awk 'NF>1{print $NF}' | xargs sudo rm # 装一个最新版内核(这边假设 generic 的内核包没有被卸载掉;否则请自行去装一个 generic 的内核包) sudo dpkg --configure -a sudo apt-get -f install dpkg --get-selections | grep "linux-image-[0-9]\+" | cut -f1 | xargs -n1 sudo apt-get install --reinstall # 确认新内核装完后立即重启,因为刚刚在用的内核应该已经被删掉了 sudo reboot |
下次升级的时候,不要再忘记卸载老版本内核哦!