summaryrefslogtreecommitdiff
path: root/recipes-core/multitech/overlayfs-init-ubi/overlayfs.init
blob: 4b9796893f328c9517578d64f07c894d965e6597 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/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"
DO_ERASE_USERDATA_FILE="/mnt/user/.persistent/mts_do_erase_userdata"
DO_CLEAR_USERDATA_FILE="/mnt/user/.persistent/mts_do_clear_userdata"

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 /run /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
    cat /proc/mounts | logpipe
    mount --make-rprivate /
    for f in $fs ; do
        mount -o noatime,move --bind $f $NEW_ROOT/$f
    done
    /sbin/pivot_root $NEW_ROOT $NEW_ROOT/orig
}

# remove old hidden and non-hidden files and folders
do_remove_old() {
    if [[ -f $DO_ERASE_USERDATA_FILE ]] ; then
        do_clear_old
    else
        shopt -s dotglob
        rm -rf $MNT_USER/*.old
        shopt -u dotglob
    fi
}

# Most efficient way to clear UBIFS file system
do_clear_old() {
    umount -l $MNT_USER
    ubiattach -m 1 || true
    [[ $(ubinfo -d 0 -N user-data | grep 'Volume ID') =~ .*[[:space:]]+([0-9]+) ]]
    DEV="/dev/ubi_${BASH_REMATCH[1]}"
    loginfo "Erase user-data partition $DEV"
    # Would be nice if ubiupdatevol took volume names instead of numbers
    ubiupdatevol ${DEV} -t
    mnt_user
}

# select files for deletion
do_select_old() {
    if [[ -f $DO_ERASE_USERDATA_FILE ]]; then
        # when "erase user data" is requested - mark all hidden and non-hidden files for deletion
        shopt -s dotglob
        trap  "shopt -u dotglob" RETURN
        loginfo "Erasing user data"
    else
        # when "clear user data" is requested - mark all non-hidden files for deletion
        loginfo "Clearing user data"
    fi

    for FILE_PATH in "$MNT_USER"/*; do
        FILE_NAME=$(basename "$FILE_PATH")
        # rename all files and folders that exist in /mnt/user
        mv "$FILE_PATH" "$MNT_USER/$FILE_NAME.old"
    done
}

do_rw_mount() {
    loginfo "Starting RW overlayfs"
    mount -t tmpfs inittemp /mnt
    mnt_user

    do_remove_old
    if [[ -f $DO_CLEAR_USERDATA_FILE ]] || [[ -f $DO_ERASE_USERDATA_FILE ]] ; then
        do_select_old
        do_remove_old
        rm -f $DO_CLEAR_USERDATA_FILE 
    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
    umount -l /var/volatile
    cgroupmnts=$(sed -r -e 's/[^[:space:]]*[[:space:]]//'  -e 's/[[:space:]]+.*//g' /proc/mounts | grep '^/orig')
    for mp in ${cgroupmnts} ; do
        if [[ $mp != /orig ]] ; then
            umount -l $mp
        fi
    done
}

do_start() {
    do_rw_mount
}

case $1 in
start)
    do_start
;;
*)
    echo "Usage: $0 {start}"
;;
esac