#!/bin/bash # Command to erase user data file system # Modified for ubifs, secure boot (no U-Boot access) MNT_USER="/mnt/user" OVERLAY="$MNT_USER/overlay" WORKDIR="$MNT_USER/work" UPPERDIR="$MNT_USER/upper" LOWERDIR="/" USER_ORIG="$UPPERDIR/orig" USER_PARTITION="ubi0:user-data" # Erase the file system DO_ERASE_PERSISTENT=$(fw_printenv erase_persistent_f | cut -d '"' -f2 | grep -Eo '[0-9]+$' || true) # Remove files not hidden DO_ERASE_ALL_EXCEPT_PERSISTENT=$(fw_printenv default_reset_f | cut -d '"' -f2 | grep -Eo '[0-9]+$' || true) pid=$$ prefix="<3>overlayrootfs-generator[${pid}]: " loginfo() { echo "${prefix}$@" >/dev/kmsg ; } logpipe() { OIFS="${IFS}" IFS=$'\n' while read ln ; do echo -n "${prefix}${ln}" >/dev/kmsg done IFS="${OIFS}" } mnt_user() { mkdir -p $MNT_USER mount -t ubifs $USER_PARTITION $MNT_USER } fs="/run /dev /proc /sys /sys/kernel/security /dev/shm /dev/pts /sys/fs/cgroup /sys/fs/cgroup/unified /sys/fs/cgroup/systemd /sys/fs/cgroup/devices /sys/fs/cgroup/freezer /sys/fs/cgroup/pids /sys/fs/cgroup/memory /dev/mqueue /sys/kernel/debug /tmp /sys/fs/fuse/connections /sys/kernel/config /var/volatile" my_switch_root() { NEW_ROOT=$1 loginfo mountinfo mount --make-rprivate / loginfo "my_switch_root: Mount file systems" for f in $fs ; do if [[ -d $NEW_ROOT/$f ]] ; then loginfo "my_switch_root: mount -o noatime,move --bind $f $NEW_ROOT/$f" mount -o noatime,move --bind "$f" "$NEW_ROOT/$f" else # loginfo "my_switch_root: Skipping $NEW_ROOT/$f" : fi done /sbin/pivot_root "$NEW_ROOT" "$NEW_ROOT"/orig } do_erase_all_except_persistent() { # Delete all files and folders except for the "${MNT_USER}/.persistent" directory. loginfo "Clearing user data. Persistent data will be left " rm -rf "${MNT_USER:?}/"* } # Most efficient way to clear UBIFS file system do_erase_persistent() { loginfo "Erasing user data" # Sys must be mounted to use ubifs utilities mount -t sysfs sysfs /sys ubiattach -m 1 >/dev/null 2>&1 || true ubinfo -d 0 -N user-data | logpipe [[ $(ubinfo -d 0 -N user-data | grep 'Volume ID') =~ .*[[:space:]]+([0-9]+) ]] DEV=/dev/ubi0_"${BASH_REMATCH[1]}" umount -l $MNT_USER loginfo "Erase user-data partition $DEV" # Would be nice if ubiupdatevol took volume names instead of numbers ubiupdatevol "${DEV}" -t 2>&1 | logpipe mnt_user } do_rw_mount() { loginfo "Starting RW overlayfs" mount -t tmpfs inittemp /mnt mnt_user # user_data is now accessible if [[ "$DO_ERASE_PERSISTENT" -eq 1 ]] ; then do_erase_persistent fw_setenv erase_persistent_f 0 fw_setenv default_reset_f 0 elif [[ "$DO_ERASE_ALL_EXCEPT_PERSISTENT" -eq 1 ]] ; then do_erase_all_except_persistent fw_setenv default_reset_f 0 fi mkdir -p $UPPERDIR $WORKDIR $OVERLAY $USER_ORIG ${MNT_USER}/.persistent loginfo "Mounting..." mount -o noatime,lowerdir=$LOWERDIR,upperdir=$UPPERDIR,workdir=$WORKDIR,rw -t overlay overlay $OVERLAY loginfo "/proc/mounts:" cat /proc/mounts | grep overlay | logpipe mkdir -p ${OVERLAY}/var/persistent mount --bind ${MNT_USER}/.persistent ${OVERLAY}/var/persistent loginfo "Switch root to $OVERLAY" my_switch_root $OVERLAY cat /proc/mounts | grep overlay | logpipe mount -o remount,rw / cat /proc/mounts | grep overlay | logpipe cat /proc/mounts | grep tmp | logpipe umount -l /tmp >/dev/null 2>&1 umount -l /var/volatile >/dev/null 2>&1 cgroupmnts=$(sed -r -e 's/[^[:space:]]*[[:space:]]//' -e 's/[[:space:]]+.*//g' /proc/mounts | grep '^/orig') for mp in ${cgroupmnts} ; do if [[ $mp != /orig ]] && [[ $mp != /orig/mnt* ]] && [[ -d $mp ]] ; then umount -l "$mp" >/dev/null 2>&1 fi done } do_start() { do_rw_mount } case $1 in start) do_start ;; *) echo "Usage: $0 {start}" ;; esac