Openwrt完整备份以及exroot挂载/overlay的思考
openwrt
OpenWrt项目是一个针对嵌入式设备的Linux操作系统。OpenWrt不是一个单一且不可更改的固件,而是提供了具有软件包管理功能的完全可写的文件系统。这使您可以从供应商提供的应用范围和配置中解脱出来,并且让您通过使用适配任何应用的软件包来定制设备。对于开发人员来说,OpenWrt是一个无需围绕它构建完整固件就能开发应用程序的框架; 对于普通用户来说,这意味着拥有了完全定制的能力,能以意想不到的方式使用该设备。
项目地址
为什么要完整备份openwrt?
为了无缝升级!为了能在升级的同时不丢失配置文件及软件包
总所周知,openwrt的文件系统的精华思想是overlay
/overlay
是什么意思呢?
OpenWRT 一般使用的文件系统是 SquashFS ,这个文件系统的特点就是:只读。
那,一个只读的文件系统,是怎么做到保存设置和安装软件的呢?
这里就是使用一个 /overlay 的分区,overlay顾名思义就是覆盖在上面一层的意思。
虽然原来的文件不能修改,但我们把修改的部分放在 overlay 分区上,然后映射到原来的位置,读取的时候就可以读到我们修改过的文件了。
但为什么要用这么复杂的方法呢? OpenWRT 当然也可以使用 EXT4 文件系统,但使用 SquashFS + overlay 的方式有一定的优点。
首先 SquashFS 是经过压缩的,在路由器这种小型 ROM 的设备可以放下更多的东西。
然后 OpenWRT 的恢复出厂设置也要依赖于这个方式。在你捅 Reset 重置的时候,它只需要把 overlay 分区清空就可以了,一切都回到了刚刷进去的样子。
如果是 EXT4 文件系统,就只能够备份每个修改的文件,在恢复出厂设置的时候复制回来,十分复杂。
当然,SquashFS + overlay 也有它的缺点,修改文件的时候会占用更多的空间。
首先你不能够删除文件,因为删除文件实际上是在 overlay 分区中写入一个删除的标识,反而占用更多的空间。
另外在修改文件的时候相当于增加了一份文件的副本,占用了双份的空间。
总结来说,overlay文件系统的优点在于只记录修改量,类似于增量更新,非常适合路由器这类小ROM和RAM的嵌入式设备
网上的备份方法遇到的问题
目前网上主要有两种完整备份openwrt的方法,
MTD(Memory Technology Device)备份
查看 firmware 所对应的 mtd 编号
1 | root@EBIN:~# cat /proc/mtd |
使用Linux的 dd命令备份完整固件
1 | dd if=/dev/mtd5 of=/tmp/firmware_backup.bin |
连上SSH,比如刷一个新固件,将 firmware_backup.bin 上传到 /tmp 下,利用 mtd 命令恢复
1 | mtd -r write /tmp/firmware_backup.bin firmware |
仅对 /overlay 打包备份
1 | tar -czvf /tmp/overlay_backup.tar.gz /overlay |
需要恢复的时候将 overlay_backup.tar.gz 上传至 /tmp ,然后清空 /overlay 并恢复备份:
1 | rm -rvf /overlay/* |
稳妥的办法:只保留设置升级,备份软件包列表,opkg恢复软件包
What to do:
备份软件包列表
Make a LIST of all currently install packages:
1 | opkg list-installed > /etc/config/my_installed_packages |
将备份脚本放到CRONTAB 里面定期执行
You might want to put the command into a CRON … depending on how much you keep changing the packages on your router:
EDIT this file, which keeps track of what to SAVE during image upgrades:/etc/sysupgrade.conf
AFTER an upgrade run this command:
勾选保留设置升级(只备份/overlay/upper/etc文件夹的内容(openwrt默认备份内容))之后,用opkg命令恢复已安装的软件包
1 | opkg update && opkg list-installed | cut -f 1 -d ' ' | sort -u > /tmp/currentpkg && cat /etc/config/my_installed_packages | cut -f 1 -d ' ' | sort -u > /tmp/oldpkg && grep -v -F -x -f /tmp/currentpkg /tmp/oldpkg > /tmp/inst && opkg install $(cat /tmp/inst | sort -u) && rm /tmp/currentpkg /tmp/oldpkg /tmp/inst |
This will compare your current (after upgrade)
exroot挂载/overlay的一些bug
严格意义上来说不算bug,不过如果你遇到的话,或许这里的解决方法能提供一些帮助
openwrt的路由器或者主机,在挂载外置SD/TF/U盘为/overlay后,如果遇到升级或者/overlay文件系统UUID不一致无法启动
原因是升级21.0.1 -> 21.0.2的openwrt后,原本作为/overlay的外置SD无法启动了,拔掉SD卡正常
分析kernel.log内核日志,其中有这么一行:“block: extroot: UUID mismatch”
UUID和系统/etc/fstab的UUID不一致,导致无法正确挂载SD卡
原来解决了一下午找不到原因,后来查阅openwrt官方文档:
If you receive a “block: extroot: UUID mismatch” error in your logs after upgrading, remove .extroot-uuid from the volume:
1 | mount /dev/sda1 /mnt |
官方的建议是把exroot的etc/.exroot-uuid删掉,因为这个可能是升级备份前的UUID,与现在挂载的UUID不一致
顺利解决!!!
有什么问题还是多看看官方的文档吧,从原理上解决问题,而不是把报错的Log随便扔到google/百度/stackoverflow上面一搜(简单问题除外),这样不利于解决问题,也没法学习到一些系统的底层框架的原理。