blob: b79b9ae7341b7e84a93b4f756697bbd6cf0aee69 [file] [log] [blame]
#!/bin/sh
SYSCFG_UBIFS_MNT=/tmp/syscfg
. /lib/functions.sh
# mtdpart: the ubifs syscfg partition
# rom: the read-only rootfs mount point
# overlay: the overlay upper directory
# ramoverlay: if ramoverlay is activated, ramoverlay=1
pre_check() {
# return 1 on failed
grep -qs ubifs /proc/filesystems || return 1
grep -qs overlayfs /proc/filesystems || return 1
[ ! -e $SYSCFG_UBIFS_MNT ] && mkdir -p $SYSCFG_UBIFS_MNT
mtdpart="$(find_mtd_part syscfg)"
[ -z "$mtdpart" ] && return 1
mtdpart_idx="$(echo $mtdpart | tr -d "/dev/mtdblock")"
rom=$(awk '/jffs2 ro/ {print $2}' /proc/mounts)
overlay=$(awk '/ubifs/ {print $2}' /proc/mounts | tail -n 1)
ramoverlay=1
grep -qs 'overlayfs:/tmp/root' /proc/mounts || ramoverlay=0
return 0
}
try_ubifs_syscfg_mount() {
overlay_mountpoint=$1
if [ -z $overlay_mountpoint ]
then
overlay_mountpoint=/overlay
fi
recover_ubifs=0
[ ! -e /dev/ubi0 ] && ubiattach -m $mtdpart_idx /dev/ubi_ctrl || recover_ubifs=1
if [ $recover_ubifs -eq 0 ]
then
ubi0_nod_id=`cat /sys/class/ubi/ubi0/dev | tr -s ":" " "`
[ ! -e /dev/ubi0 ] && mknod /dev/ubi0 c ${ubi0_nod_id}
if [ ! -e /sys/class/ubi/ubi0_0/dev ]
then
# no volume
recover_ubifs=1
else
# check for "syscfg" volume
ubi0_0_nod_id=`cat /sys/class/ubi/ubi0_0/dev | tr -s ":" " "`
[ ! -e /dev/ubi0_0 ] && mknod /dev/ubi0_0 c ${ubi0_0_nod_id}
{ ubinfo /dev/ubi0_0 | grep Name | grep -qs "syscfg" ; } || \
recover_ubifs=1
fi
fi
if [ $recover_ubifs -eq 1 ]
then
echo "ubifs syscfg partition is damaged"
echo "try to recover by formatting $mtdpart..."
[ -e /dev/ubi0 ] && ubidetach -m $mtdpart_idx
ubiformat -y -q /dev/mtd$mtdpart_idx
ubiattach -m $mtdpart_idx /dev/ubi_ctrl
ubi0_nod_id=`cat /sys/class/ubi/ubi0/dev | tr -s ":" " "`
[ ! -e /dev/ubi0 ] && mknod /dev/ubi0 c ${ubi0_nod_id}
ubimkvol /dev/ubi0 -n 0 -N syscfg -t dynamic --maxavsize
fi
# finally mount the ubifs
mount -t ubifs -o noatime ubi0:syscfg $SYSCFG_UBIFS_MNT || return 1
[ ! -d $SYSCFG_UBIFS_MNT/openwrt_overlay ] && mkdir -p $SYSCFG_UBIFS_MNT/openwrt_overlay
mount -o bind $SYSCFG_UBIFS_MNT/openwrt_overlay $overlay_mountpoint
return 0
}
with_fo_cleanup() {
# try to get rid of /tmp/root
# this will almost always fail
# unmount overlay
umount -l /tmp/root 2>&-
# umount ramfs
umount -l /tmp/root 2>&-
grep -q overlay /proc/filesystems && {
cd $overlay
(
find -type l
) | while read FILE; do
[ -z "$FILE" ] && break
if ls -la "$FILE" 2>&- | grep -q '(overlay-whiteout)'; then
rm -f "$FILE"
fi
done
}
}
pre_check
if [ ! -z "$overlay" ]
then
echo "overlayfs is mounted"
else
if [ "$ramoverlay" -eq 1 ]
then
echo "switch from ramoverlay to ubifs overlay"
overlay=/rom/overlay
try_ubifs_syscfg_mount $overlay || exit 1
# try to avoid fs changing while copying
mount -o remount,ro none / 2>&-
# copy ramoverlay to ubifs overlay
echo -n "copying files ... "
cp -a /tmp/root/* $overlay 2>&-
echo "done"
# switch back to ro rootfs (temporarily)
# and park the ramdisk ontop of /tmp/root
pivot /rom /mnt
# after pivot to rom, $overlay may change
overlay=$(awk '/ubifs/ {print $2}' /proc/mounts | tail -n 1)
mount -o move /mnt /tmp/root
# /overlay is the overlay
# /rom is the readonly
fopivot $overlay /rom
with_fo_cleanup
else
echo "try to mount overlayfs"
overlay=/overlay
try_ubifs_syscfg_mount $overlay || exit 1
fopivot $overlay /rom
fi
fi