summaryrefslogtreecommitdiff
path: root/recipes-core/multitech/overlayfs-init-ubi/overlayfs.init
blob: 7fc7f7e2ded6a0a24603c8aa54f475a862405c14 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/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="/mnt/user/.persistent/mts_do_erase_persistent"
# Remove files not hidden
DO_CLEAR_PERSISTENT="/mnt/user/.persistent/mts_do_clear_persistent"

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
    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_remove_old() {
    shopt -s dotglob
    rm -rf $MNT_USER/*.old
    shopt -u dotglob
}

# select files for deletion
do_clear_old() {
    # when "clear user data" is requested - mark all non-hidden files for deletion
    loginfo "Clearing user data. Persistent data will be left "

    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" 2>&1 | logpipe
    done
    do_remove_old
    rm -f $DO_CLEAR_PERSISTENT
}

# Most efficient way to clear UBIFS file system
do_erase_old() {
    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
    do_remove_old

    if [[ -f $DO_ERASE_PERSISTENT ]] ; then
        do_erase_old
    elif [[ -f $DO_CLEAR_PERSISTENT ]] ; then
        do_clear_old
    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 ]] && [[ -d $mp ]] ; then
            umount -l $mp >/dev/null 2>&1
        fi
    done
}


TMP=/var/volatile
# Set the suffix number in /var/oem and /var/config to match root
fix_volume_names() {
    if ! [[ $(cat /proc/cmdline) =~ root=ubi0:rootfs([0-9]+) ]] ; then
        loginfo "Cannot find root=ubi0:rootfs in /proc/cmdline"
    fi
    vol_suffix=${BASH_REMATCH[1]}
    echo $vol_suffix
    sed -r "s/(ubi0:(oem|config))([0-9]*)/\1${vol_suffix}/" /etc/fstab >${TMP}/fstab
    if ! cmp ${TMP}/fstab /etc/fstab ; then
	    loginfo "Updating fstab with new volume names"
            cp ${TMP}/fstab /etc/fstab
    fi
}

do_start() {
    do_rw_mount
    fix_volume_names
}

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