在使用sysupgrade升级的时候,默认需要把配置文件进行备份,升级完成后进行恢复。如果是-n则把配置文件删除,恢复默认配置。
1、哪些文件需要备份
使用sysupgrade -l可以列出哪些文件被修改了,后面备份的时候就是这些文件
root@openwrt:# sysupgrade -l
/etc/config/ddns
/etc/config/dhcp
/etc/config/dropbear
/etc/config/firewall
/etc/config/fstab
/etc/config/guide
/etc/config/hd-idle
/etc/config/htpdate
/etc/config/igmpproxy
/etc/config/iptv
/etc/config/led
/etc/config/mtkhnat
/etc/config/network
/etc/config/rpcd
/etc/config/samba
/etc/config/system
/etc/config/tempctrl
/etc/config/timer_reboot
/etc/config/ubootenv
/etc/config/uhttpd
/etc/config/umdns
/etc/config/upnpd
/etc/config/vsftpd
/etc/config/wifidev
/etc/config/wireless
/etc/crontabs/root
/etc/dropbear/dropbear_rsa_host_key
/etc/fw_env.config
/etc/group
/etc/hosts
/etc/inittab
/etc/opkg/keys/0b26f36ae0f4106d
/etc/opkg/keys/1035ac73cc4e59e3
/etc/passwd
/etc/profile
/etc/rc.local
/etc/shadow
/etc/shells
/etc/sysctl.conf
那这些文件是如何被检测到需要备份呢,主要就是根据/lib/upgrade/keep.d/下面的文件内容
root@openwwrt:/lib/upgrade/keep.d# ls
base-files ppp base-files-essential busybox
uboot-envtools opkg uhttpd
如base-files文件里面的内容如下
root@zihome:/lib/upgrade/keep.d# cat base-files
/etc/config/
/etc/crontabs/
/etc/dropbear/
/etc/profile.d
这就说明这几个目录、文件的内容发生变化就会被记录
那/lib/upgrade/keep.d/下面的文件是如何生成的?
方式1
位于./package/base-files/Makefile
脚本里面openwrt有标准的Makefile定义格式,如下:
define Package/base-files/conffiles
/etc/config/
/etc/config/network
/etc/config/system
/etc/crontabs/
/etc/dropbear/
/etc/ethers
/etc/group
/etc/hosts
/etc/inittab
/etc/iproute2/rt_protos
/etc/iproute2/rt_tables
/etc/passwd
/etc/profile
/etc/profile.d
/etc/protocols
/etc/rc.local
/etc/services
/etc/shadow
/etc/shells
/etc/sysctl.conf
/etc/sysupgrade.conf
$(call $(TARGET)/conffiles)
endef
所以当我们自己写的package模块,如果有配置文件需要保留,那就在对应的Makefile里面conffiles的定义,如想在test模块添加配置文件保留,如下定义即可:
define Package/test/conffiles
/etc/config/test
endef
方式2
也可以直接在文件系统中./19.07/package/base-files/files/lib/upgrade/keep.d/base-files-essential
添加文件
root@openwrt:/lib/upgrade/keep.d# cat base-files-essential
# Essential files that will be always kept
/etc/hosts
/etc/inittab
/etc/group
/etc/passwd
/etc/profile
/etc/shadow
/etc/shells
/etc/sysctl.conf
/etc/rc.local
2、备份还原过程
执行sysupgrade升级的时候,如果没有-n,则会调用do_save_conffiles()
函数,该函数会扫描/lib/upgrade/keep.d/文件下的所有内容,然后通过跟/rom/文件里面的对比,不一致则备份。
add_conffiles() {
local file="$1"
( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' \
/etc/sysupgrade.conf /lib/upgrade/keep.d/* 2>/dev/null) \
\( -type f -o -type l \) $find_filter 2>/dev/null;
list_changed_conffiles ) | sort -u > "$file"
return 0
}
# rom is used for pkgs in /rom, even if updated later
find /usr/lib/opkg/info -name "*.control" \( \
\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
\( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
\( -exec echo {} unknown \; \) \
\) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES}
具体过程可以看源码
然后生成压缩文件
export CONF_TAR=/tmp/sysupgrade.tgz
之后在升级完固件后,将压缩包进行备份
platform_copy_config() {
rm -rf $1/*
cp -af "$CONF_TAR" $1/
sync
}
注意:1907之后的openwrt,将sysupgrade代理到do_,所以很多的环境变量会变化,如这边的UPGRADE_BACKUP这个名字
等待升级启动完成,在启动脚本中,将压缩包进行解压,完成配置文件还原
./package/base-files/files/lib/preinit/80_mount_root
#!/bin/sh
# Copyright (C) 2006 OpenWrt.org
# Copyright (C) 2010 Vertical Communications
do_mount_root() {
mount_root
boot_run_hook preinit_mount_root
[ -f /sysupgrade.tgz ] && {
echo "config restore..."
cd /
mv sysupgrade.tgz /tmp
tar xzf /tmp/sysupgrade.tgz
rm -f /tmp/sysupgrade.tgz
sync
echo "tar xzf /sysupgrade.tgz...ok"
}
}
[ "$INITRAMFS" = "1" ] || boot_hook_add preinit_main do_mount_root