#!/bin/sh MOUNT_ETC=0 MOUNT_OVERLAY=1 ################################## functions ################################## mkfs_jffs2() { ! [ -x /usr/sbin/mkfs.jffs2 ] \ && ! [ -x /sbin/mkfs.jffs2 ] \ && echo "Not Found /usr/sbin/mkfs.jffs2 or /sbin/mkfs.jffs2" \ && return 1 # format to jffs2 local erase_block=$(/bin/cat /proc/mtd \ | /bin/grep "$(basename $1)" \ | /usr/bin/awk '{print $3}') /bin/mkdir -p /tmp/jffs2.dir/tmp mkfs.jffs2 -p -e 0x${erase_block} -d /tmp/jffs2.dir \ -o /tmp/jffs2.img >/dev/null || return 1 /bin/dd if=/tmp/jffs2.img of=$1 || return 1 /bin/rm -rf /tmp/jffs2.img /tmp/jffs2.dir return 0 } mkfs_ubifs() { mkfs.ubifs -x lzo -y "$1" } mount_etc() { local etc_update=0 # if enable ota, do update [ -f /etc/init.d/rc.ota-upgrade ] \ && source /etc/init.d/ota-upgrade local root_dev="$(readlink /dev/by-name/rootfs)" # if mount failed, format. case "${root_dev}" in /dev/mtdblock*) /bin/mount -t jffs2 /dev/by-name/rootfs_data /etc \ && [ -e /etc/etc_complete -a ! -e /etc/etc_need_update ] \ && return # /etc/etc_complete and /etc/etc_need_update both exist, that means we just need to update [ -e /etc/etc_complete -a -e /etc/etc_need_update ] && /bin/echo "do etc update" && etc_update=1 /bin/umount /etc [ x$etc_update = x"1" ] || { # not update, format first /bin/echo "Mount Failed: formating /dev/by-name/rootfs_data to jffs2 ..." mkfs_jffs2 "/dev/by-name/rootfs_data" || return 1 } mount -t jffs2 /dev/by-name/rootfs_data /mnt ;; /dev/ubi*) /bin/mount -t ubifs /dev/by-name/rootfs_data /etc \ && [ -e /etc/etc_complete -a ! -e /etc/etc_need_update ] \ && return # /etc/etc_complete and /etc/etc_need_update both exist, that means we just need to update [ -e /etc/etc_complete -a -e /etc/etc_need_update ] && /bin/echo "do etc update" && etc_update=1 /bin/umount /etc [ x$etc_update = x"1" ] || { # not update, format first /bin/echo "Mount Failed: formating /dev/by-name/rootfs_data to ubifs ..." mkfs_ubifs "/dev/by-name/rootfs_data" || return 1 } /bin/mount -t ubifs /dev/by-name/rootfs_data /mnt ;; *) /usr/sbin/fsck.ext4 -y /dev/by-name/rootfs_data &>/dev/null /bin/mount -t ext4 -o sync,data=journal /dev/by-name/rootfs_data /etc \ && [ -e /etc/etc_complete -a ! -e /etc/etc_need_update ] \ && return # /etc/etc_complete and /etc/etc_need_update both exist, that means we just need to update [ -e /etc/etc_complete -a -e /etc/etc_need_update ] && /bin/echo "do etc update" && etc_update=1 /bin/umount /etc [ x$etc_update = x"1" ] || { # not update, format first /bin/echo "Mount Failed: formating /dev/by-name/rootfs_data to ext4 ..." mkfs.ext4 -m 0 /dev/by-name/rootfs_data >/dev/null || return 1 } /bin/mount -t ext4 -o sync,data=journal /dev/by-name/rootfs_data /mnt ;; esac mkdir -p /tmp/etc /bin/cp -af /etc/* /tmp/etc/ # keep the wifi config [ -e /mnt/wifi/wpa_supplicant.conf ] && { /bin/echo "keep the wifi config" /bin/cp /mnt/wifi/wpa_supplicant.conf /tmp/etc/wifi/ } /bin/cp -af /tmp/etc/* /mnt/ rm -rf /tmp/etc sync [ ! -e /mnt/etc_complete ] && touch /mnt/etc_complete [ -e /mnt/etc_need_update ] && /bin/echo "etc update done" && rm -f /mnt/etc_need_update sync /bin/mount -o move /mnt /etc } mount_usr(){ local extend_name=$(fw_printenv -n extend_partition) if [ $extend_name == extendB ]; then extend_name="extend_backup" else extend_name="extend" fi local extend_partition="/dev/by-name/${extend_name}" [ -L ${extend_partition} ] || if [ ${extend_partition} == "/dev/by-name/extend" ]; then [ -L /dev/by-name/extend_backup ] || return else [ -L /dev/by-name/extend ] || return fi /bin/mkdir -p /tmp/usr /bin/mount ${extend_partition} /tmp/usr >/dev/null || { if [ ${extend_partition} == "/dev/by-name/extend" ]; then echo "****** 111 mount /dev/by-name/extend_backup /usr *******" /bin/mount /dev/by-name/extend_backup /tmp/usr > /dev/null return else echo "********** 222 mount /dev/by-name/extend /usr ********" /bin/mount /dev/by-name/extend /tmp/usr > /dev/null fi } echo "*******333 mount ${extend_partition} /usr ******" ! [ -d /tmp/usr/bin ] \ && umount /tmp/usr \ && rm -rf /tmp/usr \ && return /bin/mount -o move /tmp/usr /usr \ && rm -rf /tmp/usr } rc_mount_filesystem() { local fs_src="$1" local fs_mntpt="$2" # mount filesystem if [ -e "$fs_src" -a -d "$fs_mntpt" ]; then [ -L "$fs_src" ] && fs_src=$(readlink "$fs_src") case "$fs_src" in /dev/mtdblock*) mount -t jffs2 "$fs_src" "$fs_mntpt" 2>/dev/null if [ "$?" -ne "0" ]; then mkfs_jffs2 "$fs_src" mount -t jffs2 "$fs_src" "$fs_mntpt" 2>/dev/null fi ;; /dev/ubi*) mount -t ubifs "$fs_src" "$fs_mntpt" 2>/dev/null if [ "$?" -ne "0" ]; then mkfs_ubifs "$fs_src" mount -t ubifs "$fs_src" "$fs_mntpt" 2>/dev/null fi ;; *) /usr/sbin/fsck.ext4 -y "$fs_src" &>/dev/null mount -t ext4 "$fs_src" "$fs_mntpt" 2>/dev/null if [ "$?" -ne "0" ]; then # linux < 3.18 not support metadata_csum, e2fsprogs version:1.46.4 grep "Linux version 3.*" /proc/version >> /dev/null if [ $? -eq 0 ]; then echo "linux < 3.18, mkfs.ext4 do not use metadata and journal checksum features." mkfs.ext4 -m 0 -O ^metadata_csum "$fs_src" >/dev/null else mkfs.ext4 -m 0 "$fs_src" >/dev/null fi mount -t ext4 "$fs_src" "$fs_mntpt" 2>/dev/null fi ;; esac # restore /mnt file contexts if [ -f /sbin/restorecon ]; then /sbin/restorecon -R /mnt fi fi } rc_mount() { rc_mount_filesystem "/dev/by-name/UDISK" "/mnt/UDISK" # rc_mount_filesystem "/dev/by-name/user-res" "/mnt/user" # enable hotplug [ -x /sbin/mdev ] && { [ -f /proc/sys/kernel/hotplug ] && echo /sbin/mdev > /proc/sys/kernel/hotplug /sbin/mdev -s } } mount_overlay() { local root_dev="$(readlink /dev/by-name/rootfs)" local mount_partition_dir case "$1" in UDISK) mount_partition_dir="/mnt/UDISK" ;; rootfs_data) mount_partition_dir="/overlay" ;; *) echo "error: please choose rootfs_data or UDISK" return 1 esac case "${root_dev}" in /dev/mtdblock*) /bin/mount -t jffs2 /dev/by-name/$1 ${mount_partition_dir} || { /bin/echo "Mount Failed: formating /dev/by-name/$1 to jffs2 ..." mkfs_jffs2 "/dev/by-name/$1" || return 1 mount -t jffs2 /dev/by-name/$1 ${mount_partition_dir} } ;; /dev/ubi*) /bin/mount -t ubifs /dev/by-name/$1 ${mount_partition_dir} || { /bin/echo "Mount Failed: formating /dev/by-name/$1 to ubifs ..." mkfs_ubifs "/dev/by-name/$1" || return 1 /bin/mount -t ubifs /dev/by-name/$1 ${mount_partition_dir} } ;; *) /usr/sbin/fsck.ext4 -y /dev/by-name/$1 &>/dev/null /bin/mount -t ext4 -o sync,data=journal /dev/by-name/$1 ${mount_partition_dir} || { /bin/echo "Mount Failed: formating /dev/by-name/$1 to ext4 ..." mkfs.ext4 -m 0 /dev/by-name/$1 >/dev/null || return 1 /bin/mount -t ext4 -o sync,data=journal /dev/by-name/$1 ${mount_partition_dir} } ;; esac fgrep -sq overlay /proc/filesystems || { /bin/echo "skip mount overlayfs as kernel not support" return } # only for recovery,copy boot_partition(boot) wifi information to boot_partition(recovery) local system=$(fw_printenv -n boot_partition) if [ x"$system" = x"recovery" ]; then [ -e /overlay/upper/etc/wifi/wpa_supplicant ] && { cp -fpr /overlay/upper/etc/wifi/* /etc/wifi/ } fi #When /dev/root is readonly, such as squashfs or ext4 ro, we try to mount overlayfs.Otherwise, don't mount overlayfs fgrep -sq '/dev/root / squashfs ro' /proc/mounts || fgrep -sq '/dev/root / ext4 ro' /proc/mounts || { /bin/echo "skip mount overlayfs as now rootfs not squashfs or readonly ext4" return } # First, try to mount without a workdir, for overlayfs v22 and before. # If it fails, it means that we are probably using a v23 and # later versions that require a workdir # mount -n -t overlay overlayfs:/overlay -o rw,noatime,lowerdir=/,upperdir=/overlay /mnt || { # mkdir -p /overlay/upper /overlay/workdir # mount -n -t overlay overlayfs:/overlay -o rw,noatime,lowerdir=/,upperdir=/overlay/upper,workdir=/overlay/workdir /mnt # } local overlay_need_workdir=1 # overlayfs in linux-3.4 and linux-3.10 is v22 and before, should mount without a workdir fgrep -sq 'Linux version 3' /proc/version && overlay_need_workdir=0 local mount_overlay_dir="/overlay" [ x"${mount_partition_dir}" = x"/mnt/UDISK" ] && { mkdir -p /mnt/UDISK/overlay mount_overlay_dir="/mnt/UDISK/overlay" } if [ x"$overlay_need_workdir" = x"0" ]; then mount -n -t overlayfs overlayfs:${mount_overlay_dir} -o rw,noatime,lowerdir=/,upperdir=${mount_overlay_dir} /mnt else mkdir -p ${mount_overlay_dir}/upper ${mount_overlay_dir}/workdir mount -n -t overlay overlayfs:${mount_overlay_dir} -o rw,noatime,lowerdir=/,upperdir=${mount_overlay_dir}/upper,workdir=${mount_overlay_dir}/workdir /mnt fi mount -n /proc -o noatime,move /mnt/proc pivot_root /mnt /mnt/rom mount -n /rom/dev -o noatime,move /dev mount -n /rom/tmp -o noatime,move /tmp mount -n /rom/sys -o noatime,move /sys mount -n /rom$mount_partition_dir -o noatime,move $mount_partition_dir fgrep -sq '/rom/usr' /proc/mounts && { mount -n /rom/usr -o noatime,move /usr if [ x"$overlay_need_workdir" = x"0" ]; then mkdir -p $mount_overlay_dir/usr mount -n -t overlayfs overlayfs:${mount_overlay_dir} -o rw,noatime,lowerdir=/usr,upperdir=${mount_overlay_dir}/usr /usr else mkdir -p ${mount_overlay_dir}/upper/usr ${mount_overlay_dir}/workdir/usr mount -n -t overlay overlayfs:${mount_overlay_dir} -o rw,noatime,lowerdir=/usr,upperdir=${mount_overlay_dir}/upper/usr,workdir=${mount_overlay_dir}/workdir/usr /usr fi } [ x"$1" = x"UDISK" ] && rm -rf /overlay } set_parts_by_name() { # create by-name local parts part /bin/mkdir -p /dev/by-name parts=$partitions for part in $(/bin/echo ${parts} | /bin/sed 's/:/ /g') do [ ! -e /dev/${part#*@} ] && [ -x /sbin/mdev ] && mdev -s #for initramfs /bin/ln -fs "/dev/${part#*@}" "/dev/by-name/${part%@*}" done } etc_part=/dev/nande /bin/mount -t proc /proc /proc /bin/mount -t tmpfs tmpfs /tmp /bin/mount -t sysfs sys /sys fgrep -sq pstore /proc/filesystems && { /bin/mount -t pstore pstore /sys/fs/pstore } #fw_setenv, fw_printenv need /var/lock mkdir -p /var/lock #common but slow set_parts_by_name mount_usr [ x"$MOUNT_ETC" = x"1" ] && mount_etc # [ x"$MOUNT_OVERLAY" = x"1" ] && mount_overlay rootfs_data #choose rootfs_data or UDISK rc_mount /APP/SL100FRONTPANEL & exec /sbin/init