问题描述
很多人可能像我一样,默认允许ubuntu自动升级,一般来说是不会出现问题的。
但linux内核的升级一般来说都是升级到/boot下的,/boot多数的用户设置的都不太大,大概200M左右,而一次升级内核大概也只会占用50M左右,这样,每次升级如果都成功,那么只需要定期清理已经不打算使用的内核即可。
但是,如果事情都这么顺利的话也就不会有这篇博客产生了,我们做一个简单的设想(其实就发生在我身上…),假如你某次升级的过程中发生了错误,没能成功的升级到新内核,这样你的/boot下就会有这样一些东西:
1. 已经不打算使用的旧内核。
2. 正在使用的中间内核。
3. 比当前正在使用的版本更高的内核。
那么之后的升级就可能因为这个错误而无法升级,这里我们简单的据一个例子,假如说你生在升级63的时候出错,那么此时你的系统内就可能会有一下几个内核,61, 62 63, 64,而且还有可能在后续升级中继续出错,导致你使用的是62,而实际该升级66,我这里遇到的就是这种情况。
此时,若66因为磁盘不足再次升级失败。
那么尴尬了,你在执行sudo apt-get autoremove
的时候很可能会遇到报错,说linux-image-extra-x.x.x-66-generic
依赖linux-image-x.x.x-66-generic
,而linux-image-x.x.x-66-generic
不存在,让你使用sudo apt-get -f install
解决依赖关系,而当你执行sudo apt-get -f install时,又发现/boot空间不足。
这时,就会发生这样尴尬的情况,卸载的时候卸不掉,安装新的又安装不上,搞得头都大了,直想重做系统。
综上,就是我写这篇博文时遇到的情形。
解决办法
其实,ubuntu的报错已经把问题说的很明确了,只不过可能是中间依赖关系的限制过于强大,导致可能相关不大的软件也无法卸载,而想要把新内核安装时,磁盘又确确实实的没有空间安装,这就是上面的问题。
那么解决这个问题就有两种思路:
一种是如果让这种依赖关系不阻碍其他软件的卸载,从而达到将不需要的内核卸载,空出部分空间,将新内核安装并升级。然后将之前所有不需要的内核全部清理掉,就完成任务了。这个方案可以自行百度,但并不推荐这个方法,因为这样可能会破坏软件的依赖环境,然后可能又要花费很长时间去解决依赖关系的问题。
另外一种是想办法让/boot空间变大,变得足够升级所需,这里的方式是将/boot下的所有内容备份到一个足够大的位置,我们假设/home/xxxx/backup,建议使用rsync这个命令,具体命令如下: rsync -arv /boot /home/xxxx/backup
–这一步如果出错,后面就不要继续了,因为备份过程如果失败,可能会导致中间的文件不全,依赖关系可能会被破坏。
然后,通过软连接让操作系统认为/home/xxxx/backup就是你的/boot,这样就不会因为升级空间不足而导致升级失败。具体命令如下:
1.umount /boot
–取消当前的/boot的挂载,当然,这需要root权限
2.rm -rf /boot
–取消挂载以后,boot已经没有挂载到/下了,但文件夹仍然存在,这里将其删除。
这两步结束,后面操作没有做完的时候千万不要随便重启,因为软连接在系统正在运行的情况下,操作系统认识,但重新启动操作系统将内核丢入内存的时候,不能保证也认识软连接,比较严重的后果就是可能导致你的电脑无法启动,可能需要用启动盘进行修复。
3.ln -s /home/xxxx/backup /boot
接下来要做的是告诉操作系统,你的boot实际上是/home/xxxx/backup了。
4.这时,理论上来说,你的空间就足够了,继续执行刚才那些因为空间不足而无法操作的命令即可。比如sudo apt-get -f install
,sudo apt-get autoremove
,sudo apt-get autoclean
,auto apt-get update
,sudo apt-get upgrade
等等。
扩展小技巧
这里有一些从网上整理来的命令方便你在删除就内核的时候提供一些有用的信息。
1. sudo dpkg --get-selections | grep linux
– 这里会将你操作系统中安装一些包含linux的软件显示出来,包括一些卸载不完全的。
console-setup-linux install
libselinux1:amd64 install
libselinux1:i386 install
linux-base install
linux-firmware install
linux-generic install
linux-headers-4.4.0-66 install
linux-headers-4.4.0-66-generic install
linux-headers-generic install
linux-image-4.4.0-66-generic install
linux-image-extra-4.4.0-66-generic install
linux-image-generic install
linux-libc-dev:amd64 install
linux-sound-base install
pptp-linux install
syslinux install
syslinux-common install
syslinux-legacy install
util-linux install
可以看到,诸如7, 8, 10, 11这些都是内核相关的内容,注意,我这里显示的已经清理完毕的,所以只有* 4.4.0-66 * 这几个文件,而且这几个是有关联性的,在你决定要卸载的时候要注意将这些一同卸载,避免卸载不完全。有时候使用sudo apt-get remove xxxx
卸载的软件会在这里留下一些残留,显示的是deinstall
状态,可以使用sudo apt-get purge xxxx
来彻底删除这些残留。
2. uname -a
–可以检查你当前正在使用的内核版本,注意不要把正在使用的内核版本给卸载掉了。。。
3. sudo dpkg -P xxxx
可以使你对内核的卸载更干净,或者也可以选择使用sudo apt-get purge xxxx
。至于卸载的是否干净,可以参考第一个小命令。
说明:这里感谢我的同事,问题是我遇到的,没有想到合理的解决办法,是同事给出的解决办法,我觉得以后可能会经常用到,所以在这里进行了整理和记录。