在使用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_,所以很多的环境变量会变化,如这边的30-Openwrt config save and restore_配置文件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