blob: ff88185184660b68eb3312a4d769442512afc912 [file] [log] [blame]
Adriana Kobylak10e915a2019-05-31 13:25:36 -05001#!/bin/sh
2
3# Get the mtd device number (mtdX)
4findmtd() {
5 m="$(grep -xl "$1" /sys/class/mtd/*/name)"
6 m="${m%/name}"
7 m="${m##*/}"
8 echo "${m}"
9}
10
11# Get the ubi device number (ubiX_Y)
12findubi() {
13 u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)"
14 u="${u%/name}"
15 u="${u##*/}"
16 echo "${u}"
17}
18
19# Get the mount information
20is_mounted() {
21 grep -q "$1" /proc/mounts
22 return $?
23}
24
25# Attach the pnor mtd device to ubi.
26attach_ubi() {
27 pnormtd="$(findmtd pnor)"
28 pnor="${pnormtd#mtd}"
29 pnordev="/dev/mtd${pnor}"
30
31 if [ -d "/sys/class/ubi/ubi${pnor}" ]; then
32 # Already attached
33 return 0
34 fi
35
36 ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}"
37 rc=$?
38 if [ ${rc} -ne 0 ]; then
39 # Check the pnor mtd device is formatted as ubi by reading the first 3 byes,
40 # which should be the ascii chars 'UBI'
41 magic="$(hexdump -C -n 3 ${pnordev})"
42 if [[ "${magic}" =~ "UBI" ]]; then
43 # Device already formatted as ubi, ubiattach failed for some other reason
44 return ${rc}
45 else
46 # Format device as ubi
47 echo "Starting ubiformat ${pnordev}"
48 ubiformat "${pnordev}" -y -q
49 # Retry the ubiattach
50 ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}"
51 fi
52 fi
53}
54
55mount_squashfs() {
56 pnormtd="$(findmtd pnor)"
57 ubidev="/dev/ubi${pnormtd#mtd}"
58 mountdir="/media/${name}"
59 vol="$(findubi "${name}")"
60 img="/tmp/images/${version}/pnor.xz.squashfs"
61 filesize="$(ls -sh $img | awk -F " " {'print $1'})"
62
63 if is_mounted "${name}"; then
64 echo "${name} is already mounted."
65 return 0
66 fi
67
68 if [ ! -z "${vol}" ]; then
69 ubirmvol "${ubidev}" -N "${name}"
70 fi
71
72 if [ ! -d "${mountdir}" ]; then
73 mkdir "${mountdir}"
74 fi
75
76 # Set size of read-only partition equal to pnor.xz.squashfs
77 ubimkvol "${ubidev}" -N "${name}" -s "${filesize}"KiB --type=static
78 vol="$(findubi "${name}")"
79
80 if [ $? != 0 ]; then
81 echo "Unable to create RO volume!"
82 return 1
83 fi
84
85 ubidevid="${vol#ubi}"
86 ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
87
88 if [ $? != 0 ]; then
89 echo "Unable to update RO volume!"
90 return 1
91 fi
92
93 ubiblock --create "/dev/ubi${ubidevid}"
94
95 if [ $? != 0 ]; then
96 echo "Unable to create UBI block for RO volume!"
97 return 1
98 fi
99
100 mount -t squashfs -o ro "/dev/ubiblock${ubidevid}" "${mountdir}"
101
102 if [ $? != 0 ]; then
103 echo "Unable to mount RO volume!"
104 return 1
105 fi
106}
107
108mount_ubi() {
109 pnormtd="$(findmtd pnor)"
110 pnor="${pnormtd#mtd}"
111 ubidev="/dev/ubi${pnor}"
112 pnordev="/dev/mtd${pnor}"
113
114 if [[ "${name}" == "pnor-patch" ]]; then
115 if [[ "$(fw_printenv fieldmode 2>/dev/null)" == "fieldmode=true" ]]; then
116 return 0
117 fi
118 if [[ ! "$(hexdump -C -n 3 ${pnordev})" =~ "UBI" ]]; then
119 return 0
120 fi
121 mountdir="/usr/local/share/pnor"
122 else
123 mountdir="/media/${name}"
124 fi
125
126 if [[ "${name}" == "pnor-prsv" ]]; then
127 size="2MiB"
128 else
129 size="16MiB"
130 fi
131
132 if [ ! -d "${mountdir}" ]; then
133 mkdir -p "${mountdir}"
134 fi
135
136 vol="$(findubi "${name}")"
137 if [ -z "${vol}" ]; then
138 ubimkvol "${ubidev}" -N "${name}" -s "${size}"
139 fi
140
141 if ! is_mounted "${name}"; then
142 mountdev="ubi${pnor}:${name}"
143 mount -t ubifs "${mountdev}" "${mountdir}"
144 fi
145}
146
147umount_ubi() {
148 pnormtd="$(findmtd pnor)"
149 pnor="${pnormtd#mtd}"
150 ubidev="/dev/ubi${pnor}"
151 mountdir="/media/${name}"
152
153 if is_mounted "${name}"; then
154 umount "${mountdir}"
155 fi
156
157 vol="$(findubi "${name}")"
158 id="${vol##*_}"
159 if [ -n "${id}" ]; then
160 ubirmvol "${ubidev}" -n "${id}"
161 fi
162
163 if [ -d "${mountdir}" ]; then
164 rm -r "${mountdir}"
165 fi
166}
167
168remount_ubi() {
169 pnormtd="$(findmtd pnor)"
170 pnor="${pnormtd#mtd}"
171 pnordev="/dev/mtd${pnor}"
172
173 # Re-Attach the pnor mtd device to ubi
174 if [[ $(hexdump -C -n 3 ${pnordev}) =~ "UBI" ]]; then
175 ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}"
176 else
177 # Device not formatted as ubi.
178 return 0
179 fi
180
181 # Get information on all ubi volumes
182 ubinfo=$(ubinfo -d ${pnor})
183 presentVolumes=${ubinfo##*:}
184 IFS=', ' read -r -a array <<< "$presentVolumes"
185 for element in ${array[@]};
186 do
187 elementProperties=$(ubinfo -d $pnor -n $element)
188 # Get ubi volume name by getting rid of additional properties
189 name=${elementProperties#*Name:}
190 name="${name%Character*}"
191 name="$(echo -e "${name}" | tr -d '[:space:]')"
192
193 if [[ ${name} == pnor-prsv ]] || [[ ${name} == pnor-rw* ]] || [[ ${name} == pnor-ro* ]]; then
194 mountdir="/media/${name}"
195 if [ ! -d "${mountdir}" ]; then
196 mkdir -p "${mountdir}"
197 fi
198
199 if [[ ${name} == pnor-ro* ]]
200 then
201 ubiblock --create /dev/ubi${pnor}_${element}
202 mount -t squashfs -o ro "/dev/ubiblock${pnor}_${element}" "${mountdir}"
203 else
204 mount -t ubifs "ubi${pnor}:${name}" "${mountdir}"
205 fi
206 fi
207 done
208}
209
210update_symlinks() {
211 PNOR_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/"
212 PNOR_RO_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/ro"
213 PNOR_RO_PREFIX="/media/pnor-ro-"
214 PNOR_RW_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/rw"
215 PNOR_RW_PREFIX="/media/pnor-rw-"
216 PNOR_PRSV_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/prsv"
217 PNOR_PRSV="/media/pnor-prsv"
218 PERSISTENCE_PATH="/var/lib/obmc/openpower-pnor-code-mgmt/"
219 PNOR_PATCH_LOCATION="/usr/local/share/pnor/"
220
221 # Get a list of all active PNOR versions
222 data="$(ls -d ${PNOR_RO_PREFIX}*)"
223 IFS=$'\n' array=(${data})
224
225 currentVersion=""
226 lowestPriority=255
227 for element in ${array[@]}; do
228 #Remove the PNOR_RO_PREFIX from the path to get version ID.
229 versionId="${element#${PNOR_RO_PREFIX}}"
230
231 # Get the priority of active versions from persistence files.
232 if [[ -f "${PERSISTENCE_PATH}${versionId}" ]]; then
233 data="$(grep -r "priority" ${PERSISTENCE_PATH}${versionId})"
234 priority="${data: -1}"
235 if [[ priority -le lowestPriority ]]; then
236 lowestPriority=${priority}
237 currentVersion=${versionId}
238 fi
239 fi
240 done
241
242 # Return if no active version found
243 if [ -z $currentVersion ]; then
244 return 0;
245 fi
246
247 if [ ! -d "${PNOR_ACTIVE_PATH}" ]; then
248 mkdir -p "${PNOR_ACTIVE_PATH}"
249 fi
250
251 # If the RW or RO active links doesn't point to the version with
252 # lowest priority, then remove the symlink and create new ones.
253 if [[ $(readlink -f "${PNOR_RO_ACTIVE_PATH}") != ${PNOR_RO_PREFIX}${currentVersion} ]]; then
254 rm -f ${PNOR_RO_ACTIVE_PATH}
255 rm -rf ${PNOR_PATCH_LOCATION}*
256 ln -sfv ${PNOR_RO_PREFIX}${currentVersion} ${PNOR_RO_ACTIVE_PATH}
257 fi
258
259 if [[ $(readlink -f "${PNOR_RW_ACTIVE_PATH}") != ${PNOR_RW_PREFIX}${currentVersion} ]]; then
260 rm -f ${PNOR_RW_ACTIVE_PATH}
261 ln -sfv ${PNOR_RW_PREFIX}${currentVersion} ${PNOR_RW_ACTIVE_PATH}
262 fi
263
264 if [[ ! -h ${PNOR_PRSV_ACTIVE_PATH} ]]; then
265 ln -sfv ${PNOR_PRSV} ${PNOR_PRSV_ACTIVE_PATH}
266 fi
267}
268
269ubi_cleanup() {
270 # When ubi_cleanup is run, it expects one or no active version.
271 activeVersion=$(busctl --list --no-pager tree \
272 org.open_power.Software.Host.Updater | \
273 grep /xyz/openbmc_project/software/ | tail -c 9)
274
275 if [[ -z "$activeVersion" ]]; then
276 vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | cut -c 14-)
277 vols=(${vols})
278 else
279 vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | \
280 grep -v "$activeVersion" | cut -c 14-)
281 vols=(${vols})
282 fi
283
284 for (( index=0; index<${#vols[@]}; index++ )); do
285 name=${vols[index]}
286 umount_ubi
287 done
288}
289
290clear_volatile() {
291 service=$(mapper get-service /org/open_power/control/volatile)
292 clearVolatileEnabled=$(busctl get-property $service /org/open_power/control/volatile xyz.openbmc_project.Object.Enable Enabled)
293 if [[ "$clearVolatileEnabled" != "b true" ]]; then
294 return 0
295 fi
296
297 PNOR_TOC_FILE="pnor.toc"
298 PNOR_RO_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/ro/"
299 PNOR_RW_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/rw/"
300 PNOR_PRSV_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/prsv/"
301
302 # toc partition string format:
303 # partition27=HB_VOLATILE,0x02ba9000,0x02bae000,00,ECC,VOLATILE,READWRITE
304 tocFilePath="${PNOR_RO_ACTIVE_PATH}${PNOR_TOC_FILE}"
305 volatiles=($(grep VOLATILE "${tocFilePath}" | grep -Eo '^partition([0-9]+)=([A-Za-z0-9_]+)'))
306 for (( index=0; index<${#volatiles[@]}; index++ )); do
307 volatileName="$(echo ${volatiles[${index}]} | awk -F '=' '{print $2}')"
308
309 rwVolatile="${PNOR_RW_ACTIVE_PATH}${volatileName}"
310 if [ -f "${rwVolatile}" ]; then
311 echo "Clear $rwVolatile"
312 rm "${rwVolatile}"
313 fi
314 prsvVolatile="${PNOR_PRSV_ACTIVE_PATH}${volatileName}"
315 if [ -f "${prsvVolatile}" ]; then
316 echo "Clear $prsvVolatile"
317 rm "${prsvVolatile}"
318 fi
319 done
320 # Always reset the sensor after clearing
321 busctl set-property $service /org/open_power/control/volatile xyz.openbmc_project.Object.Enable Enabled b false
322}
323
324case "$1" in
325 ubiattach)
326 attach_ubi
327 ;;
328 squashfsmount)
329 name="$2"
330 version="$3"
331 mount_squashfs
332 ;;
333 ubimount)
334 name="$2"
335 mount_ubi
336 ;;
337 ubiumount)
338 name="$2"
339 umount_ubi
340 ;;
341 ubiremount)
342 remount_ubi
343 ;;
344 updatesymlinks)
345 update_symlinks
346 ;;
347 ubicleanup)
348 ubi_cleanup
349 ;;
350 clearvolatile)
351 clear_volatile
352 ;;
353 *)
354 echo "Invalid argument"
355 exit 1
356 ;;
357esac
358rc=$?
359if [ ${rc} -ne 0 ]; then
360 echo "$0: error ${rc}"
361 exit ${rc}
362fi