FreeBSD升级失败的处理

手里有几台机器跑着FreeBSD,有实体机也有VPS,因为都是前几年安装的,所以基本上都是跑着10.0或10.1,这两个版本现在都已经停止支持了,只是一直懒得去动,所以凑和用着。

结果没想到最近一次升级pkgng以后,pkg不能用了,搜了一下所有的解决方案都是说要升级系统,看来必须要升级了。但是一直出抽不出空来,只能用pkg-static扛着,不太方便。

好不容易等到春节放假有点时间,决定一次搞定。

先在家里的实体机试了一把——万一搞崩实体机也好弄。结果果然不顺利,第一步执行:

freebsd-update -r 10.3-RELEASE upgrade

就出错,说是找不到update.freebsd.org,但是nslookup、ping、curl试过这个域名都是通的,最后只能用IP地址连才总算成功:

freebsd-update -s 204.9.55.80 -r 10.3-RELEASE upgrade

之后就是freebsd-update install,重启,再freebsd-update install即可。

第二台是VPS,结果这个前两步倒是顺利,到了重启后再次运行freebsd-update install时,出现大量的错误:

segmentation fault (core dumped)

中断升级发现所有的命令都不可用——虽然SSH还正常连接着,但是新的连接已经不行。放狗一搜,说是因为旧的系统文件已经在升级过程中被删除,但是新版的文件没找到……

然后才想起来我用了ZFS,估计新文件在ZFS里,但是因为旧文件被删除,ZFS无法mount,所以无法找到新文件……

然而我在升级前并没有做备份……

再次重启系统——已经无法启动了。差点要重装系统的时候被我搜到这篇里的一个回复介绍了手工修复的方法:

In my case I restored system libraries with a FreeBSD 10.1-RELEASE memory stick using a similar procedure.

Boot from USB stick and exit to Live CD.

Mount the damaged FreeBSD installation on /mnt (/, /usr, /var)

Back up manually modified files from /mnt/etc to the USB stick.

Code:

	# cd /usr/freebsd-dist; for file in base.txz lib32.txz kernel.txz src.txz ; do (cat $file | tar --unlink -xvpJf - -C /mnt); done

Reboot in current restored system.

Mount the USB stick and restore the backup to /etc.

这简直是大救星啊。当然也幸好用的是Vultr的VPS,可以外挂ISO启动,不然也是没得救。

当即下载了10.3的ISO文件并上传,然后用这个盘重启了系统,mount上root盘和ZFS盘,把/etc备份到ZFS里,最后从系统盘里恢复系统文件。

中间还出了个问题是mount root盘失败,最后是用fsck修复的。

fsck -y /dev/vtbd0p2

重启,果然成功进入系统,然后赶紧恢复/etc……

杯具的是恢复完etc又挂掉了,貌似因为rc之类目录下的东西也被删除了很多,/etc/group也变成空文件……

得,重来一遍再说。

因为/etc不能完全恢复备份,就只能手工恢复了。首先是rc.conf, pf.conf等,然后是用户系统的恢复(从这个贴子里找到方法):

If you still have the full /etc/master.passwd, you can recreate /etc/passwd using pwd_mkdb(8) (-p). If not, see if /var/backups/master.passwd fits your needs and use that. And before the entire forum says what it always says, and with good reason: make backups.

从备份里恢复master.passwd后执行:

pwd_mkdb -p /etc/master.passwd

至于/etc/group,只能手工恢复了,还好东西不多。

升级第三个的时候就有经验了,反正先做个备份总是没错的。

结果备份完重启准备升级的时候叕有新的状况:

网络无法连通……

DigitalOcean这是闹哪套?

后来是在这里看到一个可能的原因,一查果然是这个/etc/rc.digitalocean.d/droplet.confsymbol link丢了。

但是手工补上重启还是不通,最后只能自己在rc.conf里把IP和路由配置写死进去才终于可以。

之后整个升级过程就很成功了。