blob: 1a206604b5d437698da04281a2d60ff058a82503 [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
Adriana Kobylak582bdea2017-08-22 14:51:18 -050062# Make space on flash before creating new volumes. This can be enhanced
63# determine current flash usage. For now only keep a "keepmax" number of them
64ubi_remove_volumes()
65{
Adriana Kobylak582bdea2017-08-22 14:51:18 -050066 rootubi="$(findrootubi)"
Adriana Kobylakac5ce002017-09-13 12:59:26 -050067 rootname="$(findname "${rootubi}")"
68 rootversion="${rootname##*-}"
69 rootkernel="kernel-${rootversion}"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050070
71 # Just keep max number of volumes before updating, don't delete the version
72 # the BMC is booted from, and when a version is identified to be deleted,
73 # delete both the rofs and kernel volumes for that version.
Adriana Kobylakac5ce002017-09-13 12:59:26 -050074 rmnames="$(findubiname_onmtd "${name%-*}-" "${ro}")"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050075 rmnames=(${rmnames})
76 ubicount="${#rmnames[@]}"
77 while [ ${ubicount} -ge ${keepmax} ]; do
78 # Loop through existing volumes and skip currently active ones
79 for (( index=0; index<${#rmnames[@]}; index++ )); do
80 rmname="${rmnames[${index}]}"
81 rmversion="${rmname##*-}"
Adriana Kobylakac5ce002017-09-13 12:59:26 -050082 [ "${rmversion}" == "${version}" ] && continue
83 rmubi="$(findubi_onmtd "rofs-${rmversion}" "${ro}")"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050084 if [[ ( "${rmubi}" != "${rootubi}" ) &&
Adriana Kobylakac5ce002017-09-13 12:59:26 -050085 ( "${rmname}" != "${rootkernel}" ) ]]; then
86 ubi_remove "rofs-${rmversion}" "${ro}"
87 ubi_remove "kernel-${rmversion}" "${ro}"
88 # Remove priority value
89 fw_setenv "${rmversion}"
Adriana Kobylak582bdea2017-08-22 14:51:18 -050090 break
91 fi
92 done
93 # Decrease count regardless to avoid an infinite loop
94 (( ubicount-- ))
95 done
96}
97
Adriana Kobylaka290eff2017-06-27 09:39:57 -050098ubi_rw() {
99 rwmtd="$(findmtd "${reqmtd}")"
100 rw="${rwmtd#mtd}"
101 ubidev="/dev/ubi${rw}"
102
103 # Create a ubi volume of size 4MB, that is the current size of the rwfs image
104 vol="$(findubi "${name}")"
105 if [ -z "${vol}" ]; then
106 ubimkvol "${ubidev}" -N "${name}" -s 4MiB
107 fi
108}
109
Adriana Kobylake9939492017-07-11 11:34:23 -0500110ubi_ro() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500111 keepmax=2 # Default 2 volumes per mtd
Adriana Kobylake9939492017-07-11 11:34:23 -0500112 romtd="$(findmtd "${reqmtd}")"
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500113 romtd2="$(findmtd "${reqmtd2}")"
114
115 if [ ! "${romtd}" == "${romtd2}" ]; then
116 # Request to use alternate mtd device, choose the non-root one
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500117 keepmax=1 # 1 volume on each of the requested mtds
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500118 rootmtd="$(findrootmtd)"
119 if [ "${rootmtd}" == "${romtd}" ]; then
120 romtd="${romtd2}"
121 fi
122 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500123 ro="${romtd#mtd}"
124 ubidev="/dev/ubi${ro}"
125
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500126 ubi_remove_volumes
127
Adriana Kobylake9939492017-07-11 11:34:23 -0500128 # Create a static ubi volume
129 # TODO Get the actual image size openbmc/openbmc#1840
130 vol="$(findubi "${name}")"
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500131 if [ ! -z "${vol}" ]; then
132 # Allow a duplicate kernel volume on the alt mtd
133 if [[ "${name}" =~ "kernel" ]]; then
Adriana Kobylakac5ce002017-09-13 12:59:26 -0500134 vol="$(findubi_onmtd "${name}" "${ro}")"
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500135 fi
136 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500137 if [ -z "${vol}" ]; then
138 ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}" --type=static
139 vol="$(findubi "${name}")"
140 fi
141}
142
143# Squashfs images need a ubi block
144ubi_block() {
145 vol="$(findubi "${name}")"
146 ubidevid="${vol#ubi}"
147 block="/dev/ubiblock${ubidevid}"
148 if [ ! -e "$block" ]; then
149 ubiblock --create "/dev/ubi${ubidevid}"
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500150 if [ $? != 0 ]; then
151 echo "Unable to create ubiblock ${name}:${ubidevid}"
152 return 1
153 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500154 fi
155}
156
157ubi_updatevol() {
158 vol="$(findubi "${name}")"
159 ubidevid="${vol#ubi}"
160 img="/tmp/images/${version}/${imgfile}"
161 ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500162 if [ $? != 0 ]; then
163 echo "Unable to update volume ${name}!"
164 return 1
165 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500166}
167
Michael Tritza694eed2017-07-13 16:26:15 -0500168ubi_remove() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500169 rmname="$1"
Adriana Kobylakac5ce002017-09-13 12:59:26 -0500170 rmmtd="$2"
171 if [ ! -z "${rmmtd}" ]; then
172 vol="$(findubi_onmtd "${rmname}" "${rmmtd}")"
173 else
174 vol="$(findubi "${rmname}")"
175 fi
Michael Tritza694eed2017-07-13 16:26:15 -0500176
177 if [ ! -z "$vol" ]; then
178 vol="${vol%_*}"
179
Saqib Khanf8d2a662017-09-07 13:57:43 -0500180 if grep -q "$rmname" /proc/mounts; then
181 mountdir=$(grep "$rmname" /proc/mounts | cut -d " " -f 2)
Michael Tritza694eed2017-07-13 16:26:15 -0500182 umount "$mountdir"
183 rm -r "$mountdir"
184 fi
185
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500186 ubirmvol "/dev/${vol}" -N "$rmname"
Michael Tritza694eed2017-07-13 16:26:15 -0500187 fi
188}
189
Michael Tritz18781172017-09-21 00:41:15 -0500190ubi_cleanup() {
191 # When ubi_cleanup is run, it expects one or no active version.
192 activeVersion=$(busctl --list --no-pager tree \
193 xyz.openbmc_project.Software.BMC.Updater | \
194 grep /xyz/openbmc_project/software/ | tail -c 9)
195
196 if [[ -z "$activeVersion" ]]; then
197 vols=$(ubinfo -a | grep -e "kernel-" -e "rofs-" | cut -c 14-)
198 vols=(${vols})
199 else
200 vols=$(ubinfo -a | grep -e "kernel-" -e "rofs-" | \
201 grep -v "$activeVersion" | cut -c 14-)
202 vols=(${vols})
203 fi
204
205 for (( index=0; index<${#vols[@]}; index++ )); do
206 ubi_remove ${vols[index]}
207 done
208}
209
Saqib Khanbb93e642017-08-10 11:24:38 -0500210remount_ubi() {
Saqib Khand6d1c442017-09-06 23:24:40 -0500211 bmcmtd="$(findmtd "bmc")"
212 altbmcmtd="$(findmtd "alt-bmc")"
213 mtds="${bmcmtd: -1}","${altbmcmtd: -1}"
Saqib Khanbb93e642017-08-10 11:24:38 -0500214
215 IFS=',' read -r -a mtds <<< "$mtds"
216 mtds=($(echo "${mtds[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
217 for mtd in ${mtds[@]}; do
218 # Re-attach mtd device to ubi if not already done
219 ubiattach /dev/ubi_ctrl -m "${mtd}" -d "${mtd}" &> /dev/null
220 # Get information on all ubi volumes
221 ubinfo=$(ubinfo -d ${mtd})
222 presentVolumes=${ubinfo##*:}
223 IFS=', ' read -r -a array <<< "$presentVolumes"
224 for element in ${array[@]}; do
225 elementProperties=$(ubinfo -d $mtd -n $element)
226 # Get ubi volume name by getting rid of additional properties
227 name=${elementProperties#*Name:}
228 name="${name%Character*}"
229 name="$(echo -e "${name}" | tr -d '[:space:]')"
230
Adriana Kobylak2c7c8d12017-08-21 11:00:56 -0500231 if [[ ${name} == rofs-* ]]; then
Saqib Khanbb93e642017-08-10 11:24:38 -0500232 mountdir="/media/${name}"
Saqib Khand793f2d2017-09-13 14:05:31 -0500233
234 if [ ! -d ${mountdir} ]; then
235 mkdir -p "${mountdir}"
236 ubiblock --create /dev/ubi${mtd}_${element} &> /dev/null
237 mount -t squashfs -o ro "/dev/ubiblock${mtd}_${element}" "${mountdir}"
238 fi
Saqib Khanbb93e642017-08-10 11:24:38 -0500239 fi
240 done
241 done
242}
243
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500244# Read the current env variable and set it on the alternate boot env
245copy_env_var_to_alt() {
246 varName=$1
247 value="$(fw_printenv -n "${varName}")"
248 fw_setenv -c /etc/alt_fw_env.config "${varName}" "${value}"
249}
250
Michael Tritza694eed2017-07-13 16:26:15 -0500251ubi_setenv() {
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500252 variable=$1
Michael Tritz8863f702017-08-25 15:47:07 -0500253 if [[ "$variable" == *"="* ]]; then
254 varName="${variable%=*}"
255 value="${variable##*=}"
256 fw_setenv "$varName" "$value"
257 else
258 fw_setenv "$variable"
259 fi
Michael Tritza694eed2017-07-13 16:26:15 -0500260}
261
Adriana Kobylak1fa612c2017-08-17 21:56:14 -0500262mtd_write() {
263 flashmtd="$(findmtd "${reqmtd}")"
264 img="/tmp/images/${version}/${imgfile}"
265 flashcp -v ${img} /dev/${flashmtd}
266}
267
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500268backup_env_vars() {
269 copy_env_var_to_alt kernelname
270 copy_env_var_to_alt ubiblock
271 copy_env_var_to_alt root
272}
273
274update_env_vars() {
275 vol="$(findubi rofs-"${version}")"
276 if [ -z "${vol}" ]; then
277 return 1
278 fi
279 ubidevid="${vol#ubi}"
280 block="/dev/ubiblock${ubidevid}"
281 if [ ! -e "${block}" ]; then
282 return 1
283 fi
284 ubi_setenv "kernelname=kernel-${version}"
285 ubi_setenv "ubiblock=$(echo "${ubidevid}" | sed 's/_/,/')"
286 ubi_setenv "root=${block}"
287}
288
Saqib Khandfc9b0c2017-09-08 10:10:08 -0500289#TODO: Replace the implementation with systemd-inhibitors lock
290# once systemd/systemd#949 is resolved
291rebootguardenable() {
292 dir="/run/systemd/system/"
293 file="reboot-guard.conf"
294 units=("reboot" "poweroff" "halt")
295
296 for unit in "${units[@]}"; do
297 mkdir -p ${dir}${unit}.target.d
298 echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}${unit}.target.d/${file}
299 done
300}
301
302#TODO: Replace the implementation with systemd-inhibitors lock
303# once systemd/systemd#949 is resolved
304rebootguarddisable() {
305 dir="/run/systemd/system/"
306 file="reboot-guard.conf"
307 units=("reboot" "poweroff" "halt")
308
309 for unit in "${units[@]}"; do
310 rm -rf ${dir}${unit}.target.d/${file}
311 done
312}
313
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500314# Create a copy in the alt mtd
315create_vol_in_alt() {
316 alt="alt-bmc"
317 altmtd="$(findmtd "${alt}")"
318 if [ ! -z "${altmtd}" ]; then
319 reqmtd="${alt}"
320 reqmtd2="${alt}"
321 ubi_ro
322 ubi_updatevol
323 fi
324}
325
Michael Tritz648655a2017-09-21 00:41:15 -0500326factory_reset() {
327 # A lock file for printenv exists on /var, which isn't mounted when this
328 # function is called. We have to read the rwreset variable out of file.
329 ubootmtd="$(findmtd "u-boot-env")"
330 grep -q -x "rwreset=true" /dev/$ubootmtd
331 if [ "$?" = "0" ]; then
332 ubi_remove "rwfs"
333 reqmtd="bmc"
334 name="rwfs"
335 ubi_rw
336 fi
337}
338
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500339case "$1" in
Adriana Kobylak1fa612c2017-08-17 21:56:14 -0500340 mtduboot)
341 reqmtd="$2"
342 version="$3"
343 imgfile="image-u-boot"
344 mtd_write
345 ;;
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500346 ubirw)
347 reqmtd="$2"
348 name="$3"
349 ubi_rw
350 ;;
Adriana Kobylake9939492017-07-11 11:34:23 -0500351 ubiro)
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500352 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
353 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
Adriana Kobylake9939492017-07-11 11:34:23 -0500354 name="$3"
355 version="$4"
356 imgfile="image-rofs"
357 imgsize="16MiB"
358 ubi_ro
Adriana Kobylake9939492017-07-11 11:34:23 -0500359 ubi_updatevol
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500360 ubi_block
Adriana Kobylake9939492017-07-11 11:34:23 -0500361 ;;
362 ubikernel)
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500363 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
364 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
Adriana Kobylake9939492017-07-11 11:34:23 -0500365 name="$3"
366 version="$4"
367 imgfile="image-kernel"
368 imgsize="4MiB"
369 ubi_ro
370 ubi_updatevol
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500371 create_vol_in_alt
Adriana Kobylake9939492017-07-11 11:34:23 -0500372 ;;
Michael Tritza694eed2017-07-13 16:26:15 -0500373 ubiremove)
374 name="$2"
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500375 ubi_remove "${name}"
Michael Tritza694eed2017-07-13 16:26:15 -0500376 ;;
Michael Tritz18781172017-09-21 00:41:15 -0500377 ubicleanup)
378 ubi_cleanup
379 ;;
Michael Tritza694eed2017-07-13 16:26:15 -0500380 ubisetenv)
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500381 ubi_setenv "$2"
Michael Tritza694eed2017-07-13 16:26:15 -0500382 ;;
Saqib Khanbb93e642017-08-10 11:24:38 -0500383 ubiremount)
384 remount_ubi
385 ;;
Saqib Khan7e4a3f22017-09-12 09:23:28 -0500386 createenvbackup)
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500387 backup_env_vars
388 ;;
Saqib Khan7e4a3f22017-09-12 09:23:28 -0500389 updateubootvars)
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500390 version="$2"
391 update_env_vars
392 ;;
Saqib Khandfc9b0c2017-09-08 10:10:08 -0500393 rebootguardenable)
394 rebootguardenable
395 ;;
396 rebootguarddisable)
397 rebootguarddisable
398 ;;
Michael Tritz648655a2017-09-21 00:41:15 -0500399 reset)
400 factory_reset
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