summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/preinit-mounts/preinit-mounts/init
blob: c7f78b1e32594b09f0ce7d7713c02d22ef6e4303 (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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/bin/sh

# Copyright 2017-2019 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# provide a couple of places in the RO root filesystem
# that can be made RW with an overlayfs

# start with /proc and /tmp mounted
[ -e /proc/mounts ] || mount -t proc proc /proc
grep -q /tmp /proc/mounts || mount -t tmpfs -o rw,nosuid,nodev tmp /tmp
grep -q /sys /proc/mounts || mount -t sysfs -o rw,nosuid,nodev,noexec sys /sys

# list of things that need to be rw at boot
NV_OVERLAYS="/etc /var /home"

# place to mount the real ubifs backing store
RWFS_MNT=/tmp/.rwfs

if grep -q "$RWFS_MNT" /proc/mounts; then
    # quit - we have already run
    exit 0
fi
mkdir -p "$RWFS_MNT"

mtd_by_name() {
    local name="$1"
    local mtd="/dev/$(grep "$name" /proc/mtd | cut -d : -f 1)"
    echo "$mtd"
}

mtdnum_by_name() {
    local name="$1"
    local mtdnum="$(grep "$name" /proc/mtd | cut -c 4)"
    echo "$mtdnum"
}

NV_MTD=rwfs
NV_MTD_DEV="$(mtd_by_name ${NV_MTD})"
NV_MTD_NUM="$(mtdnum_by_name ${NV_MTD})"

nvrw() {
    local p="$1"
    # Clear the work dir doing overlay mount
    rm -rf "${RWFS_MNT}${p}.work"
    mkdir -p "${RWFS_MNT}${p}" "${RWFS_MNT}${p}.work"
    local mname=$(echo "rwnv${p}" | sed 's,/,,g')
    local opts="lowerdir=${p},upperdir=${RWFS_MNT}${p},workdir=${RWFS_MNT}${p}.work,sync"
    mount -t overlay -o "$opts" "$mname" "$p"
}

targetted_clean() {
    local LOG_TAG="restore-defaults"
    # Do not delete server certificates for the web server or ssh
    echo "removing targetted contents:"
    cd "${RWFS_MNT}/etc"
    for file in *; do
        case $file in
            # The only files that stay are here:
            CA|RestoreDefaultConfiguration|dropbear|sdr|server.pem);;
            # All else get removed.
            *)  echo "remove $file"
                rm -rf $file;;
        esac
    done
    # nothing should be in the workdir, but clear it just in case
    rm -rf "${RWFS_MNT}/etc.work"

    # Log files remaining - but not to stdout.
    echo "Files remaining: $(ls)"

    # clean everything out of /var
    rm -rf "${RWFS_MNT}/var" "${RWFS_MNT}/var.work"
}

full_clean() {
    local OVL=''
    for OVL in $NV_OVERLAYS; do
        rm -rf "${RWFS_MNT}${OVL}" "${RWFS_MNT}${OVL}.work"
    done
}

# check for full factory reset: if so, ubiformat $NV_MTD_DEV
bootflags="0x$(sed -n 's/^.*bootflags=\([0-9a-f]*\).*$/\1/p' /proc/cmdline)"
bootflags=$((bootflags + 0))
let "restore_op = $bootflags & 0x3"
if [ $restore_op -eq 3 ]; then
    ubiformat -y "$NV_MTD_DEV"
fi

# attach a UBI device to the MTD device
NV_UBI_DEV="/dev/ubi${NV_MTD_NUM}"
if [ ! -e $NV_UBI_DEV ]; then
    if ! ubiattach -m "$NV_MTD_NUM" -d "$NV_MTD_NUM"; then
        # the attach failed, so format the MTD device and try again
        echo "Warning! Failed to attach $NV_UBI_DEV to $NV_MTD_DEV."
        echo "UBI-formatting $NV_MTD_DEV to attach again. Data on this device will be lost."
        ubiformat -y "$NV_MTD_DEV"
        ubiattach -m "$NV_MTD_NUM" -d "$NV_MTD_NUM"
    fi
