Created
April 18, 2020 21:48
-
-
Save Ansuel/7308607ec21990fb8cd51d4bc03b834d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
ubi_num= | |
find_mtd_part() { | |
local PART=$(awk -F: "/$1/{print \$1}" /proc/mtd) | |
if [ ! -z "$PART" ]; then | |
PART="${PART##mtd}" | |
if [ ! -z "$PART" ]; then | |
echo /dev/mtdblock$PART | |
fi | |
fi | |
} | |
#Since Linux 3.18-rc6, overlayfs has been renamed overlay | |
legacy_overlayfs() { | |
local ovl | |
ovl=$(cat /proc/filesystems | grep "\overlay\b" | awk '{print $2}') | |
[ "$ovl" != "overlay" ] | |
} | |
find_mount_jffs2() { | |
local options | |
local mtdpartname | |
local mtdpart | |
local dir="$1" | |
options=$(grep "^mount=" /etc/jffs2_options 2>/dev/null | sed "s/^mount=//" ) | |
if [ ! -z $options ]; then | |
options="-o $options" | |
fi | |
mkdir -p "$dir" | |
for mtdpartname in $(cat /proc/banktable/notbooted); do | |
mtdpart="$(find_mtd_part $mtdpartname)" | |
if [ -n "$mtdpart" ]; then | |
mount -t jffs2 $options "$mtdpart" "$dir" | |
if [ $? -ne 0 ]; then | |
echo "failed to mount $mtdpartname on $mtdpart as jffs2" | |
echo "retrying... by erasing and remounting" | |
mtd erase $mtdpartname | |
mount -t jffs2 $options "$mtdpart" "$dir" | |
if [ $? -ne 0 ]; then | |
echo "failed to mount $mtdpartname on $mtdpart as jffs2" | |
else | |
mtd -qq unlock $mtdpartname | |
if [ $? -ne 0 ]; then | |
echo "failed to unlock $mtdpartname, partition not writeable" | |
umount "$dir" | |
else | |
if ! legacy_overlayfs; then | |
mkdir -p "$dir/work" | |
fi | |
return 0 | |
fi | |
fi | |
else | |
mtd -qq unlock $mtdpartname | |
if [ $? -ne 0 ]; then | |
echo "failed to unlock $mtdpartname, partition not writeable" | |
umount "$dir" | |
else | |
if ! legacy_overlayfs; then | |
mkdir -p "$dir/work" | |
fi | |
return 0 | |
fi | |
fi | |
fi | |
done | |
echo "failed to find suitable partition to mount" | |
return 1 | |
} | |
find_available_ubi_num() { | |
local lastubidevice= | |
for x in $(ubinfo | grep "Present UBI devices" | cut -d':' -f2 | tr "," "\n") | |
do | |
lastubidevice=$x | |
done | |
if [ -z "$lastubidevice" ] | |
then | |
lastubidevice=ubi0 | |
fi | |
last_num=$(echo $lastubidevice | sed 's/ubi//') | |
avail_dev_num=`expr $last_num + 1` | |
echo $avail_dev_num | |
} | |
find_overlay_partition() { | |
local result=$1 | |
overlay_partition="$(cat /proc/banktable/notbooted)" | |
for partition in $overlay_partition ; do | |
if ( cat /proc/mtd | grep -i $partition ) ; then | |
eval $result="'$partition'" | |
break | |
fi | |
done | |
} | |
get_ubi_num_from_vol() { | |
volname=$1 | |
dev_count=$(ubinfo | grep "Count" | tr -dc '0-9') | |
for i in `seq 0 $(expr $dev_count - 1)` | |
do | |
ubi_count=$(ubinfo -d $i| grep "Volumes count" | tr -dc '0-9') | |
for j in `seq 0 $(expr $ubi_count - 1)` | |
do | |
ubivol=$(ubinfo -d $i -n $j |grep $volname) | |
if [ ! -z "$ubivol" ] ; then | |
ubi_num=$i | |
break; | |
fi | |
done | |
done | |
} | |
find_mount_ubifs() { | |
local dir=$1 | |
find_overlay_partition partition | |
get_ubi_num_from_vol $partition | |
if [ ! -z "$ubi_num" ] ; then | |
echo "ubi_num=$ubi_num" | |
elif ( cat /proc/mtd | grep -i "$partition" ) ; then | |
mtd_block_number=$(cat /proc/mtd | grep -i "$partition" | sed 's/^mtd//' | awk -F ':' '{print $1}') | |
echo "Detected block device: $dir for $partition" > /dev/kmsg | |
ubi_num="$(find_available_ubi_num)" | |
ubiattach -m "$mtd_block_number" -d $ubi_num /dev/ubi_ctrl | |
else | |
echo "No $partition partition found" | |
return 1 | |
fi | |
mkdir -p "$dir" | |
mount -o sync -t ubifs ubi$ubi_num:overlay $dir | |
if [ $? -ne 0 ]; then | |
echo "failed to mount ubi$ubi_num:overlay on ubifs" | |
return 1 | |
fi | |
mkdir -p $dir/work | |
return 0 | |
} | |
pivot() { # <new_root> <old_root> | |
local new=$1 | |
local old=$2 | |
mount -o move /proc $new/proc && \ | |
pivot_root $new $new$old && { | |
mount -o move $old/dev /dev | |
mount -o move $old/tmp /tmp | |
mount -o move $old/sys /sys 2>&- | |
mount -o move $old/overlay /overlay 2>&- | |
} | |
} | |
fopivot() { # <rw_root> <ro_root> | |
local rw_root=$1 | |
local ro_root=$2 | |
ovl=$(cat /proc/filesystems | grep "\overlay\b" | awk '{print $2}') | |
if [ "$ovl" = "overlay" ] #Since Linux 3.18-rc6, overlayfs has been renamed overlay | |
then | |
echo "mounting overlay fs" | |
mount -t overlay -o lowerdir=/,upperdir=/overlay/1,workdir=/overlay/0 overlay /mnt && rw_root=/mnt | |
else | |
echo "mounting overlayfs fs" | |
mount -t overlayfs -olowerdir=/,upperdir=$rw_root "overlayfs:$rw_root" /mnt && rw_root=/mnt | |
fi | |
pivot $rw_root $ro_root | |
} | |
check_banktable() { | |
if [ -f /lib/modules/$(uname -r)/bankmgr.ko ]; then | |
insmod bankmgr 2>/dev/null | |
fi | |
} | |
run_mount_checks() { | |
local mount_point="$1" | |
local checkdir=/lib/mount_modroot_checks | |
if [ ! -d "$checkdir" ]; then | |
return | |
fi | |
local loop_detect="${mount_point}/mount_check_reboot" | |
if [ -f "$loop_detect" ]; then | |
#reboot because of mount check failures | |
#do not check again, to prevent reboot loops | |
rm $loop_detect | |
return | |
fi | |
local reboot_needed="no" | |
for check in $(ls -lA $checkdir); do | |
if [ -x $checkdir/$check ]; then | |
$checkdir/$check "$mount_point" || reboot_needed="yes" | |
fi | |
done | |
if [ "$reboot_needed" = "yes" ]; then | |
touch $loop_detect | |
/sbin/reboot -f | |
fi | |
} | |
mount_root_mod() { | |
local upperdir | |
local mount_point="/tmp/modoverlay" | |
check_banktable | |
if [ -f /proc/banktable/booted ]; then | |
upperdir=/modoverlay | |
else | |
# modroot on notbooted bank not possible | |
return | |
fi | |
find_mount_jffs2 ${mount_point} | |
if [ $? -ne 0 ]; then | |
find_mount_ubifs ${mount_point} | |
if [ $? -ne 0 ]; then | |
# something went wrong | |
return | |
fi | |
fi | |
run_mount_checks ${mount_point} | |
mkdir -p $upperdir | |
echo "switching to modoverlay" | |
mount -o move /tmp/modoverlay /modoverlay 2>&- | |
for f in /lib/mount_modroot/*; do | |
[ -x $f ] && $f $upperdir | |
done | |
# mkdir -p $oldroot | |
fopivot $upperdir /rom | |
# make sure /tmp has the correct permissions ! | |
chmod 01777 /tmp | |
} | |
# Actually mount the dir | |
mount_root_mod | |
# Create needed dir | |
mkdir /saferoot | |
mkdir /modoverlay | |
# Move oldroot to saferoot | |
mount -o move /rom /saferoot | |
# Move old mount to new position | |
mount -o move /saferoot/modoverlay /modoverlay | |
# Restore original rom | |
mount -o move /saferoot/rom /rom | |
# Restore saferoot overlay | |
mount -o move /saferoot/overlay /overlay |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment