#!/bin/sh TMP_SELF_COPY=/var/run/cloned-overlay-backup action=${1} shift has_overlay() { [ -d "/overlay/upper" ] || return 1 [ "overlay" = "$(/bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }')" ] || return 1 return 0 } has_ext_overlay() { [ -d "/ext_overlay/upper" ] || return 1 grep '^overlayfs:/overlay / ' /proc/mounts | grep -Fq 'upperdir=/ext_overlay/upper' || return 1 return 0 } backup() { if ! has_overlay; then echo "only supports squashfs firmware" exit 1 fi if [ -z "$1" ]; then echo "input backup path is null" exit 1 fi local BACKUP_PATH="$1" if echo "$BACKUP_PATH" | grep -q -e '^/overlay/upper' -e '^/ext_overlay/upper' ; then echo "can not backup to /overlay/upper, /ext_overlay/upper" exit 1 fi if [ ! -d "${BACKUP_PATH}" ] && ! mkdir -p "${BACKUP_PATH}" ; then echo "backup path does not exist and can not be create" exit 1 fi local realpath="$(cd "${BACKUP_PATH}"; pwd -P)" if [ -z "$realpath" ]; then echo "cannot get absolute path of ${BACKUP_PATH}" exit 1 fi local mountpoint=$(findmnt -T $realpath -o TARGET | sed -n 2p) # while read -r; do # if [[ "x$realpath" == "x$REPLY" || "x${realpath#$REPLY/}" != "x$realpath" ]]; then # mountpoint="$REPLY" # break # fi # done < <( # cat /proc/mounts | grep -v '^overlay ' | awk 'NR>1 {print $2}' | grep -v '^/$' | \ # sort -u | \ # while read -r; do printf "%b\n" "$REPLY" ; done | \ # awk '{print length, $0}' | sort -nr | cut -d' ' -f2- # ) if [ "/" = "$mountpoint" ]; then echo "can not backup to /" exit 1 else echo "found mount point $mountpoint" fi local filename_suffix= local tar_extra_args= if has_ext_overlay; then tar_extra_args="$tar_extra_args ext_overlay/upper" filename_suffix="${filename_suffix}.s" fi local hostname=$(cat /proc/sys/kernel/hostname) local fwver=$(. /etc/openwrt_release; echo $DISTRIB_ID-$DISTRIB_RELEASE) local date=$(date +%Y-%m%d-%H%M) local backup_name="backup_overlay_${hostname}_${fwver}_${date}${filename_suffix}.overlay.tar.gz" local backup_full_path="$BACKUP_PATH/$backup_name" echo "writing backup to $backup_full_path" if tar -C / -cz overlay/upper $tar_extra_args > "$backup_full_path" ; then sync "$BACKUP_PATH" echo "backup success" return 0 else rm -f "$backup_full_path" echo "backup failed" exit 1 fi } patch_sandbox_device() { local overlay="$1" local ucidir="$overlay/upper/etc/config" local uci_section=$(uci -c "$ucidir" -q show fstab | grep '^fstab\.@mount\[[0-9]*\]\.target='"'/overlay'\$" | head -1 | grep -o '^fstab\.@mount\[[0-9]*\]') if [ -n "$uci_section" ]; then if [ "x1" = "x$(uci -c "$ucidir" get "$uci_section.enabled")" ]; then uci -c "$ucidir" -q delete "$uci_section.uuid" uci -c "$ucidir" -q delete "$uci_section.label" uci -c "$ucidir" -q delete "$uci_section.device" if [ -n "$SANDBOX_UUID" ]; then uci -c "$ucidir" set "$uci_section.uuid=$SANDBOX_UUID" elif [ -n "$SANDBOX_LABEL" ]; then uci -c "$ucidir" set "$uci_section.label=$SANDBOX_LABEL" else uci -c "$ucidir" set "$uci_section.device=$SANDBOX_DEVICE" fi uci -c "$ucidir" commit fstab echo "found and patched $overlay" return 0 fi fi return 1 } restore() { if ! has_overlay; then echo "only supports squashfs firmware" exit 1 fi if [ -z "$1" ]; then echo "input backup path is null" exit 1 fi local BACKUP_PATH_FILE="$1" if [ ! -f "${BACKUP_PATH_FILE}" ]; then echo "invalid backup file, can not restore" exit 1 fi # prevent uci cache rm -rf /var/run/uci SANDBOX_UUID= SANDBOX_LABEL= SANDBOX_DEVICE= local tar_extra_args=overlay/upper if has_ext_overlay; then tar_extra_args= if echo "${BACKUP_PATH_FILE}" | grep -q '\.s\.overlay\.tar\.gz$' ; then local uuid label device line local uci_section=$(uci -c /overlay/upper/etc/config show fstab | grep '^fstab\.@mount\[[0-9]*\]\.target='"'/overlay'\$" | head -1 | grep -o '^fstab\.@mount\[[0-9]*\]') if [ -z "$uci_section" ]; then echo "failed to find sandbox config, there is debug info:" uci -c /overlay/upper/etc/config show fstab | grep '^fstab\.[^.]*\.target='"'/overlay'\$" exit 1 fi while read line; do export -n "$line" done <