blob: da62b10da753af31b895025e3027e720b3255adf [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
32# Get the ubi device number (ubiX_Y)
33findubi() {
34 u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)"
35 u="${u%/name}"
36 u="${u##*/}"
37 echo "${u}"
38}
39
Adriana Kobylakac5ce002017-09-13 12:59:26 -050040# Get the ubi device number (ubiX_Y) on a specific mtd
Adriana Kobylak582bdea2017-08-22 14:51:18 -050041findubi_onmtd() {
Adriana Kobylakac5ce002017-09-13 12:59:26 -050042 u="$(grep -xl "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
43 u="${u%/name}"
44 u="${u##*/}"
45 echo "${u}"
46}
47
48# Get all ubi device names on a specific mtd that match requested string
49findubiname_onmtd() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -050050 u="$(grep -h "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
51 u="${u%/name}"
52 u="${u##*/}"
53 echo "${u}"
54}
55
Adriana Kobylakac5ce002017-09-13 12:59:26 -050056# Get the name from the requested ubiX_Y volume
57findname() {
58 n="$(cat /sys/class/ubi/$1/name)"
59 echo "${n}"
60}
61
Edward A. Jamesa1cb3232017-11-09 16:03:14 -060062# Set the u-boot env command that performs the factory reset if requested
63set_do_rwreset() {
64 if ! fw_printenv do_rwreset; then
65 fw_setenv do_rwreset "if test \"\${rwreset}\" = \"true\"; then ubi remove rwfs; ubi create rwfs 0x400000; fi"
66 fw_setenv obmc_bootcmd "ubi part obmc-ubi; run do_rwreset; ubi read \${loadaddr} \${kernelname}; bootm \${loadaddr}"
67 fi
68}
69
Adriana Kobylak582bdea2017-08-22 14:51:18 -050070# Make space on flash before creating new volumes. This can be enhanced
71# determine current flash usage. For now only keep a "keepmax" number of them
72ubi_remove_volumes()
73{
Adriana Kobylak582bdea2017-08-22 14:51:18 -050074 rootubi="$(findrootubi)"
Adriana Kobylakac5ce002017-09-13 12:59:26 -050075 rootname="$(findname "${rootubi}")"
76 rootversion="${rootname##*-}"
77 rootkernel="kernel-${rootversion}"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050078
79 # Just keep max number of volumes before updating, don't delete the version
80 # the BMC is booted from, and when a version is identified to be deleted,
81 # delete both the rofs and kernel volumes for that version.
Adriana Kobylakac5ce002017-09-13 12:59:26 -050082 rmnames="$(findubiname_onmtd "${name%-*}-" "${ro}")"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050083 rmnames=(${rmnames})
84 ubicount="${#rmnames[@]}"
85 while [ ${ubicount} -ge ${keepmax} ]; do
86 # Loop through existing volumes and skip currently active ones
87 for (( index=0; index<${#rmnames[@]}; index++ )); do
88 rmname="${rmnames[${index}]}"
89 rmversion="${rmname##*-}"
Adriana Kobylakac5ce002017-09-13 12:59:26 -050090 [ "${rmversion}" == "${version}" ] && continue
91 rmubi="$(findubi_onmtd "rofs-${rmversion}" "${ro}")"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050092 if [[ ( "${rmubi}" != "${rootubi}" ) &&
Adriana Kobylakac5ce002017-09-13 12:59:26 -050093 ( "${rmname}" != "${rootkernel}" ) ]]; then
94 ubi_remove "rofs-${rmversion}" "${ro}"
95 ubi_remove "kernel-${rmversion}" "${ro}"
96 # Remove priority value
97 fw_setenv "${rmversion}"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050098 break
99 fi
100 done
101 # Decrease count regardless to avoid an infinite loop
102 (( ubicount-- ))
103 done
104}
105
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500106ubi_rw() {
107 rwmtd="$(findmtd "${reqmtd}")"
108 rw="${rwmtd#mtd}"
109 ubidev="/dev/ubi${rw}"
110
111 # Create a ubi volume of size 4MB, that is the current size of the rwfs image
112 vol="$(findubi "${name}")"
113 if [ -z "${vol}" ]; then
114 ubimkvol "${ubidev}" -N "${name}" -s 4MiB
115 fi
116}
117
Adriana Kobylake9939492017-07-11 11:34:23 -0500118ubi_ro() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500119 keepmax=2 # Default 2 volumes per mtd
Adriana Kobylake9939492017-07-11 11:34:23 -0500120 romtd="$(findmtd "${reqmtd}")"
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500121 romtd2="$(findmtd "${reqmtd2}")"
122
123 if [ ! "${romtd}" == "${romtd2}" ]; then
124 # Request to use alternate mtd device, choose the non-root one
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500125 keepmax=1 # 1 volume on each of the requested mtds
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500126 rootmtd="$(findrootmtd)"
127 if [ "${rootmtd}" == "${romtd}" ]; then
128 romtd="${romtd2}"
129 fi
130 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500131 ro="${romtd#mtd}"
132 ubidev="/dev/ubi${ro}"
133
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500134 ubi_remove_volumes
135
Adriana Kobylake9939492017-07-11 11:34:23 -0500136 # Create a static ubi volume
137 # TODO Get the actual image size openbmc/openbmc#1840
138 vol="$(findubi "${name}")"
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500139 if [ ! -z "${vol}" ]; then
140 # Allow a duplicate kernel volume on the alt mtd
141 if [[ "${name}" =~ "kernel" ]]; then
Adriana Kobylakac5ce002017-09-13 12:59:26 -0500142 vol="$(findubi_onmtd "${name}" "${ro}")"
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500143 fi
144 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500145 if [ -z "${vol}" ]; then
146 ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}" --type=static
147 vol="$(findubi "${name}")"
148 fi
149}
150
151# Squashfs images need a ubi block
152ubi_block() {
153 vol="$(findubi "${name}")"
154 ubidevid="${vol#ubi}"
155 block="/dev/ubiblock${ubidevid}"
156 if [ ! -e "$block" ]; then
157 ubiblock --create "/dev/ubi${ubidevid}"
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500158 if [ $? != 0 ]; then
159 echo "Unable to create ubiblock ${name}:${ubidevid}"
160 return 1
161 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500162 fi
163}
164
165ubi_updatevol() {
166 vol="$(findubi "${name}")"
167 ubidevid="${vol#ubi}"
168 img="/tmp/images/${version}/${imgfile}"
169 ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500170 if [ $? != 0 ]; then
171 echo "Unable to update volume ${name}!"
172 return 1
173 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500174}
175
Michael Tritza694eed2017-07-13 16:26:15 -0500176ubi_remove() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500177 rmname="$1"
Adriana Kobylakac5ce002017-09-13 12:59:26 -0500178 rmmtd="$2"
179 if [ ! -z "${rmmtd}" ]; then
180 vol="$(findubi_onmtd "${rmname}" "${rmmtd}")"
181 else
182 vol="$(findubi "${rmname}")"
183 fi
Michael Tritza694eed2017-07-13 16:26:15 -0500184
185 if [ ! -z "$vol" ]; then
186 vol="${vol%_*}"
187
Saqib Khanf8d2a662017-09-07 13:57:43 -0500188 if grep -q "$rmname" /proc/mounts; then
189 mountdir=$(grep "$rmname" /proc/mounts | cut -d " " -f 2)
Michael Tritza694eed2017-07-13 16:26:15 -0500190 umount "$mountdir"
191 rm -r "$mountdir"
192 fi
193
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500194 ubirmvol "/dev/${vol}" -N "$rmname"
Michael Tritza694eed2017-07-13 16:26:15 -0500195 fi
196}
197
Michael Tritz18781172017-09-21 00:41:15 -0500198ubi_cleanup() {
199 # When ubi_cleanup is run, it expects one or no active version.
200 activeVersion=$(busctl --list --no-pager tree \
201 xyz.openbmc_project.Software.BMC.Updater | \
202 grep /xyz/openbmc_project/software/ | tail -c 9)
203
204 if [[ -z "$activeVersion" ]]; then
205 vols=$(ubinfo -a | grep -e "kernel-" -e "rofs-" | cut -c 14-)
206 vols=(${vols})
207 else
208 vols=$(ubinfo -a | grep -e "kernel-" -e "rofs-" | \
209 grep -v "$activeVersion" | cut -c 14-)
210 vols=(${vols})
211 fi
212
213 for (( index=0; index<${#vols[@]}; index++ )); do
214 ubi_remove ${vols[index]}
215 done
216}
217
Saqib Khanbb93e642017-08-10 11:24:38 -0500218remount_ubi() {
Saqib Khand6d1c442017-09-06 23:24:40 -0500219 bmcmtd="$(findmtd "bmc")"
220 altbmcmtd="$(findmtd "alt-bmc")"
221 mtds="${bmcmtd: -1}","${altbmcmtd: -1}"
Saqib Khanbb93e642017-08-10 11:24:38 -0500222
223 IFS=',' read -r -a mtds <<< "$mtds"
224 mtds=($(echo "${mtds[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
225 for mtd in ${mtds[@]}; do
226 # Re-attach mtd device to ubi if not already done
227 ubiattach /dev/ubi_ctrl -m "${mtd}" -d "${mtd}" &> /dev/null
228 # Get information on all ubi volumes
229 ubinfo=$(ubinfo -d ${mtd})
230 presentVolumes=${ubinfo##*:}
231 IFS=', ' read -r -a array <<< "$presentVolumes"
232 for element in ${array[@]}; do
233 elementProperties=$(ubinfo -d $mtd -n $element)
234 # Get ubi volume name by getting rid of additional properties
235 name=${elementProperties#*Name:}
236 name="${name%Character*}"
237 name="$(echo -e "${name}" | tr -d '[:space:]')"
238
Adriana Kobylak2c7c8d12017-08-21 11:00:56 -0500239 if [[ ${name} == rofs-* ]]; then
Saqib Khanbb93e642017-08-10 11:24:38 -0500240 mountdir="/media/${name}"
Saqib Khand793f2d2017-09-13 14:05:31 -0500241
242 if [ ! -d ${mountdir} ]; then
243 mkdir -p "${mountdir}"
244 ubiblock --create /dev/ubi${mtd}_${element} &> /dev/null
245 mount -t squashfs -o ro "/dev/ubiblock${mtd}_${element}" "${mountdir}"
246 fi
Saqib Khanbb93e642017-08-10 11:24:38 -0500247 fi
248 done
249 done
Edward A. Jamesa1cb3232017-11-09 16:03:14 -0600250
251 set_do_rwreset
Saqib Khanbb93e642017-08-10 11:24:38 -0500252}
253
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500254# Read the current env variable and set it on the alternate boot env
255copy_env_var_to_alt() {
256 varName=$1
257 value="$(fw_printenv -n "${varName}")"
258 fw_setenv -c /etc/alt_fw_env.config "${varName}" "${value}"
259}
260
Michael Tritza694eed2017-07-13 16:26:15 -0500261ubi_setenv() {
Michael Tritz3e0b0672017-12-15 15:35:14 -0600262 # The U-Boot environment maintains two banks of environment variables.
263 # The banks need to be consistent with each other to ensure that these
264 # variables can reliably be read from file. In order to guarantee that the
265 # banks are both correct, we need to run fw_setenv twice.
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500266 variable=$1
Michael Tritz8863f702017-08-25 15:47:07 -0500267 if [[ "$variable" == *"="* ]]; then
268 varName="${variable%=*}"
269 value="${variable##*=}"
270 fw_setenv "$varName" "$value"
Michael Tritz3e0b0672017-12-15 15:35:14 -0600271 fw_setenv "$varName" "$value"
Michael Tritz8863f702017-08-25 15:47:07 -0500272 else
273 fw_setenv "$variable"
Michael Tritz3e0b0672017-12-15 15:35:14 -0600274 fw_setenv "$variable"
Michael Tritz8863f702017-08-25 15:47:07 -0500275 fi
Michael Tritza694eed2017-07-13 16:26:15 -0500276}
277
Adriana Kobylak1fa612c2017-08-17 21:56:14 -0500278mtd_write() {
279 flashmtd="$(findmtd "${reqmtd}")"
280 img="/tmp/images/${version}/${imgfile}"
281 flashcp -v ${img} /dev/${flashmtd}
282}
283
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500284backup_env_vars() {
285 copy_env_var_to_alt kernelname
286 copy_env_var_to_alt ubiblock
287 copy_env_var_to_alt root
288}
289
290update_env_vars() {
291 vol="$(findubi rofs-"${version}")"
292 if [ -z "${vol}" ]; then
293 return 1
294 fi
295 ubidevid="${vol#ubi}"
296 block="/dev/ubiblock${ubidevid}"
297 if [ ! -e "${block}" ]; then
298 return 1
299 fi
300 ubi_setenv "kernelname=kernel-${version}"
301 ubi_setenv "ubiblock=$(echo "${ubidevid}" | sed 's/_/,/')"
302 ubi_setenv "root=${block}"
303}
304
Saqib Khandfc9b0c2017-09-08 10:10:08 -0500305#TODO: Replace the implementation with systemd-inhibitors lock
306# once systemd/systemd#949 is resolved
307rebootguardenable() {
308 dir="/run/systemd/system/"
309 file="reboot-guard.conf"
310 units=("reboot" "poweroff" "halt")
311
312 for unit in "${units[@]}"; do
313 mkdir -p ${dir}${unit}.target.d
314 echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}${unit}.target.d/${file}
315 done
316}
317
318#TODO: Replace the implementation with systemd-inhibitors lock
319# once systemd/systemd#949 is resolved
320rebootguarddisable() {
321 dir="/run/systemd/system/"
322 file="reboot-guard.conf"
323 units=("reboot" "poweroff" "halt")
324
325 for unit in "${units[@]}"; do
326 rm -rf ${dir}${unit}.target.d/${file}
327 done
328}
329
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500330# Create a copy in the alt mtd
331create_vol_in_alt() {
332 alt="alt-bmc"
333 altmtd="$(findmtd "${alt}")"
334 if [ ! -z "${altmtd}" ]; then
335 reqmtd="${alt}"
336 reqmtd2="${alt}"
337 ubi_ro
338 ubi_updatevol
339 fi
340}
341
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500342case "$1" in
Adriana Kobylak1fa612c2017-08-17 21:56:14 -0500343 mtduboot)
344 reqmtd="$2"
345 version="$3"
346 imgfile="image-u-boot"
347 mtd_write
348 ;;
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500349 ubirw)
350 reqmtd="$2"
351 name="$3"
352 ubi_rw
353 ;;
Adriana Kobylake9939492017-07-11 11:34:23 -0500354 ubiro)
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500355 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
356 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
Adriana Kobylake9939492017-07-11 11:34:23 -0500357 name="$3"
358 version="$4"
359 imgfile="image-rofs"
360 imgsize="16MiB"
361 ubi_ro
Adriana Kobylake9939492017-07-11 11:34:23 -0500362 ubi_updatevol
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500363 ubi_block
Adriana Kobylake9939492017-07-11 11:34:23 -0500364 ;;
365 ubikernel)
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500366 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
367 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
Adriana Kobylake9939492017-07-11 11:34:23 -0500368 name="$3"
369 version="$4"
370 imgfile="image-kernel"
371 imgsize="4MiB"
372 ubi_ro
373 ubi_updatevol
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500374 create_vol_in_alt
Adriana Kobylake9939492017-07-11 11:34:23 -0500375 ;;
Michael Tritza694eed2017-07-13 16:26:15 -0500376 ubiremove)
377 name="$2"
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500378 ubi_remove "${name}"
Michael Tritza694eed2017-07-13 16:26:15 -0500379 ;;
Michael Tritz18781172017-09-21 00:41:15 -0500380 ubicleanup)
381 ubi_cleanup
382 ;;
Michael Tritza694eed2017-07-13 16:26:15 -0500383 ubisetenv)
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500384 ubi_setenv "$2"
Michael Tritza694eed2017-07-13 16:26:15 -0500385 ;;
Saqib Khanbb93e642017-08-10 11:24:38 -0500386 ubiremount)
387 remount_ubi
388 ;;
Saqib Khan7e4a3f22017-09-12 09:23:28 -0500389 createenvbackup)
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500390 backup_env_vars
391 ;;
Saqib Khan7e4a3f22017-09-12 09:23:28 -0500392 updateubootvars)
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500393 version="$2"
394 update_env_vars
395 ;;
Saqib Khandfc9b0c2017-09-08 10:10:08 -0500396 rebootguardenable)
397 rebootguardenable
398 ;;
399 rebootguarddisable)
400 rebootguarddisable
401 ;;
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500402 *)
403 echo "Invalid argument"
404 exit 1
405 ;;
406esac
407rc=$?
408if [ ${rc} -ne 0 ]; then
409 echo "$0: error ${rc}"
410 exit ${rc}
411fi