blob: 26b83e664ec556d8bc46bf3f623f8cc376cc51d8 [file] [log] [blame]
Gunnar Millsbde58222018-01-22 18:29:31 -06001#!/bin/bash
2set -eo pipefail
Adriana Kobylaka290eff2017-06-27 09:39:57 -05003
Adriana Kobylak54c9f792017-08-17 14:08:20 -05004# Get the root mtd device number (mtdX) from "/dev/ubiblockX_Y on /"
5findrootmtd() {
6 rootmatch=" on / "
7 m="$(mount | grep "${rootmatch}" | grep "ubiblock")"
8 m="${m##*ubiblock}"
9 m="${m%_*}"
10 if [ -z "${m}" ]; then
11 # default to bmc mtd (0)
12 m=0
13 fi
14 echo "mtd${m}"
15}
16
Adriana Kobylak582bdea2017-08-22 14:51:18 -050017findrootubi() {
18 rootmatch=" on / "
19 m="$(mount | grep "${rootmatch}")"
20 m="${m##*ubiblock}"
21 m="${m% on*}"
22 echo "ubi${m}"
23}
24
Adriana Kobylaka290eff2017-06-27 09:39:57 -050025# Get the mtd device number (mtdX)
26findmtd() {
27 m="$(grep -xl "$1" /sys/class/mtd/*/name)"
28 m="${m%/name}"
29 m="${m##*/}"
30 echo "${m}"
31}
32
Eddie Jamesa804bc42018-02-01 16:46:40 -060033# Get the mtd device number only (return X of mtdX)
34findmtdnum() {
35 m="$(findmtd "$1")"
36 m="${m##mtd}"
37 echo "${m}"
38}
39
Adriana Kobylaka290eff2017-06-27 09:39:57 -050040# Get the ubi device number (ubiX_Y)
41findubi() {
42 u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)"
43 u="${u%/name}"
44 u="${u##*/}"
45 echo "${u}"
46}
47
Adriana Kobylakac5ce002017-09-13 12:59:26 -050048# Get the ubi device number (ubiX_Y) on a specific mtd
Adriana Kobylak582bdea2017-08-22 14:51:18 -050049findubi_onmtd() {
Adriana Kobylakac5ce002017-09-13 12:59:26 -050050 u="$(grep -xl "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
51 u="${u%/name}"
52 u="${u##*/}"
53 echo "${u}"
54}
55
56# Get all ubi device names on a specific mtd that match requested string
57findubiname_onmtd() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -050058 u="$(grep -h "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
59 u="${u%/name}"
60 u="${u##*/}"
61 echo "${u}"
62}
63
Adriana Kobylakac5ce002017-09-13 12:59:26 -050064# Get the name from the requested ubiX_Y volume
65findname() {
66 n="$(cat /sys/class/ubi/$1/name)"
67 echo "${n}"
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
Adriana Kobylakf846e172018-03-06 14:12:03 -0600111 # Update rwfs_size, check imgsize was specified, otherwise it'd clear the var
112 if [ ! -z "$imgsize" ]; then
113 rwsize="$(fw_printenv -n rwfs_size 2>/dev/null)" || true
114 if [[ "${imgsize}" != "${rwsize}" ]]; then
115 fw_setenv rwfs_size "${imgsize}"
116 fi
Adriana Kobylakb7059982018-02-14 16:35:30 -0600117 fi
118
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500119 vol="$(findubi "${name}")"
120 if [ -z "${vol}" ]; then
Adriana Kobylakb7059982018-02-14 16:35:30 -0600121 ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}"
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500122 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
Michael Tritzd8ac7f22018-02-07 17:04:07 -0600143 if [ -z "${imgfile}" ]; then
144 echo "Unable to create read-only volume. Image file not specified."
145 return 1
146 fi
147
148 # Create a ubi volume, dynamically sized to fit BMC image if size unspecified
149 img="/tmp/images/${version}/${imgfile}"
150 imgsize="$(stat -c '%s' ${img})"
151
Adriana Kobylake9939492017-07-11 11:34:23 -0500152 vol="$(findubi "${name}")"
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500153 if [ ! -z "${vol}" ]; then
154 # Allow a duplicate kernel volume on the alt mtd
155 if [[ "${name}" =~ "kernel" ]]; then
Adriana Kobylakac5ce002017-09-13 12:59:26 -0500156 vol="$(findubi_onmtd "${name}" "${ro}")"
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500157 fi
158 fi
Adriana Kobylake9939492017-07-11 11:34:23 -0500159 if [ -z "${vol}" ]; then
160 ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}" --type=static
161 vol="$(findubi "${name}")"
162 fi
163}
164
165# Squashfs images need a ubi block
166ubi_block() {
167 vol="$(findubi "${name}")"
168 ubidevid="${vol#ubi}"
169 block="/dev/ubiblock${ubidevid}"
170 if [ ! -e "$block" ]; then
171 ubiblock --create "/dev/ubi${ubidevid}"
172 fi
173}
174
175ubi_updatevol() {
176 vol="$(findubi "${name}")"
177 ubidevid="${vol#ubi}"
178 img="/tmp/images/${version}/${imgfile}"
179 ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
180}
181
Michael Tritza694eed2017-07-13 16:26:15 -0500182ubi_remove() {
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500183 rmname="$1"
Adriana Kobylakac5ce002017-09-13 12:59:26 -0500184 rmmtd="$2"
185 if [ ! -z "${rmmtd}" ]; then
186 vol="$(findubi_onmtd "${rmname}" "${rmmtd}")"
187 else
188 vol="$(findubi "${rmname}")"
189 fi
Michael Tritza694eed2017-07-13 16:26:15 -0500190
191 if [ ! -z "$vol" ]; then
192 vol="${vol%_*}"
193
Saqib Khanf8d2a662017-09-07 13:57:43 -0500194 if grep -q "$rmname" /proc/mounts; then
195 mountdir=$(grep "$rmname" /proc/mounts | cut -d " " -f 2)
Michael Tritza694eed2017-07-13 16:26:15 -0500196 umount "$mountdir"
197 rm -r "$mountdir"
198 fi
199
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500200 ubirmvol "/dev/${vol}" -N "$rmname"
Michael Tritza694eed2017-07-13 16:26:15 -0500201 fi
202}
203
Michael Tritz18781172017-09-21 00:41:15 -0500204ubi_cleanup() {
205 # When ubi_cleanup is run, it expects one or no active version.
206 activeVersion=$(busctl --list --no-pager tree \
207 xyz.openbmc_project.Software.BMC.Updater | \
208 grep /xyz/openbmc_project/software/ | tail -c 9)
209
210 if [[ -z "$activeVersion" ]]; then
211 vols=$(ubinfo -a | grep -e "kernel-" -e "rofs-" | cut -c 14-)
212 vols=(${vols})
213 else
214 vols=$(ubinfo -a | grep -e "kernel-" -e "rofs-" | \
215 grep -v "$activeVersion" | cut -c 14-)
216 vols=(${vols})
217 fi
218
219 for (( index=0; index<${#vols[@]}; index++ )); do
220 ubi_remove ${vols[index]}
221 done
222}
223
Saqib Khanbb93e642017-08-10 11:24:38 -0500224remount_ubi() {
Saqib Khand6d1c442017-09-06 23:24:40 -0500225 bmcmtd="$(findmtd "bmc")"
226 altbmcmtd="$(findmtd "alt-bmc")"
227 mtds="${bmcmtd: -1}","${altbmcmtd: -1}"
Saqib Khanbb93e642017-08-10 11:24:38 -0500228
229 IFS=',' read -r -a mtds <<< "$mtds"
230 mtds=($(echo "${mtds[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
231 for mtd in ${mtds[@]}; do
Saqib Khanbb93e642017-08-10 11:24:38 -0500232 # Get information on all ubi volumes
233 ubinfo=$(ubinfo -d ${mtd})
234 presentVolumes=${ubinfo##*:}
235 IFS=', ' read -r -a array <<< "$presentVolumes"
236 for element in ${array[@]}; do
237 elementProperties=$(ubinfo -d $mtd -n $element)
238 # Get ubi volume name by getting rid of additional properties
239 name=${elementProperties#*Name:}
240 name="${name%Character*}"
241 name="$(echo -e "${name}" | tr -d '[:space:]')"
242
Adriana Kobylak2c7c8d12017-08-21 11:00:56 -0500243 if [[ ${name} == rofs-* ]]; then
Saqib Khanbb93e642017-08-10 11:24:38 -0500244 mountdir="/media/${name}"
Saqib Khand793f2d2017-09-13 14:05:31 -0500245
246 if [ ! -d ${mountdir} ]; then
247 mkdir -p "${mountdir}"
Gunnar Millsbde58222018-01-22 18:29:31 -0600248 # U-Boot will create the ubiblock for the running version, but not
249 # for the version on the other chip
250 if [ ! -e "/dev/ubiblock${mtd}_${element}" ]; then
251 ubiblock --create /dev/ubi${mtd}_${element}
252 fi
Saqib Khand793f2d2017-09-13 14:05:31 -0500253 mount -t squashfs -o ro "/dev/ubiblock${mtd}_${element}" "${mountdir}"
254 fi
Saqib Khanbb93e642017-08-10 11:24:38 -0500255 fi
256 done
257 done
258}
259
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500260# Read the current env variable and set it on the alternate boot env
261copy_env_var_to_alt() {
262 varName=$1
263 value="$(fw_printenv -n "${varName}")"
264 fw_setenv -c /etc/alt_fw_env.config "${varName}" "${value}"
265}
266
Eddie Jamesa804bc42018-02-01 16:46:40 -0600267# When the alternate bmc chip boots, u-boot thinks its the primary mtdX.
268# Therefore need to swap the chip numbers when copying the ubiblock and root to
269# alternate bmc u-boot environment.
270copy_ubiblock_to_alt() {
271 value="$(fw_printenv -n ubiblock)"
272 bmcNum="$(findmtdnum "bmc")"
273 altNum="$(findmtdnum "alt-bmc")"
274 replaceAlt="${value/${altNum},/${bmcNum},}"
275
276 if [[ "${value}" == "${replaceAlt}" ]]; then
277 replaceBmc="${value/${bmcNum},/${altNum},}"
278 value=${replaceBmc}
279 else
280 value=${replaceAlt}
281 fi
282
283 fw_setenv -c /etc/alt_fw_env.config ubiblock "${value}"
284}
285
286copy_root_to_alt() {
287 value="$(fw_printenv -n root)"
288 bmcNum="$(findmtdnum "bmc")"
289 altNum="$(findmtdnum "alt-bmc")"
290 replaceAlt="${value/${altNum}_/${bmcNum}_}"
291
292 if [[ "${value}" == "${replaceAlt}" ]]; then
293 replaceBmc="${value/${bmcNum}_/${altNum}_}"
294 value=${replaceBmc}
295 else
296 value=${replaceAlt}
297 fi
298
299 fw_setenv -c /etc/alt_fw_env.config root "${value}"
300}
301
Michael Tritza694eed2017-07-13 16:26:15 -0500302ubi_setenv() {
Michael Tritz3e0b0672017-12-15 15:35:14 -0600303 # The U-Boot environment maintains two banks of environment variables.
304 # The banks need to be consistent with each other to ensure that these
305 # variables can reliably be read from file. In order to guarantee that the
306 # banks are both correct, we need to run fw_setenv twice.
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500307 variable=$1
Michael Tritz8863f702017-08-25 15:47:07 -0500308 if [[ "$variable" == *"="* ]]; then
309 varName="${variable%=*}"
310 value="${variable##*=}"
Adriana Kobylakf5ac32c2018-02-09 11:21:57 -0600311 # Write only if var is not set already to the requested value
Adriana Kobylakffd46ba2018-03-02 14:16:43 -0600312 currentValue="$(fw_printenv -n "${varName}" 2>/dev/null)" || true
Adriana Kobylakf5ac32c2018-02-09 11:21:57 -0600313 if [[ "${currenValue}" != "${value}" ]]; then
314 fw_setenv "$varName" "$value"
315 fw_setenv "$varName" "$value"
316 fi
Michael Tritz8863f702017-08-25 15:47:07 -0500317 else
318 fw_setenv "$variable"
Michael Tritz3e0b0672017-12-15 15:35:14 -0600319 fw_setenv "$variable"
Michael Tritz8863f702017-08-25 15:47:07 -0500320 fi
Michael Tritza694eed2017-07-13 16:26:15 -0500321}
322
Adriana Kobylak1fa612c2017-08-17 21:56:14 -0500323mtd_write() {
324 flashmtd="$(findmtd "${reqmtd}")"
325 img="/tmp/images/${version}/${imgfile}"
326 flashcp -v ${img} /dev/${flashmtd}
327}
328
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500329backup_env_vars() {
330 copy_env_var_to_alt kernelname
Eddie Jamesa804bc42018-02-01 16:46:40 -0600331 copy_ubiblock_to_alt
332 copy_root_to_alt
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500333}
334
335update_env_vars() {
336 vol="$(findubi rofs-"${version}")"
337 if [ -z "${vol}" ]; then
338 return 1
339 fi
340 ubidevid="${vol#ubi}"
341 block="/dev/ubiblock${ubidevid}"
342 if [ ! -e "${block}" ]; then
343 return 1
344 fi
345 ubi_setenv "kernelname=kernel-${version}"
346 ubi_setenv "ubiblock=$(echo "${ubidevid}" | sed 's/_/,/')"
347 ubi_setenv "root=${block}"
348}
349
Saqib Khandfc9b0c2017-09-08 10:10:08 -0500350#TODO: Replace the implementation with systemd-inhibitors lock
351# once systemd/systemd#949 is resolved
352rebootguardenable() {
353 dir="/run/systemd/system/"
354 file="reboot-guard.conf"
355 units=("reboot" "poweroff" "halt")
356
357 for unit in "${units[@]}"; do
358 mkdir -p ${dir}${unit}.target.d
359 echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}${unit}.target.d/${file}
360 done
361}
362
363#TODO: Replace the implementation with systemd-inhibitors lock
364# once systemd/systemd#949 is resolved
365rebootguarddisable() {
366 dir="/run/systemd/system/"
367 file="reboot-guard.conf"
368 units=("reboot" "poweroff" "halt")
369
370 for unit in "${units[@]}"; do
371 rm -rf ${dir}${unit}.target.d/${file}
372 done
373}
374
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500375# Create a copy in the alt mtd
376create_vol_in_alt() {
377 alt="alt-bmc"
378 altmtd="$(findmtd "${alt}")"
379 if [ ! -z "${altmtd}" ]; then
380 reqmtd="${alt}"
381 reqmtd2="${alt}"
382 ubi_ro
383 ubi_updatevol
384 fi
385}
386
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500387case "$1" in
Adriana Kobylak1fa612c2017-08-17 21:56:14 -0500388 mtduboot)
389 reqmtd="$2"
390 version="$3"
391 imgfile="image-u-boot"
392 mtd_write
393 ;;
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500394 ubirw)
395 reqmtd="$2"
396 name="$3"
Adriana Kobylakb7059982018-02-14 16:35:30 -0600397 imgsize="$4"
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500398 ubi_rw
399 ;;
Adriana Kobylake9939492017-07-11 11:34:23 -0500400 ubiro)
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500401 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
402 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
Adriana Kobylake9939492017-07-11 11:34:23 -0500403 name="$3"
404 version="$4"
405 imgfile="image-rofs"
Adriana Kobylake9939492017-07-11 11:34:23 -0500406 ubi_ro
Adriana Kobylake9939492017-07-11 11:34:23 -0500407 ubi_updatevol
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500408 ubi_block
Adriana Kobylake9939492017-07-11 11:34:23 -0500409 ;;
410 ubikernel)
Adriana Kobylak54c9f792017-08-17 14:08:20 -0500411 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
412 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
Adriana Kobylake9939492017-07-11 11:34:23 -0500413 name="$3"
414 version="$4"
415 imgfile="image-kernel"
Adriana Kobylake9939492017-07-11 11:34:23 -0500416 ubi_ro
417 ubi_updatevol
Adriana Kobylakddc9dca2017-09-05 15:44:35 -0500418 create_vol_in_alt
Adriana Kobylake9939492017-07-11 11:34:23 -0500419 ;;
Michael Tritza694eed2017-07-13 16:26:15 -0500420 ubiremove)
421 name="$2"
Adriana Kobylak582bdea2017-08-22 14:51:18 -0500422 ubi_remove "${name}"
Michael Tritza694eed2017-07-13 16:26:15 -0500423 ;;
Michael Tritz18781172017-09-21 00:41:15 -0500424 ubicleanup)
425 ubi_cleanup
426 ;;
Michael Tritza694eed2017-07-13 16:26:15 -0500427 ubisetenv)
Adriana Kobylak8cdb82e2017-08-22 14:18:39 -0500428 ubi_setenv "$2"
Michael Tritza694eed2017-07-13 16:26:15 -0500429 ;;
Saqib Khanbb93e642017-08-10 11:24:38 -0500430 ubiremount)
431 remount_ubi
432 ;;
Saqib Khan7e4a3f22017-09-12 09:23:28 -0500433 createenvbackup)
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500434 backup_env_vars
435 ;;
Saqib Khan7e4a3f22017-09-12 09:23:28 -0500436 updateubootvars)
Adriana Kobylake2fd46d2017-09-05 12:38:19 -0500437 version="$2"
438 update_env_vars
439 ;;
Saqib Khandfc9b0c2017-09-08 10:10:08 -0500440 rebootguardenable)
441 rebootguardenable
442 ;;
443 rebootguarddisable)
444 rebootguarddisable
445 ;;
Adriana Kobylaka290eff2017-06-27 09:39:57 -0500446 *)
447 echo "Invalid argument"
448 exit 1
449 ;;
450esac