blob: 4bb70918f00a99256d32760996eb896ef11311b8 [file] [log] [blame]
Adriana Kobylaka290eff2017-06-27 09:39:57 -05001#!/bin/sh
2
Adriana Kobylak54c9f792017-08-17 14:08:20 -05003# Get the root mtd device number (mtdX) from "/dev/ubiblockX_Y on /"
4findrootmtd() {
5 rootmatch=" on / "
6 m="$(mount | grep "${rootmatch}" | grep "ubiblock")"
7 m="${m##*ubiblock}"
8 m="${m%_*}"
9 if [ -z "${m}" ]; then
10 # default to bmc mtd (0)
11 m=0
12 fi
13 echo "mtd${m}"
14}
15
Adriana Kobylak582bdea2017-08-22 14:51:18 -050016findrootubi() {
17 rootmatch=" on / "
18 m="$(mount | grep "${rootmatch}")"
19 m="${m##*ubiblock}"
20 m="${m% on*}"
21 echo "ubi${m}"
22}
23
Adriana Kobylaka290eff2017-06-27 09:39:57 -050024# Get the mtd device number (mtdX)
25findmtd() {
26 m="$(grep -xl "$1" /sys/class/mtd/*/name)"
27 m="${m%/name}"
28 m="${m##*/}"
29 echo "${m}"
30}
31
Eddie Jamesa804bc42018-02-01 16:46:40 -060032# Get the mtd device number only (return X of mtdX)
33findmtdnum() {
34 m="$(findmtd "$1")"
35 m="${m##mtd}"
36 echo "${m}"
37}
38
Adriana Kobylaka290eff2017-06-27 09:39:57 -050039# Get the ubi device number (ubiX_Y)
40findubi() {
41 u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)"
42 u="${u%/name}"
43 u="${u##*/}"
44 echo "${u}"
45}
46
Adriana Kobylakac5ce002017-09-13 12:59:26 -050047# Get the ubi device number (ubiX_Y) on a specific mtd
Adriana Kobylak582bdea2017-08-22 14:51:18 -050048findubi_onmtd() {
Adriana Kobylakac5ce002017-09-13 12:59:26 -050049 u="$(grep -xl "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
50 u="${u%/name}"
51 u="${u##*/}"
52 echo "${u}"
53}
54
55# Get all ubi device names on a specific mtd that match requested string
56findubiname_onmtd() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -050057 u="$(grep -h "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
58 u="${u%/name}"
59 u="${u##*/}"
60 echo "${u}"
61}
62
Adriana Kobylakac5ce002017-09-13 12:59:26 -050063# Get the name from the requested ubiX_Y volume
64findname() {
65 n="$(cat /sys/class/ubi/$1/name)"
66 echo "${n}"
67}
68
Edward A. Jamesa1cb3232017-11-09 16:03:14 -060069# Set the u-boot env command that performs the factory reset if requested
70set_do_rwreset() {
71 if ! fw_printenv do_rwreset; then
72 fw_setenv do_rwreset "if test \"\${rwreset}\" = \"true\"; then ubi remove rwfs; ubi create rwfs 0x400000; fi"
73 fw_setenv obmc_bootcmd "ubi part obmc-ubi; run do_rwreset; ubi read \${loadaddr} \${kernelname}; bootm \${loadaddr}"
74 fi
75}
76
Adriana Kobylak582bdea2017-08-22 14:51:18 -050077# Make space on flash before creating new volumes. This can be enhanced
78# determine current flash usage. For now only keep a "keepmax" number of them
79ubi_remove_volumes()
80{
Adriana Kobylak582bdea2017-08-22 14:51:18 -050081 rootubi="$(findrootubi)"
Adriana Kobylakac5ce002017-09-13 12:59:26 -050082 rootname="$(findname "${rootubi}")"
83 rootversion="${rootname##*-}"
84 rootkernel="kernel-${rootversion}"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050085
86 # Just keep max number of volumes before updating, don't delete the version
87 # the BMC is booted from, and when a version is identified to be deleted,
88 # delete both the rofs and kernel volumes for that version.
Adriana Kobylakac5ce002017-09-13 12:59:26 -050089 rmnames="$(findubiname_onmtd "${name%-*}-" "${ro}")"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050090 rmnames=(${rmnames})
91 ubicount="${#rmnames[@]}"
92 while [ ${ubicount} -ge ${keepmax} ]; do
93 # Loop through existing volumes and skip currently active ones
94 for (( index=0; index<${#rmnames[@]}; index++ )); do
95 rmname="${rmnames[${index}]}"
96 rmversion="${rmname##*-}"
Adriana Kobylakac5ce002017-09-13 12:59:26 -050097 [ "${rmversion}" == "${version}" ] && continue
98 rmubi="$(findubi_onmtd "rofs-${rmversion}" "${ro}")"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050099 if [[ ( "${rmubi}" != "${rootubi}" ) &&
Adriana Kobylakac5ce002017-09-13 12:59:26 -0500100 ( "${rmname}" != "${rootkernel}" ) ]]; then
101 ubi_remove "rofs-${rmversion}" "${ro}"
102 ubi_remove "kernel-${rmversion}" "${ro}"
103 # Remove priority value
104 fw_setenv "${rmversion}"
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500105 break
106 fi
107 done
108 # Decrease count regardless to avoid an infinite loop
109 (( ubicount-- ))
110 done
111}
112
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500113ubi_rw() {
114 rwmtd="$(findmtd "${reqmtd}")"
115 rw="${rwmtd#mtd}"
116 ubidev="/dev/ubi${rw}"
117
118 # Create a ubi volume of size 4MB, that is the current size of the rwfs image
119 vol="$(findubi "${name}")"
120 if [ -z "${vol}" ]; then
121 ubimkvol "${ubidev}" -N "${name}" -s 4MiB
122 fi
123}
124
Adriana Kobylake9939492017-07-11 11:34:23 -0500125ubi_ro() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500126 keepmax=2 # Default 2 volumes per mtd
Adriana Kobylake9939492017-07-11 11:34:23 -0500127 romtd="$(findmtd "${reqmtd}")"
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500128 romtd2="$(findmtd "${reqmtd2}")"
129
130 if [ ! "${romtd}" == "${romtd2}" ]; then
131 # Request to use alternate mtd device, choose the non-root one
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500132 keepmax=1 # 1 volume on each of the requested mtds
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500133 rootmtd="$(findrootmtd)"
134 if [ "${rootmtd}" == "${romtd}" ]; then
135 romtd="${romtd2}"
136 fi
137 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500138 ro="${romtd#mtd}"
139 ubidev="/dev/ubi${ro}"
140
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500141 ubi_remove_volumes
142
Adriana Kobylake9939492017-07-11 11:34:23 -0500143 # Create a static ubi volume
144 # TODO Get the actual image size openbmc/openbmc#1840
145 vol="$(findubi "${name}")"
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500146 if [ ! -z "${vol}" ]; then
147 # Allow a duplicate kernel volume on the alt mtd
148 if [[ "${name}" =~ "kernel" ]]; then
Adriana Kobylakac5ce002017-09-13 12:59:26 -0500149 vol="$(findubi_onmtd "${name}" "${ro}")"
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500150 fi
151 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500152 if [ -z "${vol}" ]; then
153 ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}" --type=static
154 vol="$(findubi "${name}")"
155 fi
156}
157
158# Squashfs images need a ubi block
159ubi_block() {
160 vol="$(findubi "${name}")"
161 ubidevid="${vol#ubi}"
162 block="/dev/ubiblock${ubidevid}"
163 if [ ! -e "$block" ]; then
164 ubiblock --create "/dev/ubi${ubidevid}"
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500165 if [ $? != 0 ]; then
166 echo "Unable to create ubiblock ${name}:${ubidevid}"
167 return 1
168 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500169 fi
170}
171
172ubi_updatevol() {
173 vol="$(findubi "${name}")"
174 ubidevid="${vol#ubi}"
175 img="/tmp/images/${version}/${imgfile}"
176 ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500177 if [ $? != 0 ]; then
178 echo "Unable to update volume ${name}!"
179 return 1
180 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500181}
182
Michael Tritza694eed2017-07-13 16:26:15 -0500183ubi_remove() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500184 rmname="$1"
Adriana Kobylakac5ce002017-09-13 12:59:26 -0500185 rmmtd="$2"
186 if [ ! -z "${rmmtd}" ]; then
187 vol="$(findubi_onmtd "${rmname}" "${rmmtd}")"
188 else
189 vol="$(findubi "${rmname}")"
190 fi
Michael Tritza694eed2017-07-13 16:26:15 -0500191
192 if [ ! -z "$vol" ]; then
193 vol="${vol%_*}"
194
Saqib Khanf8d2a662017-09-07 13:57:43 -0500195 if grep -q "$rmname" /proc/mounts; then
196 mountdir=$(grep "$rmname" /proc/mounts | cut -d " " -f 2)
Michael Tritza694eed2017-07-13 16:26:15 -0500197 umount "$mountdir"
198 rm -r "$mountdir"
199 fi
200
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500201 ubirmvol "/dev/${vol}" -N "$rmname"
Michael Tritza694eed2017-07-13 16:26:15 -0500202 fi
203}
204
Michael Tritz18781172017-09-21 00:41:15 -0500205ubi_cleanup() {
206 # When ubi_cleanup is run, it expects one or no active version.
207 activeVersion=$(busctl --list --no-pager tree \
208 xyz.openbmc_project.Software.BMC.Updater | \
209 grep /xyz/openbmc_project/software/ | tail -c 9)
210
211 if [[ -z "$activeVersion" ]]; then
212 vols=$(ubinfo -a | grep -e "kernel-" -e "rofs-" | cut -c 14-)
213 vols=(${vols})
214 else
215 vols=$(ubinfo -a | grep -e "kernel-" -e "rofs-" | \
216 grep -v "$activeVersion" | cut -c 14-)
217 vols=(${vols})
218 fi
219
220 for (( index=0; index<${#vols[@]}; index++ )); do
221 ubi_remove ${vols[index]}
222 done
223}
224
Saqib Khanbb93e642017-08-10 11:24:38 -0500225remount_ubi() {
Saqib Khand6d1c442017-09-06 23:24:40 -0500226 bmcmtd="$(findmtd "bmc")"
227 altbmcmtd="$(findmtd "alt-bmc")"
228 mtds="${bmcmtd: -1}","${altbmcmtd: -1}"
Saqib Khanbb93e642017-08-10 11:24:38 -0500229
230 IFS=',' read -r -a mtds <<< "$mtds"
231 mtds=($(echo "${mtds[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
232 for mtd in ${mtds[@]}; do
233 # Re-attach mtd device to ubi if not already done
234 ubiattach /dev/ubi_ctrl -m "${mtd}" -d "${mtd}" &> /dev/null
235 # Get information on all ubi volumes
236 ubinfo=$(ubinfo -d ${mtd})
237 presentVolumes=${ubinfo##*:}
238 IFS=', ' read -r -a array <<< "$presentVolumes"
239 for element in ${array[@]}; do
240 elementProperties=$(ubinfo -d $mtd -n $element)
241 # Get ubi volume name by getting rid of additional properties
242 name=${elementProperties#*Name:}
243 name="${name%Character*}"
244 name="$(echo -e "${name}" | tr -d '[:space:]')"
245
Adriana Kobylak2c7c8d12017-08-21 11:00:56 -0500246 if [[ ${name} == rofs-* ]]; then
Saqib Khanbb93e642017-08-10 11:24:38 -0500247 mountdir="/media/${name}"
Saqib Khand793f2d2017-09-13 14:05:31 -0500248
249 if [ ! -d ${mountdir} ]; then
250 mkdir -p "${mountdir}"
251 ubiblock --create /dev/ubi${mtd}_${element} &> /dev/null
252 mount -t squashfs -o ro "/dev/ubiblock${mtd}_${element}" "${mountdir}"
253 fi
Saqib Khanbb93e642017-08-10 11:24:38 -0500254 fi
255 done
256 done
Edward A. Jamesa1cb3232017-11-09 16:03:14 -0600257
258 set_do_rwreset
Saqib Khanbb93e642017-08-10 11:24:38 -0500259}
260
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500261# Read the current env variable and set it on the alternate boot env
262copy_env_var_to_alt() {
263 varName=$1
264 value="$(fw_printenv -n "${varName}")"
265 fw_setenv -c /etc/alt_fw_env.config "${varName}" "${value}"
266}
267
Eddie Jamesa804bc42018-02-01 16:46:40 -0600268# When the alternate bmc chip boots, u-boot thinks its the primary mtdX.
269# Therefore need to swap the chip numbers when copying the ubiblock and root to
270# alternate bmc u-boot environment.
271copy_ubiblock_to_alt() {
272 value="$(fw_printenv -n ubiblock)"
273 bmcNum="$(findmtdnum "bmc")"
274 altNum="$(findmtdnum "alt-bmc")"
275 replaceAlt="${value/${altNum},/${bmcNum},}"
276
277 if [[ "${value}" == "${replaceAlt}" ]]; then
278 replaceBmc="${value/${bmcNum},/${altNum},}"
279 value=${replaceBmc}
280 else
281 value=${replaceAlt}
282 fi
283
284 fw_setenv -c /etc/alt_fw_env.config ubiblock "${value}"
285}
286
287copy_root_to_alt() {
288 value="$(fw_printenv -n root)"
289 bmcNum="$(findmtdnum "bmc")"
290 altNum="$(findmtdnum "alt-bmc")"
291 replaceAlt="${value/${altNum}_/${bmcNum}_}"
292
293 if [[ "${value}" == "${replaceAlt}" ]]; then
294 replaceBmc="${value/${bmcNum}_/${altNum}_}"
295 value=${replaceBmc}
296 else
297 value=${replaceAlt}
298 fi
299
300 fw_setenv -c /etc/alt_fw_env.config root "${value}"
301}
302
Michael Tritza694eed2017-07-13 16:26:15 -0500303ubi_setenv() {
Michael Tritz3e0b0672017-12-15 15:35:14 -0600304 # The U-Boot environment maintains two banks of environment variables.
305 # The banks need to be consistent with each other to ensure that these
306 # variables can reliably be read from file. In order to guarantee that the
307 # banks are both correct, we need to run fw_setenv twice.
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500308 variable=$1
Michael Tritz8863f702017-08-25 15:47:07 -0500309 if [[ "$variable" == *"="* ]]; then
310 varName="${variable%=*}"
311 value="${variable##*=}"
312 fw_setenv "$varName" "$value"
Michael Tritz3e0b0672017-12-15 15:35:14 -0600313 fw_setenv "$varName" "$value"
Michael Tritz8863f702017-08-25 15:47:07 -0500314 else
315 fw_setenv "$variable"
Michael Tritz3e0b0672017-12-15 15:35:14 -0600316 fw_setenv "$variable"
Michael Tritz8863f702017-08-25 15:47:07 -0500317 fi
Michael Tritza694eed2017-07-13 16:26:15 -0500318}
319
Adriana Kobylak1fa612c2017-08-17 21:56:14 -0500320mtd_write() {
321 flashmtd="$(findmtd "${reqmtd}")"
322 img="/tmp/images/${version}/${imgfile}"
323 flashcp -v ${img} /dev/${flashmtd}
324}
325
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500326backup_env_vars() {
327 copy_env_var_to_alt kernelname
Eddie Jamesa804bc42018-02-01 16:46:40 -0600328 copy_ubiblock_to_alt
329 copy_root_to_alt
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500330}
331
332update_env_vars() {
333 vol="$(findubi rofs-"${version}")"
334 if [ -z "${vol}" ]; then
335 return 1
336 fi
337 ubidevid="${vol#ubi}"
338 block="/dev/ubiblock${ubidevid}"
339 if [ ! -e "${block}" ]; then
340 return 1
341 fi
342 ubi_setenv "kernelname=kernel-${version}"
343 ubi_setenv "ubiblock=$(echo "${ubidevid}" | sed 's/_/,/')"
344 ubi_setenv "root=${block}"
345}
346
Saqib Khandfc9b0c2017-09-08 10:10:08 -0500347#TODO: Replace the implementation with systemd-inhibitors lock
348# once systemd/systemd#949 is resolved
349rebootguardenable() {
350 dir="/run/systemd/system/"
351 file="reboot-guard.conf"
352 units=("reboot" "poweroff" "halt")
353
354 for unit in "${units[@]}"; do
355 mkdir -p ${dir}${unit}.target.d
356 echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}${unit}.target.d/${file}
357 done
358}
359
360#TODO: Replace the implementation with systemd-inhibitors lock
361# once systemd/systemd#949 is resolved
362rebootguarddisable() {
363 dir="/run/systemd/system/"
364 file="reboot-guard.conf"
365 units=("reboot" "poweroff" "halt")
366
367 for unit in "${units[@]}"; do
368 rm -rf ${dir}${unit}.target.d/${file}
369 done
370}
371
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500372# Create a copy in the alt mtd
373create_vol_in_alt() {
374 alt="alt-bmc"
375 altmtd="$(findmtd "${alt}")"
376 if [ ! -z "${altmtd}" ]; then
377 reqmtd="${alt}"
378 reqmtd2="${alt}"
379 ubi_ro
380 ubi_updatevol
381 fi
382}
383
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500384case "$1" in
Adriana Kobylak1fa612c2017-08-17 21:56:14 -0500385 mtduboot)
386 reqmtd="$2"
387 version="$3"
388 imgfile="image-u-boot"
389 mtd_write
390 ;;
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500391 ubirw)
392 reqmtd="$2"
393 name="$3"
394 ubi_rw
395 ;;
Adriana Kobylake9939492017-07-11 11:34:23 -0500396 ubiro)
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500397 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
398 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
Adriana Kobylake9939492017-07-11 11:34:23 -0500399 name="$3"
400 version="$4"
401 imgfile="image-rofs"
402 imgsize="16MiB"
403 ubi_ro
Adriana Kobylake9939492017-07-11 11:34:23 -0500404 ubi_updatevol
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500405 ubi_block
Adriana Kobylake9939492017-07-11 11:34:23 -0500406 ;;
407 ubikernel)
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500408 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
409 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
Adriana Kobylake9939492017-07-11 11:34:23 -0500410 name="$3"
411 version="$4"
412 imgfile="image-kernel"
413 imgsize="4MiB"
414 ubi_ro
415 ubi_updatevol
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500416 create_vol_in_alt
Adriana Kobylake9939492017-07-11 11:34:23 -0500417 ;;
Michael Tritza694eed2017-07-13 16:26:15 -0500418 ubiremove)
419 name="$2"
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500420 ubi_remove "${name}"
Michael Tritza694eed2017-07-13 16:26:15 -0500421 ;;
Michael Tritz18781172017-09-21 00:41:15 -0500422 ubicleanup)
423 ubi_cleanup
424 ;;
Michael Tritza694eed2017-07-13 16:26:15 -0500425 ubisetenv)
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500426 ubi_setenv "$2"
Michael Tritza694eed2017-07-13 16:26:15 -0500427 ;;
Saqib Khanbb93e642017-08-10 11:24:38 -0500428 ubiremount)
429 remount_ubi
430 ;;
Saqib Khan7e4a3f22017-09-12 09:23:28 -0500431 createenvbackup)
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500432 backup_env_vars
433 ;;
Saqib Khan7e4a3f22017-09-12 09:23:28 -0500434 updateubootvars)
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500435 version="$2"
436 update_env_vars
437 ;;
Saqib Khandfc9b0c2017-09-08 10:10:08 -0500438 rebootguardenable)
439 rebootguardenable
440 ;;
441 rebootguarddisable)
442 rebootguarddisable
443 ;;
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500444 *)
445 echo "Invalid argument"
446 exit 1
447 ;;
448esac
449rc=$?
450if [ ${rc} -ne 0 ]; then
451 echo "$0: error ${rc}"
452 exit ${rc}
453fi