fi

# make a UBI volume on the UBI device
NV_UBI_VOL="${NV_UBI_DEV}_0"
if [ ! -e $NV_UBI_VOL ]; then
    ubimkvol "$NV_UBI_DEV" -N "$NV_MTD" -m
fi

# mount a UBIFS on the UBI volume
mount -t ubifs "$NV_UBI_VOL" "$RWFS_MNT"

if [ $restore_op -eq 1 ]; then
    targetted_clean
elif [ $restore_op -eq 2 ]; then
    full_clean
fi

for FS in $NV_OVERLAYS; do
    nvrw "$FS"
done

# make sure that /etc/fw_env.config mirrors our current uboot environment
UENV_MTD_INFO=$(grep UENV /proc/mtd)
if [ -n "$UENV_MTD_INFO" ]; then
    UENV_MTD_INFO=$(echo "$UENV_MTD_INFO" | sed 's,^\([^:]*\): \([0-9a-f]*\) \([0-9a-f]*\) .*,/dev/\1 0 0x\2 0x\3,')
    if ! grep -q "^${UENV_MTD_INFO}$" /etc/fw_env.config; then
        echo "${UENV_MTD_INFO}" > /etc/fw_env.config
        echo "Updated fw_env.config"
    fi
fi

# work around bug where /etc/machine-id will be mounted with a temporary file
# if rootfs is read-only and the file is empty
MACHINE_ID=/etc/machine-id
generate_machine_id() {
    systemd-machine-id-setup
    cp -pf "$MACHINE_ID" "${MACHINE_ID}_bkup"
}

if [ ! -s "$MACHINE_ID" ]; then
    # work around - Bug: Overlay fs fails for machine-id due to
    # origin mismatch. Clean it up, from overlay fs before re-creating
    # the same.
    if [ -e "$RWFS_MNT$MACHINE_ID" ]; then
        umount "/etc"
        rm -f "$RWFS_MNT$MACHINE_ID"
        nvrw "/etc"
        # Restore the machine-id from backup, else generate it.
        if [ -s "${MACHINE_ID}_bkup" ]; then
            cp -pf "${MACHINE_ID}_bkup" "${MACHINE_ID}"
        else
            generate_machine_id
        fi
        echo "Remounted /etc for machine-id origin mismatch"
    else
        generate_machine_id
    fi
fi

# mount persistent NV filesystem, where immortal settings live
if ! grep -q sofs /proc/mounts; then
    mkdir -p /var/sofs
    SOFS_MTD=sofs
    SOFS_MTD_DEV="$(mtd_by_name ${SOFS_MTD})"
    SOFS_MTD_NUM="$(mtdnum_by_name ${SOFS_MTD})"
    SOFS_UBI_DEV="/dev/ubi${SOFS_MTD_NUM}"

    # attach a UBI device to the MTD device
    if [ ! -e $SOFS_UBI_DEV ]; then
        if ! ubiattach -m "$SOFS_MTD_NUM" -d "$SOFS_MTD_NUM"; then
            # the attach failed, so format the MTD device and try again
            echo "Warning! Failed to attach $SOFS_UBI_DEV to $SOFS_MTD_DEV."
            echo "UBI-formatting $SOFS_MTD_DEV to attach again. Data on this device will be lost."
            ubiformat -y "$SOFS_MTD_DEV"
            ubiattach -m "$SOFS_MTD_NUM" -d "$SOFS_MTD_NUM"
        fi
    fi

    # make a UBI volume on the UBI device
    SOFS_UBI_VOL="${SOFS_UBI_DEV}_0"
    if [ ! -e $SOFS_UBI_VOL ]; then
        ubimkvol "$SOFS_UBI_DEV" -N "$SOFS_MTD" -m
    fi

    # mount a UBIFS on the UBI volume
    mount -t ubifs "$SOFS_UBI_VOL" /var/sofs
fi

echo "Finished mounting non-volatile overlays"

exec /lib/systemd/systemd